-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwavefile.cpp
More file actions
121 lines (107 loc) · 4.16 KB
/
wavefile.cpp
File metadata and controls
121 lines (107 loc) · 4.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include "wavefile.h"
#include <QDebug>
WaveFile::WaveFile(QObject *parent) : QFile(parent)
{
}
WaveFile::WaveFile(const QString &name) : QFile(name)
{
}
WaveFile::WaveFile(const QString &name, QObject *parent) : QFile(name, parent)
{
}
qint64 WaveFile::readHeader() {
qint64 result = 0;
if (!isSequential()) // true only if device is random access
result = seek(0); //true when index position of reading file is 0
if (result != 0)
{
result = (read(reinterpret_cast<char *>(&header), HeaderLength) == HeaderLength); //reading metadata into header
if (result) //true when bytes readed are HeaderLength long;
{
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 ) // true when is PCM
{
result = 0;
while (memcmp(&header.data.descriptor.id, "data", 4) != 0)
{
this->read(header.data.descriptor.size); //changing offset
read( reinterpret_cast<char *>(&header.data), 8 ); //overwrite header.data
}
qDebug() << "readHeader:file name" << fileName()
<< ": size =" << size()
<< ": data.descriptor :" << header.data.descriptor.id << header.data.descriptor.size;
}
else
{
qDebug() << "error- readHeader:: unsupported format or file demaged";
result = -2; // unsuportet format so return false
}
}
}
else //current position is not the start of the header
qDebug() << "error- readHeader:: position to read is not the start of the hearder";
if (header.wave.bitsPerSample <= 0) //correction of division by zero in many places
result = -1;
return result;
}
qint64 WaveFile::readData(double *buffer, int bufferSize, int channelId) {
qint64 result = 0;
if (channelId > header.wave.numChannels)
{
qDebug() <<"readData: warning! There is no such channel like:" << channelId
<< " - changed to channel 0" ;
channelId = 0;
}
bool ok; //helping bool for converting string to int
QString Sample, tmp;
if (header.wave.bitsPerSample > 0)
{
for (int i=0; i<bufferSize; i++)
{
if (isFirstSample)
{
isFirstSample = false;
read( (header.wave.bitsPerSample/8) * (channelId) );
}
Sample = read( (header.wave.bitsPerSample/8) * header.wave.numChannels ).toHex();
tmp = Sample.right(2);
Sample.remove(Sample.length()-2,2);//remove last 2 chars
tmp.append(Sample.right(2));
double oneSample = tmp.toInt(&ok,16);
if (oneSample > 32767)
oneSample -= 65535;
if (oneSample == 0)
buffer[i] = 0;
else
buffer[i] = oneSample/32767;
/*/____________________________FOR TESTS ONLY______________________
qDebug() << i << " one sample: " << tmp << "=" << oneSample << QString::number(tab[i]);
/*/
}
/*/____________________________FOR TESTS ONLY______________________
//qDebug() return strange results when its getting more than 2 fields from header
qDebug() << "readData:bitsPerSample:"<< header.wave.bitsPerSample<<
", numbers of channels:" << header.wave.numChannels<<
", sample rate:" << header.wave.sampleRate<<
", byte rate:" << header.wave.byteRate<<
", header length:" << HeaderLength;
/*/
}
else {
qDebug() << "error - readData:bitsPerSample: " << header.wave.bitsPerSample ;
result = -1;
}
return result;
}
bool WaveFile::seek(qint64 offset) {
return QFile::seek(offset);
}
bool WaveFile::open(OpenMode flags) {
bool result = QFile::open(flags);
if (result)
readHeader();
return result;
}