views:

855

answers:

2

Hi,

here's my problem at hand:

  1. I need to analyze audio data in realtime to find out the amplitude of the signal
  2. I can't use the AudioQueue metering functionality because it has too much delay for detecting peaks
  3. I have studied the aurioTouch example..... however...

I simply don't understand how the PCM coded buffer is converted back to the waveform displayed in the oscilloscope view. It would be exactly this wavefore I want to analyze for amplitude.

In my callback when I analyze the buffer it only has 0 and -1 in it - when using NSLog(@"%d"). This makes sense I guess because it is PCM.

I can't find the place in aurioTouch where the magic of transforming the 0 / -1 stream into a waveform happens :-((

Also once I have the waveform in memory how do I analyze the amplitude and how to convert this reading into dB?

I don't want to use FFT because I am not interested in the frequency and I hope there are other ways.

Cheers

Mat

A: 

AurioTouch is the right example to look at. Unfortunately the code is just terrible. Make sure that you only use it to get to know the concepts behind working with the RemoteIO audio unit.

The actual drawing of the waveform is happening right in the renderProc callback which is called by CoreAudio when PCM data becomes available. Look at PerformThru() in aurioTouchAppDelegate.mm:197... further down, in line 237

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

... that's where the actual PCM data is accessed. This is the data you would need to analyze in order to get peak/average power of the signal.

VoidPointer
I thought this would be the right place, but I also thought it looks too simple.....Thank you for the input!
Matthias Schorer
+2  A: 

Once you have a chunk of the waveform in memory then it's fairly easy to calculate magnitude values in dB (although you'll need to decide what you reference magnitude for 0 dB is). Typically if you want the kind of short term magnitude that you might see displayed on a VU meter then you need to rectify the instantaneous values of the waveform (you can use abs for this) and then pass these rectified values through a simple low pass filter with a time constant of the order of, say, 100 ms. To convert the values to dB you'll do this:

amplitude_dB = 20 * log10(amplitude) + calibration_dB;

where amplitude is the rectified and filtered magnitude, and calibration_dB is an offset to give you the correct amplitude for 0 dB, whatever that might be in your particular application (e.g. dB re full scale, or a calibrated dBV or dBm value).

A simple but effective low pass filter can be implemented as follows. This will be a single pole IIR (recursive) filter. Each output is dependent on the previous output value and the current input value. We have a constant factor, alpha, which effectively determines the time constant or cut-off frequency of this low pass filter.

y = alpha * x + (1.0 - alpha) * y_old;
y_old = y;
  • x = current input value
  • y = new output value
  • y_old = previous output value
  • alpha = constant which determines response of filter - a small positive number - try 0.001 to start off with and experiment
Paul R
I am not an expert in DSP, so I would be grateful if you could post the code for a low pass filter.Mat
Matthias Schorer
I have now added a simple low-pass filter implementation to the answer .
Paul R
Thanks A LOT that gets me started. I have meanwhile also successfully extracted the data from the rioBuffer :-))
Matthias Schorer
Just a question for understanding. I know LP Filters from the various synthesizers I own. A 1 pole filter means 6dB/Oct and a 4 pole filter would have 24 dB/Oct. When I understand above filter correctly I would have to run my data through it to four times get 24dB/Oct - or not?!
Matthias Schorer
Just to clarify - what we're filtering here is the _rectified_ signal, in order to get a smoothed estimate of the signal magnitude over a short time interval, so the response of the low pass filter is not particularly important. But in a general context, yes, if you cascade N identical filters with 6 dB/octave roll-off you will get 6N dB/octave.
Paul R