summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/wavplugin/wavplugin.cpp
Unidiff
Diffstat (limited to 'core/multimedia/opieplayer/wavplugin/wavplugin.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/wavplugin/wavplugin.cpp425
1 files changed, 289 insertions, 136 deletions
diff --git a/core/multimedia/opieplayer/wavplugin/wavplugin.cpp b/core/multimedia/opieplayer/wavplugin/wavplugin.cpp
index 7f63b3b..0be667f 100644
--- a/core/multimedia/opieplayer/wavplugin/wavplugin.cpp
+++ b/core/multimedia/opieplayer/wavplugin/wavplugin.cpp
@@ -19,4 +19,2 @@
19**********************************************************************/ 19**********************************************************************/
20// L.J.Potter added changes Fri 02-15-2002
21
22#include <stdio.h> 20#include <stdio.h>
@@ -29,3 +27,2 @@
29 27
30
31//#define debugMsg(a) qDebug(a) 28//#define debugMsg(a) qDebug(a)
@@ -51,3 +48,3 @@ struct ChunkData {
51 48
52const int sound_buffer_size = 512; // 4096; // you got to be kidding right? 49const int sound_buffer_size = 4096;
53 50
@@ -65,86 +62,97 @@ public:
65 int samples; 62 int samples;
66 63 int freq;
64 int chan;
65 int sampleRate;
66 int resolution;
67
67 WavPluginData() { 68 WavPluginData() {
68 max = out = sound_buffer_size; 69 max = out = sound_buffer_size;
69 wavedata_remaining = 0; 70 wavedata_remaining = 0;
70 samples_due = 0; 71 samples_due = 0;
71 samples = -1; 72 samples = -1;
72 } 73 }
73 74
74 // expands out samples to the frequency of 44kHz 75 // expands out samples to the frequency of 44kHz
75 bool add( short *output, long count, long& done, bool stereo ) 76 bool add( short *output, long count, long& done, bool stereo )
76 { 77 {
77 done = 0; 78 qDebug("add");
78 qApp->processEvents(); 79 done = 0;
79 80
80 if ( input == 0 ) { 81 if ( input == 0 ) {
81 qDebug("no input"); 82 qDebug("no input");
82 return FALSE;
83 }
84
85 while ( count ) {
86 int l,r;
87 if ( getSample(l, r) == FALSE ) {
88 qDebug("didn't get sample");
89 return FALSE; 83 return FALSE;
90 } 84 }
91 samples_due += chunkdata.samplesPerSec; 85
92 while ( count && (samples_due > chunkdata.samplesPerSec) ) { 86 while ( count ) {
93 *output++ = l; 87 int l,r;
94 if ( stereo ) 88 if ( getSample(l, r) == FALSE ) {
95 *output++ = r; 89 qDebug("didn't get sample");
96 samples_due -= chunkdata.samplesPerSec; 90 return FALSE;
97 count--; 91 }
98 done++; 92 samples_due += 44100;
93 while ( count && (samples_due > chunkdata.samplesPerSec) ) {
94 *output++ = l;
95 if ( stereo )
96 *output++ = r;
97 samples_due -= chunkdata.samplesPerSec;
98 count--;
99 done++;
100 }
99 } 101 }
102
103 return TRUE;
100 } 104 }
101 return TRUE;
102 }
103 105
104 bool initialise() { 106 bool initialise() {
105 if ( input == 0 ) 107 qDebug("initialize");
106 return FALSE; 108 if ( input == 0 )
109 return FALSE;
110
111 wavedata_remaining = -1;
112
113 while ( wavedata_remaining == -1 ) {
114 // Keep reading chunks...
115 const int n = sizeof(chunk) - sizeof(chunk.data);
116 int t = input->readBlock( (char*)&chunk, n );
117 if ( t != n ) {
118 if ( t == -1 )
119 return FALSE;
120 return TRUE;
121 }
122 if ( qstrncmp(chunk.id,"data",4) == 0 ) {
123 samples = wavedata_remaining = chunk.size;
124 } else if ( qstrncmp(chunk.id,"RIFF",4) == 0 ) {
125 char d[4];
126 if ( input->readBlock(d,4) != 4 ) {
127 return FALSE;
128 }
129 if ( qstrncmp(d,"WAVE",4) != 0 ) {
130 // skip
131 if ( chunk.size > 1000000000 || !input->at(input->at()+chunk.size-4) ) {
132 return FALSE;
133 }
134 }
135 } else if ( qstrncmp(chunk.id,"fmt ",4) == 0 ) {
136 if ( input->readBlock((char*)&chunkdata,sizeof(chunkdata)) != sizeof(chunkdata) ) {
137 return FALSE;
138 }
139#define WAVE_FORMAT_PCM 1
140 if ( chunkdata.formatTag != WAVE_FORMAT_PCM ) {
141 qDebug("WAV file: UNSUPPORTED FORMAT %d",chunkdata.formatTag);
142 return FALSE;
143 }
144 }
107 145
108 wavedata_remaining = -1;
109 146
110 while ( wavedata_remaining == -1 ) { 147
111 // Keep reading chunks... 148
112 const int n = sizeof(chunk) - sizeof(chunk.data); 149 else {
113 int t = input->readBlock( (char*)&chunk, n ); 150 // ignored chunk
114 if ( t != n ) { 151 if ( chunk.size > 1000000000 || !input->at(input->at()+chunk.size) ) {
115 if ( t == -1 ) 152 return FALSE;
116 return FALSE; 153 }
117 return TRUE; 154 }
118 } 155 } // while
119 if ( qstrncmp(chunk.id,"data",4) == 0 ) { 156
120 samples = wavedata_remaining = chunk.size; 157 return TRUE;
121 } else if ( qstrncmp(chunk.id,"RIFF",4) == 0 ) {
122 char d[4];
123 if ( input->readBlock(d,4) != 4 ) {
124 return FALSE;
125 }
126 if ( qstrncmp(d,"WAVE",4) != 0 ) {
127 // skip
128 if ( chunk.size > 1000000000 || !input->at(input->at()+chunk.size-4) ) {
129 return FALSE;
130 }
131 }
132 } else if ( qstrncmp(chunk.id,"fmt ",4) == 0 ) {
133 if ( input->readBlock((char*)&chunkdata,sizeof(chunkdata)) != sizeof(chunkdata) ) {
134 return FALSE;
135 }
136#define WAVE_FORMAT_PCM 1
137 if ( chunkdata.formatTag != WAVE_FORMAT_PCM ) {
138 qDebug("WAV file: UNSUPPORTED FORMAT %d",chunkdata.formatTag);
139 return FALSE;
140 }
141 } else {
142 // ignored chunk
143 if ( chunk.size > 1000000000 || !input->at(input->at()+chunk.size) ) {
144 return FALSE;
145 }
146 }
147 } // while
148 qDebug("bits %d", chunkdata.wBitsPerSample);
149 return TRUE;
150 } 158 }
@@ -152,43 +160,191 @@ public:
152 160
153 // gets a sample from the file 161 // gets a sample from the file
154 bool getSample(int& l, int& r) 162 bool getSample(int& l, int& r)
155 { 163 {
156 l = r = 0; 164 l = r = 0;
157 165
158 if ( input == 0 ) 166 if ( input == 0 )
159 return FALSE; 167 return FALSE;
160 168
161 if ( (wavedata_remaining < 0) || !max ) 169 if ( (wavedata_remaining < 0) || !max )
162 return FALSE; 170 return FALSE;
163 171
164 if ( out >= max ) { 172 if ( out >= max ) {
165 max = input->readBlock( (char*)data, (uint)QMIN(sound_buffer_size,wavedata_remaining) ); 173 max = input->readBlock( (char*)data, (uint)QMIN(sound_buffer_size,wavedata_remaining) );
166 174
167 wavedata_remaining -= max; 175 wavedata_remaining -= max;
168 176
169 out = 0; 177 out = 0;
170 if ( max <= 0 ) { 178 if ( max <= 0 ) {
171 max = 0; 179 max = 0;
172 return TRUE; 180 return TRUE;
173 } 181 }
174 } 182 }
175 if ( chunkdata.wBitsPerSample == 8 ) { 183 if ( resolution == 8 ) {
176 l = (data[out++] - 128) * 128; 184 l = (data[out++] - 128) * 128;
177 } else { 185 } else {
178 l = ((short*)data)[out/2]; 186 l = ((short*)data)[out/2];
179 out += 2; 187 out += 2;
180 } 188 }
181 if ( chunkdata.channels == 1 ) { 189 if ( chan == 1 ) {
182 r = l; 190 r = l;
183 } else { 191 } else {
184 if ( chunkdata.wBitsPerSample == 8 ) { 192 if ( resolution == 8 ) {
185 r = (data[out++] - 128) * 128; 193 r = (data[out++] - 128) * 128;
186 } else { 194 } else {
187 r = ((short*)data)[out/2]; 195 r = ((short*)data)[out/2];
188 out += 2; 196 out += 2;
189 } 197 }
190 } 198 }
191 return TRUE; 199 return TRUE;
192 } // getSample 200 } // getSample
201
202//////////////////////////////////////////////////////
203int getWavSettings(int fd)
204{ //this came from wmrecord
205
206 char t1[4];
207 unsigned long l1;
208 int found;
209 short fmt;
210 unsigned short ch, brate;
211 unsigned long srate;
212
213
214 /* First read in the RIFF identifier. If this is missing then the
215 * file is not a valid WAVE file.
216 */
217 if (read(fd, t1, 4)<4) {
218 qDebug(" Could not read from sound file.\n");
219 return -1;
220 }
221 if (strncmp(t1, "RIFF", 4)) {
222 qDebug(" not a valid WAV file.\n");
223 return -1;
224 }
225 /* Advance the file pointer to the next relevant field. */
226 lseek(fd, 4, SEEK_CUR);
227 /* Read in the WAVE identifier. */
228 if (read(fd, t1, 4)<4) {
229 qDebug("Could not read from sound file.\n");
230 return -1;
231 }
232 if (strncmp(t1, "WAVE", 4)) {
233 qDebug("not a valid WAV file.\n");
234 return -1;
235 }
193 236
237 /* Search through the file for the format chunk. If the end of the
238 * file is reached without finding the chunk, then the file is not a
239 * valid WAVE file.
240 */
241 found = 0;
242 while (!found) {
243 if (read(fd, t1, 4)<4) {
244 qDebug("Could not read from sound file.\n");
245 return -1;
246 }
247 if (strncmp(t1, "fmt ", 4)) {
248 /* Determine the length of the chunk found and skip to the next
249 * chunk. The chunk length is always stored in the four bytes
250 * following the chunk id.
251 */
252 if (read(fd, &l1, 4)<4) {
253 qDebug("Could not read from sound file.\n");
254 return -1;
255 }
256 lseek(fd, l1, SEEK_CUR);
257 }
258 else {
259 /* This is the format chunk, which stores the playback settings
260 * for the recording.
261 */
262 /* Skip the length field, since we don't really need it. */
263 lseek(fd, 4, SEEK_CUR);
264 /* Read in the format tag. If it has a value of 1, then there is
265 * no compression and we can attempt to play the file
266 * back. Otherwise, return.
267 */
268 if (read(fd, &fmt, 2)<2) {
269 qDebug("Could not read from format chunk.\n");
270 return -1;
271 }
272 if (fmt != 1) {
273 qDebug("Wave file contains compressed data."
274 " Unable to continue.\n");
275 return -1;
276 }
277 /* Get the stereo mode. */
278 if (read(fd, &ch, 2)<2) {
279 qDebug("Could not read from format chunk.\n");
280 return -1;
281 }
282 else {
283 chan = ch;
284 qDebug("File has %d channels", chan);
285 }
286 /* Get the sample rate. */
287 if (read(fd, &srate, 4)<4) {
288 qDebug("Could not read from format chunk.\n");
289 return -1;
290 }
291 else {
292 sampleRate = srate;
293 qDebug("File has samplerate of %d", sampleRate);
294 }
295 /* Get the bit rate. This is at the end of the format chunk. */
296 lseek(fd, 6, SEEK_CUR);
297 if (read(fd, &brate, 2)<2) {
298 qDebug("Could not read from format chunk.\n");
299 return -1;
300 }
301 else {
302 resolution = brate;
303 qDebug("File has bitrate of %d", resolution);
304 }
305
306 found++;
307 }
308 }
309
310 /* Search through the file for the data chunk. If the end of the
311 * file is reached without finding the chunk, then the file is not a
312 * valid WAVE file.
313 */
314 found = 0;
315 while (!found) {
316 if (read(fd, t1, 4)<4) {
317 qDebug("Could not read from sound file.\n");
318 return -1;
319 }
320 if (strncmp(t1, "data", 4)) {
321 /* Determine the length of the chunk found and skip to the next
322 * chunk. The chunk length is always stored in the four bytes
323 * following the chunk id.
324 */
325 if (read(fd, &l1, 4)<4) {
326 qDebug("Could not read from sound file.\n");
327 return -1;
328 }
329 lseek(fd, l1, SEEK_CUR);
330 }
331 else {
332 /* This is the data chunk, which stores the recording. */
333 /* Get the length field. */
334 if (read(fd, &l1, 4)<4) {
335 qDebug("Could not read from sound file.\n");
336 return -1;
337 }
338 else {
339 samples =l1;
340 qDebug("file has length of %d\nlasting %d seconds",l1, (( l1 / sampleRate) / chan) / 2 ); // ????
341 return l1;
342 }
343 }
344 }
345
346 return 0;
347}
348
349//////////////////////////////////////////////////
194}; 350};
@@ -209,3 +365,3 @@ WavPlugin::~WavPlugin() {
209bool WavPlugin::isFileSupported( const QString& path ) { 365bool WavPlugin::isFileSupported( const QString& path ) {
210// qDebug( "WavPlugin::isFileSupported" ); 366 debugMsg( "WavPlugin::isFileSupported" );
211 367
@@ -228,3 +384,3 @@ bool WavPlugin::isFileSupported( const QString& path ) {
228bool WavPlugin::open( const QString& path ) { 384bool WavPlugin::open( const QString& path ) {
229// qDebug( "WavPlugin::open" ); 385 qDebug( "WavPlugin::open" );
230 386
@@ -236,8 +392,9 @@ bool WavPlugin::open( const QString& path ) {
236 if ( d->input->open(IO_ReadOnly) == FALSE ) { 392 if ( d->input->open(IO_ReadOnly) == FALSE ) {
237 qDebug("couldn't open file"); 393 qDebug("couldn't open file");
238 delete d->input; 394 delete d->input;
239 d->input = 0; 395 d->input = 0;
240 return FALSE; 396 return FALSE;
241 } 397 }
242 398
399// d->getWavSettings( d->input.handle());
243 d->initialise(); 400 d->initialise();
@@ -249,3 +406,3 @@ bool WavPlugin::open( const QString& path ) {
249bool WavPlugin::close() { 406bool WavPlugin::close() {
250// qDebug( "WavPlugin::close" ); 407 qDebug( "WavPlugin::close" );
251 408
@@ -259,3 +416,3 @@ bool WavPlugin::close() {
259bool WavPlugin::isOpen() { 416bool WavPlugin::isOpen() {
260// qDebug( "WavPlugin::isOpen" ); 417 qDebug( "WavPlugin::isOpen" );
261 return ( d->input != 0 ); 418 return ( d->input != 0 );
@@ -265,3 +422,3 @@ bool WavPlugin::isOpen() {
265int WavPlugin::audioStreams() { 422int WavPlugin::audioStreams() {
266// qDebug( "WavPlugin::audioStreams" ); 423 qDebug( "WavPlugin::audioStreams" );
267 return 1; 424 return 1;
@@ -271,4 +428,4 @@ int WavPlugin::audioStreams() {
271int WavPlugin::audioChannels( int ) { 428int WavPlugin::audioChannels( int ) {
272// qDebug( "WavPlugin::audioChannels" ); 429 debugMsg( "WavPlugin::audioChannels" );
273 return d->chunkdata.channels;// 2; // ### Always scale audio to stereo samples 430 return d->chan;
274} 431}
@@ -277,4 +434,4 @@ int WavPlugin::audioChannels( int ) {
277int WavPlugin::audioFrequency( int ) { 434int WavPlugin::audioFrequency( int ) {
278// qDebug( "WavPlugin::audioFrequency %d", d->chunkdata.samplesPerSec ); 435 qDebug( "WavPlugin::audioFrequency" );
279 return d->chunkdata.samplesPerSec; //44100; // ### Always scale to frequency of 44100 436 return d->freq;
280} 437}
@@ -283,5 +440,6 @@ int WavPlugin::audioFrequency( int ) {
283int WavPlugin::audioSamples( int ) { 440int WavPlugin::audioSamples( int ) {
284// qDebug( "WavPlugin::audioSamples" ); 441 qDebug( "WavPlugin::audioSamples" );
285 return d->samples / d->chunkdata.channels/2; // ### Scaled samples will be made stereo, 442 return d->samples;
286 // Therefore if source is mono we will double the number of samples 443// return d->samples * 2 / d->chunkdata.channels; // ### Scaled samples will be made stereo,
444// // Therefore if source is mono we will double the number of samples
287} 445}
@@ -290,3 +448,3 @@ int WavPlugin::audioSamples( int ) {
290bool WavPlugin::audioSetSample( long, int ) { 448bool WavPlugin::audioSetSample( long, int ) {
291// qDebug( "WavPlugin::audioSetSample" ); 449 qDebug( "WavPlugin::audioSetSample" );
292 return FALSE; 450 return FALSE;
@@ -296,3 +454,3 @@ bool WavPlugin::audioSetSample( long, int ) {
296long WavPlugin::audioGetSample( int ) { 454long WavPlugin::audioGetSample( int ) {
297// qDebug( "WavPlugin::audioGetSample" ); 455 qDebug( "WavPlugin::audioGetSample" );
298 return 0; 456 return 0;
@@ -326,3 +484,3 @@ bool WavPlugin::audioReadStereoSamples( short *output, long samples, long& sampl
326bool WavPlugin::audioReadSamples( short *output, int channels, long samples, long& samplesMade, int ) { 484bool WavPlugin::audioReadSamples( short *output, int channels, long samples, long& samplesMade, int ) {
327// qDebug( "WavPlugin::audioReadSamples" ); 485 qDebug( "WavPlugin::audioReadSamples" );
328 return d->add( output, samples, samplesMade, channels != 1 ); 486 return d->add( output, samples, samplesMade, channels != 1 );
@@ -331,3 +489,3 @@ bool WavPlugin::audioReadSamples( short *output, int channels, long samples, lon
331double WavPlugin::getTime() { 489double WavPlugin::getTime() {
332// qDebug( "WavPlugin::getTime" ); 490 qDebug( "WavPlugin::getTime" );
333 return 0.0; 491 return 0.0;
@@ -335,7 +493,2 @@ double WavPlugin::getTime() {
335 493
336int WavPlugin::audioBitsPerSample( int ) {
337// qDebug( "WavPlugin::audioFormat %d", d->chunkdata.wBitsPerSample );
338 return d->chunkdata.wBitsPerSample; //
339}
340
341 494