-
Notifications
You must be signed in to change notification settings - Fork 0
/
regionwavereader.h
140 lines (115 loc) · 4.16 KB
/
regionwavereader.h
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#ifndef REGIONWAVEREADER_H
#define REGIONWAVEREADER_H
#include <QtCore>
#include "RegionWaveDefs.h"
class RegionWaveReader
{
private:
QFile* file;
QStringList errors;
MarkerList* markerList;
RegionList* regionList;
WaveFileInfo* info;
QString readChunkName(){
return RiffFileDefs::readString(file);
}
int readChunkSize(){
int chSize = RiffFileDefs::readInt(file);
if (chSize==-1) return chSize;
return chSize%2==0 ? chSize : (chSize+1);
}
void errorMessage(QString s){
errors.append(s);
}
public:
RegionWaveReader(){
file = new QFile();
}
RegionWaveReader(QString name){
file = new QFile(name);
}
void read(){
if (file->open(QIODevice::ReadOnly)) {
int pos = 0;
file->seek(pos);
if (readChunkName().toUpper()!="RIFF") {errorMessage("Can't read RIFF chunk"); return;}
if (readChunkSize()==-1) {errorMessage("Can't read size of RIFF chunk"); return;}
// there I read not chunk name, but riff format, wich also is writen using 4 bytes
if (readChunkName().toUpper()!="WAVE") {errorMessage("Can't read signature of WAVE format"); return;}
if (readChunkName().toLower()!="fmt ") {errorMessage("Can't read fmt chunk"); return;}
int fmtSize = readChunkSize();
if (fmtSize == -1) {errorMessage("fmt chunk size is not defined"); return;}
WaveFileInfo* wfi = new WaveFileInfo();
char *bytes = new char [16];
file->read(bytes, 16);
wfi->fromBytes(bytes, 16);
file->seek(file->pos() + fmtSize - 16);
if (readChunkName().toLower()!="data") {errorMessage("Can't read data chunk"); return;}
int dataSize = readChunkSize();
if (dataSize == -1) {errorMessage("data chunk size is not defined"); return;}
file->seek(file->pos() + dataSize);
if (readChunkName()!="cue ") {errorMessage("Can't read cue chunk"); return;}
int cueSize = readChunkSize();
int cuePointsCount = readInt(file, 4);
// CuePoint
CuePointList cuePoints;
for (int i=0; i<cuePointsCount; i++) {
CuePoint* point = new CuePoint();
if (point->readFromFile(file)!=0) {errorMessage("Can't read cue data"); return;}
cuePoints.append(point);
}
if (readChunkName().toUpper()!="LIST") {errorMessage("Can't read LIST chunk"); return;}
int listSize = readChunkSize();
if (listSize == -1) {errorMessage("Can't read LIST size chunk"); return;}
if (readChunkName()!="adtl") {errorMessage("Can't read adtl chunk"); return;}
listSize -= 4;
regionList = new RegionList;
while (listSize > 0) {
QString chName = readChunkName();
int chSize = readChunkSize();
listSize -= (chSize + 8);
if (chName == "ltxt") {
int cueID = RiffFileDefs::readInt(file, 4);
int duration = RiffFileDefs::readInt(file, 4);
CuePointList::iterator iterator = cuePoints.begin();
while (iterator!=cuePoints.end() && (*iterator)->cueID!=cueID) {
iterator++;
}
if (iterator!=cuePoints.end()){
cuePoints.erase(iterator);
regionList->append(new Region((*iterator)->sampleOffset, duration, "unknown"));
}
file->read(chSize - 8);
} else if (chName == "labl") {
file->read(chSize);
} else {
errorMessage("LIST should contain only labl and ltxt chunks"); return;
}
// listSize-=
}
markerList = new MarkerList;
CuePoint* p;
foreach(p, cuePoints){
markerList->append(new Marker(p->sampleOffset));
}
} else {
errorMessage("Can't read file " + file->fileName());
}
}
MarkerList* getMarkers(){
return markerList;
}
RegionList* getRegions(){
return regionList;
}
bool hasErrors(){
return !errors.empty();
}
QString getLastError(){
return errors.last();
}
void setFileName(QString s){
this->file->setFileName(s);
}
};
#endif // REGIONWAVEREADER_H