制定振荡器波型代码,并创建新的波型
Posted
技术标签:
【中文标题】制定振荡器波型代码,并创建新的波型【英文标题】:Working out Oscillator wave type code, and creating new wave types 【发布时间】:2012-02-08 17:31:16 【问题描述】:我想编写一些代码,在我的音调发生器应用程序中生成振荡器波类型。这个例子中的一个是正弦波,有人可以告诉我代码是如何工作的,因为我想在未来制作自定义波类型和方形、锯齿形和三角形类型。
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;
【问题讨论】:
您的问题具体是什么? 我想知道“生成样本”是如何工作的。以及如何修改它以产生不同的波浪,如锯齿、三角形和方形。 【参考方案1】:正在生成实际的正弦波样本并填充下面 sn-p 中的缓冲区
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 * frequency
除以您的采样率。
在循环通过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);
【讨论】:
有没有一种方法可以根据对波类型的了解来创建新频率。 我不太确定你在这里问什么——你的意思是正弦频率的反馈控制吗?如果是这样,那将在很大程度上取决于您的软件(和硬件)实现的其余部分......否则,信号的频率看起来是由您的ToneGeneratorViewController
的frequency
成员变量决定的。我会开始寻找那里,看看是否有一个设置器可以用来在运行时操纵该值。
对不起,我的意思是:有没有一种方法可以根据波浪类型的外观来创建新的波浪类型。所以我可以看到一个三角波然后了解如何创建一个。
是的,你可以定义一个WaveformStrategy
,它本质上是一种策略设计模式。然后,您可以将ToneGeneratorViewController
(或您用来维持采样器状态的任何结构)传递给特定的具体WaveformStrategy
实例(即SinusoidalWaveformStrategy
或SawtoothWaveformStrategy
并传递适当的时间步或omega进入computeSample()
方法并使用结果值填充buffer[frame]
)。
好的,我不知道我是否完全理解这一切,但我会继续努力,因为知识现在就在那里,谢谢。当我获得足够的代表时,我也会竖起大拇指。【参考方案2】:
要产生所需的波形,您需要将 sin() 函数替换为产生所需波形的函数。
您可能可以在带有图形示例的函数表中找到此函数,或者您可能必须创建自己的函数。创建函数逼近的方法有很多,包括多项式、傅里叶级数、带或不带插值的表查找、递归等。但这本身就是一个大主题(许多教科书等)
【讨论】:
以上是关于制定振荡器波型代码,并创建新的波型的主要内容,如果未能解决你的问题,请参考以下文章
肌电信号脉搏信号分析(去噪+特征提取)matlab源码含GUI
肌电信号脉搏信号分析(去噪+特征提取)matlab 源码含GUI
肌电信号脉搏信号分析(去噪+特征提取)matlab源码含GUI