【发布时间】:2018-12-01 15:40:27
【问题描述】:
我的目标是通过 LAN 网络传输 *.wav 文件,没有延迟或最少。
我们还分部分读取服务器机器上的文件,均为 320 字节。在此之后,我们通过 UDP 发送数据包并在 jitter-buffer 中写入接收。抖动缓冲区的大小为 10。 我应该在计时器上设置什么延迟才能获得清晰的声音?
这里是发件人:
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.";
}
这是接收器和播放器:
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();
}
【问题讨论】:
-
我没有看你的代码,因为我不熟悉Qt,但是关于通过lans发送音频的一些一般性说明: 1.虽然丢包率很低,但你还是要做好偶尔的准备数据包丢失。 2. 我没有大量的 lan 经验,但我猜你可以得到大约 100 毫秒或更短的延迟。
-
100 毫秒,流式音频的延迟太高了...是的,我准备丢包,因为我使用 UDP。但我想在输出时获得清晰的声音。我使用缓冲数据(例如在 last.fm 上这样做)
-
另外,我如何理解如果我使用:sampleRate = 8000 kHz sampleSize = 8 位并从文件中读取 320 字节,那么我在数据中有 5ms 的声音,例如抖动缓冲区的大小是 10 个单元格我有 5*10 毫秒的抖动缓冲区延迟 + 5 毫秒的打包延迟。结果我将有 55 毫秒的总延迟。不是吗?让我知道是否有误。
-
您说“100 毫秒它对于流式音频的延迟太高了......”,这取决于您的应用程序:对于语音/电话,不。可能是为了音乐。对于视频,也许(我会尝试将视频应用程序的音频总延迟保持在一个视频帧以下,通常约为 1/30 秒 = 33 毫秒)。如果您需要所有客户端以相位精确的同步播放音频,您将需要比您正在做的更复杂的方法。
-
忽略标头,未压缩的单声道 8 位 8kHz 文件在每个 320 字节块中包含 40 毫秒:1 个样本 = 8 位 = 8 字节。 8 kHz/320 个样本 = .04 秒 = 40 毫秒。请注意,我通过让单位取消 (Hz = 1/sec) en.wikipedia.org/wiki/Dimensional_analysis 来计算
标签: qt audio streaming networkstream