Skip to content

Commit

Permalink
Store record audio in WAV file format
Browse files Browse the repository at this point in the history
QML MediaPlayer can't be directed to play PCM files
  • Loading branch information
matthewvogt committed Mar 25, 2016
1 parent 554e7e6 commit c5b2caa
Showing 1 changed file with 50 additions and 2 deletions.
52 changes: 50 additions & 2 deletions plugins/declarative/src/voicecallaudiorecorder.cpp
Expand Up @@ -15,6 +15,8 @@ const QString recordingsDir("CallRecordings");
const quint16 ChannelCount = 1;
const quint16 SampleRate = 8000;
const quint16 SampleBits = 8;
const quint32 WaveHeaderLength = 44;
const quint16 WavePCMFormat = 1;

QAudioFormat getRecordingFormat()
{
Expand Down Expand Up @@ -152,7 +154,7 @@ bool VoiceCallAudioRecorder::initiateRecording(const QString &fileName)
qWarning() << "Unreadable directory:" << outputDir;
}

const QString filePath(outputDir.filePath(QString("%1.pcm").arg(QString::fromLocal8Bit(QFile::encodeName(fileName)))));
const QString filePath(outputDir.filePath(QString("%1.wav").arg(QString::fromLocal8Bit(QFile::encodeName(fileName)))));

QScopedPointer<QFile> file(new QFile(filePath));
if (!file->open(QIODevice::WriteOnly | QIODevice::Truncate)) {
Expand All @@ -161,6 +163,14 @@ bool VoiceCallAudioRecorder::initiateRecording(const QString &fileName)
return false;
}

// Leave space for the header to be placed later
const QByteArray emptyBytes(WaveHeaderLength, '\0');
if (file->write(emptyBytes) == -1) {
qWarning() << "Unable to write header space to file:" << filePath;
emit recordingError(FileCreation);
return false;
}

QDBusMessage enableRecording(createEnableVoicecallRecordingMessage(true));
if (!QDBusConnection::systemBus().send(enableRecording)) {
qWarning() << "Unable to request recording activation" << QDBusConnection::systemBus().lastError();
Expand Down Expand Up @@ -193,11 +203,49 @@ void VoiceCallAudioRecorder::terminateRecording()
}
}
if (output) {
bool success = false;

// We need to write the header to the file
const quint32 fileLength = output->size();
const quint32 dataLength = fileLength - WaveHeaderLength;

if (dataLength > 0) {
QByteArray waveHeader;
{
QDataStream os(&waveHeader, QIODevice::WriteOnly);
os.setByteOrder(QDataStream::LittleEndian);

os.writeRawData("RIFF", 4);
os << quint32(fileLength - 8); // Total data length
os.writeRawData("WAVE", 4);
os.writeRawData("fmt ", 4);
os << quint32(16); // fmt header length
os << quint16(WavePCMFormat);
os << quint16(ChannelCount);
os << quint32(SampleRate);
os << quint32(SampleRate * ChannelCount * (SampleBits / CHAR_BIT)); // data rate
os << quint16(SampleBits/ CHAR_BIT); // bytes per sample
os << quint16(SampleBits);
os.writeRawData("data", 4);
os << quint32(dataLength);
}

if (output->seek(0) && output->write(waveHeader) == waveHeader.length()) {
success = true;
} else {
qWarning() << "Unable to write header to file:" << output->fileName();
}
}

const QString fileName(output->fileName());
output->close();
output.reset();

emit callRecorded(fileName, label);
if (success) {
emit callRecorded(fileName, label);
} else {
emit recordingError(FileStorage);
}
}
if (active) {
active = false;
Expand Down

0 comments on commit c5b2caa

Please sign in to comment.