Diffstat (limited to 'core/multimedia/opieplayer/libmad/libmadplugin.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | core/multimedia/opieplayer/libmad/libmadplugin.cpp | 302 |
1 files changed, 151 insertions, 151 deletions
diff --git a/core/multimedia/opieplayer/libmad/libmadplugin.cpp b/core/multimedia/opieplayer/libmad/libmadplugin.cpp index 9d04f7e..9f8ba65 100644 --- a/core/multimedia/opieplayer/libmad/libmadplugin.cpp +++ b/core/multimedia/opieplayer/libmad/libmadplugin.cpp | |||
@@ -38,25 +38,25 @@ | |||
38 | #if defined(HAVE_MMAP) | 38 | #if defined(HAVE_MMAP) |
39 | # include <sys/mman.h> | 39 | # include <sys/mman.h> |
40 | #endif | 40 | #endif |
41 | #include "libmadplugin.h" | 41 | #include "libmadplugin.h" |
42 | 42 | ||
43 | 43 | ||
44 | extern "C" { | 44 | extern "C" { |
45 | #include "mad.h" | 45 | #include "mad.h" |
46 | } | 46 | } |
47 | 47 | ||
48 | 48 | ||
49 | #define MPEG_BUFFER_SIZE 65536 | 49 | #define MPEG_BUFFER_SIZE 65536 |
50 | //#define debugMsg(a) qDebug(a) | 50 | //#define debugMsg(a) qDebug(a) |
51 | #define debugMsg(a) | 51 | #define debugMsg(a) |
52 | 52 | ||
53 | 53 | ||
54 | class Input { | 54 | class Input { |
55 | public: | 55 | public: |
56 | char const *path; | 56 | char const *path; |
57 | int fd; | 57 | int fd; |
58 | #if defined(HAVE_MMAP) | 58 | #if defined(HAVE_MMAP) |
59 | void *fdm; | 59 | void *fdm; |
60 | #endif | 60 | #endif |
61 | unsigned char *data; | 61 | unsigned char *data; |
62 | unsigned long length; | 62 | unsigned long length; |
@@ -136,122 +136,122 @@ LibMadPlugin::LibMadPlugin() { | |||
136 | 136 | ||
137 | 137 | ||
138 | LibMadPlugin::~LibMadPlugin() { | 138 | LibMadPlugin::~LibMadPlugin() { |
139 | close(); | 139 | close(); |
140 | delete d; | 140 | delete d; |
141 | } | 141 | } |
142 | 142 | ||
143 | 143 | ||
144 | bool LibMadPlugin::isFileSupported( const QString& path ) { | 144 | bool LibMadPlugin::isFileSupported( const QString& path ) { |
145 | debugMsg( "LibMadPlugin::isFileSupported" ); | 145 | debugMsg( "LibMadPlugin::isFileSupported" ); |
146 | 146 | ||
147 | // Mpeg file extensions | 147 | // Mpeg file extensions |
148 | //"mp2","mp3","m1v","m2v","m2s","mpg","vob","mpeg","ac3" | 148 | // "mp2","mp3","m1v","m2v","m2s","mpg","vob","mpeg","ac3" |
149 | // Other media extensions | 149 | // Other media extensions |
150 | // "wav","mid","mod","s3m","ogg","avi","mov","sid" | 150 | // "wav","mid","mod","s3m","ogg","avi","mov","sid" |
151 | 151 | ||
152 | char *ext = strrchr( path.latin1(), '.' ); | 152 | char *ext = strrchr( path.latin1(), '.' ); |
153 | 153 | ||
154 | // Test file extension | 154 | // Test file extension |
155 | if ( ext ) { | 155 | if ( ext ) { |
156 | if ( strncasecmp(ext, ".mp2", 4) == 0 ) | 156 | if ( strncasecmp(ext, ".mp2", 4) == 0 ) |
157 | return TRUE; | 157 | return TRUE; |
158 | if ( strncasecmp(ext, ".mp3", 4) == 0 ) | 158 | if ( strncasecmp(ext, ".mp3", 4) == 0 ) |
159 | return TRUE; | 159 | return TRUE; |
160 | } | 160 | } |
161 | 161 | ||
162 | return FALSE; | 162 | return FALSE; |
163 | } | 163 | } |
164 | 164 | ||
165 | 165 | ||
166 | bool LibMadPlugin::open( const QString& path ) { | 166 | bool LibMadPlugin::open( const QString& path ) { |
167 | debugMsg( "LibMadPlugin::open" ); | 167 | debugMsg( "LibMadPlugin::open" ); |
168 | 168 | ||
169 | d->bad_last_frame = 0; | 169 | d->bad_last_frame = 0; |
170 | d->flush = TRUE; | 170 | d->flush = TRUE; |
171 | info = QString( "" ); | 171 | info = QString( "" ); |
172 | 172 | ||
173 | //qDebug( "Opening %s", path.latin1() ); | 173 | //qDebug( "Opening %s", path.latin1() ); |
174 | 174 | ||
175 | d->input.path = path.latin1(); | 175 | d->input.path = path.latin1(); |
176 | d->input.fd = ::open( d->input.path, O_RDONLY ); | 176 | d->input.fd = ::open( d->input.path, O_RDONLY ); |
177 | if (d->input.fd == -1) { | 177 | if (d->input.fd == -1) { |
178 | qDebug("error opening %s", d->input.path ); | 178 | qDebug("error opening %s", d->input.path ); |
179 | return FALSE; | 179 | return FALSE; |
180 | } | 180 | } |
181 | 181 | ||
182 | printID3Tags(); | 182 | printID3Tags(); |
183 | 183 | ||
184 | #if defined(HAVE_MMAP) | 184 | #if defined(HAVE_MMAP) |
185 | struct stat stat; | 185 | struct stat stat; |
186 | if (fstat(d->input.fd, &stat) == -1) { | 186 | if (fstat(d->input.fd, &stat) == -1) { |
187 | qDebug("error calling fstat"); return FALSE; | 187 | qDebug("error calling fstat"); return FALSE; |
188 | } | 188 | } |
189 | if (S_ISREG(stat.st_mode) && stat.st_size > 0) { | 189 | if (S_ISREG(stat.st_mode) && stat.st_size > 0) { |
190 | d->input.length = stat.st_size; | 190 | d->input.length = stat.st_size; |
191 | d->input.fdm = map_file(d->input.fd, &d->input.length); | 191 | d->input.fdm = map_file(d->input.fd, &d->input.length); |
192 | if (d->input.fdm == 0) { | 192 | if (d->input.fdm == 0) { |
193 | qDebug("error mmapping file"); return FALSE; | 193 | qDebug("error mmapping file"); return FALSE; |
194 | } | 194 | } |
195 | d->input.data = (unsigned char *)d->input.fdm; | 195 | d->input.data = (unsigned char *)d->input.fdm; |
196 | } | 196 | } |
197 | #endif | 197 | #endif |
198 | 198 | ||
199 | if (d->input.data == 0) { | 199 | if (d->input.data == 0) { |
200 | d->input.data = (unsigned char *)malloc(MPEG_BUFFER_SIZE); | 200 | d->input.data = (unsigned char *)malloc(MPEG_BUFFER_SIZE); |
201 | if (d->input.data == 0) { | 201 | if (d->input.data == 0) { |
202 | qDebug("error allocating input buffer"); | 202 | qDebug("error allocating input buffer"); |
203 | return FALSE; | 203 | return FALSE; |
204 | } | 204 | } |
205 | d->input.length = 0; | 205 | d->input.length = 0; |
206 | } | 206 | } |
207 | 207 | ||
208 | d->input.eof = 0; | 208 | d->input.eof = 0; |
209 | 209 | ||
210 | mad_stream_init(&d->stream); | 210 | mad_stream_init(&d->stream); |
211 | mad_frame_init(&d->frame); | 211 | mad_frame_init(&d->frame); |
212 | mad_synth_init(&d->synth); | 212 | mad_synth_init(&d->synth); |
213 | 213 | ||
214 | return TRUE; | 214 | return TRUE; |
215 | } | 215 | } |
216 | 216 | ||
217 | 217 | ||
218 | bool LibMadPlugin::close() { | 218 | bool LibMadPlugin::close() { |
219 | debugMsg( "LibMadPlugin::close" ); | 219 | debugMsg( "LibMadPlugin::close" ); |
220 | 220 | ||
221 | int result = TRUE; | 221 | int result = TRUE; |
222 | 222 | ||
223 | mad_synth_finish(&d->synth); | 223 | mad_synth_finish(&d->synth); |
224 | mad_frame_finish(&d->frame); | 224 | mad_frame_finish(&d->frame); |
225 | mad_stream_finish(&d->stream); | 225 | mad_stream_finish(&d->stream); |
226 | 226 | ||
227 | #if defined(HAVE_MMAP) | 227 | #if defined(HAVE_MMAP) |
228 | if (d->input.fdm) { | 228 | if (d->input.fdm) { |
229 | if (unmap_file(d->input.fdm, d->input.length) == -1) { | 229 | if (unmap_file(d->input.fdm, d->input.length) == -1) { |
230 | qDebug("error munmapping file"); | 230 | qDebug("error munmapping file"); |
231 | result = FALSE; | 231 | result = FALSE; |
232 | } | 232 | } |
233 | d->input.fdm = 0; | 233 | d->input.fdm = 0; |
234 | d->input.data = 0; | 234 | d->input.data = 0; |
235 | } | 235 | } |
236 | #endif | 236 | #endif |
237 | 237 | ||
238 | if (d->input.data) { | 238 | if (d->input.data) { |
239 | free(d->input.data); | 239 | free(d->input.data); |
240 | d->input.data = 0; | 240 | d->input.data = 0; |
241 | } | 241 | } |
242 | 242 | ||
243 | if (::close(d->input.fd) == -1) { | 243 | if (::close(d->input.fd) == -1) { |
244 | qDebug("error closing file %s", d->input.path); | 244 | qDebug("error closing file %s", d->input.path); |
245 | result = FALSE; | 245 | result = FALSE; |
246 | } | 246 | } |
247 | 247 | ||
248 | d->input.fd = 0; | 248 | d->input.fd = 0; |
249 | 249 | ||
250 | return result; | 250 | return result; |
251 | } | 251 | } |
252 | 252 | ||
253 | 253 | ||
254 | bool LibMadPlugin::isOpen() { | 254 | bool LibMadPlugin::isOpen() { |
255 | debugMsg( "LibMadPlugin::isOpen" ); | 255 | debugMsg( "LibMadPlugin::isOpen" ); |
256 | return ( d->input.fd != 0 ); | 256 | return ( d->input.fd != 0 ); |
257 | } | 257 | } |
@@ -314,167 +314,167 @@ bool LibMadPlugin::audioReadSamples( short *, int, long, int ) { | |||
314 | 314 | ||
315 | bool LibMadPlugin::audioReReadSamples( short *, int, long, int ) { | 315 | bool LibMadPlugin::audioReReadSamples( short *, int, long, int ) { |
316 | debugMsg( "LibMadPlugin::audioReReadSamples" ); | 316 | debugMsg( "LibMadPlugin::audioReReadSamples" ); |
317 | return FALSE; | 317 | return FALSE; |
318 | } | 318 | } |
319 | */ | 319 | */ |
320 | 320 | ||
321 | bool LibMadPlugin::read() { | 321 | bool LibMadPlugin::read() { |
322 | debugMsg( "LibMadPlugin::read" ); | 322 | debugMsg( "LibMadPlugin::read" ); |
323 | int len; | 323 | int len; |
324 | 324 | ||
325 | if (d->input.eof) | 325 | if (d->input.eof) |
326 | return FALSE; | 326 | return FALSE; |
327 | 327 | ||
328 | #if defined(HAVE_MMAP) | 328 | #if defined(HAVE_MMAP) |
329 | if (d->input.fdm) { | 329 | if (d->input.fdm) { |
330 | unsigned long skip = 0; | 330 | unsigned long skip = 0; |
331 | 331 | ||
332 | if (d->stream.next_frame) { | 332 | if (d->stream.next_frame) { |
333 | struct stat stat; | 333 | struct stat stat; |
334 | 334 | ||
335 | if (fstat(d->input.fd, &stat) == -1) | 335 | if (fstat(d->input.fd, &stat) == -1) |
336 | return FALSE; | 336 | return FALSE; |
337 | 337 | ||
338 | if (stat.st_size + MAD_BUFFER_GUARD <= (signed)d->input.length) | 338 | if (stat.st_size + MAD_BUFFER_GUARD <= (signed)d->input.length) |
339 | return FALSE; | 339 | return FALSE; |
340 | 340 | ||
341 | // file size changed; update memory map | 341 | // file size changed; update memory map |
342 | skip = d->stream.next_frame - d->input.data; | 342 | skip = d->stream.next_frame - d->input.data; |
343 | 343 | ||
344 | if (unmap_file(d->input.fdm, d->input.length) == -1) { | 344 | if (unmap_file(d->input.fdm, d->input.length) == -1) { |
345 | d->input.fdm = 0; | 345 | d->input.fdm = 0; |
346 | d->input.data = 0; | 346 | d->input.data = 0; |
347 | return FALSE; | 347 | return FALSE; |
348 | } | 348 | } |
349 | 349 | ||
350 | d->input.length = stat.st_size; | 350 | d->input.length = stat.st_size; |
351 | 351 | ||
352 | d->input.fdm = map_file(d->input.fd, &d->input.length); | 352 | d->input.fdm = map_file(d->input.fd, &d->input.length); |
353 | if (d->input.fdm == 0) { | 353 | if (d->input.fdm == 0) { |
354 | d->input.data = 0; | 354 | d->input.data = 0; |
355 | return FALSE; | 355 | return FALSE; |
356 | } | 356 | } |
357 | 357 | ||
358 | d->input.data = (unsigned char *)d->input.fdm; | 358 | d->input.data = (unsigned char *)d->input.fdm; |
359 | } | 359 | } |
360 | 360 | ||
361 | mad_stream_buffer(&d->stream, d->input.data + skip, d->input.length - skip); | 361 | mad_stream_buffer(&d->stream, d->input.data + skip, d->input.length - skip); |
362 | 362 | ||
363 | } else | 363 | } else |
364 | #endif | 364 | #endif |
365 | { | 365 | { |
366 | if (d->stream.next_frame) { | 366 | if (d->stream.next_frame) { |
367 | memmove(d->input.data, d->stream.next_frame, | 367 | memmove(d->input.data, d->stream.next_frame, |
368 | d->input.length = &d->input.data[d->input.length] - d->stream.next_frame); | 368 | d->input.length = &d->input.data[d->input.length] - d->stream.next_frame); |
369 | } | 369 | } |
370 | 370 | ||
371 | do { | 371 | do { |
372 | len = ::read(d->input.fd, d->input.data + d->input.length, MPEG_BUFFER_SIZE - d->input.length); | 372 | len = ::read(d->input.fd, d->input.data + d->input.length, MPEG_BUFFER_SIZE - d->input.length); |
373 | } | 373 | } |
374 | while (len == -1 && errno == EINTR); | 374 | while (len == -1 && errno == EINTR); |
375 | 375 | ||
376 | if (len == -1) { | 376 | if (len == -1) { |
377 | qDebug("error reading audio"); | 377 | qDebug("error reading audio"); |
378 | return FALSE; | 378 | return FALSE; |
379 | } | 379 | } |
380 | else if (len == 0) { | 380 | else if (len == 0) { |
381 | d->input.eof = 1; | 381 | d->input.eof = 1; |
382 | 382 | ||
383 | assert(MPEG_BUFFER_SIZE - d->input.length >= MAD_BUFFER_GUARD); | 383 | assert(MPEG_BUFFER_SIZE - d->input.length >= MAD_BUFFER_GUARD); |
384 | 384 | ||
385 | while (len < MAD_BUFFER_GUARD) | 385 | while (len < MAD_BUFFER_GUARD) |
386 | d->input.data[d->input.length + len++] = 0; | 386 | d->input.data[d->input.length + len++] = 0; |
387 | } | 387 | } |
388 | 388 | ||
389 | mad_stream_buffer(&d->stream, d->input.data, d->input.length += len); | 389 | mad_stream_buffer(&d->stream, d->input.data, d->input.length += len); |
390 | } | 390 | } |
391 | 391 | ||
392 | return TRUE; | 392 | return TRUE; |
393 | } | 393 | } |
394 | 394 | ||
395 | 395 | ||
396 | static mad_fixed_t left_err, right_err; | 396 | static mad_fixed_t left_err, right_err; |
397 | static const int bits = 16; | 397 | static const int bits = 16; |
398 | static const int shift = MAD_F_FRACBITS + 1 - bits; | 398 | static const int shift = MAD_F_FRACBITS + 1 - bits; |
399 | 399 | ||
400 | 400 | ||
401 | inline long audio_linear_dither( mad_fixed_t sample, mad_fixed_t& error ) | 401 | inline long audio_linear_dither( mad_fixed_t sample, mad_fixed_t& error ) |
402 | { | 402 | { |
403 | sample += error; | 403 | sample += error; |
404 | mad_fixed_t quantized = (sample >= MAD_F_ONE) ? MAD_F_ONE - 1 : ( (sample < -MAD_F_ONE) ? -MAD_F_ONE : sample ); | 404 | mad_fixed_t quantized = (sample >= MAD_F_ONE) ? MAD_F_ONE - 1 : ( (sample < -MAD_F_ONE) ? -MAD_F_ONE : sample ); |
405 | quantized &= ~((1L << shift) - 1); | 405 | quantized &= ~((1L << shift) - 1); |
406 | error = sample - quantized; | 406 | error = sample - quantized; |
407 | return quantized >> shift; | 407 | return quantized >> shift; |
408 | } | 408 | } |
409 | 409 | ||
410 | 410 | ||
411 | inline void audio_pcm( short *data, unsigned int nsamples, mad_fixed_t *left, mad_fixed_t *right ) | 411 | inline void audio_pcm( short *data, unsigned int nsamples, mad_fixed_t *left, mad_fixed_t *right ) |
412 | { | 412 | { |
413 | if ( right ) { | 413 | if ( right ) { |
414 | while (nsamples--) { | 414 | while (nsamples--) { |
415 | data[0] = audio_linear_dither( *left++, left_err ); | 415 | data[0] = audio_linear_dither( *left++, left_err ); |
416 | data[1] = audio_linear_dither( *right++, right_err ); | 416 | data[1] = audio_linear_dither( *right++, right_err ); |
417 | data += 2; | 417 | data += 2; |
418 | } | 418 | } |
419 | } else { | 419 | } else { |
420 | while (nsamples--) { | 420 | while (nsamples--) { |
421 | data[0] = data[1] = audio_linear_dither( *left++, left_err ); | 421 | data[0] = data[1] = audio_linear_dither( *left++, left_err ); |
422 | data += 2; | 422 | data += 2; |
423 | } | 423 | } |
424 | } | 424 | } |
425 | } | 425 | } |
426 | 426 | ||
427 | 427 | ||
428 | bool LibMadPlugin::decode( short *output, long samples, long& samplesMade ) { | 428 | bool LibMadPlugin::decode( short *output, long samples, long& samplesMade ) { |
429 | debugMsg( "LibMadPlugin::decode" ); | 429 | debugMsg( "LibMadPlugin::decode" ); |
430 | 430 | ||
431 | static int buffered = 0; | 431 | static int buffered = 0; |
432 | static mad_fixed_t buffer[2][65536 * 2]; | 432 | static mad_fixed_t buffer[2][65536 * 2]; |
433 | int offset = buffered; | 433 | int offset = buffered; |
434 | samplesMade = 0; | 434 | samplesMade = 0; |
435 | 435 | ||
436 | static int maxBuffered = 8000; // 65536; | 436 | static int maxBuffered = 8000; // 65536; |
437 | 437 | ||
438 | if ( samples > maxBuffered ) | 438 | if ( samples > maxBuffered ) |
439 | samples = maxBuffered; | 439 | samples = maxBuffered; |
440 | 440 | ||
441 | if ( d->flush ) { | 441 | if ( d->flush ) { |
442 | buffered = 0; | 442 | buffered = 0; |
443 | offset = 0; | 443 | offset = 0; |
444 | d->flush = FALSE; | 444 | d->flush = FALSE; |
445 | } | 445 | } |
446 | 446 | ||
447 | while ( buffered < maxBuffered ) { | 447 | while ( buffered < maxBuffered ) { |
448 | 448 | ||
449 | while (mad_frame_decode(&d->frame, &d->stream) == -1) { | 449 | while (mad_frame_decode(&d->frame, &d->stream) == -1) { |
450 | if (!MAD_RECOVERABLE(d->stream.error)) { | 450 | if (!MAD_RECOVERABLE(d->stream.error)) { |
451 | debugMsg( "feed me" ); | 451 | debugMsg( "feed me" ); |
452 | return FALSE; // Feed me | 452 | return FALSE; // Feed me |
453 | } | 453 | } |
454 | if ( d->stream.error == MAD_ERROR_BADCRC ) { | 454 | if ( d->stream.error == MAD_ERROR_BADCRC ) { |
455 | mad_frame_mute(&d->frame); | 455 | mad_frame_mute(&d->frame); |
456 | qDebug( "error decoding, bad crc" ); | 456 | qDebug( "error decoding, bad crc" ); |
457 | } | 457 | } |
458 | } | 458 | } |
459 | 459 | ||
460 | mad_synth_frame(&d->synth, &d->frame); | 460 | mad_synth_frame(&d->synth, &d->frame); |
461 | int decodedSamples = d->synth.pcm.length; | 461 | int decodedSamples = d->synth.pcm.length; |
462 | memcpy( &(buffer[0][offset]), d->synth.pcm.samples[0], decodedSamples * sizeof(mad_fixed_t) ); | 462 | memcpy( &(buffer[0][offset]), d->synth.pcm.samples[0], decodedSamples * sizeof(mad_fixed_t) ); |
463 | if ( d->synth.pcm.channels == 2 ) | 463 | if ( d->synth.pcm.channels == 2 ) |
464 | memcpy( &(buffer[1][offset]), d->synth.pcm.samples[1], decodedSamples * sizeof(mad_fixed_t) ); | 464 | memcpy( &(buffer[1][offset]), d->synth.pcm.samples[1], decodedSamples * sizeof(mad_fixed_t) ); |
465 | offset += decodedSamples; | 465 | offset += decodedSamples; |
466 | buffered += decodedSamples; | 466 | buffered += decodedSamples; |
467 | } | 467 | } |
468 | 468 | //qApp->processEvents(); | |
469 | audio_pcm( output, samples, buffer[0], (d->synth.pcm.channels == 2) ? buffer[1] : 0 ); | 469 | audio_pcm( output, samples, buffer[0], (d->synth.pcm.channels == 2) ? buffer[1] : 0 ); |
470 | // audio_pcm( output, samples, buffer[1], buffer[0] ); | 470 | // audio_pcm( output, samples, buffer[1], buffer[0] ); |
471 | // audio_pcm( output, samples, buffer[0], buffer[1] ); | 471 | // audio_pcm( output, samples, buffer[0], buffer[1] ); |
472 | samplesMade = samples; | 472 | samplesMade = samples; |
473 | memmove( buffer[0], &(buffer[0][samples]), (buffered - samples) * sizeof(mad_fixed_t) ); | 473 | memmove( buffer[0], &(buffer[0][samples]), (buffered - samples) * sizeof(mad_fixed_t) ); |
474 | if ( d->synth.pcm.channels == 2 ) | 474 | if ( d->synth.pcm.channels == 2 ) |
475 | memmove( buffer[1], &(buffer[1][samples]), (buffered - samples) * sizeof(mad_fixed_t) ); | 475 | memmove( buffer[1], &(buffer[1][samples]), (buffered - samples) * sizeof(mad_fixed_t) ); |
476 | buffered -= samples; | 476 | buffered -= samples; |
477 | 477 | ||
478 | return TRUE; | 478 | return TRUE; |
479 | } | 479 | } |
480 | 480 | ||
@@ -484,95 +484,95 @@ bool LibMadPlugin::audioReadMonoSamples( short *, long, long&, int ) { | |||
484 | return FALSE; | 484 | return FALSE; |
485 | } | 485 | } |
486 | 486 | ||
487 | 487 | ||
488 | bool LibMadPlugin::audioReadStereoSamples( short *output, long samples, long& samplesMade, int ) { | 488 | bool LibMadPlugin::audioReadStereoSamples( short *output, long samples, long& samplesMade, int ) { |
489 | */ | 489 | */ |
490 | bool LibMadPlugin::audioReadSamples( short *output, int /*channels*/, long samples, long& samplesMade, int ) { | 490 | bool LibMadPlugin::audioReadSamples( short *output, int /*channels*/, long samples, long& samplesMade, int ) { |
491 | debugMsg( "LibMadPlugin::audioReadStereoSamples" ); | 491 | debugMsg( "LibMadPlugin::audioReadStereoSamples" ); |
492 | 492 | ||
493 | static bool needInput = TRUE; | 493 | static bool needInput = TRUE; |
494 | 494 | ||
495 | if ( samples == 0 ) | 495 | if ( samples == 0 ) |
496 | return FALSE; | 496 | return FALSE; |
497 | 497 | ||
498 | do { | 498 | do { |
499 | if ( needInput ) | 499 | if ( needInput ) |
500 | if ( !read() ) { | 500 | if ( !read() ) { |
501 | // if ( d->input.eof ) | 501 | // if ( d->input.eof ) |
502 | // needInput = FALSE; | 502 | // needInput = FALSE; |
503 | // else | 503 | // else |
504 | return FALSE; | 504 | return FALSE; |
505 | } | 505 | } |
506 | 506 | ||
507 | needInput = FALSE; | 507 | needInput = FALSE; |
508 | 508 | ||
509 | if ( decode( output, samples, samplesMade ) ) | 509 | if ( decode( output, samples, samplesMade ) ) |
510 | return TRUE; | 510 | return TRUE; |
511 | else | 511 | else |
512 | needInput = TRUE; | 512 | needInput = TRUE; |
513 | } | 513 | } |
514 | while ( ( samplesMade < samples ) && ( !d->input.eof ) ); | 514 | while ( ( samplesMade < samples ) && ( !d->input.eof ) ); |
515 | /* | 515 | /* |
516 | static bool firstTimeThru = TRUE; | 516 | static bool firstTimeThru = TRUE; |
517 | 517 | ||
518 | if ( firstTimeThru ) { | 518 | if ( firstTimeThru ) { |
519 | firstTimeThru = FALSE; | 519 | firstTimeThru = FALSE; |
520 | decode( output, samples, samplesMade ); | 520 | decode( output, samples, samplesMade ); |
521 | return FALSE; | 521 | return FALSE; |
522 | } else | 522 | } else |
523 | */ | 523 | */ |
524 | return FALSE; | 524 | return FALSE; |
525 | } | 525 | } |
526 | 526 | ||
527 | 527 | ||
528 | double LibMadPlugin::getTime() { | 528 | double LibMadPlugin::getTime() { |
529 | debugMsg( "LibMadPlugin::getTime" ); | 529 | debugMsg( "LibMadPlugin::getTime" ); |
530 | return 0.0; | 530 | return 0.0; |
531 | } | 531 | } |
532 | 532 | ||
533 | 533 | ||
534 | void LibMadPlugin::printID3Tags() { | 534 | void LibMadPlugin::printID3Tags() { |
535 | debugMsg( "LibMadPlugin::printID3Tags" ); | 535 | debugMsg( "LibMadPlugin::printID3Tags" ); |
536 | 536 | ||
537 | char id3v1[128 + 1]; | 537 | char id3v1[128 + 1]; |
538 | 538 | ||
539 | if ( ::lseek( d->input.fd, -128, SEEK_END ) == -1 ) { | 539 | if ( ::lseek( d->input.fd, -128, SEEK_END ) == -1 ) { |
540 | qDebug( "error seeking to id3 tags" ); | 540 | qDebug( "error seeking to id3 tags" ); |
541 | return; | 541 | return; |
542 | } | 542 | } |
543 | 543 | ||
544 | if ( ::read( d->input.fd, id3v1, 128 ) != 128 ) { | 544 | if ( ::read( d->input.fd, id3v1, 128 ) != 128 ) { |
545 | qDebug( "error reading in id3 tags" ); | 545 | qDebug( "error reading in id3 tags" ); |
546 | return; | 546 | return; |
547 | } | 547 | } |
548 | 548 | ||
549 | if ( ::strncmp( (const char *)id3v1, "TAG", 3 ) != 0 ) { | 549 | if ( ::strncmp( (const char *)id3v1, "TAG", 3 ) != 0 ) { |
550 | debugMsg( "sorry, no id3 tags" ); | 550 | debugMsg( "sorry, no id3 tags" ); |
551 | } else { | 551 | } else { |
552 | int len[5] = { 30, 30, 30, 4, 30 }; | 552 | int len[5] = { 30, 30, 30, 4, 30 }; |
553 | QString label[5] = { tr( "Title" ), tr( "Artist" ), tr( "Album" ), tr( "Year" ), tr( "Comment" ) }; | 553 | QString label[5] = { tr( "Title" ), tr( "Artist" ), tr( "Album" ), tr( "Year" ), tr( "Comment" ) }; |
554 | char *ptr = id3v1 + 3, *ptr2 = ptr + len[0]; | 554 | char *ptr = id3v1 + 3, *ptr2 = ptr + len[0]; |
555 | qDebug( "ID3 tags in file:" ); | 555 | qDebug( "ID3 tags in file:" ); |
556 | info = ""; | 556 | info = ""; |
557 | for ( int i = 0; i < 5; ptr += len[i], i++, ptr2 += len[i] ) { | 557 | for ( int i = 0; i < 5; ptr += len[i], i++, ptr2 += len[i] ) { |
558 | char push = *ptr2; | 558 | char push = *ptr2; |
559 | *ptr2 = '\0'; | 559 | *ptr2 = '\0'; |
560 | char *ptr3 = ptr2; | 560 | char *ptr3 = ptr2; |
561 | while ( ptr3-1 >= ptr && isspace(ptr3[-1]) ) ptr3--; | 561 | while ( ptr3-1 >= ptr && isspace(ptr3[-1]) ) ptr3--; |
562 | char push2 = *ptr3; *ptr3 = '\0'; | 562 | char push2 = *ptr3; *ptr3 = '\0'; |
563 | if ( strcmp( ptr, "" ) ) | 563 | if ( strcmp( ptr, "" ) ) |
564 | info += ( i != 0 ? ", " : "" ) + label[i] + ": " + ptr; | 564 | info += ( i != 0 ? ", " : "" ) + label[i] + ": " + ptr; |
565 | //qDebug( info.latin1() ); | 565 | //qDebug( info.latin1() ); |
566 | *ptr3 = push2; | 566 | *ptr3 = push2; |
567 | *ptr2 = push; | 567 | *ptr2 = push; |
568 | } | 568 | } |
569 | if (id3v1[126] == 0 && id3v1[127] != 0) | 569 | if (id3v1[126] == 0 && id3v1[127] != 0) |
570 | info += tr( ", Track: " ) + id3v1[127]; | 570 | info += tr( ", Track: " ) + id3v1[127]; |
571 | } | 571 | } |
572 | 572 | ||
573 | if ( ::lseek(d->input.fd, 0, SEEK_SET) == -1 ) { | 573 | if ( ::lseek(d->input.fd, 0, SEEK_SET) == -1 ) { |
574 | qDebug( "error seeking back to beginning" ); | 574 | qDebug( "error seeking back to beginning" ); |
575 | return; | 575 | return; |
576 | } | 576 | } |
577 | } | 577 | } |
578 | 578 | ||