Streaming with portAudio + Multichannel Processing
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
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