I am trying to develop a server that will stream real time audio to a client. Right now I am able to stream the "audio/pcm" audio data through the default input device from the computer and able to print the amplitude in a painter on the server widget. The problem is that when I receive the raw audio data on the client, I cannot create an intelligible output out of that audio data.

Qt Code:
  1. void AudioStreamer::on_listen_clicked()
  2. {
  3. //This method formats the audio and then defines the device
  4. m_format.setSampleRate(8000);//QAudioFormat m_format;
  5. m_format.setChannelCount(1);
  6. m_format.setSampleSize(16);
  7. m_format.setSampleType(QAudioFormat::SignedInt);
  8. m_format.setByteOrder(QAudioFormat::LittleEndian);
  9. m_format.setCodec("audio/pcm");
  10.  
  11. QAudioDeviceInfo devinfo(QAudioDeviceInfo::defaultInputDevice());
  12. if (!devinfo.isFormatSupported(m_format)) {
  13. qWarning() << "Default format not supported - trying to use nearest";
  14. m_format = devinfo.nearestFormat(m_format);
  15. }
  16.  
  17. m_audioInfo = new AudioInfo(m_format, this);
  18.  
  19. m_audioInput = new QAudioInput(devinfo, m_format, this);
  20. connect(m_audioInfo, SIGNAL(update(QByteArray)), SLOT(refreshDisplay(QByteArray)));
  21. quint16 port = ui->portNumber->text().toInt();
  22. server = new Server(port, this);
  23.  
  24.  
  25. m_audioInfo->start();
  26. m_audioInput->start(m_audioInfo);
  27.  
  28. ui->portNumber->setEnabled(false);
  29. ui->listen->setEnabled(false);
  30. }
  31.  
  32.  
  33. void AudioStreamer::refreshDisplay(QByteArray data)
  34. {
  35. //This method streams the audio through the server
  36. server->writeData(data);
  37. m_canvas->setLevel(m_audioInfo->level());
  38. }
To copy to clipboard, switch view to plain text mode 

Please ignore m_audioInfo and AudioInfo as they are only used for painting the amplitude of the audio on the input device.

When I am trying the play the received audio by the client, I am also trying to print the different properties of the audio format:

Qt Code:
  1. void Client::readyRead()
  2. {
  3. QByteArray data;
  4.  
  5. while (socket->bytesAvailable() > 0)
  6. data.append(socket->readAll());
  7.  
  8. qDebug() << "The size of the WAV file is: " << data.size();
  9. QBuffer* audio_buffer = new QBuffer(&data);
  10. audio_buffer->open(QIODevice::ReadOnly);
  11. qDebug() << audio_buffer->size();
  12.  
  13. QAudioFormat format;
  14.  
  15. format.setSampleSize(16);
  16. format.setSampleRate(8000);
  17. format.setChannelCount(1);
  18. format.setCodec("audio/pcm");
  19. format.setByteOrder(QAudioFormat::LittleEndian);
  20. format.setSampleType(QAudioFormat::SignedInt);
  21.  
  22. QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
  23. if (!info.isFormatSupported(format)) {
  24. qWarning()<<"raw audio format not supported by backend, cannot play audio.";
  25. return;
  26. }
  27. qDebug() << info.deviceName();
  28.  
  29. QAudioOutput* testoutput = new QAudioOutput(info, format);
  30. testoutput->start(audio_buffer);
  31.  
  32. // ...then wait for the sound to finish
  33. QEventLoop loop;
  34. QObject::connect(testoutput, SIGNAL(stateChanged(QAudio::State)), &loop, SLOT(quit()));
  35. do {
  36. loop.exec();
  37. } while(testoutput->state() == QAudio::ActiveState);
  38.  
  39. // Define the header components
  40. char fileType[4];
  41. qint32 fileSize;
  42. char waveName[4];
  43. char fmtName[3];
  44. qint32 fmtLength;
  45. short fmtType;
  46. short numberOfChannels;
  47. qint32 sampleRate;
  48. qint32 sampleRateXBitsPerSampleXChanngelsDivEight;
  49. short bitsPerSampleXChannelsDivEightPointOne;
  50. short bitsPerSample;
  51. char dataHeader[4];
  52. qint32 dataSize;
  53.  
  54. // Create a data stream to analyze the data
  55.  
  56. QDataStream analyzeHeaderDS(&data,QIODevice::ReadOnly);
  57. analyzeHeaderDS.setByteOrder(QDataStream::LittleEndian);
  58.  
  59. // Now pop off the appropriate data into each header field defined above
  60.  
  61. analyzeHeaderDS.readRawData(fileType,4); // "RIFF"
  62. analyzeHeaderDS >> fileSize; // File Size
  63. analyzeHeaderDS.readRawData(waveName,4); // "WAVE"
  64. analyzeHeaderDS.readRawData(fmtName,3); // "fmt"
  65. analyzeHeaderDS >> fmtLength; // Format length
  66. analyzeHeaderDS >> fmtType; // Format type
  67. analyzeHeaderDS >> numberOfChannels; // Number of channels
  68. analyzeHeaderDS >> sampleRate; // Sample rate
  69. analyzeHeaderDS >> sampleRateXBitsPerSampleXChanngelsDivEight; // (Sample Rate * BitsPerSample * Channels) / 8
  70. analyzeHeaderDS >> bitsPerSampleXChannelsDivEightPointOne; // (BitsPerSample * Channels) / 8.1
  71. analyzeHeaderDS >> bitsPerSample; // Bits per sample
  72. analyzeHeaderDS.readRawData(dataHeader,4); // "data" header
  73. analyzeHeaderDS >> dataSize; // Data Size
  74.  
  75. // Print the header
  76.  
  77. qDebug() << "WAV File Header read:";
  78. qDebug() << "File Type: " << QString::fromUtf8(fileType);
  79. qDebug() << "File Size: " << fileSize;
  80. qDebug() << "WAV Marker: " << QString::fromUtf8(waveName);
  81. qDebug() << "Format Name: " << QString::fromUtf8(fmtName);
  82. qDebug() << "Format Length: " << fmtLength;
  83. qDebug() << "Format Type: " << fmtType;
  84. qDebug() << "Number of Channels: " << numberOfChannels;
  85. qDebug() << "Sample Rate: " << sampleRate;
  86. qDebug() << "Sample Rate * Bits/Sample * Channels / 8: " << sampleRateXBitsPerSampleXChanngelsDivEight;
  87. qDebug() << "Bits per Sample * Channels / 8.1: " << bitsPerSampleXChannelsDivEightPointOne;
  88. qDebug() << "Bits per Sample: " << bitsPerSample;
  89. qDebug() << "Data Header: " << QString::fromUtf8(dataHeader);
  90. qDebug() << "Data Size: " << dataSize;
  91.  
  92. delete audio_buffer;
  93. delete testoutput;
  94. output.writeData(data);
  95. }
To copy to clipboard, switch view to plain text mode 

But all the output is either empty or garbage and the audio output is intelligible.

So I am wondering if I have to write some header in the streamed audio? I know that Qt has QAudioEncoderSetting class. But how do I use it with QAudioInput to make the streamed audio properly formatted and intelligible?

Thank you.