How can I play streaming audio over Ethernet in Qt?

My goal is to transfer a * .wav file over a local network without delay or with a minimum.

We also read the file on the server machine in parts, 320 bytes each. After that, we send packets over UDP and record the reception in jitter-buffer. The jitter buffer size is 10. What delays should be set on timers for clear sound?

Here is the sender:

void MainWindow::on_start_tx_triggered() { timer1 = new QTimer (this); udpSocketout = new QUdpSocket(this); qDebug()<<"Start"; for (int i = 0; i < playlist.size(); ++i) { inputFile.setFileName(playlist.at(i)); qDebug()<<inputFile.fileName(); if (!inputFile.open(QIODevice::ReadOnly)) { qDebug()<< "file not found;"; } } connect(timer1, SIGNAL(timeout()), this, SLOT(writeDatagrams())); timer1->start(5); } void MainWindow::writeDatagrams() { if(!inputFile.atEnd()){ payloadout = inputFile.read(320); } qDebug()<<payloadout; QDataStream out(&datagramout, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_7); out << qint64(0); out << payloadout; out.device()->seek(qint64(0)); out << qint64(datagramout.size() - sizeof(qint64)); qint64 writtenBytes = udpSocketout->writeDatagram(datagramout, remoteHOST, remotePORT); qDebug() << "Sent " << writtenBytes << " bytes."; } 

Here is the receiver and player:

 void MainWindow::on_start_rx_triggered() { udpSocketin = new QUdpSocket(this); udpSocketin->bind(localHOST, localPORT); connect(udpSocketin, SIGNAL(readyRead()), this, SLOT(readDatagrams())); QDataStream out(&datagramout, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_7); timer2 = new QTimer (this); connect(timer2, SIGNAL(timeout()), this, SLOT(playbuff())); timer2->start(50); audioout = new QAudioOutput(format, this); } void MainWindow::readDatagrams() { datagramin.resize(udpSocketin->pendingDatagramSize()); qint64 receiveBytes = udpSocketin->readDatagram(datagramin.data(), datagramin.size()); qDebug() << "Receive " << receiveBytes << " bytes."; QDataStream in(&datagramin, QIODevice::ReadOnly); in.setVersion(QDataStream::Qt_4_7); quint64 size = 0; if(in.device()->size() > sizeof(quint64)) { in >> size; } else return; if(in.device()->size() < size) return; in >> payloadin; qDebug() << payloadin.size(); emit jitterbuff(); } void MainWindow::jitterbuff() { if (buff_pos < SIZE_OF_BUF) { QDataStream out(&buffered, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_7); out << payloadin; buff_pos++; } else buff_pos = 0; } void MainWindow::playbuff() { qDebug() << "YES!!!"; buffer = new QBuffer(&buffered); buffer->open(QIODevice::ReadOnly); audioout->start(buffer); QEventLoop loop; QTimer::singleShot(50, &loop, SLOT(quit())); loop.exec(); buffer->close(); } 
+8
source share
1 answer

This issue has been resolved. QAdioOutput has two modes; there are push and pull. I give a pointer to a QIODevice and write data directly. Decision:

Reading UDP socket:

 void MainWindow::on_start_rx_triggered() { udpSocketin = new QUdpSocket(this); udpSocketin->bind(localPORT); connect(udpSocketin, SIGNAL(readyRead()), this, SLOT(readDatagrams())); QDataStream out(&datagramout, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_7); timer2 = new QTimer (this); connect(timer2, SIGNAL(timeout()), this, SLOT(playbuff())); timer2->setInterval(15*9); audioout = new QAudioOutput(format, this); input = audioout->start(); } void MainWindow::readDatagrams() { if (udpSocketin->hasPendingDatagrams()){ datagramin.resize(udpSocketin->pendingDatagramSize()); qint64 receiveBytes = udpSocketin->readDatagram(datagramin.data(), datagramin.size()); if (receiveBytes <= 0) { msg.warning(this, "File ERROR", "The end!", QMessageBox::Ok); emit on_stop_rx_triggered(); } QDataStream in(&datagramin, QIODevice::ReadOnly); in.setVersion(QDataStream::Qt_4_7); quint64 size = 0; if(in.device()->size() > sizeof(quint64)) { in >> size; } else return; in >> rxfilename; in >> name; in >> payloadin; emit jitterbuff(); } void MainWindow::jitterbuff() { if (buff_pos < SIZE_OF_BUF) { buffered.append(payloadin); buff_pos++; } else { timer2->start(); buffered.clear(); buff_pos = 0; } } void MainWindow::playbuff() { if (!buffered.isEmpty()) { buffer = new QBuffer(&buffered); buffer->open(QIODevice::ReadOnly); input->write(buffered); buffer->close(); } } 

Write to UDP socket:

 void MainWindow::on_start_tx_triggered() { timer1 = new QTimer (this); udpSocketout = new QUdpSocket(this); inputFile.setFileName(playlist.at(playIDfile)); if (!inputFile.open(QIODevice::ReadOnly)) { msg.warning(this, "File ERROR", "File not found!", QMessageBox::Ok); return; } fileinfo = new QFileInfo (inputFile); txfilename = fileinfo->fileName(); ui->playedFile->setText("Now played: " + txfilename); connect(timer1, SIGNAL(timeout()), this, SLOT(writeDatagrams())); timer1->start(15); } void MainWindow::writeDatagrams() { if(!inputFile.atEnd()){ payloadout = inputFile.read(SIZE_OF_SOUND); QDataStream out(&datagramout, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_7); out << qint64(0); out << txfilename; out << name; out << payloadout; out.device()->seek(qint64(0)); out << qint64(datagramout.size() - sizeof(qint64)); qint64 writtenBytes = udpSocketout->writeDatagram(datagramout, remoteHOST, remotePORT); } } 

If someone has a problem, I will try to help him / her.

+7
source

All Articles