Russian Qt Forum

Qt => Мультимедиа => Тема начата: ti0 от Январь 04, 2016, 23:53



Название: QAudioOutput и waitForBytesWritten
Отправлено: ti0 от Январь 04, 2016, 23:53
Всем привет!. Не могу справится с QAudioOutput. В нете все примеры с использованием сигнал/слотов, но мне это не подходит. Дело в том, что блокирующая функция waitForBytesWritten тупо не работает. Пытаюсь в бесконечном цикле опрашивать QAudioOutput::bytesFree(), и если буфер пуст, пишу туда данные, но звук получается с прерываниями. Когда я задаю размер буфера QAudioOutput::setBufferSize(16384), bytesFree возвращает 16380 - почему??
Параметры аудио у меня такие:
setSampleRate(48000);
setChannelCount(1);
setSampleSize(16);
setCodec("audio/pcm");
setByteOrder(QAudioFormat::LittleEndian);
setSampleType(QAudioFormat::SignedInt);

Прошу помощи, кто работал с QAudioOutput без сигнал/слотов


Название: Re: QAudioOutput и waitForBytesWritten
Отправлено: joffadark от Январь 05, 2016, 15:31
Не помню почему, но с QAudioOutput не сложилось по тем же причинам (дерганный звук). И как не старался его адаптировать, лучше не выходило.

Переделал в итоге на PortAudio с собственным простейшим Thread-safe буфером.

Когда есть готовый для воспроизведения PCM (например, после декодирования), кидаешь это в буфер (запись происходит в конец), который сам "следит" за своим размером. Когда PortAudio просит новую порцию на воспроизведения из буфера достается требуемое количество семплов.
Буфер защищен мьютексом, естесственно (так как дергается из разных нитей).

Если в буфере, по каким-то причинам (очень маловероятно такое. но, например, проблемы с сетью), нет данных, буфер "отдает" нули. Если при записи буфер уже распух до предела, то просто не добавляем новые PCM данные (тоже маловероятная вещь). На практике, размер данных в буфере болтается около нуля.
 


Название: Re: QAudioOutput и waitForBytesWritten
Отправлено: ti0 от Январь 05, 2016, 23:09
Я приложение для Android пишу. PortAudio там не пашет, хотя либа хорошая


Название: Re: QAudioOutput и waitForBytesWritten
Отправлено: Kurles от Январь 08, 2016, 12:06
Пытаюсь в бесконечном цикле опрашивать QAudioOutput::bytesFree(), и если буфер пуст, пишу туда данные, но звук получается с прерываниями.
Батарейку так посадишь быстро скорее всего.

Прошу помощи, кто работал с QAudioOutput без сигнал/слотов
Если хочешь работать в синхронном режиме - можно попробовать использовать QEventLoop, псевдокод:

Цитировать
    QAudioOutput *audioOutput;

    QEventLoop el;
    // после обработки аудио данных выход из евент лупа
    connect(audioOutput, SIGNAL(notify()), &el, SLOT(quit()));   
   
    // 40 миллисекунд интервал
    audioOutput->setNotifyInterval(40);
    QIODevice *ioDev = audioOutput->start();
    while (true) {
        // пишем аудиоданные длинной 40 мс
        ioDev->write(audioDataLenghtOf40Ms);
        // запускаем евентлуп
        el.exec();
        // .. по прошествии 40 мс решаем выходить ли из цикла или дальше проигрывать
    }

хыЖ чем сигналы и слоты не угодили?


Название: Re: QAudioOutput и waitForBytesWritten
Отправлено: ti0 от Январь 10, 2016, 15:54
Спасибо всем, я уже разобрался) В поставке Qt есть пример, по нему и делал. П.С. Бесконечный цикл грузит проц компа на 50%. Поставил sleep в 1 мс, нагрузка упала до 1 - 3 %


Название: Re: QAudioOutput и waitForBytesWritten
Отправлено: Akon от Январь 19, 2016, 13:28
Чтобы не было прерываний в звуковуху заталкиваются два (можно и больше) буфера. Когда первый воспроизведется, сразу же подхватится второй, а вам будет в этот момент предложено зарядить третий и т.д. Это называется двойной буферизацией. С одним буфером вы всегда будете иметь "щелчки".

Почему сигналы не подходят?