2013-03-23 8 views
3

Я пытаюсь начать работу с PortAudio. Я могу без проблем создать собранный файл примера paex_sine.c. Это синусоидальная волна на левом канале и различная частота синусоидальной волны на правом канале. Это нормально работает без ошибок.5.1 Каналы с PortAudio

Моя установка - это 32-разрядный ПК под управлением Puppy Linux Slacko 5.5. Он имеет SoundBlaster SB0200 с микросхемой EMU10k1x. Библиотека Alsa v1.0.26, а драйвер - v1.0.24. Я проверил все 5.1 каналов, используя эту команду:

% speaker-test -Dplug:surround51 -c6

Тестовые играет правильно звучать на каждом из 6-ти каналов, хотя это жалуются сломанных труб. Вероятно, это связано с тем, что буфер не достаточно велик в тестовой программе для всех 6 каналов.

Проблема, с которой я сталкиваюсь, заключается в том, что, когда я изменяю «paex_sine.c», чтобы работать на 6 каналах вместо двух, он будет воспроизводить звук только через правые и передние левые каналы. Ошибок не сообщается, и 2 канала звучат так, как должны. Я слышал, что в некоторых случаях каналы должны быть отключены. В AlsaMixer и Puppy's «Retrovol» (который отражает AlsaMixer), я установил Master, PCM и Surround на максимальный объем, без звука. Может ли быть микшер в PortAudio, который мне также нужно включить? Я могу правильно и правильно переключаться между работающим динамиком и работать с измененным примером paex_sine и слышать только 2 канала. Вот paex_sine.c что я модифицировал:

 

    /** @file paex_sine.c 
     @ingroup examples_src 
     @brief Play a sine wave for several seconds. 
     @author Ross Bencina <[email protected]> 
     @author Phil Burk <[email protected]> 
    */ 
    /* 
    * $Id: paex_sine.c 1752 2011-09-08 03:21:55Z philburk $ 
    * 
    * This program uses the PortAudio Portable Audio Library. 
    * For more information see: http://www.portaudio.com/ 
    * Copyright (c) 1999-2000 Ross Bencina and Phil Burk 
    * 
    * Permission is hereby granted, free of charge, to any person obtaining 
    * a copy of this software and associated documentation files 
    * (the "Software"), to deal in the Software without restriction, 
    * including without limitation the rights to use, copy, modify, merge, 
    * publish, distribute, sublicense, and/or sell copies of the Software, 
    * and to permit persons to whom the Software is furnished to do so, 
    * subject to the following conditions: 
    * 
    * The above copyright notice and this permission notice shall be 
    * included in all copies or substantial portions of the Software. 
    * 
    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
    * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
    * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
    * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 
    * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
    * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
    * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
    */ 

    /* 
    * The text above constitutes the entire PortAudio license; however, 
    * the PortAudio community also makes the following non-binding requests: 
    * 
    * Any person wishing to distribute modifications to the Software is 
    * requested to send the modifications to the original developer so that 
    * they can be incorporated into the canonical version. It is also 
    * requested that these non-binding requests be included along with the 
    * license above. 
    */ 
    #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) 
    #endif 

    #define TABLE_SIZE (200) 
    typedef struct 
    { 
     float sine[TABLE_SIZE]; 
     int left_phase; 
     int right_phase; 
     int left2_phase; 
     int right2_phase; 
     int left3_phase; 
     int right3_phase; 
     char message[20]; 
    } 
    paTestData; 

    /* This routine will be called by the PortAudio engine when audio is needed. 
    ** It may called at interrupt level on some machines so don't do anything 
    ** that could mess up the system like calling malloc() or free(). 
    */ 
    static int patestCallback(const void *inputBuffer, void *outputBuffer, 
           unsigned long framesPerBuffer, 
           const PaStreamCallbackTimeInfo* timeInfo, 
           PaStreamCallbackFlags statusFlags, 
           void *userData) 
    { 
     paTestData *data = (paTestData*)userData; 
     float *out = (float*)outputBuffer; 
     unsigned long i; 

     (void) timeInfo; /* Prevent unused variable warnings. */ 
     (void) statusFlags; 
     (void) inputBuffer; 

     for(i=0; i<framesPerBuffer; i++) 
     { 
      *out++ = data->sine[data->left_phase]; /* left */ 
      *out++ = data->sine[data->right_phase]; /* right */ 
      *out++ = data->sine[data->left2_phase]; /* left */ 
      *out++ = data->sine[data->right2_phase]; /* right */ 
      *out++ = data->sine[data->left3_phase]; /* left */ 
      *out++ = data->sine[data->right3_phase]; /* right */ 
      data->left_phase += 1; 
      if(data->left_phase >= TABLE_SIZE) data->left_phase -= TABLE_SIZE; 
      data->right_phase += 3; /* higher pitch so we can distinguish left and right. */ 
      if(data->right_phase >= TABLE_SIZE) data->right_phase -= TABLE_SIZE; 
      data->left2_phase += 5; 
      if(data->left2_phase >= TABLE_SIZE) data->left2_phase -= TABLE_SIZE; 
      data->right2_phase += 7; /* higher pitch so we can distinguish left and right. */ 
      if(data->right2_phase >= TABLE_SIZE) data->right2_phase -= TABLE_SIZE; 
      data->left3_phase += 9; 
      if(data->left3_phase >= TABLE_SIZE) data->left3_phase -= TABLE_SIZE; 
      data->right3_phase += 11; /* higher pitch so we can distinguish left and right. */ 
      if(data->right3_phase >= TABLE_SIZE) data->right3_phase -= TABLE_SIZE; 
     } 

     return paContinue; 
    } 

    /* 
    * This routine is called by portaudio when playback is done. 
    */ 
    static void StreamFinished(void* userData) 
    { 
     paTestData *data = (paTestData *) userData; 
     printf("Stream Completed: %s\n", data->message); 
    } 

    /*******************************************************************/ 
    int main(void); 
    int main(void) 
    { 
     PaStreamParameters outputParameters; 
     PaStream *stream; 
     PaError err; 
     paTestData data; 
     int i; 


     printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER); 

     /* initialise sinusoidal wavetable */ 
     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; 

     err = Pa_Initialize(); 
     if(err != paNoError) goto error; 

     outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ 
     if (outputParameters.device == paNoDevice) { 
      fprintf(stderr,"Error: No default output device.\n"); 
      goto error; 
     } 
     outputParameters.channelCount = 6;  /* 5.1 Channel Output */ 
     outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */ 
     outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency; 
     outputParameters.hostApiSpecificStreamInfo = NULL; 

     err = Pa_OpenStream(
        &stream, 
        NULL, /* no input */ 
        &outputParameters, 
        SAMPLE_RATE, 
        FRAMES_PER_BUFFER, 
        paClipOff,  /* we won't output out of range samples so don't bother clipping them */ 
        patestCallback, 
        &data); 
     if(err != paNoError) goto error; 

     sprintf(data.message, "No Message"); 
     err = Pa_SetStreamFinishedCallback(stream, &StreamFinished); 
     if(err != paNoError) goto error; 

     err = Pa_StartStream(stream); 
     if(err != paNoError) goto error; 

     printf("Play for %d seconds.\n", NUM_SECONDS); 
     Pa_Sleep(NUM_SECONDS * 1000); 

     err = Pa_StopStream(stream); 
     if(err != paNoError) goto error; 

     err = Pa_CloseStream(stream); 
     if(err != paNoError) goto error; 

     Pa_Terminate(); 
     printf("Test finished.\n"); 

     return err; 
    error: 
     Pa_Terminate(); 
     fprintf(stderr, "An error occured while using the portaudio stream\n"); 
     fprintf(stderr, "Error number: %d\n", err); 
     fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err)); 
     return err; 
    } 

