在SDL回调函数中以特定频率播放波形

时间:2009-11-02 23:31:44

标签: c audio callback sdl waveform

我的波形长64个样本。如果采样率为44100 hz,我如何播放(循环)此波形以使其播放任意频率?

频率=样本中的采样率/波形持续时间

因此频率应为689hz(44100/64)。如果我想要它,65.41hz(C-2),我必须这样做:

65.41 = 44100 / x

求解x得到aprox。 674.208。因此,我需要弄清楚播放波形的速度,以获得此频率。所以我们可以解决这个等式:

64 * x = 674.208

并获得约10.5。因此波形需要以其原始速度的10.5%播放。

这是我的代码:

double smp_index = 0;
double freq = .105;

void callback(void *data, Uint8 *buf, int len){
    int i;
    s8 *out;
    out = (s8*) buf;
    if(smp_index < waveform_length){
        for(i = 0; i < len; i ++){
            out[i] = smpdata[(int)smp_index];
            smp_index +=freq;
            if(smp_index >= waveform_length)
                smp_index = 0;
        }
    }
}

因此产生的音频应该是音符C-2,但它更像是D-2。是演员

(int)smp_index

导致问题?我看不到任何其他方法来实现这一目标......

2 个答案:

答案 0 :(得分:2)

实际上,主要问题不在于您的代码,而在于您的推理。

  

所以我们可以解决这个等式:

     

64 * x = 674.208

     

并获得大约10.5。

到目前为止一切顺利。 (实际上674.208应该是674.246,但这是因为你之前将65.41分为4位有效数字。)

  

因此波形需要以其原始速度的10.5%播放。

没有!波形必须减慢 10.5倍。这意味着它必须以1/10.5 = 0.095或原始速度的9.5%播放。

答案 1 :(得分:1)

演员(int)smp_index 导致问题。它只是拉伸波 - 这是质量损失(也许你应该让你的波数据超过64个样本),但不可能改变频率。最有可能的问题是:

        if(smp_index > realLength)
            smp_index = 0;

应该是:

        if(smp_index >= realLength)
            smp_index -= realLength;

我还有其他一些注意事项:

  

频率=样本中的采样率/波形持续时间

嗯,如果用“波形持续时间”表示波浪的周期,则为是。即如果您的64样本波形是周期为64的正弦波,则为是。如果它是32或16那么事情会有所不同。如果它不是64分(如48或30)那么你的波形首先不是周期性的。

现在:

u32 waveform_length;
out = (s8*) buf;
if(smp_index < waveform_length){

waveform_length的价值是多少?看起来没有初始化给我......