如何在portaudio中实时更改参数

Posted

技术标签:

【中文标题】如何在portaudio中实时更改参数【英文标题】:How to change parameters realtimely in portaudio 【发布时间】:2014-09-25 00:47:25 【问题描述】:

使用端口音频,我想实时更改参数。

喜欢(使用 C): 正弦波 440hz -> 我用 getchar() 输入 '500' -> 正弦波 500hz

但是我找不到方法。

有人知道好的分辨率吗?

我的愿景:此代码(http://goo.gl/UJJlTw) + getchar()(从 CUI/终端更改频率)

【问题讨论】:

您的问题是生成具有可变频率的音调,还是在不停止音频生成的情况下从用户那里获取输入? 感谢评论。它“产生频率可变的音调”。 (点赞->portaudio.com/docs/v19-doxydocs/paex__sine_8c_source.html 【参考方案1】:

下面是一个简化的剪切 N 粘贴,在每次调用时 增加/减少频率 - 听起来有点像 重复 zureee zuraaaa, zureee zuraaa ...

var phi = 0,
    dphi = 2.0 * Math.PI * given_node.sample_freq /
    given_node.sample_rate;

for (var curr_sample = 0; curr_sample < given_node.BUFF_SIZE; curr_sample++, phi += dphi) 

    synthesized_output_buffer[curr_sample] = Math.sin(phi);


given_node.sample_freq *= given_node.freq_factor;

if (given_node.sample_freq <
    given_node.MIN_FREQ) 

    given_node.freq_factor = given_node.increasing_freq_factor;

 else if (given_node.sample_freq > given_node.MAX_FREQ) 

    given_node.freq_factor = given_node.decreasing_freq_factor;

【讨论】:

【参考方案2】:

This other example from portaudio documentation 展示了如何使用synchronous write I/O method 生成正弦波。

下面是这个示例的简化 sn-p,它跳过了 portaudio 初始化调用并生成单个通道,重点关注主要的信号生成机制:

/* initialization */
int phase = 0;
int phase_increment = (int) (frequency * TABLE_SIZE / ((double) SAMPLING_RATE) + 0.5);
...
/* signal generation loop */
for (;;)

  ...
  for( j=0; j < FRAMES_PER_BUFFER; j++ )
  
    buffer[j][0] = sine[phase];
    phase += phase_increment;
    if( phase_increment >= TABLE_SIZE ) left_phase -= TABLE_SIZE;
  
  err = Pa_WriteStream( stream, buffer, FRAMES_PER_BUFFER );

生成具有实时变化频率的正弦波在概念上与生成具有固定频率的正弦波没有太大区别。主要区别在于您需要更新phase_increment 以匹配新的所需频率。因此,一旦您从用户界面读取了 new_frequency,您将重新计算 phase_increment 并准备生成下一个样本:

/* signal generation loop */
for (;;)

  ...
  for( j=0; j < FRAMES_PER_BUFFER; j++ )
  
    buffer[j][0] = sine[phase];
    phase += phase_increment;
    if( phase_increment >= TABLE_SIZE ) left_phase -= TABLE_SIZE;
  
  err = Pa_WriteStream( stream, buffer, FRAMES_PER_BUFFER );

  /* now update phase_increment as per new frequency */
  phase_increment = (int) (new_frequency * TABLE_SIZE / ((double) SAMPLING_RATE) + 0.5);
  /* then next loop iteration will be generating a sine wave at the new frequency */

请注意,正弦波生成使用表查找,其中 sine 是一个表,其中包含 sin 函数在完整 2π 周期内的预计算值。这通常是为了提高效率。

【讨论】:

以上是关于如何在portaudio中实时更改参数的主要内容,如果未能解决你的问题,请参考以下文章

如何最大限度地提高实时处理性能(Portaudio)

初始化 PortAudio:主机错误

如何在封装在类中的回调函数上发送指针

如何将 PortAudio 包含到 pyinstaller onefile 构建中

在 portaudio 中管理频道

如何使用 PyAudio 或 PortAudio 获取设备的音频采样率列表?