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