У меня возникает очень своеобразная проблема с обратными вызовами аудио в моем приложении для Android (использующем NDK/OpenSL ES). Я вывожу потоковое аудио с частотой 44,1 кГц и 512 кадрами (что дает мне время обратного вызова 11,6 мс). В обратном вызове я синтезирую пару сигналов, фильтров и т. д. (как синтезатор). Из-за оптимизации я никогда не превышаю 5 мс времени обратного вызова. Однако, когда я включаю определенный эффект (цифровую линию задержки), обратный вызов начинает занимать значительно больше времени. Цифровая линия задержки подскочит с 7,5 мс (после обработки всех голосов/фильтров) до 100–350 мс.
Это самая запутанная часть; примерно через 1 или 2 секунды время выполнения цифровой задержки подскочит с очень высокого значения до времени завершения 0,2 мс для каждого обратного вызова.
Почему Android-приложению потребовалось много времени, чтобы завершить мой код обработки цифровой задержки для первых нескольких обратных вызовов, а затем утихнуть до очень короткого и приятного для звука времени? Я сейчас немного в растерянности и не знаю, как это исправить. Чтобы подтвердить, это происходит только с методом обработки задержки. Это просто стандартная цифровая линия задержки (вы можете найти ее на github), и я чувствую, что алгоритм здесь не проблема...
Что-то вроде псевдокода/грубого наброска того, как выглядит мой аудио код обратного вызова:
static bool myAudioCallback(void *userData, short int *audIO, int numSamples, int srate) {
AudioData *data = (AudioData *)userData;
// Resets pointer array values to 0
for (int i = 0; i < numSamples; i++) data->buffer[i] = 0;
// Voice Generation Block
for (int voice = 0; voice < data->numVoices; voice++) {
// Reset voice buffers:
for (int i = 0; i < numSamples; i++) data->voiceBuffer[i] = 0;
// Generate Voice
data->voiceManager[voice]->generateVoiceBlock(data->voiceBuffer, numSamples);
// Sum voices
for (int i = 0; i < numSamples; i++) data->buffer[i] += data->voiceBuffer[i]];
}
// When app first starts, delayEnabled = false so user must click on a
// button on the UI to enable it.
// Trouble is that when we enable processDelay(double *buffer, in frames) the
// first time, we get a long execution time.
if (data->delayEnabled) {
data->delay->processDelay(data->buffer, numSamples);
}
// Conversion loop
for (int i = 0; i < numSamples; i++) {
double sample = clipOutput(data->buffer[i]);
audIO[2*i] = audIO[(2*i)+1] = CONV_FLT_TO_16BIT(sample * data->volume);
}
}
Спасибо!