7

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

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

因此频率应为 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

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

4

2 回答 2

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% 或 9.5% 播放。

于 2009-11-03T22:45:07.560 回答
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多少?对我来说似乎未初始化...

于 2009-11-02T23:52:33.053 回答