+0

Что такое информация о 'maxOutputChannels' устройства? –

+0

maxOutputChannels = 128 – user1890673

+0

В команде управления динамиком, если я пропущу переключатель -Dplug: surround51, он ведет себя одинаково - только передние левые и правые правые создают звук, хотя я все еще указал 6 каналов. – user1890673

ответ

2

Без plug:, не будет никакой автоматической передискретизации.

Portaudio не позволяет установить собственное имя устройства, так что вы должны определить, у вас есть устройство в ~/.asoundrc или /etc/asound.conf, как это:

pcm.mydevice = "plug:surround51" 

и выберите, что в Portaudio (искать его с Pa_GetDeviceCount/Pa_GetDeviceInfo). С другой стороны, сделать это устройство по умолчанию с:

pcm.!default = "plug:surround51" 
+0

Я не знаком с этим типом файла. Как я могу адаптировать этот пример: pcm.card0 { типа HW карты 0 } ctl.card0 { типа HW карты 0 } ли я просто лавировать это на конец файла ?: pcm.card0 = "plug: surround51" – user1890673

+0

Замените исходное определение 'pcm.card0'. –

+0

Ни один из этих (A, B, C ниже) не имеет значения, максимальные каналы все еще = 128, все еще только передний и правый и передний левый звук.Теперь я использую «patest_multi_sine», потому что он должен воспроизводиться на всех динамиках без изменений. [[[A]]] pcm.card0 = "plug: surround51" ctl.card0 {type hw card 0} [[[B]]] pcm.card0 {plug surround51} ctl.card0 {type hw card 0} [[ [C]]] pcm.card0 {type hw card 0 plug surround51} ctl.card0 {type hw card 0} – user1890673

1

Я изменил свой ~/.asoundrc к:

 
pcm.!default plug:surround51:Live 

И исправили проблему.

 Смежные вопросы

  • Нет связанных вопросов^_^