IOS Sine Wave Generation - Sound Click

I am making a synthesizer for iOS. After playing around and trying to learn the basic sound, I ran into a problem that I can't get my head down. My sine wave is hitting at regular intervals and I think it has to do with phase. I have looked through several tutorials and books on this subject and everyone says that I am doing it right.

If anyone would be kind enough to look at my code for me, we would be very grateful.

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;
}

      

+3


source to share


3 answers


Phase may overflow at the wrong point

Replace this:

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

      



from

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

      

+5


source


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, which leads to a break.

+2


source


A great debugging technique for these types of problems is to look at your sound in an oscilloscope or wave editor. By seeing exactly when and how often a click occurs, there are usually several clues as to why the click occurs.

The same technique can be used with signals that are not "audio" signals such as envelope generators, etc. Just make sure you reject the speakers!

+1


source







All Articles