Pa_GetStreamTime возвращает 0 раз

Я читаю аудиофайлы wav с помощью PortAudio. Функция обратного вызова работает нормально, и файлы воспроизводятся в Ubuntu нормально, как и должно быть. Проблема в том, что когда я пытаюсь получить время с помощью Pa_GetStreamTime, поскольку он возвращает 0, я читал документацию и примеры portaudio, но не смог найти способ устранения неполадок или хотя бы пример использования этой функции. Я просмотрел документацию по API здесь, но пока ничего не известно. Если кто-то может дать подсказку, это было бы очень признательно. Ниже приведена часть реализации, в которой выполняется функция обратного вызова. Я использую Qt, так как моей конечной целью является отображение FTT любого файла wav. Заранее спасибо.

int playAudio::patestCallback(const void *inputBuffer, void *outputBuffer,
                       unsigned long framesPerBuffer,
                       const PaStreamCallbackTimeInfo* timeInfo,
                       PaStreamCallbackFlags statusFlags,
                       void *userData)
{

    /* Cast data passed through stream to our structure. */
    //  data = (WAV*)userData;
    float *out = (float*)outputBuffer;
    (void) inputBuffer; /* Prevent unused variable warning. */

    /*terminates the stream flows and reset cursor.*/
    if (cursor == playAudio::SubChunk2Size / 4)
    {
        cursor = 0;
        return paComplete;
    }

    for (int i = 0; i < framesPerBuffer; i++)
    {
        if (cursor == playAudio::SubChunk2Size / 4) break; // breaks if samples reached last.
        *(out++) = pLeftChannel[cursor];
        *(out++) = pRightChannel[cursor];
        cursor++;

    }
    //  qDebug()<<cursor;
    playAudio::audioTime = Pa_GetStreamTime(stream);
    qDebug() << playAudio::audioTime;
    return paContinue;
}

person JC_Onp    schedule 03.10.2016    source источник


Ответы (1)


Чтобы процитировать документацию для аудио обратного вызова PortAudio:

Прежде чем мы начнем, важно понять, что обратный вызов — это деликатное место. Это связано с тем, что некоторые системы выполняют обратный вызов в специальном потоке или обработчике прерывания, и он редко обрабатывается так же, как остальная часть вашего кода. Для большинства современных систем вы не сможете вызвать сбои, выполнив запрещенные вызовы в обратном вызове, но если вы хотите, чтобы ваш код воспроизводил звук без сбоев, вам нужно убедиться, что вы избегаете вызовов функций, которые могут занимать неограниченное время. количество времени на выполнение. То, что именно это, зависит от вашей платформы, но почти наверняка включает следующее: выделение/освобождение памяти, ввод-вывод (включая файловый ввод-вывод, а также консольный ввод-вывод, например printf()) , переключение контекста (например, exec() или yield()), операции с мьютексами или что-то еще, что может зависеть от ОС. Если вы считаете, что короткие критические разделы безопасны, прочтите об инверсии приоритетов. Планировщики Windows и Mac OS не имеют безопасного предотвращения инверсии приоритетов в реальном времени. Для других платформ требуются специальные флаги мьютекса. Кроме того, небезопасно вызывать любые функции PortAudio API в обратном вызове, за исключением случаев, когда это явно разрешено в документации.

Акцент мой.

Другими словами, вызов Pa_GetStreamTime() из обратного вызова является поведением undefined. Но вам не нужно вызывать эту функцию в первую очередь. Почему? Поскольку четвертым параметром обратного вызова является структура PaStreamCallbackTimeInfo, содержащая ту же самую информация о времени, к которой вы пытаетесь получить доступ.

Кроме того, этот вызов qDebug, скорее всего, испортит воспроизведение звука. Запись в stdout просто занимает слишком много времени внутри аудио обратного вызова в реальном времени.

person MrEricSir    schedule 04.10.2016
comment
Спасибо, действительно, я пробовал эту структуру PaStreamCall... раньше, потому что я не хотел испортить функцию обратного вызова, но в элементе currentTime я получил 0 с; используя outputBufferDACtime, я мог видеть время данных, но не знал, как с этим справиться, я добавлял их, но результат не имел смысла, поэтому попытался Pa_getStreamTime дать тот же результат, что и при использовании currentTime. Насчет qDebug вы правы, в моем случае вопросов не дает, со временем будет удален. Если вы можете поделиться информацией с помощью portaudio и получить время или знаете, как обрабатывать эти данные из timeInfo.OutputBufferDACTime. - person JC_Onp; 04.10.2016