1

如何在运行时使用 C++ 生成音频?我只是在寻找一个起点。论坛上有人建议我尝试让程序播放给定频率和幅度的方波。

我听说现代计算机使用 PCM 样本对音频进行编码:在特定时间单位(例如 48 kHz)的给定速率下,声音的幅度以给定的分辨率(例如 16 位)记录。如果我生成这样的样本,我如何让我的扬声器播放它?我目前正在使用窗户。如果可能的话,我宁愿避免使用任何额外的库,但我会选择一个非常轻便的库。

这是我尝试使用此原理生成方波样本:

signed short* Generate_Square_Wave(
    signed short a_amplitude , 
    signed short a_frequency ,
    signed short a_sample_rate )
{
    signed short* sample = new signed short[a_sample_rate];

    for( signed short c = 0; c == a_sample_rate; c++ )
    {
        if( c % a_frequency < a_frequency / 2 )
            sample[c] = a_amplitude;
        else
            sample[c] = -a_amplitude;
    }

    return sample;
}

我这样做正确吗?如果是这样,我该如何处理生成的样本来让我的扬声器播放它?

4

2 回答 2

1

您的循环必须使用 c < a_sample_rate 以避免缓冲区溢出。

要输出声音,您可以调用 waveOutOpen 和其他 waveOut... 函数。它们都列在这里:

http://msdn.microsoft.com/en-us/library/windows/desktop/dd743834(v=vs.85).aspx

于 2013-10-01T02:10:00.507 回答
0

您使用的代码会生成一个真正的方波,二进制类型的方波,简而言之,这是现实生活中不存在的波形类型。实际上,您听到的大多数(几乎所有)声音都是不同频率的正弦波的组合。

因为您的样本是按原样创建的,所以它们会产生混叠,其中较高的频率伪装成较低的频率,从而导致音频伪影。为了向自己演示这一点,请编写一个小程序,将代码的频率从 20 到 20,000 赫兹扫描。您会听到声音在频率升高时不会平稳上升。你会听到人工制品。

维基百科有一篇关于方波的优秀文章:https ://en.m.wikipedia.org/wiki/Square_wave

生成方波的一种方法是执行快速傅里叶逆变换,将一系列频率测量值转换为一系列基于时间的样本。然后生成方波就是向例程提供组成方波的不同频率的正弦波测量值的集合,并且输出是具有单个波形周期的缓冲器。

生成音频波的计算成本很高,因此通常要做的是生成音频样本数组并以不同的速度播放它们以播放不同的频率。这称为波表合成。

看看下面的链接:

https://www.earlevel.com/main/2012/05/04/a-wavetable-oscillator%E2%80%94part-1/

还有一些关于限制信号的频带以及为什么有必要:

https://dsp.stackexchange.com/questions/22652/why-band-limit-a-signal

于 2019-05-19T06:15:33.850 回答