【问题标题】:5.1 Channels with PortAudio5.1 带有 PortAudio 的频道
【发布时间】:2013-03-23 21:18:44
【问题描述】:

我正在尝试开始使用 PortAudio。我能够毫无问题地构建捆绑的示例文件“paex_sine.c”。这是左声道上的正弦波和右声道上不同频率的正弦波。这可以正常工作,没有错误。

我的设置是一台运行 Puppy Linux Slacko 5.5 的 32 位 PC。它有一个带有 EMU10k1x 芯片的 SoundBlaster SB0200。 Alsa 库是 v1.0.26,驱动程序是 v1.0.24。我已经使用这个命令测试了所有 5.1 通道:

% 扬声器测试 -Dplug:surround51 -c6

测试在 6 个通道中的每一个上都能正常播放声音,但它确实抱怨管道损坏。这可能是因为测试程序中的缓冲区对于所有 6 个通道都不够大。

我遇到的问题是,当我将“paex_sine.c”修改为在 6 个通道而不是 2 个通道上运行时,它只会通过右前和左前通道播放声音。没有报告错误,并且 2 个通道听起来应该。我听说在某些情况下必须取消静音。在 AlsaMixer 和 Puppy 的“Retrovol”(反映 AlsaMixer)中,我已将 Master、PCM 和 Surround 设置为最大音量,未静音。 PortAudio 中是否有我也必须取消静音的混音器?我可以在正确运行扬声器测试和运行修改后的 paex_sine 示例和只听到 2 个通道之间来回切换。这是我修改过的 paex_sine.c:

/** @file paex_sine.c @ingroup examples_src @brief 播放几秒钟的正弦波。 @作者罗斯·本西纳 @作者菲尔伯克 */ /* * $Id:paex_sine.c 1752 2011-09-08 03:21:55Z 菲尔伯克 $ * * 该程序使用 PortAudio 便携式音频库。 * 欲了解更多信息,请参阅:http://www.portaudio.com/ * 版权所有 (c) 1999-2000 Ross Bencina 和 Phil Burk * * 特此免费授予任何获得许可的人 * 该软件和相关文档文件的副本 *(“软件”),不受限制地处理软件, * 包括但不限于使用、复制、修改、合并、 * 发布、分发、再许可和/或出售软件的副本, * 并允许向其提供软件的人这样做, * 须符合以下条件: * * 以上版权声明和本许可声明为 * 包含在软件的所有副本或大部分内容中。 * * 软件按“原样”提供,不提供任何形式的保证, * 明示或暗示,包括但不限于 * 适销性、特定用途的适用性和非侵权性。 * 在任何情况下,作者或版权所有者均不承担任何责任 * 任何索赔、损害赔偿或其他责任,无论是在诉讼中 * 合同、侵权或其他原因,由、不相关或相关 * 与软件或软件中的使用或其他交易有关。 */ /* * 以上文字构成整个 PortAudio 许可证;然而, * PortAudio 社区还提出以下非约束性请求: * * 任何希望分发对软件的修改的人 * 要求将修改发送给原始开发人员,以便 * 它们可以合并到规范版本中。也是 * 要求将这些不具约束力的请求与 * 上面的许可证。 */ #include #include #include “portaudio.h” #define NUM_SECONDS (30) #define SAMPLE_RATE (44100) #define FRAMES_PER_BUFFER (192)//(64) #ifndef M_PI #define M_PI (3.14159265) #万一 #define TABLE_SIZE (200) 类型定义结构 { 浮动正弦[TABLE_SIZE]; 诠释左相; int right_phase; int left2_phase; 诠释 right2_phase; int left3_phase; int right3_phase; 字符消息[20]; } 测试数据; /* 当需要音频时,PortAudio 引擎将调用此例程。 ** 它可能在某些机器上以中断级别调用,所以不要做任何事情 ** 这可能会像调用 malloc() 或 free() 一样搞砸系统。 */ 静态 int patestCallback( const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, 常量 PaStreamCallbackTimeInfo* 时间信息, PaStreamCallbackFlags statusFlags, 无效*用户数据) { paTestData *data = (paTestData*)userData; 浮动 *out = (float*)outputBuffer; 无符号长 i; (无效)时间信息; /* 防止未使用的变量警告。 */ (void) 状态标志; (void) 输入缓冲区; for(i=0;i正弦[数据->left_phase]; /* 剩下 */ *out++ = 数据->正弦[数据->right_phase]; /* 对 */ *out++ = 数据->正弦[数据->left2_phase]; /* 剩下 */ *out++ = 数据->正弦[数据->right2_phase]; /* 对 */ *out++ = 数据->正弦[数据->left3_phase]; /* 剩下 */ *out++ = 数据->正弦[数据->right3_phase]; /* 对 */ 数据->left_phase += 1; if( 数据->left_phase >= TABLE_SIZE ) 数据->left_phase -= TABLE_SIZE; 数据->right_phase += 3; /* 更高的音高,这样我们就可以区分左右。 */ if( 数据->right_phase >= TABLE_SIZE ) 数据->right_phase -= TABLE_SIZE; 数据->left2_phase += 5; if( 数据->left2_phase >= TABLE_SIZE ) 数据->left2_phase -= TABLE_SIZE; 数据->right2_phase += 7; /* 更高的音高,这样我们就可以区分左右。 */ if( 数据->right2_phase >= TABLE_SIZE ) 数据->right2_phase -= TABLE_SIZE; 数据->left3_phase += 9; if( 数据->left3_phase >= TABLE_SIZE ) 数据->left3_phase -= TABLE_SIZE; 数据->right3_phase += 11; /* 更高的音高,这样我们就可以区分左右。 */ 如果(数据->right3_phase >= TABLE_SIZE)数据->right3_phase -= TABLE_SIZE; } 返回pa继续; } /* * 播放完成时,portaudio 会调用此例程。 */ 静态无效流完成(无效*用户数据) { paTestData *data = (paTestData *) userData; printf("流完成:%s\n", data->message ); } /************************************************* ******************/ 诠释主要(无效); 诠释主要(无效) { PaStreamParameters 输出参数; PaStream *流; PaError 错误; paTestData 数据; 诠释我; printf("PortAudio 测试:输出正弦波。SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER); /* 初始化正弦波表 */ for(i=0;idefaultLowOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; 错误 = Pa_OpenStream( &溪流, NULL, /* 没有输入 */ &输出参数, 采样率, FRAMES_PER_BUFFER, paClipOff, /* 我们不会输出超出范围的样本,所以不要费心剪裁它们 */ Patest回调, &数据 ); if( err != paNoError ) 转到错误; sprintf(data.message,“无消息”); err = Pa_SetStreamFinishedCallback(stream, &StreamFinished); if( err != paNoError ) 转到错误; 错误 = Pa_StartStream( 流 ); if( err != paNoError ) 转到错误; printf("播放 %d 秒。\n", NUM_SECONDS ); Pa_Sleep(NUM_SECONDS * 1000); 错误 = Pa_StopStream( 流 ); if( err != paNoError ) 转到错误; 错误 = Pa_CloseStream( 流 ); if( err != paNoError ) 转到错误; Pa_Terminate(); printf("测试完成。\n"); 返回错误; 错误: Pa_Terminate(); fprintf( stderr, "使用 portaudio 流时出错\n" ); fprintf(stderr, "错误号: %d\n", err ); fprintf(stderr, "错误信息: %s\n", Pa_GetErrorText( err ) ); 返回错误; }

