AFV initial commit

This commit is contained in:
Roland Rossgotterer
2019-09-14 21:18:26 +02:00
committed by Mat Sutcliffe
parent 7030302e73
commit b5a2f2ad13
100 changed files with 6821 additions and 25 deletions

View File

@@ -0,0 +1,133 @@
#include <qendian.h>
#include <QVector>
#include <QDebug>
// #include "utils.h"
#include "wavfile.h"
struct chunk
{
char id[4];
quint32 size;
};
struct RIFFHeader
{
chunk descriptor; // "RIFF"
char type[4]; // "WAVE"
};
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;
DATAHeader dataHeader;
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 || header.wave.audioFormat == 3))
{
// Read off remaining header information
if (qFromLittleEndian<quint32>(header.wave.descriptor.size) > sizeof(WAVEHeader))
{
// Extended data available
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;
// Establish format
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.setChannelCount(qFromLittleEndian<quint16>(header.wave.numChannels));
m_fileFormat.setCodec("audio/pcm");
m_fileFormat.setSampleRate(qFromLittleEndian<quint32>(header.wave.sampleRate));
m_fileFormat.setSampleSize(qFromLittleEndian<quint16>(header.wave.bitsPerSample));
if (header.wave.audioFormat == 1 || header.wave.audioFormat == 0)
{
m_fileFormat.setSampleType(bps == 8 ? QAudioFormat::UnSignedInt : QAudioFormat::SignedInt);
}
else
{
m_fileFormat.setSampleType(QAudioFormat::Float);
}
}
else
{
result = false;
}
}
m_headerLength = pos();
if (memcmp(&dataHeader.descriptor.id, "data", 4) == 0)
{
qint32 dataLength = qFromLittleEndian<qint32>(dataHeader.descriptor.size);
m_audioData = read(dataLength);
if (m_audioData.size() != dataLength)
{
return false;
m_audioData.clear();
}
}
return result;
}

View File

@@ -0,0 +1,28 @@
#ifndef WAVFILE_H
#define WAVFILE_H
#include <QObject>
#include <QFile>
#include <QAudioFormat>
class WavFile : public QFile
{
public:
WavFile(QObject *parent = 0);
using QFile::open;
bool open(const QString &fileName);
const QAudioFormat &fileFormat() const;
qint64 headerLength() const;
QByteArray audioData() { return m_audioData; }
private:
bool readHeader();
private:
QAudioFormat m_fileFormat;
qint64 m_headerLength;
QByteArray m_audioData;
};
#endif // WAVFILE_H