summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/libmad/libmadplugin.cpp
Unidiff
Diffstat (limited to 'core/multimedia/opieplayer/libmad/libmadplugin.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libmad/libmadplugin.cpp72
1 files changed, 38 insertions, 34 deletions
diff --git a/core/multimedia/opieplayer/libmad/libmadplugin.cpp b/core/multimedia/opieplayer/libmad/libmadplugin.cpp
index 1989b4a..428fc28 100644
--- a/core/multimedia/opieplayer/libmad/libmadplugin.cpp
+++ b/core/multimedia/opieplayer/libmad/libmadplugin.cpp
@@ -1,81 +1,86 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2001 Trolltech AS. All rights reserved. 2** Copyright (C) 2001 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20// largly modified by Maximilian Reiss <max.reiss@gmx.de> 20// largly modified by Maximilian Reiss <max.reiss@gmx.de>
21 21
22#include "libmadplugin.h"
23
24/* OPIE */
25#include <qpe/config.h>
26#include <opie2/odebug.h>
27
28/* QT */
29#include <qapplication.h>
30#include <qmessagebox.h>
31#include <qregexp.h>
32
33/* STD */
22#include <stdio.h> 34#include <stdio.h>
23#include <stdarg.h> 35#include <stdarg.h>
24#include <stdlib.h> 36#include <stdlib.h>
25#include <sys/types.h> 37#include <sys/types.h>
26#include <sys/stat.h> 38#include <sys/stat.h>
27#include <fcntl.h> 39#include <fcntl.h>
28#include <unistd.h> 40#include <unistd.h>
29#include <string.h> 41#include <string.h>
30#include <ctype.h> 42#include <ctype.h>
31#include <errno.h> 43#include <errno.h>
32#include <time.h> 44#include <time.h>
33#include <locale.h> 45#include <locale.h>
34#include <math.h> 46#include <math.h>
35#include <assert.h> 47#include <assert.h>
36 48
37#include <qapplication.h>
38#include <qmessagebox.h>
39#include <qregexp.h>
40
41#include <qpe/config.h>
42
43// for network handling 49// for network handling
44#include <netinet/in.h> 50#include <netinet/in.h>
45#include <netdb.h> 51#include <netdb.h>
46#include <linux/limits.h> 52#include <linux/limits.h>
47#include <sys/socket.h> 53#include <sys/socket.h>
48#include <arpa/inet.h> 54#include <arpa/inet.h>
49#include <unistd.h> 55#include <unistd.h>
50 56
51 57
52//#define HAVE_MMAP 58//#define HAVE_MMAP
53 59
54#if defined(HAVE_MMAP) 60#if defined(HAVE_MMAP)
55# include <sys/mman.h> 61# include <sys/mman.h>
56#endif 62#endif
57#include "libmadplugin.h"
58 63
59 64
60extern "C" { 65extern "C" {
61#include "mad.h" 66#include "mad.h"
62} 67}
63 68
64 69
65#define MPEG_BUFFER_SIZE 65536 70#define MPEG_BUFFER_SIZE 65536
66//#define MPEG_BUFFER_SIZE 32768 //16384 // 8192 71//#define MPEG_BUFFER_SIZE 32768 //16384 // 8192
67//#define debugMsg(a) qDebug(a) 72//#define debugMsg(a) qDebug(a)
68#define debugMsg(a) 73#define debugMsg(a)
69 74
70 75
71class Input { 76class Input {
72public: 77public:
73 char const *path; 78 char const *path;
74 int fd; 79 int fd;
75#if defined(HAVE_MMAP) 80#if defined(HAVE_MMAP)
76 void *fdm; 81 void *fdm;
77#endif 82#endif
78 unsigned long fileLength; 83 unsigned long fileLength;
79 unsigned char *data; 84 unsigned char *data;
80 unsigned long length; 85 unsigned long length;
81 int eof; 86 int eof;
@@ -361,259 +366,258 @@ int LibMadPlugin::http_open(const QString& path ) {
361 http_request[4] = 0; 366 http_request[4] = 0;
362 if (strcmp(http_request, "200 ")) { 367 if (strcmp(http_request, "200 ")) {
363 fprintf(stderr, "http_open: "); 368 fprintf(stderr, "http_open: ");
364 do { 369 do {
365 read(tcp_sock, &c, sizeof(char)); 370 read(tcp_sock, &c, sizeof(char));
366 fprintf(stderr, "%c", c); 371 fprintf(stderr, "%c", c);
367 } while (c != '\r'); 372 } while (c != '\r');
368 fprintf(stderr, "\n"); 373 fprintf(stderr, "\n");
369 return (0); 374 return (0);
370 } 375 }
371#endif 376#endif
372 377
373 QString name; 378 QString name;
374 QString genre; 379 QString genre;
375 QString bitrate; 380 QString bitrate;
376 QString url; 381 QString url;
377 QString message = tr("Info: "); 382 QString message = tr("Info: ");
378 do { 383 do {
379 384
380 int len; 385 int len;
381 386
382 len = http_read_line(tcp_sock, http_request, sizeof(http_request)); 387 len = http_read_line(tcp_sock, http_request, sizeof(http_request));
383 388
384 if (len == -1) { 389 if (len == -1) {
385 // qDebug( "http_open: "+ QString(strerror(errno)) +"\n"); 390 // odebug << "http_open: "+ QString(strerror(errno)) +"\n" << oendl;
386 return 0; 391 return 0;
387 } 392 }
388 393
389 if (QString(http_request).left(9) == "Location:") { 394 if (QString(http_request).left(9) == "Location:") {
390 /* redirect */ 395 /* redirect */
391 ::close(tcp_sock); 396 ::close(tcp_sock);
392 http_request[strlen(http_request) - 1] = '\0'; 397 http_request[strlen(http_request) - 1] = '\0';
393 return http_open(&http_request[10]); 398 return http_open(&http_request[10]);
394 } 399 }
395 400
396 if (QString(http_request).left(4) == "ICY ") { 401 if (QString(http_request).left(4) == "ICY ") {
397 /* This is shoutcast/icecast streaming */ 402 /* This is shoutcast/icecast streaming */
398 if (strncmp(http_request + 4, "200 ", 4)) { 403 if (strncmp(http_request + 4, "200 ", 4)) {
399 // qDebug("http_open: " + QString(http_request) + "\n"); 404 // odebug << "http_open: " + QString(http_request) + "\n" << oendl;
400 return 0; 405 return 0;
401 } 406 }
402 } else if (QString(http_request).left(4) == "icy-") { 407 } else if (QString(http_request).left(4) == "icy-") {
403 /* we can have: icy-noticeX, icy-name, icy-genre, icy-url, icy-pub, icy-metaint, icy-br */ 408 /* we can have: icy-noticeX, icy-name, icy-genre, icy-url, icy-pub, icy-metaint, icy-br */
404 if ( QString( http_request ).left( 8 ) == "icy-name" ) { 409 if ( QString( http_request ).left( 8 ) == "icy-name" ) {
405 name = tr("Name: ") + QString(http_request).mid(9, (QString(http_request).length())- 9 ); 410 name = tr("Name: ") + QString(http_request).mid(9, (QString(http_request).length())- 9 );
406 } else if ( QString( http_request ).left( 9 ) == "icy-genre" ) { 411 } else if ( QString( http_request ).left( 9 ) == "icy-genre" ) {
407 genre = tr("Genre: ") + QString(http_request).mid(10, (QString(http_request).length())-10 ); 412 genre = tr("Genre: ") + QString(http_request).mid(10, (QString(http_request).length())-10 );
408 } else if ( QString( http_request ).left( 6 ) == "icy-br" ) { 413 } else if ( QString( http_request ).left( 6 ) == "icy-br" ) {
409 bitrate = tr("Bitrate: ") + QString(http_request).mid(7, (QString(http_request).length())- 7 ); 414 bitrate = tr("Bitrate: ") + QString(http_request).mid(7, (QString(http_request).length())- 7 );
410 } else if ( QString( http_request ).left( 7 ) == "icy-url" ) { 415 } else if ( QString( http_request ).left( 7 ) == "icy-url" ) {
411 url = tr("URL: ") + QString(http_request).mid(8, (QString(http_request).length())- 8 ); 416 url = tr("URL: ") + QString(http_request).mid(8, (QString(http_request).length())- 8 );
412 } else if ( QString( http_request ).left( 10 ) == "icy-notice" ) { 417 } else if ( QString( http_request ).left( 10 ) == "icy-notice" ) {
413 message += QString(http_request).mid(11, QString(http_request).length()-11 ) ; 418 message += QString(http_request).mid(11, QString(http_request).length()-11 ) ;
414 } 419 }
415 } 420 }
416 } while (strcmp(http_request, "\n") != 0); 421 } while (strcmp(http_request, "\n") != 0);
417 422
418 info = QString(name + genre + url + bitrate + message).replace( QRegExp("\n"), " : " ); 423 info = QString(name + genre + url + bitrate + message).replace( QRegExp("\n"), " : " );
419 424
420 // qDebug("Stream info: " + info); 425 // odebug << "Stream info: " + info << oendl;
421 426
422 return (tcp_sock); 427 return (tcp_sock);
423} 428}
424 429
425 430
426 431
427bool LibMadPlugin::open( const QString& path ) { 432bool LibMadPlugin::open( const QString& path ) {
428 debugMsg( "LibMadPlugin::open" ); 433 debugMsg( "LibMadPlugin::open" );
429 Config cfg("OpiePlayer"); 434 Config cfg("OpiePlayer");
430 cfg.setGroup("Options"); 435 cfg.setGroup("Options");
431 bufferSize = cfg.readNumEntry("MPeg_BufferSize",MPEG_BUFFER_SIZE); 436 bufferSize = cfg.readNumEntry("MPeg_BufferSize",MPEG_BUFFER_SIZE);
432 // qDebug("buffer size is %d", bufferSize); 437 // odebug << "buffer size is " << bufferSize << "" << oendl;
433 d->bad_last_frame = 0; 438 d->bad_last_frame = 0;
434 d->flush = TRUE; 439 d->flush = TRUE;
435 info = QString( "" ); 440 info = QString( "" );
436 441
437 //qDebug( "Opening %s", path.latin1() ); 442 //odebug << "Opening " << path << "" << oendl;
438 443
439 if (path.left( 4 ) == "http" ) { 444 if (path.left( 4 ) == "http" ) {
440 // in case of any error we get 0 here 445 // in case of any error we get 0 here
441 if ( !(http_open(path) == 0) ) { 446 if ( !(http_open(path) == 0) ) {
442 d->input.fd = http_open(path); 447 d->input.fd = http_open(path);
443 } else { 448 } else {
444 return FALSE; 449 return FALSE;
445 } 450 }
446 } else { 451 } else {
447 d->input.path = path.latin1(); 452 d->input.path = path.latin1();
448 d->input.fd = ::open( d->input.path, O_RDONLY ); 453 d->input.fd = ::open( d->input.path, O_RDONLY );
449 // thats a better place, since it should only seek for ID3 tags on mp3 files, not streams 454 // thats a better place, since it should only seek for ID3 tags on mp3 files, not streams
450 printID3Tags(); 455 printID3Tags();
451 } 456 }
452 if (d->input.fd == -1) { 457 if (d->input.fd == -1) {
453 // qDebug("error opening %s", d->input.path ); 458 // odebug << "error opening " << d->input.path << "" << oendl;
454 return FALSE; 459 return FALSE;
455 } 460 }
456 461
457 struct stat stat; 462 struct stat stat;
458 if (fstat(d->input.fd, &stat) == -1) { 463 if (fstat(d->input.fd, &stat) == -1) {
459 // qDebug("error calling fstat"); return FALSE; 464 // odebug << "error calling fstat" << oendl; return FALSE;
460 } 465 }
461 if (S_ISREG(stat.st_mode) && stat.st_size > 0) 466 if (S_ISREG(stat.st_mode) && stat.st_size > 0)
462 d->input.fileLength = stat.st_size; 467 d->input.fileLength = stat.st_size;
463 else 468 else
464 d->input.fileLength = 0; 469 d->input.fileLength = 0;
465 470
466#if defined(HAVE_MMAP) 471#if defined(HAVE_MMAP)
467 if (S_ISREG(stat.st_mode) && stat.st_size > 0) { 472 if (S_ISREG(stat.st_mode) && stat.st_size > 0) {
468 d->input.length = stat.st_size; 473 d->input.length = stat.st_size;
469 d->input.fdm = map_file(d->input.fd, &d->input.length); 474 d->input.fdm = map_file(d->input.fd, &d->input.length);
470 if (d->input.fdm == 0) { 475 if (d->input.fdm == 0) {
471 // qDebug("error mmapping file"); return FALSE; 476 // odebug << "error mmapping file" << oendl; return FALSE;
472 } 477 }
473 d->input.data = (unsigned char *)d->input.fdm; 478 d->input.data = (unsigned char *)d->input.fdm;
474 } 479 }
475#endif 480#endif
476 481
477 if (d->input.data == 0) { 482 if (d->input.data == 0) {
478 d->input.data = (unsigned char *)malloc( bufferSize /*MPEG_BUFFER_SIZE*/); 483 d->input.data = (unsigned char *)malloc( bufferSize /*MPEG_BUFFER_SIZE*/);
479 if (d->input.data == 0) { 484 if (d->input.data == 0) {
480 // qDebug("error allocating input buffer"); 485 // odebug << "error allocating input buffer" << oendl;
481 return FALSE; 486 return FALSE;
482 } 487 }
483 d->input.length = 0; 488 d->input.length = 0;
484 } 489 }
485 490
486 d->input.eof = 0; 491 d->input.eof = 0;
487 492
488 mad_stream_init(&d->stream); 493 mad_stream_init(&d->stream);
489 mad_frame_init(&d->frame); 494 mad_frame_init(&d->frame);
490 mad_synth_init(&d->synth); 495 mad_synth_init(&d->synth);
491 496
492 return TRUE; 497 return TRUE;
493} 498}
494 499
495 500
496bool LibMadPlugin::close() { 501bool LibMadPlugin::close() {
497 debugMsg( "LibMadPlugin::close" ); 502 debugMsg( "LibMadPlugin::close" );
498 503
499 int result = TRUE; 504 int result = TRUE;
500 505
501 mad_synth_finish(&d->synth); 506 mad_synth_finish(&d->synth);
502 mad_frame_finish(&d->frame); 507 mad_frame_finish(&d->frame);
503 mad_stream_finish(&d->stream); 508 mad_stream_finish(&d->stream);
504 509
505#if defined(HAVE_MMAP) 510#if defined(HAVE_MMAP)
506 if (d->input.fdm) { 511 if (d->input.fdm) {
507 if (unmap_file(d->input.fdm, d->input.length) == -1) { 512 if (unmap_file(d->input.fdm, d->input.length) == -1) {
508 // qDebug("error munmapping file"); 513 // odebug << "error munmapping file" << oendl;
509 result = FALSE; 514 result = FALSE;
510 } 515 }
511 d->input.fdm = 0; 516 d->input.fdm = 0;
512 d->input.data = 0; 517 d->input.data = 0;
513 } 518 }
514#endif 519#endif
515 520
516 if (d->input.data) { 521 if (d->input.data) {
517 free(d->input.data); 522 free(d->input.data);
518 d->input.data = 0; 523 d->input.data = 0;
519 } 524 }
520 525
521 if (::close(d->input.fd) == -1) { 526 if (::close(d->input.fd) == -1) {
522 // qDebug("error closing file %s", d->input.path); 527 // odebug << "error closing file " << d->input.path << "" << oendl;
523 result = FALSE; 528 result = FALSE;
524 } 529 }
525 530
526 d->input.fd = 0; 531 d->input.fd = 0;
527 532
528 return result; 533 return result;
529} 534}
530 535
531 536
532bool LibMadPlugin::isOpen() { 537bool LibMadPlugin::isOpen() {
533 debugMsg( "LibMadPlugin::isOpen" ); 538 debugMsg( "LibMadPlugin::isOpen" );
534 return ( d->input.fd != 0 ); 539 return ( d->input.fd != 0 );
535} 540}
536 541
537 542
538int LibMadPlugin::audioStreams() { 543int LibMadPlugin::audioStreams() {
539 debugMsg( "LibMadPlugin::audioStreams" ); 544 debugMsg( "LibMadPlugin::audioStreams" );
540 return 1; 545 return 1;
541} 546}
542 547
543 548
544int LibMadPlugin::audioChannels( int ) { 549int LibMadPlugin::audioChannels( int ) {
545 debugMsg( "LibMadPlugin::audioChannels" ); 550 debugMsg( "LibMadPlugin::audioChannels" );
546/* 551/*
547 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 ); 552 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 );
548 qDebug( "LibMadPlugin::audioChannels: %i", d->frame.header.mode > 0 ? 2 : 1 ); 553 odebug << "LibMadPlugin::audioChannels: " << d->frame.header.mode > 0 ? 2 : 1 << "" << oendl;
549 return d->frame.header.mode > 0 ? 2 : 1; 554 return d->frame.header.mode > 0 ? 2 : 1;
550*/ 555*/
551 return 2; 556 return 2;
552} 557}
553 558
554 559
555int LibMadPlugin::audioFrequency( int ) { 560int LibMadPlugin::audioFrequency( int ) {
556 debugMsg( "LibMadPlugin::audioFrequency" ); 561 debugMsg( "LibMadPlugin::audioFrequency" );
557 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 ); 562 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 );
558 // qDebug( "LibMadPlugin::audioFrequency: %i", d->frame.header.samplerate ); 563 // odebug << "LibMadPlugin::audioFrequency: " << d->frame.header.samplerate << "" << oendl;
559 return d->frame.header.samplerate; 564 return d->frame.header.samplerate;
560} 565}
561 566
562 567
563int LibMadPlugin::audioSamples( int ) { 568int LibMadPlugin::audioSamples( int ) {
564 debugMsg( "LibMadPlugin::audioSamples" ); 569 debugMsg( "LibMadPlugin::audioSamples" );
565 570
566 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 ); 571 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 );
567 mad_header_decode( (struct mad_header *)&d->frame.header, &d->stream ); 572 mad_header_decode( (struct mad_header *)&d->frame.header, &d->stream );
568/* 573/*
569 qDebug( "LibMadPlugin::audioSamples: %i*%i", d->frame.header.duration.seconds, 574 odebug << "LibMadPlugin::audioSamples: " << d->frame.header.duration.seconds << "*" << d->frame.header.samplerate << oendl;
570 d->frame.header.samplerate );
571 return d->frame.header.duration.seconds * d->frame.header.samplerate; 575 return d->frame.header.duration.seconds * d->frame.header.samplerate;
572*/ 576*/
573 if ( d->frame.header.bitrate == 0 ) 577 if ( d->frame.header.bitrate == 0 )
574 return 0; 578 return 0;
575 int samples = (d->input.fileLength / (d->frame.header.bitrate/8)) * d->frame.header.samplerate; 579 int samples = (d->input.fileLength / (d->frame.header.bitrate/8)) * d->frame.header.samplerate;
576 580
577 // qDebug( "LibMadPlugin::audioSamples: %i * %i * 8 / %i", (int)d->input.fileLength, 581 // qDebug( "LibMadPlugin::audioSamples: %i * %i * 8 / %i", (int)d->input.fileLength,
578 // (int)d->frame.header.samplerate, (int)d->frame.header.bitrate ); 582 // (int)d->frame.header.samplerate, (int)d->frame.header.bitrate );
579 // qDebug( "LibMadPlugin::audioSamples: %i", samples ); 583 // odebug << "LibMadPlugin::audioSamples: " << samples << "" << oendl;
580 584
581 return samples; 585 return samples;
582 586
583// return 10000000; 587// return 10000000;
584} 588}
585 589
586 590
587bool LibMadPlugin::audioSetSample( long, int ) { 591bool LibMadPlugin::audioSetSample( long, int ) {
588 debugMsg( "LibMadPlugin::audioSetSample" ); 592 debugMsg( "LibMadPlugin::audioSetSample" );
589 593
590// long totalSamples = audioSamples(0); 594// long totalSamples = audioSamples(0);
591// if ( totalSamples <= 1 ) 595// if ( totalSamples <= 1 )
592// return FALSE; 596// return FALSE;
593 597
594// // Seek to requested position 598// // Seek to requested position
595// qDebug( "seek pos: %i", (int)((double)pos * d->input.fileLength / totalSamples) ); 599// odebug << "seek pos: " << (int)((double)pos * d->input.fileLength / totalSamples) << "" << oendl;
596// ::lseek( d->input.fd, (long)((double)pos * d->input.fileLength / totalSamples), SEEK_SET ); 600// ::lseek( d->input.fd, (long)((double)pos * d->input.fileLength / totalSamples), SEEK_SET );
597// mad_stream_sync(&d->stream); 601// mad_stream_sync(&d->stream);
598 602
599// mad_stream_init(&d->stream); 603// mad_stream_init(&d->stream);
600// mad_frame_init(&d->frame); 604// mad_frame_init(&d->frame);
601// mad_synth_init(&d->synth); 605// mad_synth_init(&d->synth);
602 606
603// return TRUE; 607// return TRUE;
604 debugMsg( "LibMadPlugin::audioSetSample" ); 608 debugMsg( "LibMadPlugin::audioSetSample" );
605 return FALSE; 609 return FALSE;
606} 610}
607 611
608 612
609long LibMadPlugin::audioGetSample( int ) { 613long LibMadPlugin::audioGetSample( int ) {
610 debugMsg( "LibMadPlugin::audioGetSample" ); 614 debugMsg( "LibMadPlugin::audioGetSample" );
611 return 0; 615 return 0;
612} 616}
613 617
614/* 618/*
615bool LibMadPlugin::audioReadSamples( short *, int, long, int ) { 619bool LibMadPlugin::audioReadSamples( short *, int, long, int ) {
616debugMsg( "LibMadPlugin::audioReadSamples" ); 620debugMsg( "LibMadPlugin::audioReadSamples" );
617return FALSE; 621return FALSE;
618} 622}
619 623
@@ -659,49 +663,49 @@ bool LibMadPlugin::read() {
659 if (d->input.fdm == 0) { 663 if (d->input.fdm == 0) {
660 d->input.data = 0; 664 d->input.data = 0;
661 return FALSE; 665 return FALSE;
662 } 666 }
663 667
664 d->input.data = (unsigned char *)d->input.fdm; 668 d->input.data = (unsigned char *)d->input.fdm;
665 } 669 }
666 670
667 mad_stream_buffer(&d->stream, d->input.data + skip, d->input.length - skip); 671 mad_stream_buffer(&d->stream, d->input.data + skip, d->input.length - skip);
668 672
669 } else 673 } else
670#endif 674#endif
671 { 675 {
672 if (d->stream.next_frame) { 676 if (d->stream.next_frame) {
673 memmove(d->input.data, d->stream.next_frame, 677 memmove(d->input.data, d->stream.next_frame,
674 d->input.length = &d->input.data[d->input.length] - d->stream.next_frame); 678 d->input.length = &d->input.data[d->input.length] - d->stream.next_frame);
675 } 679 }
676 680
677 do { 681 do {
678 len = ::read(d->input.fd, d->input.data + d->input.length, bufferSize /* MPEG_BUFFER_SIZE*/ - d->input.length); 682 len = ::read(d->input.fd, d->input.data + d->input.length, bufferSize /* MPEG_BUFFER_SIZE*/ - d->input.length);
679 } 683 }
680 while (len == -1 && errno == EINTR); 684 while (len == -1 && errno == EINTR);
681 685
682 if (len == -1) { 686 if (len == -1) {
683 // qDebug("error reading audio"); 687 // odebug << "error reading audio" << oendl;
684 return FALSE; 688 return FALSE;
685 } 689 }
686 else if (len == 0) { 690 else if (len == 0) {
687 d->input.eof = 1; 691 d->input.eof = 1;
688 692
689 assert(bufferSize /*MPEG_BUFFER_SIZE*/ - d->input.length >= MAD_BUFFER_GUARD); 693 assert(bufferSize /*MPEG_BUFFER_SIZE*/ - d->input.length >= MAD_BUFFER_GUARD);
690 694
691 while (len < MAD_BUFFER_GUARD) 695 while (len < MAD_BUFFER_GUARD)
692 d->input.data[d->input.length + len++] = 0; 696 d->input.data[d->input.length + len++] = 0;
693 } 697 }
694 698
695 mad_stream_buffer(&d->stream, d->input.data, d->input.length += len); 699 mad_stream_buffer(&d->stream, d->input.data, d->input.length += len);
696 } 700 }
697 701
698 return TRUE; 702 return TRUE;
699} 703}
700 704
701 705
702static mad_fixed_t left_err, right_err; 706static mad_fixed_t left_err, right_err;
703static const int bits = 16; 707static const int bits = 16;
704static const int shift = MAD_F_FRACBITS + 1 - bits; 708static const int shift = MAD_F_FRACBITS + 1 - bits;
705 709
706 710
707inline long audio_linear_dither( mad_fixed_t sample, mad_fixed_t& error ) { 711inline long audio_linear_dither( mad_fixed_t sample, mad_fixed_t& error ) {
@@ -737,49 +741,49 @@ bool LibMadPlugin::decode( short *output, long samples, long& samplesMade ) {
737 int offset = buffered; 741 int offset = buffered;
738 samplesMade = 0; 742 samplesMade = 0;
739 743
740 static int maxBuffered = 8000; // 65536; 744 static int maxBuffered = 8000; // 65536;
741 745
742 if ( samples > maxBuffered ) { 746 if ( samples > maxBuffered ) {
743 samples = maxBuffered; 747 samples = maxBuffered;
744 } 748 }
745 749
746 if ( d->flush ) { 750 if ( d->flush ) {
747 buffered = 0; 751 buffered = 0;
748 offset = 0; 752 offset = 0;
749 d->flush = FALSE; 753 d->flush = FALSE;
750 } 754 }
751 755
752 while ( buffered < maxBuffered ) { 756 while ( buffered < maxBuffered ) {
753 757
754 while (mad_frame_decode(&d->frame, &d->stream) == -1) { 758 while (mad_frame_decode(&d->frame, &d->stream) == -1) {
755 if (!MAD_RECOVERABLE(d->stream.error)) { 759 if (!MAD_RECOVERABLE(d->stream.error)) {
756 debugMsg( "feed me" ); 760 debugMsg( "feed me" );
757 return FALSE; // Feed me 761 return FALSE; // Feed me
758 } 762 }
759 if ( d->stream.error == MAD_ERROR_BADCRC ) { 763 if ( d->stream.error == MAD_ERROR_BADCRC ) {
760 mad_frame_mute(&d->frame); 764 mad_frame_mute(&d->frame);
761 // qDebug( "error decoding, bad crc" ); 765 // odebug << "error decoding, bad crc" << oendl;
762 } 766 }
763 } 767 }
764 768
765 mad_synth_frame(&d->synth, &d->frame); 769 mad_synth_frame(&d->synth, &d->frame);
766 int decodedSamples = d->synth.pcm.length; 770 int decodedSamples = d->synth.pcm.length;
767 memcpy( &(buffer[0][offset]), d->synth.pcm.samples[0], decodedSamples * sizeof(mad_fixed_t) ); 771 memcpy( &(buffer[0][offset]), d->synth.pcm.samples[0], decodedSamples * sizeof(mad_fixed_t) );
768 if ( d->synth.pcm.channels == 2 ) 772 if ( d->synth.pcm.channels == 2 )
769 memcpy( &(buffer[1][offset]), d->synth.pcm.samples[1], decodedSamples * sizeof(mad_fixed_t) ); 773 memcpy( &(buffer[1][offset]), d->synth.pcm.samples[1], decodedSamples * sizeof(mad_fixed_t) );
770 offset += decodedSamples; 774 offset += decodedSamples;
771 buffered += decodedSamples; 775 buffered += decodedSamples;
772 } 776 }
773 777
774//qApp->processEvents(); 778//qApp->processEvents();
775 audio_pcm( output, samples, buffer[0], (d->synth.pcm.channels == 2) ? buffer[1] : 0 ); 779 audio_pcm( output, samples, buffer[0], (d->synth.pcm.channels == 2) ? buffer[1] : 0 );
776// audio_pcm( output, samples, buffer[1], buffer[0] ); 780// audio_pcm( output, samples, buffer[1], buffer[0] );
777// audio_pcm( output, samples, buffer[0], buffer[1] ); 781// audio_pcm( output, samples, buffer[0], buffer[1] );
778 samplesMade = samples; 782 samplesMade = samples;
779 memmove( buffer[0], &(buffer[0][samples]), (buffered - samples) * sizeof(mad_fixed_t) ); 783 memmove( buffer[0], &(buffer[0][samples]), (buffered - samples) * sizeof(mad_fixed_t) );
780 if ( d->synth.pcm.channels == 2 ) { 784 if ( d->synth.pcm.channels == 2 ) {
781 memmove( buffer[1], &(buffer[1][samples]), (buffered - samples) * sizeof(mad_fixed_t) ); 785 memmove( buffer[1], &(buffer[1][samples]), (buffered - samples) * sizeof(mad_fixed_t) );
782 } 786 }
783 buffered -= samples; 787 buffered -= samples;
784 788
785 return TRUE; 789 return TRUE;
@@ -800,70 +804,70 @@ bool LibMadPlugin::audioReadSamples( short *output, int /*channels*/, long sampl
800 if ( !read() ) { 804 if ( !read() ) {
801 return FALSE; 805 return FALSE;
802 } 806 }
803 807
804 needInput = FALSE; 808 needInput = FALSE;
805 809
806 if ( decode( output, samples, samplesMade ) ) 810 if ( decode( output, samples, samplesMade ) )
807 return TRUE; 811 return TRUE;
808 else 812 else
809 needInput = TRUE; 813 needInput = TRUE;
810 } 814 }
811 while ( ( samplesMade < samples ) && ( !d->input.eof ) ); 815 while ( ( samplesMade < samples ) && ( !d->input.eof ) );
812 816
813 return FALSE; 817 return FALSE;
814} 818}
815 819
816 820
817double LibMadPlugin::getTime() { 821double LibMadPlugin::getTime() {
818 debugMsg( "LibMadPlugin::getTime" ); 822 debugMsg( "LibMadPlugin::getTime" );
819 return 0.0; 823 return 0.0;
820} 824}
821 825
822 826
823void LibMadPlugin::printID3Tags() { 827void LibMadPlugin::printID3Tags() {
824 // qDebug( "LibMadPlugin::printID3Tags" ); 828 // odebug << "LibMadPlugin::printID3Tags" << oendl;
825 829
826 char id3v1[128 + 1]; 830 char id3v1[128 + 1];
827 831
828 if ( ::lseek( d->input.fd, -128, SEEK_END ) == -1 ) { 832 if ( ::lseek( d->input.fd, -128, SEEK_END ) == -1 ) {
829 // qDebug( "error seeking to id3 tags" ); 833 // odebug << "error seeking to id3 tags" << oendl;
830 return; 834 return;
831 } 835 }
832 836
833 if ( ::read( d->input.fd, id3v1, 128 ) != 128 ) { 837 if ( ::read( d->input.fd, id3v1, 128 ) != 128 ) {
834 // qDebug( "error reading in id3 tags" ); 838 // odebug << "error reading in id3 tags" << oendl;
835 return; 839 return;
836 } 840 }
837 841
838 if ( ::strncmp( (const char *)id3v1, "TAG", 3 ) != 0 ) { 842 if ( ::strncmp( (const char *)id3v1, "TAG", 3 ) != 0 ) {
839 debugMsg( "sorry, no id3 tags" ); 843 debugMsg( "sorry, no id3 tags" );
840 } else { 844 } else {
841 int len[5] = { 30, 30, 30, 4, 30 }; 845 int len[5] = { 30, 30, 30, 4, 30 };
842 QString label[5] = { tr( "Title" ), tr( "Artist" ), tr( "Album" ), tr( "Year" ), tr( "Comment" ) }; 846 QString label[5] = { tr( "Title" ), tr( "Artist" ), tr( "Album" ), tr( "Year" ), tr( "Comment" ) };
843 char *ptr = id3v1 + 3, *ptr2 = ptr + len[0]; 847 char *ptr = id3v1 + 3, *ptr2 = ptr + len[0];
844 // qDebug( "ID3 tags in file:" ); 848 // odebug << "ID3 tags in file:" << oendl;
845 info = ""; 849 info = "";
846 for ( int i = 0; i < 5; ptr += len[i], i++, ptr2 += len[i] ) { 850 for ( int i = 0; i < 5; ptr += len[i], i++, ptr2 += len[i] ) {
847 char push = *ptr2; 851 char push = *ptr2;
848 *ptr2 = '\0'; 852 *ptr2 = '\0';
849 char *ptr3 = ptr2; 853 char *ptr3 = ptr2;
850 while ( ptr3-1 >= ptr && isspace(ptr3[-1]) ) ptr3--; 854 while ( ptr3-1 >= ptr && isspace(ptr3[-1]) ) ptr3--;
851 char push2 = *ptr3; *ptr3 = '\0'; 855 char push2 = *ptr3; *ptr3 = '\0';
852 if ( strcmp( ptr, "" ) ) { 856 if ( strcmp( ptr, "" ) ) {
853 if( ((QString)ptr).find(" ") == -1) // don't add anything that has blanks 857 if( ((QString)ptr).find(" ") == -1) // don't add anything that has blanks
854 info += ( i != 0 ? ", " : "" ) + label[i] + ": " + ptr; 858 info += ( i != 0 ? ", " : "" ) + label[i] + ": " + ptr;
855 } 859 }
856// qDebug( info.latin1() ); 860// odebug << info.latin1() << oendl;
857 *ptr3 = push2; 861 *ptr3 = push2;
858 *ptr2 = push; 862 *ptr2 = push;
859 } 863 }
860 if (id3v1[126] == 0 && id3v1[127] != 0) 864 if (id3v1[126] == 0 && id3v1[127] != 0)
861 info += tr( ", Track: " ) + id3v1[127]; 865 info += tr( ", Track: " ) + id3v1[127];
862 } 866 }
863 867
864 if ( ::lseek(d->input.fd, 0, SEEK_SET) == -1 ) { 868 if ( ::lseek(d->input.fd, 0, SEEK_SET) == -1 ) {
865 // qDebug( "error seeking back to beginning" ); 869 // odebug << "error seeking back to beginning" << oendl;
866 return; 870 return;
867 } 871 }
868} 872}
869 873