iOS正弦波生成 – 可听见的点击

我正在为iOS创建合成器。 在玩完并试图学习核心音频之后,我遇到了一个我无法理解的问题。 我的正弦波会定期发出咔哒声,我猜这与相位有关。 我看过几本关于这个主题的指南和书籍,并且都表明我正确地做了。

如果有人愿意为我查看我的代码,我将不胜感激。

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

相位可能在错误的点上溢出

替换这个:

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

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

如果您的频率不是整数值,那么这一行:

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

将调整并旋转相位不等于2pi的量,从而产生不连续性。

针对这些类型问题的一种很好的调试技术是在示波器或波形编辑器中查看音频。 准确查看点击发生的时间和频率通常会提供一些关于点击发生原因的线索。

相同的技术可以用于非“音频”信号的信号,例如包络发生器等。只需确保关闭扬声器!