Я пытаюсь открыть поток в PortAudio - PullRequest
0 голосов
/ 20 апреля 2020

Я использую этот API: Pa_OpenStream ()

    // Open line-in stream
        err = Pa_OpenStream(&m_stream,
            &m_inputParameters,
            &m_outputParameters,
            44100, // sample rate 
            128, // frames per buffer 
            0, // paClipOff
            OmniLineInCallback,
            NULL);

, и я получаю ошибку = -9993, т.е. paBadIODeviceCombination.

Я настроил устройство ввода и вывода, и я хочу записывать со входа и передавать на выходное устройство воспроизведения.

я не знаю, почему я получаю эту ошибку?!

Благодарим Вас за помощь, Авиэль

Ответы [ 2 ]

0 голосов
/ 21 апреля 2020

ОК, при вызове Pa_GetDeviceCount () я получаю много доступных устройств. В настоящее время у меня есть звуковая карта onborad и звуковая карта USB. (у каждого из них есть устройства ввода и вывода), когда я настраиваю ввод и вывод звуковой карты OnBoard, все работает нормально. но когда я настраиваю вход USB-карты и выход встроенной карты, он возвращает err = paInvalidDevice.

также я увидел, что каждая карта имеет несколько устройств, которые отличаются по hostApi (paInDevelopment = 0, paDirectSound = 1, paMME = 2)

в чем разница между ними? и какое устройство выбрать? это нормально, чтобы смешивать между ними, то есть выбрать устройство ввода, у которого есть "paDirectSound" и выход, который имеет "paInDevelopment"?

еще одна вещь, на которую я обратил внимание, это частота дискретизации и количество каналов, это нормально, чтобы есть ввод с частотой дискретизации 44100 и выводом 48000?

и еще одна вещь: вы сконфигурировали переменные: nSampleRate nBufferSize в соответствии с чем?

спасибо, aviel.

0 голосов
/ 20 апреля 2020

Убедитесь, что вы передали правильные параметры методу. Для этого вы можете сделать следующее.

  1. Инициализировать PortAudio через Pa_Initialize()
  2. Проверьте, какие аудиоустройства действительно доступны для вас через PortAudio. Используйте Pa_GetDeviceCount(), а затем Pa_GetDeviceInfo() для каждого доступного устройства. Посмотрите, сколько входов и выходов действительно доступно для каждого устройства, и не передавайте количество больше, чем оно поддерживает.

  3. Заполните соответствующие поля структуры PaStreamParameters правильными значения.

Вот так я открываю свое устройство ASIO / CoreAudio (я также использую Qt Framework, но это не влияет на значение примера).

Как Я запускаю библиотеку и нахожу нужное устройство:

int MyClass::initSoundInterfaces()
{
    int result = -1; // target ASIO/CoreAudio device index

    PaError err = Pa_Initialize();

    const PaDeviceInfo* deviceInfo;
    int numDevices = Pa_GetDeviceCount();

    for( int DevIndex=0; DevIndex<numDevices; DevIndex++ )
    {
        deviceInfo = Pa_GetDeviceInfo( DevIndex );

        QString str = Pa_GetHostApiInfo(deviceInfo->hostApi)->name;

        qDebug() << "DEV: ApiInfo: " << str;
        qDebug() << "defaultSampleRate = " << deviceInfo->defaultSampleRate;
        qDebug() << "maxInputChannels = " << deviceInfo->maxInputChannels;
        qDebug() << "maxOutputChannels = " << deviceInfo->maxOutputChannels;

        QRegExp reg_exp(".*(ASIO|Core.*Audio).*", Qt::CaseInsensitive);

        if( str.contains(reg_exp) )
        {
            if(deviceInfo->maxInputChannels > 0
                && deviceInfo->maxOutputChannels > 1)
            {
                result = DevIndex;
                break;
            }
        }
    }
    return result;
}

Затем я передаю указанный индекс устройства следующему методу, чтобы открыть и запустить поток:

bool MyClass::startAudio(int DevIndex)
{
    PaError err = paNoError;

    PaStreamParameters in_param;
    in_param.device = DevIndex;

    g_ChannelCount = min(Pa_GetDeviceInfo(DevIndex)->maxInputChannels,
        MAX_INPUT_COUNT);

    in_param.channelCount = g_ChannelCount;
    in_param.hostApiSpecificStreamInfo = NULL;
    in_param.sampleFormat = paFloat32 | paNonInterleaved; 
    in_param.suggestedLatency = 0;
    // Pa_GetDeviceInfo(DevIndex)->defaultLowInputLatency;

    PaStreamParameters out_param;
    out_param.device = DevIndex;    
    out_param.channelCount = 2; // I do not need more than 2 output channels
    out_param.hostApiSpecificStreamInfo = NULL;
    out_param.sampleFormat = paFloat32 | paNonInterleaved; // Not all devices support 32 bits
    out_param.suggestedLatency = 0;
    // Pa_GetDeviceInfo(DevIndex)->defaultLowOutputLatency;

    if(err == paNoError)
    {
        err = Pa_OpenStream(&stream,
            &in_param,                             
            &out_param,
            nSampleRate, 
            cBufferSize/*paFramesPerBufferUnspecified*/,
            paNoFlag,
            process,
            0);     
    }  

    err = Pa_StartStream(stream); 
    ...
}
...