diff options
author | Max Horn | 2003-11-29 12:11:01 +0000 |
---|---|---|
committer | Max Horn | 2003-11-29 12:11:01 +0000 |
commit | f00cd05b331cb5db1dfee140608d6189385950a4 (patch) | |
tree | db1e0105eb9ef2cd266620357c551c5a058f4d37 /sound/mp3.cpp | |
parent | 493d64d91b9944cd91da6539cb41ee561ddafd92 (diff) | |
download | scummvm-rg350-f00cd05b331cb5db1dfee140608d6189385950a4.tar.gz scummvm-rg350-f00cd05b331cb5db1dfee140608d6189385950a4.tar.bz2 scummvm-rg350-f00cd05b331cb5db1dfee140608d6189385950a4.zip |
moved Audio CD (emulation) code from scumm/sound.cpp to sound/, so that it may be reused by other engines in the future
svn-id: r11421
Diffstat (limited to 'sound/mp3.cpp')
-rw-r--r-- | sound/mp3.cpp | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/sound/mp3.cpp b/sound/mp3.cpp new file mode 100644 index 0000000000..db73f7f394 --- /dev/null +++ b/sound/mp3.cpp @@ -0,0 +1,127 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "stdafx.h" + +#include "sound/mp3.h" +#include "common/file.h" +#include "common/util.h" + +#ifdef USE_MAD +MP3TrackInfo::MP3TrackInfo(File *file) { + struct mad_stream stream; + struct mad_frame frame; + unsigned char buffer[8192]; + unsigned int buflen = 0; + int count = 0; + + // Check the format and bitrate + mad_stream_init(&stream); + mad_frame_init(&frame); + + while (1) { + if (buflen < sizeof(buffer)) { + int bytes; + + bytes = file->read(buffer + buflen, sizeof(buffer) - buflen); + if (bytes <= 0) { + if (bytes == -1) { + warning("Invalid file format"); + goto error; + } + break; + } + + buflen += bytes; + } + + mad_stream_buffer(&stream, buffer, buflen); + + while (1) { + if (mad_frame_decode(&frame, &stream) == -1) { + if (!MAD_RECOVERABLE(stream.error)) + break; + + if (stream.error != MAD_ERROR_BADCRC) + continue; + } + + if (count++) + break; + } + + if (count || stream.error != MAD_ERROR_BUFLEN) + break; + + memmove(buffer, stream.next_frame, + buflen = &buffer[buflen] - stream.next_frame); + } + + if (count) + memcpy(&_mad_header, &frame.header, sizeof(mad_header)); + else { + warning("Invalid file format"); + goto error; + } + + mad_frame_finish(&frame); + mad_stream_finish(&stream); + // Get file size + _size = file->size(); + _file = file; + _error_flag = false; + return; + +error: + mad_frame_finish(&frame); + mad_stream_finish(&stream); + _error_flag = true; + delete file; +} + +int MP3TrackInfo::play(SoundMixer *mixer, PlayingSoundHandle *handle, int startFrame, int duration) { + unsigned int offset; + mad_timer_t durationTime; + + // 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; + _file->seek(offset, SEEK_SET); + + // Calc delay + if (!duration) { + // FIXME: Using _size here is a problem if offset (or equivalently + // startFrame) is non-zero. + mad_timer_set(&durationTime, (_size * 8) / _mad_header.bitrate, + (_size * 8) % _mad_header.bitrate, _mad_header.bitrate); + } else { + mad_timer_set(&durationTime, duration / 75, duration % 75, 75); + } + + // Play it + return mixer->playMP3CDTrack(handle, _file, durationTime); +} + +MP3TrackInfo::~MP3TrackInfo() { + if (! _error_flag) + _file->close(); +} + +#endif |