Crunchex
Crunchex

Reputation: 317

Can you use a PortAudio callback to write back to a stream's input buffer?

At a highlevel, my goal is take the microphone input from one stream, do some processing on it, and copy that to the microphone input to another stream. With the latter being my default device, my other applications (which for reasons that are out of my hands, can't specify any other device) can record from the default device and still get processed input.

Here's a snippet of my code:

int stream1_callback(const void *card_capture, void *card_playback, unsigned long frameCount, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData) {
    main_t *data = (main_t *) userData;

    // UNUSED(card_capture);
    UNUSED(card_playback);
    UNUSED(frameCount);
    UNUSED(timeInfo);
    UNUSED(statusFlags);
    // UNUSED(userData);

    deinterleave_i16_i16(card_capture, data->mic_unprocessed, NUM_MICS, BLOCKSIZE_48KHZ);
    printf("De-interleaved!\n");

    process_microphones(data->mic_unprocessed, data->mic_processed);
    printf("Processed!\n");

    return 0;
}

int stream2_callback(const void *inputBuffer, void *outputBuffer, unsigned long frameCount, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData) {
    main_t *data = (main_t *) userData;

    // UNUSED(inputBuffer);
    UNUSED(outputBuffer);
    UNUSED(frameCount);
    UNUSED(timeInfo);
    UNUSED(statusFlags);
    // UNUSED(userData);

    interleave_i16_i16(data->mic_processed, (int16 *)inputBuffer, 1, BLOCKSIZE_16KHZ);
    printf("Interleaved!\n");

    return 0;
}

int main() {
    // ...

    /* -- setup stream1 -- */
    err = Pa_OpenStream(&stream1, &stream1InputParams, NULL, 48000, BLOCKSIZE_48KHZ, paNoFlag, stream1_callback, &main_data);
    if (err != paNoError) {
        goto error;
    }

    /* -- setup stream2 -- */
    err = Pa_OpenDefaultStream(&stream2, 1, 0, paInt16, 16000, BLOCKSIZE_16KHZ, stream2_callback, &main_data);
    if (err != paNoError) {
        goto error;
    }

    //...
}

So I'm wondering if the callback's input buffer is actually writable. Or if there is some other (better) way that I can write to the input of another device.

Upvotes: 0

Views: 421

Answers (1)

CL.
CL.

Reputation: 180020

In general, capture devices cannot be written to; they go directly to the hardware.

To be able to inject your own samples data into a capture device, its driver must be written to allow that. This is the case for the loopback driver, snd-aloop.

Upvotes: 2

Related Questions