From f001a43830d86fd3e8d4a2b6c70ef5e7a9cb0740 Mon Sep 17 00:00:00 2001 From: Lars Persson Date: Sun, 26 Jun 2005 19:44:55 +0000 Subject: Updated Scummvm MP3 implementation with patch so it works with Symbian multithreading. This openingen/closing the file for each chunk to read. This does only affect the Symbian build and the other ports should work as normal. svn-id: r18466 --- sound/mp3.cpp | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 2 deletions(-) (limited to 'sound/mp3.cpp') diff --git a/sound/mp3.cpp b/sound/mp3.cpp index 0bc670bed3..415ce04821 100644 --- a/sound/mp3.cpp +++ b/sound/mp3.cpp @@ -66,6 +66,10 @@ public: bool isStereo() const { return _isStereo; } int getRate() const { return _frame.header.samplerate; } +#ifdef __SYMBIAN32__ + // Used to store the last position stream was read for symbian + int _lastReadPosition; +#endif }; @@ -84,7 +88,16 @@ MP3InputStream::MP3InputStream(File *file, mad_timer_t duration) { mad_synth_init(&_synth); _duration = duration; + +#if defined(__SYMBIAN32__) + // Symbian can't share filehandles between different threads. + // So create a new file and seek that to the other filehandles position + _file= new (ELeave)File; + _file->open(file->name()); + _file->seek(file->pos()); +#else _file = file; +#endif _posInFrame = 0; _bufferSize = 128 * 1024; // Default buffer size is 128K @@ -106,7 +119,16 @@ MP3InputStream::MP3InputStream(File *file, uint32 size) { mad_synth_init(&_synth); _duration = mad_timer_zero; + +#if defined(__SYMBIAN32__) + // Symbian can't share filehandles between different threads. + // So create a new file and seek that to the other filehandles position + _file= new (ELeave)File; + _file->open(file->name()); + _file->seek(file->pos()); +#else _file = file; +#endif _posInFrame = 0; _bufferSize = size ? size : (128 * 1024); // Default buffer size is 128K @@ -115,6 +137,9 @@ MP3InputStream::MP3InputStream(File *file, uint32 size) { // If a size is specified, we do not perform any further read operations if (size) { +#ifdef __SYMBIAN32__ + delete _file; +#endif _file = 0; } else { _file->incRef(); @@ -130,6 +155,9 @@ MP3InputStream::~MP3InputStream() { if (_file) _file->decRef(); +#ifdef __SYMBIAN32__ + delete _file; +#endif } bool MP3InputStream::init() { @@ -173,6 +201,16 @@ void MP3InputStream::refill(bool first) { // Read the next frame (may have to retry several times, e.g. // to skip over ID3 information). + // must reopen file at current position +#ifdef __SYMBIAN32__ + // For symbian we must check that an alternative file pointer is created, see if its open + // If not re-open file and seek to the last read position + if(_file && !_file->isOpen()){ + _file->open(_file->name()); + _file->seek(_lastReadPosition); + } +#endif + while (mad_frame_decode(&_frame, &_stream)) { if (_stream.error == MAD_ERROR_BUFLEN) { int offset; @@ -226,6 +264,14 @@ void MP3InputStream::refill(bool first) { // Synthesise the frame into PCM samples and reset the buffer position mad_synth_frame(&_synth, &_frame); _posInFrame = 0; + +#ifdef __SYMBIAN32__ + // For symbian we now store the last read position and then close the file + if(_file){ + _lastReadPosition=_file->pos(); + _file->close(); + } +#endif } inline bool MP3InputStream::eosIntern() const { @@ -293,9 +339,23 @@ public: MP3TrackInfo::MP3TrackInfo(File *file) { +#ifdef __SYMBIAN32__ + // This data is taking a rather big room on symbians limited stack + // Create the buffers on the heap instead and let the stream and frame be references instead + struct mad_stream* streamptr = (struct mad_stream*)malloc(sizeof(struct mad_stream)); + struct mad_frame* frameptr = (struct mad_frame*)malloc(sizeof(struct mad_frame)); + unsigned char* bufferptr = (unsigned char*)malloc(8192); + + struct mad_stream& stream = *streamptr; + struct mad_frame& frame = *frameptr; + unsigned char* buffer = bufferptr; + int sizeofbuffer = 8192; +#else struct mad_stream stream; struct mad_frame frame; unsigned char buffer[8192]; + int sizeofbuffer = sizeof(buffer); +#endif unsigned int buflen = 0; int count = 0; @@ -304,10 +364,10 @@ MP3TrackInfo::MP3TrackInfo(File *file) { mad_frame_init(&frame); while (1) { - if (buflen < sizeof(buffer)) { + if (buflen < sizeofbuffer) { int bytes; - bytes = file->read(buffer + buflen, sizeof(buffer) - buflen); + bytes = file->read(buffer + buflen, sizeofbuffer - buflen); if (bytes <= 0) { if (bytes == -1) { warning("Invalid file format"); @@ -354,6 +414,12 @@ MP3TrackInfo::MP3TrackInfo(File *file) { _size = file->size(); _file = file; _error_flag = false; +#ifdef __SYMBIAN32__ + // Free the heap reservations + free(frameptr); + free(streamptr); + free(bufferptr); +#endif return; error: @@ -361,6 +427,12 @@ error: mad_stream_finish(&stream); _error_flag = true; delete file; +#ifdef __SYMBIAN32__ + // Free the heap reservations + free(frameptr); + free(streamptr); + free(bufferptr); +#endif } void MP3TrackInfo::play(Audio::Mixer *mixer, Audio::SoundHandle *handle, int startFrame, int duration) { @@ -369,6 +441,11 @@ void MP3TrackInfo::play(Audio::Mixer *mixer, Audio::SoundHandle *handle, int sta // Calc offset. As all bitrates are in kilobit per seconds, the division by 200 is always exact offset = (startFrame * (_mad_header.bitrate / (8 * 25))) / 3; +#ifdef __SYMBIAN32__ + // Reopen the file if it is not open yet + if(!_file->isOpen()) + _file->open(_file->name()); +#endif _file->seek(offset, SEEK_SET); // Calc delay -- cgit v1.2.3