PortAudio / portaudio

PortAudio is a cross-platform, open-source C language library for real-time audio input and output.
Other
1.45k stars 303 forks source link

Error [-9984] Incompatible host API specific stream info #903

Closed shalinsirwani closed 1 month ago

shalinsirwani commented 5 months ago

(Please use the mailing list for support requests and general discussion. This is only for actual bugs.)

Describe the bug Error [-9984] Incompatible host API specific stream info, while passing PaWasapiStreamInfo to hostApiSpecificStreamInfo.

To Reproduce Steps to reproduce the behavior. Include code if applicable. 1.

#include <iostream>
#include <fstream>
#include <vector>
#include "portaudio.h"
#include "pa_win_wasapi.h"

#define SAMPLE_RATE  (16000)
#define FRAMES_PER_BUFFER (320)
#define NUM_CHANNELS    (1)
#define DITHER_FLAG     (0)
#define WRITE_TO_FILE   ("output.raw")

using namespace std;

int main() {
    PaError err;
    PaStream* stream;
    ofstream outputFile(WRITE_TO_FILE, ios::binary);
    std::cout << Pa_GetVersionText();
    err = Pa_Initialize();
    if (err != paNoError) {
        cout << "PortAudio error: " << Pa_GetErrorText(err) << endl;
        return -1;
    }
    int id = 0;
    const PaHostApiInfo* ptr = Pa_GetHostApiInfo(Pa_GetDeviceInfo(Pa_GetDefaultInputDevice())->hostApi);
    bool isWasapi = Pa_GetHostApiInfo(Pa_GetDeviceInfo(id)->hostApi)->type == paWASAPI;

    struct PaWasapiStreamInfo wasapiInfo;
    wasapiInfo.size = sizeof(PaWasapiStreamInfo);
    wasapiInfo.version = 1;
    wasapiInfo.hostApiType = paWASAPI;
    wasapiInfo.streamCategory = eAudioCategorySpeech;
    wasapiInfo.flags = paWinWasapiExplicitSampleFormat;
    wasapiInfo.streamOption = eStreamOptionMatchFormat;

    PaStreamParameters inputParameters;
    inputParameters.device = Pa_GetDefaultInputDevice();
    inputParameters.channelCount = NUM_CHANNELS;
    inputParameters.sampleFormat = paInt16;
    inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
    inputParameters.hostApiSpecificStreamInfo = &wasapiInfo;

    err = Pa_OpenStream(
        &stream,
        &inputParameters,
        NULL,  /* no output */
        SAMPLE_RATE,
        FRAMES_PER_BUFFER,
        paClipOff,
        NULL,  /* no callback, use blocking API */
        NULL); /* no callback, so no callback userData */
    if (err != paNoError) {
        cout << "PortAudio error: " << Pa_GetErrorText(err) << endl;
        return -1;
    }

    err = Pa_StartStream(stream);
    if (err != paNoError) {
        cout << "PortAudio error: " << Pa_GetErrorText(err) << endl;
        return -1;
    }

    cout << "Recording..." << endl;

    vector<int16_t> samples;
    int numSamples = 0;

    while (true) {
        err = Pa_ReadStream(stream, &samples[0], FRAMES_PER_BUFFER);
        if (err && numSamples != 0)
            break;
        numSamples += FRAMES_PER_BUFFER;
        for (auto& sample : samples)
            outputFile.write((char*)&sample, sizeof(int16_t));
    }

    cout << "Finished recording." << endl;

    err = Pa_StopStream(stream);
    if (err != paNoError) {
        cout << "PortAudio error: " << Pa_GetErrorText(err) << endl;
        return -1;
    }

    err = Pa_CloseStream(stream);
    if (err != paNoError) {
        cout << "PortAudio error: " << Pa_GetErrorText(err) << endl;
        return -1;
    }

    outputFile.close();

    Pa_Terminate();
    return 0;
}

Expected behavior A clear and concise description of what you expected to happen. => I was expecting it should start recording without any error

Actual behavior What actually happened. Include a recording if helpful. Error messages or logs longer than a page should be attached as a .txt file.

=> Getting error -9984 (Incompatible host API specific stream info)

Desktop (please complete the following information):

Additional context Add any other context about the problem here. NA

Note: PortAudio is a community supported project. If you have a solution, please create a Pull Request for us to consider.

dechamps commented 5 months ago

Your code contains:

inputParameters.device = Pa_GetDefaultInputDevice();
…
inputParameters.hostApiSpecificStreamInfo = &wasapiInfo;

Unless you messed around with PortAudio host API build options, the default input device will not be a WASAPI device. It will be an MME device.

You cannot use a WASAPI stream info struct with a non-WASAPI device, hence the "Incompatible host API specific stream info" error.

If you want to pick the default WASAPI input device, set the device index to Pa_GetHostApiInfo(Pa_HostApiTypeIdToHostApiIndex(paWASAPI))->defaultInputDevice.

shalinsirwani commented 5 months ago

After applying Pa_GetHostApiInfo(Pa_HostApiTypeIdToHostApiIndex(paWASAPI))->defaultInputDevice

I am getting error : - WASAPI ERROR PAERROR: -9997 : Invalid sample rate

dechamps commented 5 months ago

That's a completely different issue that could have any number of causes. I would start with trying a more standard sample rate (such as 44100 or 48000), a more typical channel count (2) and without passing any WASAPI stream info at first. Then once you get a setup that works, you can add options back until you find the one that's causing problems.

shalinsirwani commented 5 months ago

Got it. But is there any way to start recording with following options : - 1) sample rate 16k 2) channel 1 3) speech mode 4) frame per buffer 320 5) wasapi mode

RossBencina commented 1 month ago

Not a bug.