Я работаю над проигрыванием аудио от аудиопотока с помощью VC ++ с библиотекой QtMultimedia. Так как я не слишком испытан с библиотеками QT, я запустил путем чтения в .wav файле и записи этого в буфер:
ifstream wavFile;
char* file = "error_ex.wav";
wavFile.open( file, ios::binary );
После этого я использовал .read ifstream (), функционируют и пишут все данные в буфер. После того, как буфер записан, он отослан аудио устройству записи, которое готовит его к QT:
QByteArray fData;
for( int i = 0; i < (int)data.size(); ++i )
{
fData.push_back(data.at(i));
}
m_pBuffer->open(QIODevice::ReadWrite);
m_pBuffer->write( fData );
m_pBuffer->close();
(m_pBuffer имеет тип QBuffer),
После того как QBuffer готов, я пытаюсь играть буфер:
QIODevice* ioDevice = m_pAudioOut->start();
ioDevice->write( m_pBuffer->buffer() );
(m_pAudioOut имеет тип QAudioOutput),
Это приводит к маленькому поп от докладчиков, и затем он прекращает играть. Какие-либо идеи, почему?
Выполнение Visual Studio 2008 на Windows XP SP2, пользующемся библиотекой Qt 4.6.3.
Как указал Фрэнк, если вам нужно просто воспроизводить аудиоданные из файла, API более высокого уровня выполнит эту работу и упростит код вашего приложения. Фонон будет одним из вариантов; в качестве альтернативы проект QtMobility предоставляет API QMediaPlayer для высокоуровневых вариантов использования.
Учитывая, что вопрос конкретно касается использования QIODevice , однако, и что вы упомянули, что чтение из файла WAV было всего лишь вашим первоначальным подходом, я предполагаю, что вам действительно нужен потоковый API, т. Е. Один что позволяет клиенту управлять буферизацией, а не передавать это управление абстракции более высокого уровня, такой как Phonon.
QAudioOutput может использоваться в двух разных режимах, в зависимости от того, какая перегрузка start ()
вызывается:
«Режим извлечения»: void QAudioOutput :: start (QIODevice *)
В этом режиме QAudioOutput будет извлекать данные из предоставленного QIODevice без дальнейшего вмешательства со стороны клиента. Это хороший выбор, если используется QIODevice, предоставляемый Qt (например, QFile , QAbstractSocket и т. Д.).
«Режим передачи»: QIODevice * QAudioOutput :: start ()
В этом режиме клиент QAudioOutput должен передать режим аудиоустройству, вызвав QIODevice :: write ()
. Это нужно будет делать в цикле, например:
qint64 dataRemaining = ...// присваиваем здесь правильное значение
while (dataRemaining) {
qint64 bytesWritten = audioOutput-> запись (буфер, dataRemaining);
dataRemaining - = bytesWritten;
buffer + = bytesWritten;
// Затем ждем ненадолго
}
Как реализовано ожидание, будет зависеть от контекста вашего приложения - если звук записывается из выделенного потока, это может быть просто sleep () . В качестве альтернативы, если звук записывается из основного потока, вы, вероятно, захотите, чтобы запись запускалась QTimer .
Поскольку вы ничего не упоминаете об использовании цикла вокруг вызовов write () в вашем приложении, похоже, что происходит то, что вы пишете короткий сегмент данных (который воспроизводится как всплывающий), а затем не больше не пишу.
Вы можете увидеть код, использующий оба режима в приложении examples / multimedia / audiooutput, которое поставляется с Qt.
Вы уверены, что используете правильный (высокоуровневый) API? Было бы странно, если бы вам пришлось обрабатывать потоки данных и буферизацию вручную. Кроме того, QIODevice::write() не обязательно записывает весь буфер, но может остановиться после n байт, как и POSIX write() (поэтому всегда нужно проверять возвращаемое значение).
Я пока не изучал QtMultimedia, но используя более зрелый Phonon, вывод видео и аудио работал просто отлично для меня в прошлом. Это работает так:
Есть также примеры в Qt.