Reputation: 51
First, I'm trying to send audio data from one process to other via the UDP protocol on localhost.
First, the program reads voice from the microphone and sends it via UDP socket:
#include <QApplication>
#include <QIODevice>
#include <QtMultimediaKit/QAudioOutput>
#include <QtMultimediaKit/QAudioInput>
#include <QtMultimediaKit/QAudioFormat>
#include <QUdpSocket>
int main(int argc, char** argv){
QApplication app(argc, argv);
QAudioFormat format;
format.setSampleRate(128000);
format.setChannelCount(1);
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::UnSignedInt);
QAudioInput* input = new QAudioInput(format);
QUdpSocket* socket = new QUdpSocket();
socket->connectToHost("127.0.0.1", 1002);
input->start(socket);
return app.exec();
}
I check data sending in by Wireshark, and I think data is sent. So many UDP packages per second on the 1002 port.
The second program should read UDP packages and play it in the output device:
#include "UDPPlayer.h"
#include <QDebug>
UDPPlayer::UDPPlayer(){
socket = new QUdpSocket();
socket->bind(1002);
QAudioFormat format;
format.setSampleRate(128000);
format.setChannelCount(1);
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::UnSignedInt);
output = new QAudioOutput(format);
connect(socket, SIGNAL(readyRead()), this, SLOT(playData()));
}
void UDPPlayer::playData(){
qDebug() << "data";
output->start(socket);
}
The problem is the following: playData()
is never called ("data" is never printed). Does it mean that the socket is never readyRead
? But I see these packages by Wireshark. What am I doing wrong?
Upvotes: 1
Views: 4314
Reputation: 2881
You need make sure that the format used is supported by the input and output devices.
You also need to create a QIODevice
from the output device, in order to write data to it, such data you will get with socket->readDatagram()
And you need to do something like this:
main.cpp:
#include <QApplication>
#include <QIODevice>
#include <QtMultimedia/QAudioOutput>
#include <QtMultimedia/QAudioInput>
#include <QtMultimedia/QAudioFormat>
#include <QUdpSocket>
#include "udpplayer.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
new UDPPlayer();
QAudioFormat format;
format.setSampleRate(128000);
format.setChannelCount(1);
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::UnSignedInt);
//If format isn't supported find the nearest supported
QAudioDeviceInfo info(QAudioDeviceInfo::defaultInputDevice());
if (!info.isFormatSupported(format))
format = info.nearestFormat(format);
QAudioInput* input = new QAudioInput(format);
QUdpSocket* socket = new QUdpSocket();
socket->connectToHost("127.0.0.1", 1002);
input->start(socket);
return a.exec();
}
udpplayer.h:
#include <QObject>
#include <QtMultimedia/QAudioOutput>
#include <QtMultimedia/QAudioInput>
#include <QtMultimedia/QAudioFormat>
#include <QUdpSocket>
class UDPPlayer : public QObject
{
Q_OBJECT
public:
explicit UDPPlayer(QObject *parent = 0);
private slots:
void playData();
private:
QAudioOutput *output;
QUdpSocket *socket;
QIODevice *device;
};
udpplayer.cpp:
UDPPlayer::UDPPlayer(QObject *parent) : QObject(parent)
{
socket = new QUdpSocket();
socket->bind(1002);
QAudioFormat format;
format.setSampleRate(128000);
format.setChannelCount(1);
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::UnSignedInt);
QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
if (!info.isFormatSupported(format))
format = info.nearestFormat(format);
output = new QAudioOutput(format);
device = output->start();
connect(socket, SIGNAL(readyRead()), this, SLOT(playData()));
}
void UDPPlayer::playData()
{
//You need to read datagrams from the udp socket
while (socket->hasPendingDatagrams())
{
QByteArray data;
data.resize(socket->pendingDatagramSize());
socket->readDatagram(data.data(), data.size());
device->write(data.data(), data.size());
}
}
Upvotes: 2