iPhone - как измерить амплитуду кодированного сигнала PCM - PullRequest
8 голосов
/ 30 января 2010

вот моя проблема под рукой:

  1. Мне нужно анализировать аудиоданные в режиме реального времени, чтобы узнать амплитуду сигнала
  2. Я не могу использовать функцию измерения AudioQueue, потому что у нее слишком большая задержка для обнаружения пиков
  3. Я изучил пример aurioTouch ..... однако ...

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

В моем обратном вызове, когда я анализирую буфер, он содержит только 0 и -1 - при использовании NSLog (@ "% d"). Это имеет смысл, я думаю, потому что это PCM.

Я не могу найти место в aurioTouch, где происходит волшебство преобразования потока 0 / -1 в форму волны: - ((

Кроме того, когда у меня есть сигнал в памяти, как мне проанализировать амплитуду и как преобразовать это значение в дБ?

Я не хочу использовать БПФ, потому что меня не интересует частота, и я надеюсь, что есть другие способы.

Приветствия

Mat

Ответы [ 2 ]

10 голосов
/ 30 января 2010

Если у вас есть часть формы волны в памяти, тогда довольно легко вычислить значения амплитуды в дБ (хотя вам нужно будет решить, на какую опорную величину вы указываете 0 дБ). Как правило, если вы хотите, чтобы кратковременная величина отображалась на измерителе VU, вам необходимо исправить мгновенные значения формы сигнала (для этого можно использовать abs), а затем пропустить эти выпрямленные значения с помощью простого фильтра нижних частот. с постоянной времени порядка, скажем, 100 мс. Чтобы преобразовать значения в дБ, вы сделаете это:

amplitude_dB = 20 * log10(amplitude) + calibration_dB;

где амплитуда - это выпрямленная и отфильтрованная амплитуда, а калибровка_дБ - это смещение, чтобы дать вам правильную амплитуду для 0 дБ, независимо от того, что может быть в вашем конкретном приложении (например, дБ для полной шкалы или калиброванное значение дБВ или дБм) .

Простой, но эффективный фильтр нижних частот может быть реализован следующим образом. Это будет однополюсный БИХ (рекурсивный) фильтр. Каждый выход зависит от предыдущего выходного значения и текущего входного значения. У нас есть постоянный коэффициент, альфа, который эффективно определяет постоянную времени или частоту среза этого фильтра нижних частот.

y = alpha * x + (1.0 - alpha) * y_old;
y_old = y;
  • x = текущее значение ввода
  • y = новое выходное значение
  • y_old = предыдущее выходное значение
  • alpha = константа, которая определяет отклик фильтра - небольшое положительное число - попробуйте начать с 0,001 и поэкспериментируйте
1 голос
/ 30 января 2010

AurioTouch - правильный пример для просмотра. К сожалению, код просто ужасен. Убедитесь, что вы используете его только для ознакомления с принципами работы с аудиоустройством RemoteIO.

Фактическое рисование формы волны происходит прямо в обратном вызове renderProc, который вызывается CoreAudio, когда становятся доступными данные PCM. Посмотрите на PerformThru () в aurioTouchAppDelegate.mm:197 ... дальше вниз, в строке 237

SInt8 *data_ptr = (SInt8 *)(ioData->mBuffers[0].mData);

... вот где доступны фактические данные PCM. Это данные, которые вам необходимо проанализировать, чтобы получить пиковую / среднюю мощность сигнала.

...