I would use a Biquad filter, or possibly more than one in a chain to get a
sharper rolloff, see:
Paul Sanders.
----- Original Message -----
Sent: Saturday, September 08, 2012 3:10 PM
Subject: low pass filter inside callback
I have an app where I am trying to do some visualisation that
responds to the lower frequencies of audio being played.
My setup is:
AUGraph with remoteIO either side
ASBD = 16bit LPCM
The audio is all working fine, I have an avassetreader pulling data from
the ipod library into a ring buffer and my callback is pushing that buffer into
ioData and it's all playing without issue.
I have managed to get some db readings going using vsdp, based on the
novocaine sample code. Currently this is where i am at:
I have a scratch buffer that get's populated using the following code which
converts from my 16bit ints to floats
vDSP_vflt16(ioData->mBuffers[0].mData, 1, audioObject->scratchBuffer,
1, inNumberFrames);
I am then using the following code to get some db readings out and put them
into a location that i can get to from my ui code.
vDSP_vsq(audioObject->scratchBuffer, 1,
audioObject->scratchBuffer, 1, inNumberFrames*2); float meanVal =
0.0; vDSP_meanv(audioObject->scratchBuffer, 1, &meanVal,
inNumberFrames*2); float _one_ =
1.0; vDSP_vdbcon(&meanVal, 1, &one, &meanVal, 1, 1,
0); audioObject->decibels = audioObject->decibels + 0.2*(meanVal -
audioObject->decibels);
What I am hoping to do is to get the decibels to only be sensitive to the
lower frequencies (bass) so i can do some visualisations. What I mean by
sensitive is to only see the db value increase when a lower frequency is
present. I have looked through piles of fft/vdsp code and read a heap of stuff,
pretty much everything I can find, but doing fft may be a little bit too complex
for what i am after.
I think that essentially what i want to do is put a low pass filter on the
scratch buffer before getting the db reading and that should give me what I am
after.
Something like this:
#define FILTERFACTOR 0.1
Value = (newAcceleration * FILTERFACTOR) + (previousValue *
(1.0 – FILTERFACTOR));
previousValue = value;
In order to implement this, my code looks like this currently:
#define FILTERFACTOR
0.1
float filteredSampleAmplitude,
previousSampleAmplitude;
for (int i=0; i <
inNumberFrames; i++) { float
sampleAmplitude = abs(audioObject->scratchBuffer[i]);
filteredSampleAmplitude = FILTERFACTOR * sampleAmplitude +
(1.0 - FILTERFACTOR) * previousSampleAmplitude;
previousSampleAmplitude = filteredSampleAmplitude;
audioObject->scratchBuffer[i] =
filteredSampleAmplitude; }
While I am still getting some readings out of this but not the contrast i
am after and based on everything I've read about the accelerate framework I'm
not sure if this is the most efficient way to process the samples in a
callback.
Does anyone have any other ideas to do what I am looking for?
Cheers,
Ash
|