карту? Возникают щелчки из-за задержки между пакетами. Один пакет (звук 200мс) система воспроизводит сразу и между воспроизведением следующего(поступает через 200мс) происходит этот самый щелчок. На одной машине реализовал через временную задержку для выдачи первого пакета на карту и она как надо все воспроизводила без какого-либо шума в виде щелчков. А на этой запустил - все те же щелчки. Буффер в QAudioOutput только усугубляет ситуацию
ивент луп задействован или еще какой-то не детерминируемый по исполнению код?
Нет. Все в основном потоке
покажи какой код
кросс платформа нужна прям обязательно?
Как я понял, только для поддержки unix-систем
я бы посмотрел функции общения с драйверами в режиме нотификации при завершении операции, чтоб следующий кусок отправлялся по колбэку, когда драйвер завершил обработку. Не писал звуковые штуки, но я бы смотрел в этом направлении
void Oscilloscope::connect(){ QObject::connect(_connector, &CfiConnector::audioDataReceived, this, &Oscilloscope::updateLine); if (_configs->getOutToCard()) QObject::connect(_connector, &CfiConnector::audioDataReceived, this, &Oscilloscope::writeToAudiocard); } void CfiConnector::onReadyRead(){ while (_localSocket.hasPendingDatagrams()){ auto datagram = _localSocket.receiveDatagram(); if(datagram.senderAddress() != _remoteAddress && datagram.senderPort() != _remotePort) return; auto data = datagram.data(); switch(data.at(0)){ case 0x03: emit audioDataReceived(data); break; default: break; } } } void Oscilloscope::writeToAudiocard(const QByteArray &bytes){ QVector<qint16> linear; linear.reserve(2000); std::transform(bytes.begin() + 16, bytes.end(), std::back_inserter(linear), [](char byte)->qint16 { return Oscilloscope::indexTo(byte); }); _audioOut->writeData(reinterpret_cast<const char*>(linear.data()), 4000); } qint64 AudioOut::writeData(const char *data, qint64 maxlen){ //_buffer.writeData(QByteArray(data, maxlen)); _ioDevice->write(data, maxlen); return 0; } Вот 4 связанные между собой функции
Ох. Тогда надо лезть в библиотеки драйвера Хорошо. Чекну, спасибо
ну ивентлуп в полный рост у тебя тут
Ну эти никуда не убрать, пожалуй. Разве что на месте приеме передавать на карту, посмотрю чуть позже
Если кто-нибудь будет долбится об такую же хрень, оставлю здесь: qint64 AudioOut::writeData(const char *data, qint64 maxlen){ std::vector<char> vData(data, data+maxlen); _buffer.insert(_buffer.end(), vData.begin(), vData.end()); _writeFunction(this); return 0; } void AudioOut::delayWriteToCard() { _sink->setNotifyInterval(100); connect(_sink, &QAudioOutput::notify, this, &AudioOut::writeToCard); QTimer::singleShot(DELAY_TIME, this, &AudioOut::writeToCard); _writeFunction = &AudioOut::writeToCard; } void AudioOut::writeToCard(){ int min = qMin((int)_buffer.size(), _sink->bytesFree()); qDebug() << "AudioOut::writeToCard" << min << _sink->bytesFree() << _buffer.size(); if (_sink->bytesFree() > 0){ _ioDevice->write(_buffer.data(), min); _buffer.erase(_buffer.begin(), _buffer.begin() + min); } } void AudioOut::start() { if (_sink->state() == QAudio::StoppedState){ _sink->stop(); _writeFunction = &AudioOut::delayWriteToCard; //_buffer.reset(); _ioDevice = _sink->start(); } } void AudioOut::stop() { disconnect(_sink, &QAudioOutput::notify, this, &AudioOut::writeToCard); _sink->stop(); }
лучше сделай простую демку и выложи где-то, чтобы потом кто-то мог собрать и попробовать.
На выходных тогда закину куда-нибудь
Обсуждают сегодня