summaryrefslogtreecommitdiff
authorllornkcor <llornkcor>2003-02-25 23:36:47 (UTC)
committer llornkcor <llornkcor>2003-02-25 23:36:47 (UTC)
commitbde9ed97c92b6f7eefa8a66d9f58aa4c78127733 (patch) (unidiff)
tree4a74c6083acd5d89e191aaa3629040fb4449ff71
parent689847f2dcaabdfca266efd3c99c81b833bf6e9f (diff)
downloadopie-bde9ed97c92b6f7eefa8a66d9f58aa4c78127733.zip
opie-bde9ed97c92b6f7eefa8a66d9f58aa4c78127733.tar.gz
opie-bde9ed97c92b6f7eefa8a66d9f58aa4c78127733.tar.bz2
add proper number of samples reporting
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libmad/libmadplugin.cpp52
1 files changed, 43 insertions, 9 deletions
diff --git a/core/multimedia/opieplayer/libmad/libmadplugin.cpp b/core/multimedia/opieplayer/libmad/libmadplugin.cpp
index 9a1ab2a..9d1ff8c 100644
--- a/core/multimedia/opieplayer/libmad/libmadplugin.cpp
+++ b/core/multimedia/opieplayer/libmad/libmadplugin.cpp
@@ -30,97 +30,98 @@
30#include <ctype.h> 30#include <ctype.h>
31#include <errno.h> 31#include <errno.h>
32#include <time.h> 32#include <time.h>
33#include <locale.h> 33#include <locale.h>
34#include <math.h> 34#include <math.h>
35#include <assert.h> 35#include <assert.h>
36 36
37#include <qapplication.h> 37#include <qapplication.h>
38#include <qmessagebox.h> 38#include <qmessagebox.h>
39#include <qregexp.h> 39#include <qregexp.h>
40 40
41#include <qpe/config.h> 41#include <qpe/config.h>
42 42
43// for network handling 43// for network handling
44#include <netinet/in.h> 44#include <netinet/in.h>
45#include <netdb.h> 45#include <netdb.h>
46#include <linux/limits.h> 46#include <linux/limits.h>
47#include <sys/socket.h> 47#include <sys/socket.h>
48#include <arpa/inet.h> 48#include <arpa/inet.h>
49#include <unistd.h> 49#include <unistd.h>
50 50
51 51
52//#define HAVE_MMAP 52//#define HAVE_MMAP
53 53
54#if defined(HAVE_MMAP) 54#if defined(HAVE_MMAP)
55# include <sys/mman.h> 55# include <sys/mman.h>
56#endif 56#endif
57#include "libmadplugin.h" 57#include "libmadplugin.h"
58 58
59 59
60extern "C" { 60extern "C" {
61#include "mad.h" 61#include "mad.h"
62} 62}
63 63
64 64
65#define MPEG_BUFFER_SIZE 65536 65#define MPEG_BUFFER_SIZE 65536
66//#define MPEG_BUFFER_SIZE 32768 //16384 // 8192 66//#define MPEG_BUFFER_SIZE 32768 //16384 // 8192
67//#define debugMsg(a) qDebug(a) 67//#define debugMsg(a) qDebug(a)
68#define debugMsg(a) 68#define debugMsg(a)
69 69
70 70
71class Input { 71class Input {
72public: 72public:
73 char const *path; 73 char const *path;
74 int fd; 74 int fd;
75#if defined(HAVE_MMAP) 75#if defined(HAVE_MMAP)
76 void *fdm; 76 void *fdm;
77#endif 77#endif
78 unsigned char *data; 78 unsigned long fileLength;
79 unsigned char *data;
79 unsigned long length; 80 unsigned long length;
80 int eof; 81 int eof;
81}; 82};
82 83
83 84
84class Output { 85class Output {
85public: 86public:
86 mad_fixed_t attenuate; 87 mad_fixed_t attenuate;
87 struct filter *filters; 88 struct filter *filters;
88 unsigned int channels_in; 89 unsigned int channels_in;
89 unsigned int channels_out; 90 unsigned int channels_out;
90 unsigned int speed_in; 91 unsigned int speed_in;
91 unsigned int speed_out; 92 unsigned int speed_out;
92 const char *path; 93 const char *path;
93}; 94};
94 95
95 96
96# if defined(HAVE_MMAP) 97# if defined(HAVE_MMAP)
97static void *map_file(int fd, unsigned long *length) 98static void *map_file(int fd, unsigned long *length)
98{ 99{
99 void *fdm; 100 void *fdm;
100 101
101 *length += MAD_BUFFER_GUARD; 102 *length += MAD_BUFFER_GUARD;
102 103
103 fdm = mmap(0, *length, PROT_READ, MAP_SHARED, fd, 0); 104 fdm = mmap(0, *length, PROT_READ, MAP_SHARED, fd, 0);
104 if (fdm == MAP_FAILED) 105 if (fdm == MAP_FAILED)
105 return 0; 106 return 0;
106 107
107# if defined(HAVE_MADVISE) 108# if defined(HAVE_MADVISE)
108 madvise(fdm, *length, MADV_SEQUENTIAL); 109 madvise(fdm, *length, MADV_SEQUENTIAL);
109# endif 110# endif
110 111
111 return fdm; 112 return fdm;
112} 113}
113 114
114 115
115static int unmap_file(void *fdm, unsigned long length) 116static int unmap_file(void *fdm, unsigned long length)
116{ 117{
117 if (munmap(fdm, length) == -1) 118 if (munmap(fdm, length) == -1)
118 return -1; 119 return -1;
119 120
120 return 0; 121 return 0;
121} 122}
122# endif 123# endif
123 124
124 125
125static inline QString tr( const char *str ) { 126static inline QString tr( const char *str ) {
126 // Apparently this is okay from a plugin as it runs in the process space of the owner of the plugin 127 // Apparently this is okay from a plugin as it runs in the process space of the owner of the plugin
@@ -408,101 +409,106 @@ int LibMadPlugin::http_open(const QString& path ) {
408 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 );
409 } else if ( QString( http_request ).left( 7 ) == "icy-url" ) { 410 } else if ( QString( http_request ).left( 7 ) == "icy-url" ) {
410 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 );
411 } else if ( QString( http_request ).left( 10 ) == "icy-notice" ) { 412 } else if ( QString( http_request ).left( 10 ) == "icy-notice" ) {
412 message += QString(http_request).mid(11, QString(http_request).length()-11 ) ; 413 message += QString(http_request).mid(11, QString(http_request).length()-11 ) ;
413 } 414 }
414 } 415 }
415 } while (strcmp(http_request, "\n") != 0); 416 } while (strcmp(http_request, "\n") != 0);
416 417
417 info = QString(name + genre + url + bitrate + message).replace( QRegExp("\n"), " : " ); 418 info = QString(name + genre + url + bitrate + message).replace( QRegExp("\n"), " : " );
418 419
419 qDebug("Stream info: " + info); 420 qDebug("Stream info: " + info);
420 421
421 return (tcp_sock); 422 return (tcp_sock);
422} 423}
423 424
424 425
425 426
426bool LibMadPlugin::open( const QString& path ) { 427bool LibMadPlugin::open( const QString& path ) {
427 debugMsg( "LibMadPlugin::open" ); 428 debugMsg( "LibMadPlugin::open" );
428 Config cfg("OpiePlayer"); 429 Config cfg("OpiePlayer");
429 cfg.setGroup("Options"); 430 cfg.setGroup("Options");
430 bufferSize = cfg.readNumEntry("MPeg_BufferSize",MPEG_BUFFER_SIZE); 431 bufferSize = cfg.readNumEntry("MPeg_BufferSize",MPEG_BUFFER_SIZE);
431 qDebug("buffer size is %d", bufferSize); 432 qDebug("buffer size is %d", bufferSize);
432 d->bad_last_frame = 0; 433 d->bad_last_frame = 0;
433 d->flush = TRUE; 434 d->flush = TRUE;
434 info = QString( "" ); 435 info = QString( "" );
435 436
436 //qDebug( "Opening %s", path.latin1() ); 437 //qDebug( "Opening %s", path.latin1() );
437 438
438 if (path.left( 4 ) == "http" ) { 439 if (path.left( 4 ) == "http" ) {
439 // in case of any error we get 0 here 440 // in case of any error we get 0 here
440 if ( !(http_open(path) == 0) ) { 441 if ( !(http_open(path) == 0) ) {
441 d->input.fd = http_open(path); 442 d->input.fd = http_open(path);
442 } else { 443 } else {
443 return FALSE; 444 return FALSE;
444 } 445 }
445 } else { 446 } else {
446 d->input.path = path.latin1(); 447 d->input.path = path.latin1();
447 d->input.fd = ::open( d->input.path, O_RDONLY ); 448 d->input.fd = ::open( d->input.path, O_RDONLY );
448 // 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
449 printID3Tags(); 450 printID3Tags();
450 } 451 }
451 if (d->input.fd == -1) { 452 if (d->input.fd == -1) {
452 qDebug("error opening %s", d->input.path ); 453 qDebug("error opening %s", d->input.path );
453 return FALSE; 454 return FALSE;
454 } 455 }
455 456
456#if defined(HAVE_MMAP)
457 struct stat stat; 457 struct stat stat;
458 if (fstat(d->input.fd, &stat) == -1) { 458 if (fstat(d->input.fd, &stat) == -1) {
459 //qDebug("error calling fstat"); return FALSE; 459 qDebug("error calling fstat"); return FALSE;
460 } 460 }
461 if (S_ISREG(stat.st_mode) && stat.st_size > 0)
462 d->input.fileLength = stat.st_size;
463 else
464 d->input.fileLength = 0;
465
466#if defined(HAVE_MMAP)
461 if (S_ISREG(stat.st_mode) && stat.st_size > 0) { 467 if (S_ISREG(stat.st_mode) && stat.st_size > 0) {
462 d->input.length = stat.st_size; 468 d->input.length = stat.st_size;
463 d->input.fdm = map_file(d->input.fd, &d->input.length); 469 d->input.fdm = map_file(d->input.fd, &d->input.length);
464 if (d->input.fdm == 0) { 470 if (d->input.fdm == 0) {
465 qDebug("error mmapping file"); return FALSE; 471 qDebug("error mmapping file"); return FALSE;
466 } 472 }
467 d->input.data = (unsigned char *)d->input.fdm; 473 d->input.data = (unsigned char *)d->input.fdm;
468 } 474 }
469#endif 475#endif
470 476
471 if (d->input.data == 0) { 477 if (d->input.data == 0) {
472 d->input.data = (unsigned char *)malloc( bufferSize /*MPEG_BUFFER_SIZE*/); 478 d->input.data = (unsigned char *)malloc( bufferSize /*MPEG_BUFFER_SIZE*/);
473 if (d->input.data == 0) { 479 if (d->input.data == 0) {
474 qDebug("error allocating input buffer"); 480 qDebug("error allocating input buffer");
475 return FALSE; 481 return FALSE;
476 } 482 }
477 d->input.length = 0; 483 d->input.length = 0;
478 } 484 }
479 485
480 d->input.eof = 0; 486 d->input.eof = 0;
481 487
482 mad_stream_init(&d->stream); 488 mad_stream_init(&d->stream);
483 mad_frame_init(&d->frame); 489 mad_frame_init(&d->frame);
484 mad_synth_init(&d->synth); 490 mad_synth_init(&d->synth);
485 491
486 return TRUE; 492 return TRUE;
487} 493}
488 494
489 495
490bool LibMadPlugin::close() { 496bool LibMadPlugin::close() {
491 debugMsg( "LibMadPlugin::close" ); 497 debugMsg( "LibMadPlugin::close" );
492 498
493 int result = TRUE; 499 int result = TRUE;
494 500
495 mad_synth_finish(&d->synth); 501 mad_synth_finish(&d->synth);
496 mad_frame_finish(&d->frame); 502 mad_frame_finish(&d->frame);
497 mad_stream_finish(&d->stream); 503 mad_stream_finish(&d->stream);
498 504
499#if defined(HAVE_MMAP) 505#if defined(HAVE_MMAP)
500 if (d->input.fdm) { 506 if (d->input.fdm) {
501 if (unmap_file(d->input.fdm, d->input.length) == -1) { 507 if (unmap_file(d->input.fdm, d->input.length) == -1) {
502 qDebug("error munmapping file"); 508 qDebug("error munmapping file");
503 result = FALSE; 509 result = FALSE;
504 } 510 }
505 d->input.fdm = 0; 511 d->input.fdm = 0;
506 d->input.data = 0; 512 d->input.data = 0;
507 } 513 }
508#endif 514#endif
@@ -510,109 +516,137 @@ bool LibMadPlugin::close() {
510 if (d->input.data) { 516 if (d->input.data) {
511 free(d->input.data); 517 free(d->input.data);
512 d->input.data = 0; 518 d->input.data = 0;
513 } 519 }
514 520
515 if (::close(d->input.fd) == -1) { 521 if (::close(d->input.fd) == -1) {
516 qDebug("error closing file %s", d->input.path); 522 qDebug("error closing file %s", d->input.path);
517 result = FALSE; 523 result = FALSE;
518 } 524 }
519 525
520 d->input.fd = 0; 526 d->input.fd = 0;
521 527
522 return result; 528 return result;
523} 529}
524 530
525 531
526bool LibMadPlugin::isOpen() { 532bool LibMadPlugin::isOpen() {
527 debugMsg( "LibMadPlugin::isOpen" ); 533 debugMsg( "LibMadPlugin::isOpen" );
528 return ( d->input.fd != 0 ); 534 return ( d->input.fd != 0 );
529} 535}
530 536
531 537
532int LibMadPlugin::audioStreams() { 538int LibMadPlugin::audioStreams() {
533 debugMsg( "LibMadPlugin::audioStreams" ); 539 debugMsg( "LibMadPlugin::audioStreams" );
534 return 1; 540 return 1;
535} 541}
536 542
537 543
538int LibMadPlugin::audioChannels( int ) { 544int LibMadPlugin::audioChannels( int ) {
539 debugMsg( "LibMadPlugin::audioChannels" ); 545 debugMsg( "LibMadPlugin::audioChannels" );
540/* 546/*
541 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 ); 547 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 );
542 qDebug( "LibMadPlugin::audioChannels: %i", d->frame.header.mode > 0 ? 2 : 1 ); 548 qDebug( "LibMadPlugin::audioChannels: %i", d->frame.header.mode > 0 ? 2 : 1 );
543 return d->frame.header.mode > 0 ? 2 : 1; 549 return d->frame.header.mode > 0 ? 2 : 1;
544*/ 550*/
545 return 2; 551 return 2;
546} 552}
547 553
548 554
549int LibMadPlugin::audioFrequency( int ) { 555int LibMadPlugin::audioFrequency( int ) {
550 debugMsg( "LibMadPlugin::audioFrequency" ); 556 debugMsg( "LibMadPlugin::audioFrequency" );
551 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 ); 557 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 );
552 qDebug( "LibMadPlugin::audioFrequency: %i", d->frame.header.samplerate ); 558 qDebug( "LibMadPlugin::audioFrequency: %i", d->frame.header.samplerate );
553 return d->frame.header.samplerate; 559 return d->frame.header.samplerate;
554} 560}
555 561
556 562
557int LibMadPlugin::audioSamples( int ) { 563int LibMadPlugin::audioSamples( int ) {
558 debugMsg( "LibMadPlugin::audioSamples" ); 564 debugMsg( "LibMadPlugin::audioSamples" );
565
566 long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 );
567 mad_header_decode( (struct mad_header *)&d->frame.header, &d->stream );
568/*
569 qDebug( "LibMadPlugin::audioSamples: %i*%i", d->frame.header.duration.seconds,
570 d->frame.header.samplerate );
571 return d->frame.header.duration.seconds * d->frame.header.samplerate;
572*/
573 if ( d->frame.header.bitrate == 0 )
574 return 0;
575 int samples = (d->input.fileLength / (d->frame.header.bitrate/8)) * d->frame.header.samplerate;
576
577 qDebug( "LibMadPlugin::audioSamples: %i * %i * 8 / %i", (int)d->input.fileLength,
578 (int)d->frame.header.samplerate, (int)d->frame.header.bitrate );
579 qDebug( "LibMadPlugin::audioSamples: %i", samples );
559 580
560 // long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 ); 581 return samples;
561// mad_header_decode( (struct mad_header *)&d->frame.header, &d->stream );
562// qDebug( "LibMadPlugin::audioSamples: %i*%i", d->frame.header.duration.seconds, d->frame.header.samplerate );
563// return d->frame.header.duration.seconds * d->frame.header.samplerate;
564 582
565 return 10000000; 583// return 10000000;
566} 584}
567 585
568 586
569bool LibMadPlugin::audioSetSample( long, int ) { 587bool LibMadPlugin::audioSetSample( long, int ) {
570 debugMsg( "LibMadPlugin::audioSetSample" ); 588 debugMsg( "LibMadPlugin::audioSetSample" );
589
590// long totalSamples = audioSamples(0);
591// if ( totalSamples <= 1 )
592// return FALSE;
593
594// // Seek to requested position
595// qDebug( "seek pos: %i", (int)((double)pos * d->input.fileLength / totalSamples) );
596// ::lseek( d->input.fd, (long)((double)pos * d->input.fileLength / totalSamples), SEEK_SET );
597// mad_stream_sync(&d->stream);
598
599// mad_stream_init(&d->stream);
600// mad_frame_init(&d->frame);
601// mad_synth_init(&d->synth);
602
603// return TRUE;
604 debugMsg( "LibMadPlugin::audioSetSample" );
571 return FALSE; 605 return FALSE;
572} 606}
573 607
574 608
575long LibMadPlugin::audioGetSample( int ) { 609long LibMadPlugin::audioGetSample( int ) {
576 debugMsg( "LibMadPlugin::audioGetSample" ); 610 debugMsg( "LibMadPlugin::audioGetSample" );
577 return 0; 611 return 0;
578} 612}
579 613
580/* 614/*
581bool LibMadPlugin::audioReadSamples( short *, int, long, int ) { 615bool LibMadPlugin::audioReadSamples( short *, int, long, int ) {
582debugMsg( "LibMadPlugin::audioReadSamples" ); 616debugMsg( "LibMadPlugin::audioReadSamples" );
583return FALSE; 617return FALSE;
584} 618}
585 619
586 620
587bool LibMadPlugin::audioReReadSamples( short *, int, long, int ) { 621bool LibMadPlugin::audioReReadSamples( short *, int, long, int ) {
588debugMsg( "LibMadPlugin::audioReReadSamples" ); 622debugMsg( "LibMadPlugin::audioReReadSamples" );
589 return FALSE; 623 return FALSE;
590 } 624 }
591*/ 625*/
592 626
593bool LibMadPlugin::read() { 627bool LibMadPlugin::read() {
594 debugMsg( "LibMadPlugin::read" ); 628 debugMsg( "LibMadPlugin::read" );
595 int len; 629 int len;
596 630
597 if (d->input.eof) 631 if (d->input.eof)
598 return FALSE; 632 return FALSE;
599 633
600#if defined(HAVE_MMAP) 634#if defined(HAVE_MMAP)
601 if (d->input.fdm) { 635 if (d->input.fdm) {
602 unsigned long skip = 0; 636 unsigned long skip = 0;
603 637
604 if (d->stream.next_frame) { 638 if (d->stream.next_frame) {
605 struct stat stat; 639 struct stat stat;
606 640
607 if (fstat(d->input.fd, &stat) == -1) 641 if (fstat(d->input.fd, &stat) == -1)
608 return FALSE; 642 return FALSE;
609 643
610 if (stat.st_size + MAD_BUFFER_GUARD <= (signed)d->input.length) 644 if (stat.st_size + MAD_BUFFER_GUARD <= (signed)d->input.length)
611 return FALSE; 645 return FALSE;
612 646
613 // file size changed; update memory map 647 // file size changed; update memory map
614 skip = d->stream.next_frame - d->input.data; 648 skip = d->stream.next_frame - d->input.data;
615 649
616 if (unmap_file(d->input.fdm, d->input.length) == -1) { 650 if (unmap_file(d->input.fdm, d->input.length) == -1) {
617 d->input.fdm = 0; 651 d->input.fdm = 0;
618 d->input.data = 0; 652 d->input.data = 0;