Diffstat (limited to 'noncore/multimedia/opierec/wavFile.cpp') (more/less context) (show whitespace changes)
-rw-r--r-- | noncore/multimedia/opierec/wavFile.cpp | 303 |
1 files changed, 303 insertions, 0 deletions
diff --git a/noncore/multimedia/opierec/wavFile.cpp b/noncore/multimedia/opierec/wavFile.cpp new file mode 100644 index 0000000..09695aa --- a/dev/null +++ b/noncore/multimedia/opierec/wavFile.cpp | |||
@@ -0,0 +1,303 @@ | |||
1 | //wavFile.cpp | ||
2 | #include "wavFile.h" | ||
3 | #include "qtrec.h" | ||
4 | |||
5 | #include <qdatetime.h> | ||
6 | #include <qstring.h> | ||
7 | #include <qmessagebox.h> | ||
8 | #include <qdir.h> | ||
9 | |||
10 | #include <qpe/timestring.h> | ||
11 | #include <qpe/config.h> | ||
12 | |||
13 | #include <errno.h> | ||
14 | |||
15 | #include <sys/time.h> | ||
16 | #include <sys/types.h> | ||
17 | #include <sys/vfs.h> | ||
18 | |||
19 | #include <fcntl.h> | ||
20 | #include <math.h> | ||
21 | #include <mntent.h> | ||
22 | #include <stdio.h> | ||
23 | #include <stdlib.h> | ||
24 | #include <unistd.h> | ||
25 | |||
26 | WavFile::WavFile( QObject * parent,const QString &fileName, bool makeNwFile, int sampleRate, | ||
27 | int channels, int resolution, int format ) | ||
28 | : QObject( parent) | ||
29 | { | ||
30 | qDebug("new wave file"); | ||
31 | bool b = makeNwFile; | ||
32 | wavSampleRate=sampleRate; | ||
33 | wavFormat=format; | ||
34 | wavChannels=channels; | ||
35 | wavResolution=resolution; | ||
36 | useTmpFile=false; | ||
37 | if( b) { | ||
38 | newFile(); | ||
39 | } else { | ||
40 | openFile(fileName); | ||
41 | } | ||
42 | } | ||
43 | |||
44 | bool WavFile::newFile() { | ||
45 | |||
46 | qDebug("Set up new file"); | ||
47 | Config cfg("QpeRec"); | ||
48 | cfg.setGroup("Settings"); | ||
49 | |||
50 | currentFileName=cfg.readEntry("directory",QDir::homeDirPath()); | ||
51 | QString date; | ||
52 | date = TimeString::dateString( QDateTime::currentDateTime(),false,true); | ||
53 | date.replace(QRegExp("'"),""); | ||
54 | date.replace(QRegExp(" "),"_"); | ||
55 | date.replace(QRegExp(":"),"."); | ||
56 | date.replace(QRegExp(","),""); | ||
57 | |||
58 | QString currentFile=date; | ||
59 | if(currentFileName.right(1).find("/",0,true) == -1) | ||
60 | currentFileName += "/" + date; | ||
61 | else | ||
62 | currentFileName += date; | ||
63 | currentFileName+=".wav"; | ||
64 | |||
65 | qDebug("set up file for recording: "+currentFileName); | ||
66 | char *pointer; | ||
67 | |||
68 | if( currentFileName.find("/mnt",0,true) == -1 | ||
69 | && currentFileName.find("/tmp",0,true) == -1 ) { | ||
70 | // if destination file is most likely in flash (assuming jffs2) | ||
71 | // we have to write to a different filesystem first | ||
72 | |||
73 | useTmpFile = true; | ||
74 | pointer=tmpnam(NULL); | ||
75 | qDebug("Opening tmp file %s",pointer); | ||
76 | track.setName( pointer); | ||
77 | |||
78 | } else { //just use regular file.. no moving | ||
79 | |||
80 | useTmpFile = false; | ||
81 | track.setName( currentFileName); | ||
82 | } | ||
83 | if(!track.open( IO_ReadWrite | IO_Truncate)) { | ||
84 | QString errorMsg=(QString)strerror(errno); | ||
85 | qDebug(errorMsg); | ||
86 | QMessageBox::message("Note", "Error opening file.\n" +errorMsg); | ||
87 | |||
88 | return false; | ||
89 | } else { | ||
90 | setWavHeader( track.handle() , &hdr); | ||
91 | } | ||
92 | return true; | ||
93 | } | ||
94 | |||
95 | WavFile::~WavFile() { | ||
96 | |||
97 | closeFile(); | ||
98 | } | ||
99 | |||
100 | void WavFile::closeFile() { | ||
101 | if(track.isOpen()) | ||
102 | track.close(); | ||
103 | } | ||
104 | |||
105 | int WavFile::openFile(const QString ¤tFileName) { | ||
106 | qDebug("open play file "+currentFileName); | ||
107 | closeFile(); | ||
108 | |||
109 | track.setName(currentFileName); | ||
110 | |||
111 | if(!track.open(IO_ReadOnly)) { | ||
112 | QString errorMsg=(QString)strerror(errno); | ||
113 | qDebug("<<<<<<<<<<< "+errorMsg+currentFileName); | ||
114 | QMessageBox::message("Note", "Error opening file.\n" +errorMsg); | ||
115 | return -1; | ||
116 | } else { | ||
117 | parseWavHeader( track.handle()); | ||
118 | } | ||
119 | return track.handle(); | ||
120 | } | ||
121 | |||
122 | bool WavFile::setWavHeader(int fd, wavhdr *hdr) { | ||
123 | |||
124 | strncpy((*hdr).riffID, "RIFF", 4); // RIFF | ||
125 | strncpy((*hdr).wavID, "WAVE", 4); //WAVE | ||
126 | strncpy((*hdr).fmtID, "fmt ", 4); // fmt | ||
127 | (*hdr).fmtLen = 16; // format length = 16 | ||
128 | |||
129 | if( wavFormat == WAVE_FORMAT_PCM) { | ||
130 | (*hdr).fmtTag = 1; // PCM | ||
131 | qDebug("set header WAVE_FORMAT_PCM"); | ||
132 | } | ||
133 | else { | ||
134 | (*hdr).fmtTag = WAVE_FORMAT_DVI_ADPCM; //intel ADPCM | ||
135 | qDebug("set header WAVE_FORMAT_DVI_ADPCM"); | ||
136 | } | ||
137 | |||
138 | // (*hdr).nChannels = 1;//filePara.channels;// ? 2 : 1*/; // channels | ||
139 | (*hdr).nChannels = wavChannels;// ? 2 : 1*/; // channels | ||
140 | |||
141 | (*hdr).sampleRate = wavSampleRate; //samples per second | ||
142 | (*hdr).avgBytesPerSec = (wavSampleRate)*( wavChannels*(wavResolution/8)); // bytes per second | ||
143 | (*hdr).nBlockAlign = wavChannels*( wavResolution/8); //block align | ||
144 | (*hdr).bitsPerSample = wavResolution; //bits per sample 8, or 16 | ||
145 | |||
146 | strncpy((*hdr).dataID, "data", 4); | ||
147 | |||
148 | write( fd,hdr, sizeof(*hdr)); | ||
149 | qDebug("writing header: bitrate%d, samplerate %d, channels %d", | ||
150 | wavResolution, wavSampleRate, wavChannels); | ||
151 | return true; | ||
152 | } | ||
153 | |||
154 | bool WavFile::adjustHeaders(int fd, int total) { | ||
155 | lseek(fd, 4, SEEK_SET); | ||
156 | int i = total + 36; | ||
157 | write( fd, &i, sizeof(i)); | ||
158 | lseek( fd, 40, SEEK_SET); | ||
159 | write( fd, &total, sizeof(total)); | ||
160 | qDebug("adjusting header %d", total); | ||
161 | return true; | ||
162 | } | ||
163 | |||
164 | int WavFile::parseWavHeader(int fd) { | ||
165 | qDebug("Parsing wav header"); | ||
166 | char string[4]; | ||
167 | int found; | ||
168 | short fmt; | ||
169 | unsigned short ch, bitrate; | ||
170 | unsigned long samplerrate, longdata; | ||
171 | |||
172 | if (read(fd, string, 4) < 4) { | ||
173 | qDebug(" Could not read from sound file.\n"); | ||
174 | return -1; | ||
175 | } | ||
176 | if (strncmp(string, "RIFF", 4)) { | ||
177 | qDebug(" not a valid WAV file.\n"); | ||
178 | return -1; | ||
179 | } | ||
180 | lseek(fd, 4, SEEK_CUR); | ||
181 | if (read(fd, string, 4) < 4) { | ||
182 | qDebug("Could not read from sound file.\n"); | ||
183 | return -1; | ||
184 | } | ||
185 | if (strncmp(string, "WAVE", 4)) { | ||
186 | qDebug("not a valid WAV file.\n"); | ||
187 | return -1; | ||
188 | } | ||
189 | found = 0; | ||
190 | |||
191 | while (!found) { | ||
192 | if (read(fd, string, 4) < 4) { | ||
193 | qDebug("Could not read from sound file.\n"); | ||
194 | return -1; | ||
195 | } | ||
196 | if (strncmp(string, "fmt ", 4)) { | ||
197 | if (read(fd, &longdata, 4) < 4) { | ||
198 | qDebug("Could not read from sound file.\n"); | ||
199 | return -1; | ||
200 | } | ||
201 | lseek(fd, longdata, SEEK_CUR); | ||
202 | } else { | ||
203 | lseek(fd, 4, SEEK_CUR); | ||
204 | if (read(fd, &fmt, 2) < 2) { | ||
205 | qDebug("Could not read format chunk.\n"); | ||
206 | return -1; | ||
207 | } | ||
208 | if (fmt != WAVE_FORMAT_PCM && fmt != WAVE_FORMAT_DVI_ADPCM) { | ||
209 | qDebug("Wave file contains unknown format." | ||
210 | " Unable to continue.\n"); | ||
211 | return -1; | ||
212 | } | ||
213 | wavFormat = fmt; | ||
214 | // compressionFormat=fmt; | ||
215 | qDebug("compressionFormat is %d", fmt); | ||
216 | if (read(fd, &ch, 2) < 2) { | ||
217 | qDebug("Could not read format chunk.\n"); | ||
218 | return -1; | ||
219 | } else { | ||
220 | wavChannels = ch; | ||
221 | qDebug("File has %d channels", ch); | ||
222 | } | ||
223 | if (read(fd, &samplerrate, 4) < 4) { | ||
224 | qDebug("Could not read from format chunk.\n"); | ||
225 | return -1; | ||
226 | } else { | ||
227 | wavSampleRate = samplerrate; | ||
228 | // sampleRate = samplerrate; | ||
229 | qDebug("File has samplerate of %d",(int) samplerrate); | ||
230 | } | ||
231 | lseek(fd, 6, SEEK_CUR); | ||
232 | if (read(fd, &bitrate, 2) < 2) { | ||
233 | qDebug("Could not read format chunk.\n"); | ||
234 | return -1; | ||
235 | } else { | ||
236 | wavResolution=bitrate; | ||
237 | // resolution = bitrate; | ||
238 | qDebug("File has bitrate of %d", bitrate); | ||
239 | } | ||
240 | found++; | ||
241 | } | ||
242 | } | ||
243 | found = 0; | ||
244 | while (!found) { | ||
245 | if (read(fd, string, 4) < 4) { | ||
246 | qDebug("Could not read from sound file.\n"); | ||
247 | return -1; | ||
248 | } | ||
249 | |||
250 | if (strncmp(string, "data", 4)) { | ||
251 | if (read(fd, &longdata, 4)<4) { | ||
252 | qDebug("Could not read from sound file.\n"); | ||
253 | return -1; | ||
254 | } | ||
255 | |||
256 | lseek(fd, longdata, SEEK_CUR); | ||
257 | } else { | ||
258 | if (read(fd, &longdata, 4) < 4) { | ||
259 | qDebug("Could not read from sound file.\n"); | ||
260 | return -1; | ||
261 | } else { | ||
262 | wavNumberSamples = longdata; | ||
263 | qDebug("file has length of %d \nlasting %d seconds", longdata, | ||
264 | (( longdata / wavSampleRate) / wavChannels) / ( wavChannels*( wavResolution/8)) ); | ||
265 | // wavSeconds = (( longdata / wavSampleRate) / wavChannels) / ( wavChannels*( wavResolution/8)); | ||
266 | |||
267 | return longdata; | ||
268 | } | ||
269 | } | ||
270 | } | ||
271 | |||
272 | lseek(fd, 0, SEEK_SET); | ||
273 | |||
274 | return 0; | ||
275 | } | ||
276 | |||
277 | QString WavFile::trackName() { | ||
278 | return track.name(); | ||
279 | } | ||
280 | |||
281 | int WavFile::wavHandle(){ | ||
282 | return track.handle(); | ||
283 | } | ||
284 | |||
285 | int WavFile::getFormat() { | ||
286 | return wavFormat; | ||
287 | } | ||
288 | |||
289 | int WavFile::getResolution() { | ||
290 | return wavResolution; | ||
291 | } | ||
292 | |||
293 | int WavFile::getSampleRate() { | ||
294 | return wavSampleRate; | ||
295 | } | ||
296 | |||
297 | int WavFile::getNumberSamples() { | ||
298 | return wavNumberSamples; | ||
299 | } | ||
300 | |||
301 | bool WavFile::isTempFile() { | ||
302 | return useTmpFile; | ||
303 | } | ||