Portaudio:通过调用功能播放多个生成的声音

PortAudio: Play multiple generated sounds by calling function

本文关键字:声音 播放 调用 功能 Portaudio      更新时间:2023-10-16

大约一周前,我已经开始使用Portaudio库玩。我已经检查了大多数教程/测试示例,但还没有看到我需要的解决方案。我正在制作简单的音序器 - 我已经在钢琴卷上绘制了绘画声音,但是现在我需要以某种方式使其听起来。我想知道是否有可能这样工作:

  • 运行一种可以播放一种声音的方法
  • 将声音的频率和持续时间作为该方法的参数,
  • 播放多种声音(即同时发出三种声音,bu调用三种方法)。

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

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

我会为您提供一个简单的示例(对于sine wave),然后您可以创建您感兴趣的其他类型的波。

  • 采样率(例如8000,16000等)
  • 振幅(实际值取决于输出格式,但最好在0-1中具有值并将其转换为任何格式 您喜欢/需要)
  • 频率(表示为采样率的一部分)
  • 持续时间(以秒为单位)

音调数据(样本)的缓冲长度由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存储样品。这样,您不必担心内存分配/交易。

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

您也可以将振幅作为paramater传递,但在幅度上方的示例中是硬编码。另外,请参见(https://en.wikipedia.org/wiki/wiki/triangle_wave,https://en.wikipedia.org/wiki/wiki/square_wave)

上述程序是生成音频音调的快速方法。小修正:而不是

const float freq = frequency/samplingRate; 

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