制定振荡器波型代码,并创建新的波型

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

【讨论】:

有没有一种方法可以根据对波类型的了解来创建新频率。 我不太确定你在这里问什么——你的意思是正弦频率的反馈控制吗?如果是这样,那将在很大程度上取决于您的软件(和硬件)实现的其余部分......否则,信号的频率看起来是由您的ToneGeneratorViewControllerfrequency 成员变量决定的。我会开始寻找那里,看看是否有一个设置器可以用来在运行时操纵该值。 对不起,我的意思是:有没有一种方法可以根据波浪类型的外观来创建新的波浪类型。所以我可以看到一个三角波然后了解如何创建一个。 是的,你可以定义一个WaveformStrategy,它本质上是一种策略设计模式。然后,您可以将ToneGeneratorViewController(或您用来维持采样器状态的任何结构)传递给特定的具体WaveformStrategy 实例(即SinusoidalWaveformStrategySawtoothWaveformStrategy 并传递适当的时间步或omega进入computeSample() 方法并使用结果值填充buffer[frame])。 好的,我不知道我是否完全理解这一切,但我会继续努力,因为知识现在就在那里,谢谢。当我获得足够的代表时,我也会竖起大拇指。【参考方案2】:

要产生所需的波形,您需要将 sin() 函数替换为产生所需波形的函数。

您可能可以在带有图形示例的函数表中找到此函数,或者您可能必须创建自己的函数。创建函数逼近的方法有很多,包括多项式、傅里叶级数、带或不带插值的表查找、递归等。但这本身就是一个大主题(许多教科书等)

【讨论】:

以上是关于制定振荡器波型代码,并创建新的波型的主要内容,如果未能解决你的问题,请参考以下文章

linux下音频设备驱动

肌电信号脉搏信号分析(去噪+特征提取)matlab源码含GUI

肌电信号脉搏信号分析(去噪+特征提取)matlab 源码含GUI

肌电信号脉搏信号分析(去噪+特征提取)matlab源码含GUI

肌电信号基于matlab GUI脉搏信号处理系统含Matlab源码 1062期

Python - 使用 +/- 振荡值迭代数据框并根据条件创建新列