Как сделать так, чтобы индикатор уровня звука при записи и воспроизведении на iPhone выглядел одинаково? - PullRequest
1 голос
/ 04 марта 2011

Я отображаю измеритель уровня звука для записи и воспроизведения этой записи.Значения уровня от 0 до 1,0.Я рисую полосу, представляющую значение 0 - 1.0 на экране.Чтобы получить уровни звука для записи, я использую:

OSStatus status = AudioQueueGetProperty(aqData.mQueue, kAudioQueueProperty_CurrentLevelMeter, aqLevelMeterState, &levelMeterStateDataSize);

float level = aqLevelMeterState[0].mAveragePower;

Для воспроизведения я использую:

// soundPlayer is an AVSoundPlayer
float level = [soundPlayer averagePowerForChannel:0];

Я нормализую уровень от 0 до 1,0.

Прямо сейчас они выглядят очень по-разному, показывая бар.Шкала индикатора записи находится на нижнем уровне, а индикатор воспроизведения, при воспроизведении того же записанного звука, остается посередине.

Я пытаюсь заставить эти два метра выглядеть одинаково, но я довольно плохо знаком с аудио.Я провел небольшое исследование и знаю, что запись возвращает значение RMS, а воспроизведение возвращает его в децибелах.

Может ли кто-нибудь, кто разбирается в аудио, указать мне на ссылки или документы или дать небольшую подсказку, чтобы разобраться в этих двух значениях, чтобы я мог заставить их выглядеть одинаково?

Ответы [ 2 ]

1 голос
/ 05 марта 2011

Децибелы логарифмически масштабируются. Таким образом, вы, вероятно, хотите некоторое уравнение, такое как:

myDb = 20.0 * log (myRMS / scaleFactor);

где-нибудь, где вам нужно будет откалибровать scaleFactor, чтобы соответствовать значениям, которые вы хотите получить для полной шкалы.

1 голос
/ 04 марта 2011

Это среднеквадратическое значение или среднеквадратичное значение для данного интервала таймера. Среднеквадратическое значение вычисляется путем суммирования квадрата каждого значения сигнала для общего значения, деления на число выборок для получения среднего значения и последующего взятия квадратного корня из среднего значения.

     uint64 avgTotal;
    for(int i =0; i < sampleCount; i++)
       avgTotal+= (sample[i]*sample[i])/(uint64)sampleCount; //divide to help with overlfow

    float rms = sqrt(avgTotal);

Вы должны понимать, какие данные вы воспроизводите, чтобы получить значения сигналов. Время, которое вы считаете, не должно иметь большого значения. 50-80мс должно это сделать.

...