Generación de onda sinusoidal de iOS: clic audible

Estoy en el process de crear un sintetizador para iOS. Después de jugar y tratar de aprender audio básico, he encontrado un problema que no puedo evitar. Mi onda sinusoidal hace un ruido de clic en intervalos regulares, lo que supongo que está relacionado con la fase. He mirado varias guías y libros sobre el tema, y ​​todos sugieren que lo estoy haciendo correctamente.

Si alguien sería tan amable de ver mi código para mí, sería muy apreciado.

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

    La fase puede desbordarse en el punto incorrecto.

    Reemplace esto:

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

    con

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

    Si su frecuencia no es exactamente un valor integer, entonces esta línea:

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

    ajustará y rotará la fase en una cantidad no igual a 2pi, produciendo así una discontinuidad.

    Una gran técnica de debugging para este tipo de problemas es mirar su audio en un osciloscopio o un editor de ondas. Ver exactamente cuándo y con qué frecuencia ocurre un clic generalmente proporcionará algunas pistas sobre por qué ocurre el clic.

    La misma técnica se puede usar con señales que no son señales de "audio", como generadores de sobres, etc. ¡Solo asegúrese de bajar los altavoces!