Russian Qt Forum
Май 12, 2024, 22:30 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QAudioOutput и waitForBytesWritten  (Прочитано 6818 раз)
ti0
Новичок

Offline Offline

Сообщений: 38


Просмотр профиля
« : Январь 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 без сигнал/слотов
Записан
joffadark
Гость
« Ответ #1 : Январь 05, 2016, 15:31 »

Не помню почему, но с QAudioOutput не сложилось по тем же причинам (дерганный звук). И как не старался его адаптировать, лучше не выходило.

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

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

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

Offline Offline

Сообщений: 38


Просмотр профиля
« Ответ #2 : Январь 05, 2016, 23:09 »

Я приложение для Android пишу. PortAudio там не пашет, хотя либа хорошая
Записан
Kurles
Бывалый
*****
Offline Offline

Сообщений: 480



Просмотр профиля
« Ответ #3 : Январь 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 мс решаем выходить ли из цикла или дальше проигрывать
    }

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

Код
C++ (Qt)
while(!asleep()) sheep++;
ti0
Новичок

Offline Offline

Сообщений: 38


Просмотр профиля
« Ответ #4 : Январь 10, 2016, 15:54 »

Спасибо всем, я уже разобрался) В поставке Qt есть пример, по нему и делал. П.С. Бесконечный цикл грузит проц компа на 50%. Поставил sleep в 1 мс, нагрузка упала до 1 - 3 %
Записан
Akon
Гость
« Ответ #5 : Январь 19, 2016, 13:28 »

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

Почему сигналы не подходят?
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.066 секунд. Запросов: 20.