OSStatus MusicPlayerCallback (
void * inRefCon,
AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData) {
MusicPlaybackState *musicPlaybackState = (MusicPlaybackState*) inRefCon;
double sampleinp;
double A,omega,sn,cs,alpha,Bandwidth;
double dbGain;
double a0,a1,a2,b0,b1,b2;
dbGain = 1.0;
A=pow(10.0,dbGain/40.0);
Bandwidth = 2.0;
omega=2 * M_PI * 800.0/44100.0;
sn=sin(omega);
cs=cos(omega);
alpha=sn*sinh(((M_LN2/2)*Bandwidth*omega)/sn);
//Peak Filter Biquad
b0 =1.0 + alpha * A;
b1 = (-2.0 * cs);
b2 = 1.0 - alpha * A;
a0 = 1.0 + (alpha /A);
a1 = -2.0 * cs;
a2 = 1.0 - (alpha /A);
double b0a0, b1a0, b2a0, a1a0, a2a0;
double static x1;
double static x2;
double static y1;
double static y2;
b0a0=b0/a0;
b1a0=b1/a0;
b2a0=b2/a0;
a1a0=a1/a0;
a2a0=a2/a0;
for (int i = 0 ; i < ioData->mNumberBuffers; i++){
AudioBuffer buffer = ioData->mBuffers[i];
AudioSampleType *outSample = buffer.mData;
for (int j = 0; j < inNumberFrames*2; j++){
sampleinp = *musicPlaybackState->samplePtr++;
outSample[j] = b0a0 * sampleinp +
b1a0 * x1 +
b2a0 * x2 -
a1a0 * y1 -
a2a0 * y2;
x2=x1;
x1=sampleinp;
y2=y1;
y1=outSample[j];
}}
return noErr;
}
Having Clicks/pop problems. Someone PLEASE HELP... I don't know what I'm doing wrong. This is in Xcode using C in Objective-C. I tried making the Coeff Global and Static but no luck. The Audio file using is a .caf I tried .wav but still no good....
Thanks, sorry for the general cry for help. I'm new to this site.. I'm trying to add an Peak filter in my app but everytime I use a slider or just leave the gain at 1 I get pops and clicks. It seems as everthing is there and working properly as far as holding the previous samples etc. I also get some type of phase when changing the frequency or the bandwidth. I'm so confused been studying dsp for a few months now, I think it's something with Objective-C and a lil user error. It seem to go away when changing the sample to a SInt32 but the left channel disappears when changing freq.
Dsp.h
typedef struct {
void* audioData;
UInt32 audioDataByteCount;
SInt16 *samplePtr;
} MusicPlaybackState;
Pops and clicks are unwanted audio artifacts caused by the powering up and down of components within the audio subsystem. This is noticeable on PCs when an audio module is either loaded or unloaded (at module load time the sound card is powered up and causes a popping noise on the speakers).
As per hotpaw2's answer, here's the plot of your filter's response:
from pylab import *
import scipy.signal as signal
def biquad_peak(omega, gain_db, bandwidth):
sn = sin(omega)
cs = cos(omega)
alpha = sn * sinh(log(2) / 2 * bandwidth * omega / sn)
gain_sqrt = 10.0 ** (gain_db / 40.0)
# feed-forward coefficients
b0 = 1.0 + alpha * gain_sqrt
b1 = -2.0 * cs
b2 = 1.0 - alpha * gain_sqrt
# feedback coefficients
a0 = 1.0 + (alpha / gain_sqrt)
a1 = -2.0 * cs
a2 = 1.0 - (alpha / gain_sqrt)
# normalize by a0
B = array([b0, b1, b2]) / a0
A = array([a0, a1, a2]) / a0
return B, A
omega = 2 * pi * 800.0 / 44100.0
gain_db = 1.0
bandwidth = 2.0
B, A = biquad_peak(omega, gain_db, bandwidth)
w, H = signal.freqz(B, A)
f = w / pi * 22050.0
plot(f, abs(H), 'r')
gain = 10.0 ** (gain_db / 20.0)
print "Gain:", gain
plot(f, gain*ones(len(f)), 'b--'); grid()
The peak gain is set to 1.1220184543 (i.e. 1 dB). You can see how the filter causes most of the audible range to have a gain greater than 1.
Edit 2: If this is for an adjustable EQ, then it's up to the user to set the gain that avoids distortion. Plus I doubt the extreme problem you describe would be caused by a mild gain of 1 dB over a narrow band for a typical audio track. I think instead it's because your audio has interleaved stereo data. Each of these channels needs to be filtered separately. I've taken a crack at modifying your nested loop to accomplish this:
a0 = 1.0 + alpha / A;
a1 = -2.0 * cs / a0;
a2 = (1.0 - alpha / A) / a0;
b0 = (1.0 + alpha * A) / a0;
b1 = -2.0 * cs / a0;
b2 = (1.0 - alpha * A) / a0;
double static x11, x12, x21, x22;
double static y11, y12, y21, y22;
double x0, y0;
for (int i = 0; i < ioData->mNumberBuffers; i++) {
AudioBuffer buffer = ioData->mBuffers[i];
AudioSampleType *outSample = buffer.mData;
for (int j = 0; j < inNumberFrames*2; j++) {
/* x0 is in the range of SInt16: -32768 to 32767 */
x0 = *musicPlaybackState->samplePtr++;
y0 = b0 * x0 +
b1 * x11 +
b2 * x12 -
a1 * y11 -
a2 * y12;
outSample[j] = fmax(fmin(y0, 32767.0), -32768.0);
x12 = x11;
x11 = x0;
y12 = y11;
y11 = y0
j++;
x0 = *musicPlaybackState->samplePtr++;
y0 = b0 * x0 +
b1 * x21 +
b2 * x22 -
a1 * y21 -
a2 * y22;
outSample[j] = fmax(fmin(y0, 32767.0), -32768.0);
x22 = x21;
x21 = x0;
y22 = y21;
y21 = y0;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With