wavfile.cpp Example File
demos/spectrum/app/wavfile.cpp
 
 
 #include <QtCore/qendian.h>
 #include <QVector>
 #include <QDebug>
 #include "utils.h"
 #include "wavfile.h"
 struct chunk
 {
     char        id[4];
     quint32     size;
 };
 struct RIFFHeader
 {
     chunk       descriptor;     
     char        type[4];        
 };
 struct WAVEHeader
 {
     chunk       descriptor;
     quint16     audioFormat;
     quint16     numChannels;
     quint32     sampleRate;
     quint32     byteRate;
     quint16     blockAlign;
     quint16     bitsPerSample;
 };
 struct DATAHeader
 {
     chunk       descriptor;
 };
 struct CombinedHeader
 {
     RIFFHeader  riff;
     WAVEHeader  wave;
 };
 WavFile::WavFile(QObject *parent)
     : QFile(parent)
     , m_headerLength(0)
 {
 }
 bool WavFile::open(const QString &fileName)
 {
     close();
     setFileName(fileName);
     return QFile::open(QIODevice::ReadOnly) && readHeader();
 }
 const QAudioFormat &WavFile::fileFormat() const
 {
     return m_fileFormat;
 }
 qint64 WavFile::headerLength() const
 {
 return m_headerLength;
 }
 bool WavFile::readHeader()
 {
     seek(0);
     CombinedHeader header;
     bool result = read(reinterpret_cast<char *>(&header), sizeof(CombinedHeader)) == sizeof(CombinedHeader);
     if (result) {
         if ((memcmp(&header.riff.descriptor.id, "RIFF", 4) == 0
             || memcmp(&header.riff.descriptor.id, "RIFX", 4) == 0)
             && memcmp(&header.riff.type, "WAVE", 4) == 0
             && memcmp(&header.wave.descriptor.id, "fmt ", 4) == 0
             && (header.wave.audioFormat == 1 || header.wave.audioFormat == 0)) {
             
             DATAHeader dataHeader;
             if (qFromLittleEndian<quint32>(header.wave.descriptor.size) > sizeof(WAVEHeader)) {
                 
                 quint16 extraFormatBytes;
                 if (peek((char*)&extraFormatBytes, sizeof(quint16)) != sizeof(quint16))
                     return false;
                 const qint64 throwAwayBytes = sizeof(quint16) + qFromLittleEndian<quint16>(extraFormatBytes);
                 if (read(throwAwayBytes).size() != throwAwayBytes)
                     return false;
             }
             if (read((char*)&dataHeader, sizeof(DATAHeader)) != sizeof(DATAHeader))
                 return false;
             
             if (memcmp(&header.riff.descriptor.id, "RIFF", 4) == 0)
                 m_fileFormat.setByteOrder(QAudioFormat::LittleEndian);
             else
                 m_fileFormat.setByteOrder(QAudioFormat::BigEndian);
             int bps = qFromLittleEndian<quint16>(header.wave.bitsPerSample);
             m_fileFormat.setChannels(qFromLittleEndian<quint16>(header.wave.numChannels));
             m_fileFormat.setCodec("audio/pcm");
             m_fileFormat.setFrequency(qFromLittleEndian<quint32>(header.wave.sampleRate));
             m_fileFormat.setSampleSize(qFromLittleEndian<quint16>(header.wave.bitsPerSample));
             m_fileFormat.setSampleType(bps == 8 ? QAudioFormat::UnSignedInt : QAudioFormat::SignedInt);
         } else {
             result = false;
         }
     }
     m_headerLength = pos();
     return result;
 }