Добрый день
Работаю над программой, которая должна стримить аудио и воспроизводить его.
Включил в свой msvs-qt-проект для этой цели oggz, libfishsound и RtAudio.
Пишу сейчас непосредственно проигрыватель.
Суть проблемы в том, что при воспроизведении звук страшно "заикается".
libfishsound декодирует для меня ogg-файл, предоставляя pcm-данные.
Для проверки корректности этих данных я сливал их в wav-файл с помощью либы libsndfile - в винампе этот файл воспроизводился корректно (однако, с какими-то негромкими пощелкиваниями на басах).
Помимо RtAudio я успел использовать portaudio - получил то же самое. Причем пробовал метод и с callback'ом и с блокирующей записью.
Во всех случаях пробовал играть с различными программными настройками для этих либ.
А до всего этого также пробовал QAudioOutput, но кроме шипения ничего не получил
Я собрал минималистичный проект, в котором считываются pcm-данные из файлика. Данные я слил в файлик с помощью основного проекта.
Как результат - при его воспроизведении тоже получилось заикание.
RtAudio в данной конфигурации использует direct sound. PCM-данные имеют тип float interleaved.
Если кто-нибудь подозревает в чем проблема, подскажите, пожалуйста
Я с этим уже довольно долго не разберусь никак.
Может быть, я неправильно использую выходящий от декодера float** в моем проекте?
Я нагло интерпретирую его как void* и скармливаю RtAudio. Ни при каких других испробованных мною вариаций ничего хорошего не воспроизводилось вообще Скомпилированный проект (для прверки) можно скачать
тут.
Исходники (msvs10) -
здесь.
Файл с обрезком pcm в них приложил.
#include <QtCore/QCoreApplication>
#include <QFile.h>
#include <QDebug.h>
#include "RtAudio.h"
RtAudio *rtAudio;
RtAudio::StreamParameters streamParams;
RtAudio::StreamOptions streamOptions;
unsigned int sampleRate;
unsigned int bufferSize;
QFile pcmfile; // Файл с pcm-данными
// Функция заполнения буфера данными
int feed(char *buffer, quint32 nFrames)
{
if ( pcmfile.atEnd() )
return 1;
Q_ASSERT (
// Непосредственное чтение данных из файла в buffer
pcmfile.read ( buffer, nFrames*sizeof(float) ) != -1 );
return 0;
}
// Callback для RtAudio, просто вызывающий feed с двумя параметрами
int RtCallback(void *outputBuffer, void *inputBuffer, quint32 nFrames,
double streamTime, RtAudioStreamStatus status, void *userData)
{
if ( status )
qDebug() << "Stream overflow detected!";
return feed ( (char*)outputBuffer, nFrames );
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// Инициализация RtAudio, заполнение параметров стрима
rtAudio = new RtAudio( RtAudio::WINDOWS_DS );
streamParams.deviceId = rtAudio -> getDefaultOutputDevice();
streamParams.firstChannel = 0;
streamParams.nChannels = 2;
streamOptions.flags = 0 /*RTAUDIO_MINIMIZE_LATENCY*/;
streamOptions.numberOfBuffers = 2;
streamOptions.priority = 0;
streamOptions.streamName = "default";
sampleRate = 44100;
bufferSize = 4096; // (пробовал различный размер буфера и их число - все равно заикается)
Q_ASSERT ( rtAudio -> getDeviceCount() > 0 ); // проверка наличия устройства для воспр-я
pcmfile.setFileName ( "pcmdata-truncated" );
Q_ASSERT( pcmfile.open( QIODevice::ReadOnly ));
rtAudio -> openStream( &streamParams, 0, RTAUDIO_FLOAT32,
sampleRate, &bufferSize, RtCallback, 0, &streamOptions );
// Старт воспроизведения
rtAudio -> startStream();
return a.exec();
}