我想编写一些在我的音调生成器应用程序中生成振荡器波形类型的代码。这个例子中的波是正弦波,有人可以告诉我代码是如何工作的吗,因为我想在将来制作自定义波类型以及方形、锯齿和三角形类型。
OSStatus RenderTone(
void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
// Fixed amplitude is good enough for our purposes
const double amplitude = 0.25;
// Get the tone parameters out of the view controller
ToneGeneratorViewController *viewController =
(ToneGeneratorViewController *)inRefCon;
double theta = viewController->theta;
double theta_increment = 2.0 * M_PI * viewController->frequency / viewController->sampleRate;
// This is a mono tone generator so we only need the first buffer
const int channel = 0;
Float32 *buffer = (Float32 *)ioData->mBuffers[channel].mData;
// Generate the samples
for (UInt32 frame = 0; frame < inNumberFrames; frame++)
{
buffer[frame] = sin(theta) * amplitude;
theta += theta_increment;
if (theta > 2.0 * M_PI)
{
theta -= 2.0 * M_PI;
}
}
// Store the theta back in the view controller
viewController->theta = theta;
return noErr;
}
最佳答案
正在生成实际的正弦波样本并填充下面代码片段中的缓冲区
for (UInt32 frame = 0; frame < inNumberFrames; frame++)
{
buffer[frame] = sin(theta) * amplitude;
theta += theta_increment;
if (theta > 2.0 * M_PI)
{
theta -= 2.0 * M_PI;
}
}
在分配 buffer[frame]
的行中,您正在调用 sin(theta) *amplitude
,并且对于 for< 的每次迭代
循环,您将根据频率和采样率将 theta
增加一些有限的步长,通过
double theta_increment = 2.0 * M_PI * viewController->frequency / viewController->sampleRate;
这本质上是将 2.0 * PI * 频率
除以采样率。
在循环 for
循环时增加 theta
变量基本上是一次推进一个样本的时间步,直到缓冲区已满(即 frame = = iNumberFrames
)。
如果您想生成除正弦波之外的其他波形,只需将以下行替换为其他函数即可:
buffer[frame] = sin(theta) * amplitude;
即举例来说,您想要收敛为三角波的无限傅立叶级数中的前三项;然后你可能会得到以下内容......
buffer[frame] = (8 / pow(M_PI,2)) * (sin(theta) - sin(3*theta)/9 + sin(5*theta)/25);
关于objective-c - 制定振荡器波形代码并创建新的波形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9198436/