PortAudio:通过调用函数播放多个生成的声音

PortAudio: Play multiple generated sounds by calling function

我大约一周前开始使用 PortAudio 库。我已经检查了大多数 tutorial/test 示例,但没有看到我需要的解决方案。我正在制作简单的音序器 - 我已经在钢琴卷轴上绘制了作为块的声音,但现在我需要以某种方式让它听起来。我想知道是否有可能让它像这样工作:

在示例文件中看起来更复杂。当我想播放多个正弦波时,我必须合并所有这些波,然后将这些数据提供给流。

也许有人有更好的解决方案来解决这个问题?

我只是给你一个简单的例子(对于sine wave),然后你可以创建你感兴趣的其他类型的波。需要的输入参数是

  • sampling rate (e.g 8000, 16000 etc)
  • amplitude (the actual values depend on the output format but it's best to have values in the range 0-1 and convert them to whatever format you like/need)
  • frequency (expressed as a fraction of the sampling rate)
  • duration (in seconds)

音调数据(样本)的缓冲区长度由 tone duration 秒乘以 sampling rate 确定。

创建正弦波的实际代码可能如下所示

//global variables
const float PI = 3.141593;
const unsigned samplingRate = 8000;
const float amp = 0.8;

float *GenerateTone(float frequency, unsigned duration, unsigned &bufferLen){

     const float freq = frequency/samplingRate; //(e.g 440 / 8000 = 0,055)

     bufferLen = samplingRate * duration;

     float *buffer = new float[bufferLen]

     for(int i = 0; i < bufferLen; i++ ){

        buffer[i] = amp * sin(2 * PI*freq  * ((float)i)/samplingRate);

        }
    return buffer;
}   

你可以这样调用这个函数

unsigned len;
float *pTone = GenerateTone(440, 1, len);//len is an out parameter
...
delete [] pTone; //deallocatone memory when you no longer need it

在C++中,您也可以使用std::vector来存储样本。这样就不用担心内存了allocation/deallocation.

std::vector<float> v; //make vector global  
const float PI = 3.141593;
const unsigned samplingRate = 8000;
const float amp = 0.8;

void GenerateTone(float frequency, unsigned duration){

  const amp = 0.8f;

  const float freq = frequency/samplingRate; 

  const unsigned len = samplingRate * duration; 
  for(int i = 0; i < len; i++ )
        v.push_back(amp * sin(2*PI*freq  * ((float)i)/sampleRate));

}

您也可以将振幅作为参数传递,但在上面的示例中,振幅是硬编码的。另外,请参阅 (https://en.wikipedia.org/wiki/Triangle_wave, https://en.wikipedia.org/wiki/Square_wave )

以上程序是一种快速生成音频的方法。 小更正: 而不是

const float freq = frequency/samplingRate; 

应该是: const float freq = frequency; // 即。将频率直接传递到 sin()