bingoStack
bingoStack

Reputation: 47

PortAudio iterate through audio data

As I am new to PortAudio, I tried an example program from the internet. The program is able to record the input of a microphone through a callback function.

I want to get every single sample of the recorded audio represented as a numeric value (e.g. float). I cannot figure out where the recorded data of the mic is stored.

This is the callback function:

static int recordCallback(const void *inputBuffer, void *outputBuffer,
    unsigned long framesPerBuffer,
    const PaStreamCallbackTimeInfo* timeInfo,
    PaStreamCallbackFlags statusFlags,
    void *userData)
{
    paTestData *data = (paTestData*)userData;
    const SAMPLE *rptr = (const SAMPLE*)inputBuffer;
    SAMPLE *wptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
    long framesToCalc;
    long i;
    int finished;
    unsigned long framesLeft = data->maxFrameIndex - data->frameIndex;

    (void)outputBuffer; /* Prevent unused variable warnings. */
    (void)timeInfo;
    (void)statusFlags;
    (void)userData;
    if (framesLeft < framesPerBuffer)
    {
        framesToCalc = framesLeft;
        finished = paComplete;
    }
    else
    {
        framesToCalc = framesPerBuffer;
        finished = paContinue;
    }

    if (inputBuffer == NULL)
    {
        for (i = 0; i<framesToCalc; i++)
        {
            *wptr++ = SAMPLE_SILENCE;  /* left */
            if (NUM_CHANNELS == 2) *wptr++ = SAMPLE_SILENCE;  /* right */
        }
    }
    else
    {
        cout << endl << "SAMPLE" << endl;
        for (i = 0; i<framesToCalc; i++)
        {
            *wptr++ = *rptr++;  /* left */
            //cout << rptr<<endl;
            if (NUM_CHANNELS == 2) *wptr++ = *rptr++;  /* right */
        }
    }
    data->frameIndex += framesToCalc;
    return finished;
}

The audio input stream is initialized here:

err = Pa_OpenStream(
        &stream,
        &inputParameters,
        NULL,                  /* &outputParameters, */
        SAMPLE_RATE,
        FRAMES_PER_BUFFER,
        paClipOff,      /* we won't output out of range samples so don't bother clipping them */
        recordCallback,
        &data);

Upvotes: 1

Views: 734

Answers (1)

Archie
Archie

Reputation: 2672

The incoming data is stored in the inputBuffer pointer of the callback. Depending on the inputParameters used when calling Pa_OpenStream one should be able to cast the input buffer into an array of corresponding data type (e.g. if paFloat32 is used as sample format, then the buffer can be interpreted as const float*).

It is recommended that in the callback function you copy the incoming data into another buffer for further processing (outside of the callback).

Multiple channels samples are interleaved in the buffer. For example for stereo input inputBuffer[0] is the first sample for the left channer, inputBuffr[1] is the first sample to the right channel, inputBuffer[2] is the 2nd sample for the left channel, etc. Total number of samples is provided via framesPerBuffer argument of the callback.

Upvotes: 2

Related Questions