aboutsummaryrefslogtreecommitdiff
path: root/sound/mp3.cpp
diff options
context:
space:
mode:
authorMax Horn2003-11-29 12:11:01 +0000
committerMax Horn2003-11-29 12:11:01 +0000
commitf00cd05b331cb5db1dfee140608d6189385950a4 (patch)
treedb1e0105eb9ef2cd266620357c551c5a058f4d37 /sound/mp3.cpp
parent493d64d91b9944cd91da6539cb41ee561ddafd92 (diff)
downloadscummvm-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.cpp127
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