Streaming with portAudio + Multichannel Processing

5

summary

I want to use PortAudio to process streaming audio Multi-channel input when using audio interface (4ch, 8ch...) Here's how to write the code for

environment

portAudio win10 WASAPI (Note that multi-channel input was not possible with DirectSound, multi-channel can be used/not depends on the OS and sound driver)

Source code (C)

  • Use portAduio to open a device
  • Callback function handles audio streaming
  • Isolate an input channel from streaming in a callback function
portaudio_multiInput_sample.c
PaStream *stream;
PaError err;

static int NUM_OF_CHANNEL = 4;
/* Open an audio I/O stream. */
err = Pa_OpenDefaultStream( &stream,
                            NUM_OF_CHANNEL,          /* 4 input channels */
                            0,          /* no output channel*/
                            NULL,  /* 32 bit floating point output */
                            SAMPLE_RATE,
                            256,        /* frames per buffer, i.e. the number
                                               of sample frames that PortAudio will
                                               request from the callback. Many apps
                                               may want to use
                                               paFramesPerBufferUnspecified, which
                                               tells PortAudio to pick the best,
                                               possibly changing, buffer size.*/
                            Callback, /* this is your callback function */
                            &data ); /*This is a pointer that will be passed to
                                      your callback*/
if( err != paNoError ) goto error;

static int Callback( const void *inputBuffer, void *outputBuffer,
                           unsigned long framesPerBuffer,
                           const PaStreamCallbackTimeInfo* timeInfo,
                           PaStreamCallbackFlags statusFlags,
                           void *userData )
{
  //入力信号は16bitの音声信号
  SP16 **recogData; 

  //チャンネルごとのメモリ確保
  recogData = (SP16**)malloc(sizeof(SP16*) * NUM_OF_CHANNEL);
  for(int i=0; i<NUM_OF_CHANNEL; i++)
    recogData[i] = (flaot*)malloc(sizeof(SP16*) * framesPerBuffer);

  //ストリーミングからチャンネル毎に信号を切り分ける
  SP16 *in = (SP16*)inputBuffer;
  for (int j=0; j<NUM_OF_CHANNEL; j++)
    for (int i=0; i<framesPerBuffer; i++)
      recogData[j][i] = in[i*NUM_OF_CHANNEL+j];
}

gist

The streaming input is isolated in the following parts:

//ストリーミングからチャンネル毎に信号を切り分ける
SP16 *in = (SP16*)inputBuffer;
for (int j=0; j<NUM_OF_CHANNEL; j++)
  for (int i=0; i<framesPerBuffer; i++)
    recogData[j][i] = in[i*NUM_OF_CHANNEL+j];

explanation

For streaming, the data passed to callback as inputBuffer variables is | 1ch data| | 2ch data| | 3ch data |...| Data | of NCH Each data length is passed as a framePerBuffer argument for streaming So I'm cutting these out with a for statement.

Notes

When opening streaming, if "sampling rate and bit depth on the audio interface side" and "sampling rate and bit depth specified by the program" do not match, an error is spewed It is necessary to match the three points of the audio interface configuration, the audio driver of the software, and the program of portaudio

Share:
5
masaki mori
Author by

masaki mori

Updated on April 17, 2018