iOS sine wave generation - audible clicking

喜夏-厌秋 提交于 2019-12-10 21:47:05

问题


I am in the process of creating a synthesiser for iOS. After playing around and attempting to learn core audio, I have encountered a problem that I cannot get my head around. My sine wave makes a clicking noise on regular intervals, which Im guessing is related to the phase. I have looked at several guides and books on the subject, and all suggest that I am doing it correctly.

If anybody would be so kind to look at my code for me it would be greatly appreciated.

static OSStatus renderInput(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
{


    // Get a reference to the object that was passed with the callback
    // In this case, the AudioController passed itself so
    // that you can access its data.
    AudioController *THIS = (AudioController*)inRefCon;

    // Get a pointer to the dataBuffer of the AudioBufferList
    AudioSampleType *outA = (AudioSampleType *)ioData->mBuffers[0].mData;

    float freq = THIS->Frequency;   
    float phase = THIS->sinPhase;

    float envValue;
    float sinSignal;

    // The amount the phase changes in  single sample
    double phaseIncrement = 2 * M_PI * freq / kGraphSampleRate;

    // Loop through the callback buffer, generating samples
    for (UInt32 i = 0; i < inNumberFrames; ++i) {       

        sinSignal = sin(phase);

        envValue = THIS->env.tick();

        // Put the sample into the buffer
        // Scale the -1 to 1 values float to
        // -32767 to 32767 and then cast to an integer
        outA[i] = (SInt16)(((sinSignal * 32767.0f) / 2) * envValue);

        phase = phase + phaseIncrement;

        if (phase >= (2 * M_PI * freq)) {
            phase = phase - (2 * M_PI * freq);
        }
    }

    // Store the phase for the next callback.
    THIS->sinPhase = phase;

    return noErr;
}

回答1:


The phase can overflow on wrong point

Replace this:

if (phase >= (2 * M_PI * freq)) {
    phase = phase - (2 * M_PI * freq); 
} 

with

if (phase >= (2 * M_PI)) { 
    phase = phase - (2 * M_PI); 
} 



回答2:


If your frequency is not exactly an integer value, then this line:

phase = phase - (2 * M_PI * freq);

will adjust and rotate the phase by an amount not equal to 2pi, thus producing a discontinuity.




回答3:


A great debugging technique for these types of problems is to look at your audio in an oscilloscope or wave editor. Seeing exactly when and how often a click occurs will usually provide a few clues as to why the click is happening.

The same technique can be used with signals that aren't 'audio' signals such as envelope generators etc. Just make sure you turn down your speakers!



来源:https://stackoverflow.com/questions/10000552/ios-sine-wave-generation-audible-clicking

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!