开发者

How to prevent popping sound when generating iPhone audio with remoteIO?

开发者 https://www.devze.com 2023-01-30 14:29 出处:网络
So, a little while back I was working on a wave generator app and having some problems, but Kenny Winker was a real lifesaver and helped me to basically get everything going. One problem I ended up wi

So, a little while back I was working on a wave generator app and having some problems, but Kenny Winker was a real lifesaver and helped me to basically get everything going. One problem I ended up with, however, is the fact that whenever I change the value of the frequency I'm using (and to a much lesser extent when I change the value of the volume), I end up with these ugly crackly "popping" noises. This is a problem as the whole point is to be able to smoothly alter the frequency and volume of a wave with a slider, and what sounds like crumpling paper can really ruin that effect. Here is the code of my OSStatus that controls volume/frequency.

OSStatus playbackCallback(void *inRefCon,
                      AudioUnitRenderActionFlags *ioActionFlags,
              开发者_Python百科        const AudioTimeStamp *inTimeStamp,
                      UInt32 inBusNumber, 
                      UInt32 inNumberFrames,
                      AudioBufferList *ioData) {    

SlidersViewController *me = (SlidersViewController *)inRefCon;

static int phase = 1;

for(UInt32 i = 0; i < ioData->mNumberBuffers; i++) {

    int samples = ioData->mBuffers[i].mDataByteSize / sizeof(SInt16);

    SInt16 values[samples];

    float waves;


    for(int j = 0; j < samples; j++) {


        waves = 0;



        waves += sin(kWaveform * me.fr1 * phase)*(me.vol1);
        waves += sin(kWaveform * me.fr2 * phase)*(me.vol2);
        waves += sin(kWaveform * me.fr3 * phase)*(me.vol3);
        waves *= sin(kWaveform * (me.fr4/100) * phase)*(me.vol4);   
        waves *= 32500 / 4;

        values[j] = (SInt16)waves;
        values[j] += values[j]<<16;

        phase++;


    }

    memcpy(ioData->mBuffers[i].mData, values, samples * sizeof(SInt16));

}

return noErr;}

As you might see, the obj-c variables "fr1"-"fr4" control frequency, while "vol1" to "vol4" control amplitude. These values are updated every time

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {}

or

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {}

is triggered. Any ideas on how to fix this to make it sound smoother? Thanks!


You are multiplying in your inner loop to calculate phase. Any change in the frequency multiplier and you get a potential big jump in phase, and thus a "pop".

Instead of multiplying, add the delta-phase in your inner loop. Since the delta-phase will only change by a small amount, so will the phase, and there will be much smaller discontinuities.

deltaPhase = 2.0 * pi * yourFrequency / sampleRate ;


My guess is that you're just changing the wave parameters without smoothly interpolating between the two values, thus your waveform gets broken and sounds "staticky".

Change your wave generation function so that it interpolates between the old value (at the beginning of the frame) and the new value (at the end of the frame).


I think the following post will solve your question:

http://cocoawithlove.com/2010/10/ios-tone-generator-introduction-to.html

0

精彩评论

暂无评论...
验证码 换一张
取 消