#include <QObject>#include <QIODevice>#include <QUdpSocket>#include <QHostAddress>#include <QAudioInput>#include <QAudioOutput>#include <QDebug>// Function returns constant audio format of all audio streams.QAudioFormat GetStreamAudioFormat(void);// Class produces a device to send audio over the network.class AudioTransmitter : public QIODevice{ Q_OBJECT public: QUdpSocket socket; QHostAddress localHOST; quint16 localPORT; QHostAddress remoteHOST; quint16 remotePORT; AudioTransmitter(QHostAddress localHost, quint16 localPort, QHostAddress remoteHost, quint16 remotePort); qint64 writeData(const char *data, qint64 len); qint64 readData(char *data, qint64 maxlen);};// Class produces a device to recieve audio from the network.class AudioReciever : public QIODevice{ Q_OBJECT public: QUdpSocket socket; QHostAddress localHOST; quint16 localPORT; QHostAddress remoteHOST; quint16 remotePORT; AudioReciever(QHostAddress localHost, quint16 localPort, QHostAddress remoteHost, quint16 remotePort); bool Bind(void); qint64 readData(char *data, qint64 maxlen); qint64 writeData(const char *data, qint64 len); bool isSequential(void) const; bool seek(qint64 pos); void Clear(void);};QAudioFormat GetStreamAudioFormat(void){ QAudioFormat format; format.setSampleRate(8000); format.setChannels(1); format.setSampleSize(8); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleType(QAudioFormat::UnSignedInt); QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice(); if (!info.isFormatSupported(format)) { qDebug()<< "default format not supported try to use nearest"; format = info.nearestFormat(format); } return format;}//////////////////////////////////// AudioTransmitter Class//////////////////////////////////AudioTransmitter::AudioTransmitter(QHostAddress localHost, quint16 localPort, QHostAddress remoteHost, quint16 remotePort){ localHOST = localHost; localPORT = localPort; remoteHOST = remoteHost; remotePORT = remotePort;}qint64 AudioTransmitter::writeData(const char *data, qint64 len){ qint64 writtenBytes = socket.writeDatagram(data, len, remoteHOST, remotePORT); //qDebug() << "Sent " << writtenBytes << " bytes."; return writtenBytes;}qint64 AudioTransmitter::readData(char *data, qint64 maxlen){ Q_UNUSED(data); Q_UNUSED(maxlen); qDebug() << "IOError: device is write-only."; return 0;}//////////////////////////////////// AudioReciever Class//////////////////////////////////AudioReciever::AudioReciever(QHostAddress localHost, quint16 localPort, QHostAddress remoteHost, quint16 remotePort){ localHOST = localHost; localPORT = localPort; remoteHOST = remoteHost; remotePORT = remotePort;}bool AudioReciever::Bind(void){ connect(&socket, SIGNAL(readyRead()), this, SIGNAL(readyRead())); return socket.bind(localHOST, localPORT, QUdpSocket::DontShareAddress); //qDebug() << "Successfully binded to" << localHOST.toString() << ":" << localPORT << ".";}qint64 AudioReciever::readData(char *data, qint64 maxlen){ qint64 readBytes = 0;// for (unsigned int i=0; i<2; i++)// if (socket.hasPendingDatagrams()) readBytes = socket.readDatagram(data, maxlen); qDebug() << "Recieved " << readBytes << " bytes."; return readBytes;}qint64 AudioReciever::writeData(const char *data, qint64 len){ Q_UNUSED(data); Q_UNUSED(len); qDebug() << "IOError: device is read-only."; return 0;}bool AudioReciever::isSequential(void) const{ return true;}bool AudioReciever::seek(qint64 pos){ Q_UNUSED(pos); return false;}void AudioReciever::Clear(void){// char * data;// qint64 size = 320;// while (socket.hasPendingDatagrams())// socket.readDatagram(data,size);}
#include <QThread>#include "audio.h"class VoIPClient : public QThread{ Q_OBJECT public: explicit VoIPClient(QObject *parent = 0); ~VoIPClient(void); void SetLocalHost(QHostAddress HOST); void SetLocalPort(quint16 PORT); void SetRemoteHost(QHostAddress HOST); void SetRemotePort(quint16 PORT); void GetUserInfo(QString LOGIN); public slots: void Call(void); void FinishCall(void); void ResumePlaying(void); void ResumePlaying(QAudio::State); private slots: void StartPlaying(void); protected: void run(void); private: QHostAddress localHOST; QHostAddress remoteHOST; quint16 localPORT; quint16 remotePORT; QAudioInput * audio_input; QAudioOutput * audio_output; AudioTransmitter * transmitter; AudioReciever * reciever; void StartConversation(void); void StopConversation(void); volatile bool stopped; signals: };VoIPClient::VoIPClient(QObject *parent) : QThread(parent){ stopped = false;}VoIPClient::~VoIPClient(void){}void VoIPClient::run(void){ QAudioFormat format = GetStreamAudioFormat(); audio_input = new QAudioInput(format); audio_output = new QAudioOutput(format); transmitter = new AudioTransmitter(localHOST, localPORT, remoteHOST, remotePORT); reciever = new AudioReciever(localHOST, localPORT, remoteHOST, remotePORT); //connect(audio_output, SIGNAL(stateChanged(QAudio::State)), this, SLOT(ResumePlaying(QAudio::State))); connect(reciever, SIGNAL(readyRead()), this, SLOT(ResumePlaying())); reciever->Bind(); transmitter->open(QIODevice::WriteOnly | QIODevice::Truncate); reciever->open(QIODevice::ReadOnly); audio_output->start(reciever);// reciever->Clear(); audio_input->start(transmitter); qDebug() << "Started conversation with" << remoteHOST.toString() << "."; exec(); audio_input->stop(); audio_output->stop(); transmitter->close(); reciever->close(); delete audio_input; delete audio_output; delete transmitter; delete reciever; qDebug() << "Finished conversation.";}void VoIPClient::Call(void){ start();}void VoIPClient::FinishCall(void){ exit(0);}void VoIPClient::StartConversation(void){}void VoIPClient::StopConversation(void){}void VoIPClient::StartPlaying(void){ audio_output->start(reciever);}void VoIPClient::ResumePlaying(void){ if (audio_output->state() != QAudio::ActiveState) { audio_output->stop(); audio_output->start(reciever); }}void VoIPClient::ResumePlaying(QAudio::State state){ if (state != QAudio::ActiveState) { audio_output->stop(); audio_output->start(reciever); }}void VoIPClient::SetLocalHost(QHostAddress HOST){ localHOST = HOST;}void VoIPClient::SetLocalPort(quint16 PORT){ localPORT = PORT;}void VoIPClient::SetRemoteHost(QHostAddress HOST){ remoteHOST = HOST;}void VoIPClient::SetRemotePort(quint16 PORT){ remotePORT = PORT;}
AudioReciever::Bind(){ connect(&socket, SIGNAL(readyRead()), this, SLOT(myPrivateReadSocket()));...}AudioReciever::myPrivateReadSocket(){// QByteArray m_datagram is private bufferwhile (udpSocket->hasPendingDatagrams()) { QByteArray tmp; tmp.resize(udpSocket->pendingDatagramSize()); socket.readDatagram(tmp.data(), tmp.size()); m_datagram.append(tmp); } emit readyRead(); }qint64 AudioReciever::readData(char *data, qint64 maxlen){ qint64 readBytes = qMin(m_datagram.size(), maxlen); // copy readBytes bytes from m_datagram to data and remove this bytes from m_datagram return readBytes;}
bool AudioReciever::Bind(void){ connect(&socket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); return socket.bind(localHOST, localPORT, QUdpSocket::DontShareAddress);}void AudioReciever::readPendingDatagrams(void){ while (socket.hasPendingDatagrams()) { QByteArray tmp; tmp.resize(socket.pendingDatagramSize()); socket.readDatagram(tmp.data(), tmp.size()); m_datagram.append(tmp); } emit readyRead();}qint64 AudioReciever::readData(char *data, qint64 maxlen){ qint64 readBytes = qMin(qint64(m_datagram.size()), maxlen); if (readBytes > 0) { QByteArray tmp = m_datagram.left(readBytes); m_datagram.remove(0,readBytes); data = new char[readBytes]; char * tmp_ptr = tmp.data(); for (unsigned int i = 0; i < readBytes; i++) data[i] = tmp_ptr[i]; qDebug() << "Recieved " << readBytes << " bytes."; } return readBytes;}
void VoIPClient::ResumePlaying(void){ if (audio_output->state() != QAudio::ActiveState) { audio_output->stop(); audio_output->start(reciever); }}
connect(reciever, SIGNAL(readyRead()), this, SLOT(ResumePlaying()));
#include <QObject>#include <QtGlobal>#include <QIODevice>#include <QUdpSocket>#include <QHostAddress>#include <QAudioInput>#include <QAudioOutput>#include <QDebug>// Function returns constant audio format of all audio streams.QAudioFormat GetStreamAudioFormat(void);// Class produces a device to send audio over the network.class AudioTransmitter : public QIODevice{ Q_OBJECT public: AudioTransmitter(quint16 localPort, QHostAddress remoteHost, quint16 remotePort); qint64 writeData(const char *data, qint64 len); qint64 readData(char *data, qint64 maxlen); private: QUdpSocket socket; quint16 localPORT; QHostAddress remoteHOST; quint16 remotePORT;};// Class produces a device to recieve audio from the network.class AudioReciever : public QIODevice{ Q_OBJECT public: AudioReciever(quint16 localPort, QHostAddress remoteHost, quint16 remotePort); bool Bind(void); bool isSequential(void) const; bool seek(qint64 pos); qint64 readData(char *data, qint64 maxlen); qint64 writeData(const char *data, qint64 len); private: QUdpSocket socket; quint16 localPORT; QHostAddress remoteHOST; quint16 remotePORT; QByteArray buffer; private slots: void readPendingDatagrams(void);};QAudioFormat GetStreamAudioFormat(void){ QAudioFormat format; format.setSampleRate(8000); format.setChannels(1); format.setSampleSize(8); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleType(QAudioFormat::UnSignedInt); QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice(); if (!info.isFormatSupported(format)) { qDebug()<< "default format not supported try to use nearest"; format = info.nearestFormat(format); } return format;}//////////////////////////////////// AudioTransmitter Class//////////////////////////////////AudioTransmitter::AudioTransmitter(quint16 localPort, QHostAddress remoteHost, quint16 remotePort){ localPORT = localPort; remoteHOST = remoteHost; remotePORT = remotePort;}qint64 AudioTransmitter::writeData(const char *data, qint64 len){ qint64 writtenBytes = socket.writeDatagram(data, len, remoteHOST, remotePORT); return writtenBytes;}qint64 AudioTransmitter::readData(char *data, qint64 maxlen){ Q_UNUSED(data); Q_UNUSED(maxlen); qDebug() << "IOError: device is write-only."; return 0;}//////////////////////////////////// AudioReciever Class//////////////////////////////////AudioReciever::AudioReciever(quint16 localPort, QHostAddress remoteHost, quint16 remotePort){ localPORT = localPort; remoteHOST = remoteHost; remotePORT = remotePort;}bool AudioReciever::Bind(void){ connect(&socket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); return socket.bind(QHostAddress::Any, localPORT, QUdpSocket::DontShareAddress);}bool AudioReciever::isSequential(void) const{ return true;}bool AudioReciever::seek(qint64 pos){ Q_UNUSED(pos); return false;}void AudioReciever::readPendingDatagrams(void){ while (socket.hasPendingDatagrams()) { QByteArray tmp; tmp.resize(socket.pendingDatagramSize()); socket.readDatagram(tmp.data(), tmp.size()); buffer.append(tmp); } emit readyRead();}qint64 AudioReciever::readData(char *data, qint64 maxlen){ qint64 readBytes = qMin(qint64(buffer.size()), maxlen); if (readBytes > 0) { QByteArray tmp = buffer.left(readBytes); buffer.remove(0,readBytes); data = new char[readBytes]; char * tmp_ptr = tmp.data(); for (unsigned int i = 0; i < readBytes; i++) data[i] = tmp_ptr[i]; qDebug() << "Recieved " << readBytes << " bytes."; } return readBytes;}qint64 AudioReciever::writeData(const char *data, qint64 len){ Q_UNUSED(data); Q_UNUSED(len); qDebug() << "IOError: device is read-only."; return 0;}
#include <QThread>class VoIPClient : public QThread{ Q_OBJECT public: explicit VoIPClient(QObject *parent = 0); ~VoIPClient(void); void SetLocalPort(quint16 PORT); void SetRemoteHost(QHostAddress HOST); void SetRemotePort(quint16 PORT); public slots: void Call(void); void FinishCall(void); void ResumePlaying(void); void ResumePlaying(QAudio::State); protected: void run(void); private: QHostAddress remoteHOST; quint16 localPORT; quint16 remotePORT; QAudioInput * audio_input; QAudioOutput * audio_output; AudioTransmitter * transmitter; AudioReciever * reciever; };VoIPClient::VoIPClient(QObject *parent) : QThread(parent){}VoIPClient::~VoIPClient(void){}void VoIPClient::run(void){ QAudioFormat format = GetStreamAudioFormat(); audio_input = new QAudioInput(format); audio_output = new QAudioOutput(format); transmitter = new AudioTransmitter(localPORT, remoteHOST, remotePORT); reciever = new AudioReciever(localPORT, remoteHOST, remotePORT); //connect(audio_output, SIGNAL(stateChanged(QAudio::State)), this, SLOT(ResumePlaying(QAudio::State))); connect(reciever, SIGNAL(readyRead()), this, SLOT(ResumePlaying())); reciever->Bind(); transmitter->open(QIODevice::WriteOnly | QIODevice::Truncate); reciever->open(QIODevice::ReadOnly); audio_output->start(reciever); audio_input->start(transmitter); qDebug() << "Started conversation with" << remoteHOST.toString() << "."; exec(); audio_input->stop(); audio_output->stop(); transmitter->close(); reciever->close(); delete audio_input; delete audio_output; delete transmitter; delete reciever; qDebug() << "Finished conversation.";}void VoIPClient::Call(void){ start();}void VoIPClient::FinishCall(void){ exit(0);}void VoIPClient::ResumePlaying(void){ if (audio_output->state() != QAudio::ActiveState) { audio_output->start(reciever); }}void VoIPClient::ResumePlaying(QAudio::State state){ if (state != QAudio::ActiveState) { audio_output->start(reciever); }}void VoIPClient::SetLocalPort(quint16 PORT){ localPORT = PORT;}void VoIPClient::SetRemoteHost(QHostAddress HOST){ remoteHOST = HOST;}void VoIPClient::SetRemotePort(quint16 PORT){ remotePORT = PORT;}
QMutexLocker locker(&mutex); QByteArray tmp = buffer.left(readBytes); buffer.remove(0,readBytes);locker.unlock();
AudioReciever::AudioReciever(quint16 localPort, QHostAddress remoteHost, quint16 remotePort){ localPORT = localPort; remoteHOST = remoteHost; remotePORT = remotePort; dest = new QFile("C:\\test.raw"); dest->open(QIODevice::WriteOnly | QIODevice::Truncate);}AudioReciever::~AudioReciever(void){ dest->close(); delete dest;}bool AudioReciever::Bind(void){ connect(&socket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); return socket.bind(QHostAddress::Any, localPORT, QUdpSocket::DontShareAddress);}bool AudioReciever::isSequential(void) const{ return true;}bool AudioReciever::seek(qint64 pos){ Q_UNUSED(pos); return false;}void AudioReciever::readPendingDatagrams(void){ while (socket.hasPendingDatagrams()) { QByteArray tmp; tmp.resize(socket.pendingDatagramSize()); socket.readDatagram(tmp.data(), tmp.size()); QMutexLocker locker(&mutex); buffer.append(tmp); locker.unlock(); qDebug() << "Recieved " << tmp.size() << " bytes."; emit readyRead(); }}qint64 AudioReciever::readData(char *data, qint64 maxlen){ qint64 readBytes = qMin(qint64(buffer.size()), maxlen); if (readBytes > 0) { QMutexLocker locker(&mutex); QByteArray tmp = buffer.left(readBytes); buffer.remove(0,readBytes); locker.unlock(); data = new char[readBytes]; qstrncpy(data, tmp.data(), readBytes); dest->write(tmp.data(), tmp.size()); qDebug() << "Returned from AudioReciever::readData():" << readBytes; } return readBytes;}qint64 AudioReciever::writeData(const char *data, qint64 len){ Q_UNUSED(data); Q_UNUSED(len); qDebug() << "IOError: device is read-only."; return 0;}
void VoIPClient::ResumePlaying(void){ if (audio_output->state() != QAudio::ActiveState) { audio_output->start(reciever); }}
QAudio::ActiveState == QAudio::IdleState
#include <QObject>#include <QIODevice>#include <QUdpSocket>#include <QHostAddress>#include <QAudioInput>#include <QAudioOutput>// Function returns constant audio format of all audio streams.QAudioFormat GetStreamAudioFormat(void);// Class produces a device to capture and send audio over the network.class AudioTransmitter : public QObject{ Q_OBJECT public: AudioTransmitter(quint16 localPort, QHostAddress remoteHost, quint16 remotePort); void Start(void); void Stop(void); private: QUdpSocket socket; QAudioInput * audio_input; QIODevice * audio_device; quint16 localPORT; QHostAddress remoteHOST; quint16 remotePORT; const qint64 maxsize; private slots: void sendDatagrams(void);};// Class produces a device to recieve audio from the network and play it.class AudioReciever : public QObject{ Q_OBJECT public: AudioReciever(quint16 localPort, QHostAddress remoteHost, quint16 remotePort); bool Start(void); void Stop(void); private: QUdpSocket socket; QAudioOutput * audio_output; QIODevice * audio_device; quint16 localPORT; QHostAddress remoteHOST; quint16 remotePORT; private slots: void readPendingDatagrams(void);};QAudioFormat GetStreamAudioFormat(void){ QAudioFormat format; format.setSampleRate(44100); format.setChannels(1); format.setSampleSize(16); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleType(QAudioFormat::UnSignedInt); QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice(); if (!info.isFormatSupported(format)) format = info.nearestFormat(format); return format;}//////////////////////////////////// AudioTransmitter Class//////////////////////////////////AudioTransmitter::AudioTransmitter(quint16 localPort, QHostAddress remoteHost, quint16 remotePort) : maxsize(8192){ localPORT = localPort; remoteHOST = remoteHost; remotePORT = remotePort;}void AudioTransmitter::Start(void){ audio_input = new QAudioInput(GetStreamAudioFormat()); audio_device = audio_input->start(); connect(audio_device, SIGNAL(readyRead()), this, SLOT(sendDatagrams()));}void AudioTransmitter::Stop(void){ audio_input->stop(); delete audio_input; socket.close(); disconnect(audio_device, SIGNAL(readyRead()), this, SLOT(sendDatagrams()));}void AudioTransmitter::sendDatagrams(void){ QByteArray tmp = audio_device->read(maxsize); socket.writeDatagram(tmp.data(), tmp.size(), remoteHOST, remotePORT);}//////////////////////////////////// AudioReciever Class//////////////////////////////////AudioReciever::AudioReciever(quint16 localPort, QHostAddress remoteHost, quint16 remotePort){ localPORT = localPort; remoteHOST = remoteHost; remotePORT = remotePort;}bool AudioReciever::Start(void){ audio_output = new QAudioOutput(GetStreamAudioFormat()); audio_device = audio_output->start(); connect(&socket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); return socket.bind(QHostAddress::Any, localPORT, QUdpSocket::DontShareAddress);}void AudioReciever::Stop(void){ audio_output->stop(); delete audio_output; socket.close(); disconnect(&socket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));}void AudioReciever::readPendingDatagrams(void){ while (socket.hasPendingDatagrams()) { qint64 size = socket.pendingDatagramSize(); char * data = new char[size]; socket.readDatagram(data, size); audio_device->write(data, size); }}
#include <QThread>class VoIPClient : public QThread{ Q_OBJECT public: explicit VoIPClient(QObject *parent = 0); void SetLocalPort(quint16 PORT); void SetRemoteHost(QHostAddress HOST); void SetRemotePort(quint16 PORT); public slots: void Call(void); void FinishCall(void); protected: void run(void); private: AudioTransmitter * transmitter; AudioReciever * reciever; QHostAddress remoteHOST; quint16 localPORT; quint16 remotePORT; };VoIPClient::VoIPClient(QObject *parent) : QThread(parent){}void VoIPClient::run(void){ transmitter = new AudioTransmitter(localPORT, remoteHOST, remotePORT); reciever = new AudioReciever(localPORT, remoteHOST, remotePORT); reciever->Start(); transmitter->Start(); exec(); transmitter->Stop(); reciever->Stop(); delete transmitter; delete reciever;}void VoIPClient::Call(void){ start();}void VoIPClient::FinishCall(void){ exit(0);}void VoIPClient::SetLocalPort(quint16 PORT){ localPORT = PORT;}void VoIPClient::SetRemoteHost(QHostAddress HOST){ remoteHOST = HOST;}void VoIPClient::SetRemotePort(quint16 PORT){ remotePORT = PORT;}