mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-13 15:45:42 +08:00
AFV initial commit
This commit is contained in:
committed by
Mat Sutcliffe
parent
7030302e73
commit
b5a2f2ad13
133
src/blacksound/wav/wavfile.cpp
Normal file
133
src/blacksound/wav/wavfile.cpp
Normal 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;
|
||||
}
|
||||
28
src/blacksound/wav/wavfile.h
Normal file
28
src/blacksound/wav/wavfile.h
Normal 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
|
||||
Reference in New Issue
Block a user