3

我正在尝试开始使用 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 播放几秒钟的正弦波。
        @作者罗斯·本西纳 <rossb@audiomulch.com>
        @作者菲尔伯克 <philburk@softsynth.com>
    */
    /*
     * $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 <stdio.h>
    #include <math.h>
    #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<framesPerBuffer;i++)
        {
            *out++ = 数据->正弦[数据->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;i<TABLE_SIZE;i++)
        {
            data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
        }
        data.left_phase = data.right_phase = 0;
        data.left2_phase = data.right2_phase = 0;
        data.left3_phase = data.right3_phase = 0;

        错误 = Pa_Initialize();
        if( err != paNoError ) 转到错误;

        outputParameters.device = Pa_GetDefaultOutputDevice(); /* 默认输出设备 */
        if (outputParameters.device == paNoDevice) {
          fprintf(stderr,"错误:没有默认输出设备。\n");
          转到错误;
        }
        outputParameters.channelCount = 6; /* 5.1 声道输出 */
        outputParameters.sampleFormat = paFloat32; /* 32 位浮点输出 */
        outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
        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 ) );
        返回错误;
    }

4

2 回答 2

2

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

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

pcm.mydevice = "plug:surround51"

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

pcm.!default = "plug:surround51"
于 2013-03-24T10:18:47.347 回答
1

我将 ~/.asoundrc 更改为:

pcm.!默认插头:surround51:Live

这解决了这个问题。

于 2013-03-29T00:17:10.497 回答