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

问题描述 投票:1回答:1

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

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

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

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

c++ audio portaudio
1个回答
1
投票

我将给你一个简单的例子(对于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));

}

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

© www.soinside.com 2019 - 2024. All rights reserved.