ios audio queue - как измерить уровень звука в буфере?

Я работаю над приложением, которое должно обрабатывать аудиосигнал. Мне нужно измерить уровень звука в каждом из получаемых буферов (с помощью функции обратного вызова). Некоторое время я искал в Интернете и обнаружил, что есть встроенное свойство под названием Current level metering:

AudioQueueGetProperty(recordState->queue,kAudioQueueProperty_CurrentLevelMeter,meters,&dlen);

Это свойство дает мне средний или пиковый уровень звука, но он не синхронизируется с текущим буфером. Я понял, что мне нужно самому рассчитать уровень звука из данных буфера, поэтому у меня было следующее:

double calcAudioRMS (SInt16 * audioData, int numOfSamples)
{
double RMS, adPercent;
RMS = 0;

for (int i=0; i<numOfSamples; i++)
{
    adPercent=audioData[i]/32768.0f;
    RMS += adPercent*adPercent;
}
RMS = sqrt(RMS / numOfSamples);
return RMS;
}

Эта функция получает аудиоданные (записанные в Sint16) и количество отсчетов в текущем буфере. Цифры, которые я получаю, действительно находятся между 0 и 1, но они кажутся довольно случайными и низкими по сравнению с числами, которые я получил от встроенного измерителя уровня звука.

Формат аудио записи:

format->mSampleRate = 8000.0;
format->mFormatID = kAudioFormatLinearPCM; 
format->mFramesPerPacket = 1;
format->mChannelsPerFrame = 1;
format->mBytesPerFrame = 2;
format->mBytesPerPacket = 2;
format->mBitsPerChannel = 16;
format->mReserved = 0;
format->mFormatFlags = kLinearPCMFormatFlagIsSignedInteger |kLinearPCMFormatFlagIsPacked;

У меня вопрос, как получить правильные значения из буфера? Есть ли для этого встроенная функция \ свойство? Или я должен сам рассчитать уровень звука, и как это сделать?

Заранее спасибо.


person Gal Malka    schedule 14.01.2013    source источник
comment
вы можете поделиться исходным кодом?   -  person iosMentalist    schedule 09.09.2016


Ответы (1)


Ваш расчет среднеквадратичной мощности верен. Я был бы склонен сказать, что у вас меньше образцов, чем у Apple, или что-то подобное, и это объяснит разницу. Вы можете проверить это, введя громкую синусоиду и проверив, что Apple (и вы) вычислили среднеквадратичную мощность как 1 / sqrt (2).

Если нет веской причины, я бы использовал расчеты мощности Apple. Я их использовал, и они мне кажутся хорошими. Кроме того, обычно вам не нужна RMS-мощность, вам нужна RMS-мощность в децибелах или используйте константу kAudioQueueProperty_CurrentLevelMeterDB. (Это зависит от того, пытаетесь ли вы построить измеритель звука или действительно отображаете мощность звука)

person jfaller    schedule 14.01.2013
comment
Спасибо jfaller. Я попробовал громкую чистую синусоиду и установил Apple CurrentLevelMeter на 1, а мой - на 0,70. Что мы об этом думаем? - person Gal Malka; 14.01.2013
comment
Apple исправляет 1 / sqrt (2). Попробуйте умножить свои результаты на sqrt (2), и они согласятся с результатами Apple. - person jfaller; 26.01.2013