【问题讨论】:

  • 设备信息的maxOutputChannels是什么?
  • maxOutputChannels = 128
  • 在扬声器测试命令中,如果我跳过 -Dplug:surround51 开关,它的行为方式相同 - 只有左前和右前发出声音,即使我仍然指定了 6 个通道.
  • 如果我运行“pa_devs”示例,这将打印出设备索引和相应的名称。在我修改过的示例程序(最初发布)中,如果我将 outputParameters.device 强制设置为名为“surround51”(10)的索引,则最大通道数会报告为 6,但随后示例会阻塞并抱怨采样率无效。

标签: alsa portaudio surround


【解决方案1】:

没有plug:,将不会自动重采样。

PortAudio 不允许设置您自己的设备名称,因此您必须在~/.asoundrc/etc/asound.conf 中定义您自己的设备,如下所示:

pcm.mydevice = "plug:surround51"

然后在 PortAudio 中选择它(使用 Pa_GetDeviceCount/Pa_GetDeviceInfo 搜索它)。 或者,将其设为默认设备:

pcm.!default = "plug:surround51"

【讨论】:

  • 我不熟悉这种类型的文件。我该如何调整这个例子:pcm.card0 { type hw card 0 } ctl.card0 { type hw card 0 } 我只是把它贴到文件的末尾吗?:pcm.card0 = "plug:surround51"
  • 替换原来的pcm.card0定义。
  • 这些(下面的A、B、C)都没有任何区别,最大通道仍然= 128,仍然只有右前和左前发出声音。我现在使用“patest_multi_sine”,因为它应该在所有扬声器上播放而无需修改。 [[[A]]] pcm.card0 = "plug:surround51" ctl.card0 { 键入硬件卡 0 } [[[B]]] pcm.card0 { 插入环绕 51 } ctl.card0 { 键入硬件卡 0 } [[ [C]]] pcm.card0 { 输入硬件卡 0 插头环绕 51 } ctl.card0 { 输入硬件卡 0 }
  • B和C的语法错误。您是否选择了card0 设备?
  • 如何选择card0设备?在源文件中,我使用 outputParameters.device=Pa_GetDefaultOutputDevice(),它需要一个数字。有没有办法更改默认设备?请理解,我对此很陌生,基本上不知道自己在做什么 - 感谢您的耐心等待。
【解决方案2】:

我将 ~/.asoundrc 更改为:

pcm.!默认插头:surround51:Live

这就解决了问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-16
    • 1970-01-01
    • 2016-08-31
    • 1970-01-01
    • 2015-12-16
    • 2016-06-27
    • 2019-07-30
    • 2019-11-10
    相关资源
    最近更新 更多