aboutsummaryrefslogtreecommitdiff
path: root/backends/audiocd
diff options
context:
space:
mode:
authorAlejandro Marzini2010-06-09 05:39:27 +0000
committerAlejandro Marzini2010-06-09 05:39:27 +0000
commit9f2358612a934de87ac9787effba11dd8b2b925b (patch)
treea915bd868ad4d0ea3970a7d208541467d7d75640 /backends/audiocd
parent7840aa196670000be3ff1baa03f99de0e34c61ad (diff)
downloadscummvm-rg350-9f2358612a934de87ac9787effba11dd8b2b925b.tar.gz
scummvm-rg350-9f2358612a934de87ac9787effba11dd8b2b925b.tar.bz2
scummvm-rg350-9f2358612a934de87ac9787effba11dd8b2b925b.zip
Created DefaultAudioCDManager and SdlAudioCDManager
svn-id: r49532
Diffstat (limited to 'backends/audiocd')
-rw-r--r--backends/audiocd/default/default-audiocd.cpp124
-rw-r--r--backends/audiocd/default/default-audiocd.h68
-rw-r--r--backends/audiocd/sdl/sdl-audiocd.cpp135
-rw-r--r--backends/audiocd/sdl/sdl-audiocd.h54
4 files changed, 381 insertions, 0 deletions
diff --git a/backends/audiocd/default/default-audiocd.cpp b/backends/audiocd/default/default-audiocd.cpp
new file mode 100644
index 0000000000..ebe5553611
--- /dev/null
+++ b/backends/audiocd/default/default-audiocd.cpp
@@ -0,0 +1,124 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "backends/audiocd/default/default-audiocd.h"
+#include "sound/audiostream.h"
+#include "common/util.h"
+#include "common/system.h"
+
+DefaultAudioCDManager::DefaultAudioCDManager() {
+ _cd.playing = false;
+ _cd.track = 0;
+ _cd.start = 0;
+ _cd.duration = 0;
+ _cd.numLoops = 0;
+ _mixer = g_system->getMixer();
+ _emulating = false;
+ assert(_mixer);
+}
+
+void DefaultAudioCDManager::play(int track, int numLoops, int startFrame, int duration, bool only_emulate) {
+ if (numLoops != 0 || startFrame != 0) {
+ _cd.track = track;
+ _cd.numLoops = numLoops;
+ _cd.start = startFrame;
+ _cd.duration = duration;
+
+ // Try to load the track from a compressed data file, and if found, use
+ // that. If not found, attempt to start regular Audio CD playback of
+ // the requested track.
+ char trackName[2][16];
+ sprintf(trackName[0], "track%d", track);
+ sprintf(trackName[1], "track%02d", track);
+ Audio::SeekableAudioStream *stream = 0;
+
+ for (int i = 0; !stream && i < 2; ++i)
+ stream = Audio::SeekableAudioStream::openStreamFile(trackName[i]);
+
+ // Stop any currently playing emulated track
+ _mixer->stopHandle(_handle);
+
+ if (stream != 0) {
+ Audio::Timestamp start = Audio::Timestamp(0, startFrame, 75);
+ Audio::Timestamp end = duration ? Audio::Timestamp(0, startFrame + duration, 75) : stream->getLength();
+
+ /*
+ FIXME: Seems numLoops == 0 and numLoops == 1 both indicate a single repetition,
+ while all other positive numbers indicate precisely the number of desired
+ repetitions. Finally, -1 means infinitely many
+ */
+ _emulating = true;
+ _mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle,
+ Audio::makeLoopingAudioStream(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops));
+ } else {
+ _emulating = false;
+ if (!only_emulate)
+ playCD(track, numLoops, startFrame, duration);
+ }
+ }
+}
+
+void DefaultAudioCDManager::stop() {
+ if (_emulating) {
+ // Audio CD emulation
+ _mixer->stopHandle(_handle);
+ _emulating = false;
+ } else {
+ // Real Audio CD
+ stopCD();
+ }
+}
+
+bool DefaultAudioCDManager::isPlaying() const {
+ if (_emulating) {
+ // Audio CD emulation
+ return _mixer->isSoundHandleActive(_handle);
+ } else {
+ // Real Audio CD
+ return pollCD();
+ }
+}
+
+void DefaultAudioCDManager::update() {
+ if (_emulating) {
+ // Check whether the audio track stopped playback
+ if (!_mixer->isSoundHandleActive(_handle)) {
+ // FIXME: We do not update the numLoops parameter here (and in fact,
+ // currently can't do that). Luckily, only one engine ever checks
+ // this part of the AudioCD status, namely the SCUMM engine; and it
+ // only checks whether the track is currently set to infinite looping
+ // or not.
+ _emulating = false;
+ }
+ } else {
+ updateCD();
+ }
+}
+
+DefaultAudioCDManager::Status DefaultAudioCDManager::getStatus() const {
+ Status info = _cd;
+ info.playing = isPlaying();
+ return info;
+}
diff --git a/backends/audiocd/default/default-audiocd.h b/backends/audiocd/default/default-audiocd.h
new file mode 100644
index 0000000000..0680b4fd65
--- /dev/null
+++ b/backends/audiocd/default/default-audiocd.h
@@ -0,0 +1,68 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef BACKENDS_AUDIOCD_DEFAULT_H
+#define BACKENDS_AUDIOCD_DEFAULT_H
+
+#include "common/noncopyable.h"
+#include "sound/mixer.h"
+
+class DefaultAudioCDManager : Common::NonCopyable {
+public:
+ DefaultAudioCDManager();
+ virtual ~DefaultAudioCDManager() {}
+
+ struct Status {
+ bool playing;
+ int track;
+ int start;
+ int duration;
+ int numLoops;
+ };
+
+ // Emulated CD functions, engines should call this functions
+ void play(int track, int numLoops, int startFrame, int duration, bool only_emulate = false);
+ void stop();
+ bool isPlaying() const;
+ void update();
+ virtual Status getStatus() const; // Subclasses should override for better status results
+
+protected:
+
+ // Real CD functions. Let Subclasses implement the real code
+ virtual bool openCD(int drive) { return false; }
+ virtual void updateCD() {}
+ virtual bool pollCD() const { return false; }
+ virtual void playCD(int track, int num_loops, int start_frame, int duration) {}
+ virtual void stopCD() {}
+
+ Audio::SoundHandle _handle;
+ bool _emulating;
+
+ Status _cd;
+ Audio::Mixer *_mixer;
+};
+
+#endif
diff --git a/backends/audiocd/sdl/sdl-audiocd.cpp b/backends/audiocd/sdl/sdl-audiocd.cpp
new file mode 100644
index 0000000000..7668bb80f5
--- /dev/null
+++ b/backends/audiocd/sdl/sdl-audiocd.cpp
@@ -0,0 +1,135 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#if defined(WIN32) || defined(UNIX) || defined(MACOSX)
+
+#include "backends/audiocd/sdl/sdl-audiocd.h"
+
+SdlAudioCDManager::SdlAudioCDManager()
+ :
+ _cdrom(0),
+ _cdTrack(0),
+ _cdNumLoops(0),
+ _cdStartFrame(0),
+ _cdDuration(0),
+ _cdEndTime(0),
+ _cdStopTime(0) {
+
+}
+
+SdlAudioCDManager::~SdlAudioCDManager() {
+ if (_cdrom) {
+ SDL_CDStop(_cdrom);
+ SDL_CDClose(_cdrom);
+ }
+}
+
+bool SdlAudioCDManager::openCD(int drive) {
+ if (SDL_InitSubSystem(SDL_INIT_CDROM) == -1)
+ _cdrom = NULL;
+ else {
+ _cdrom = SDL_CDOpen(drive);
+ // Did it open? Check if _cdrom is NULL
+ if (!_cdrom) {
+ warning("Couldn't open drive: %s", SDL_GetError());
+ } else {
+ _cdNumLoops = 0;
+ _cdStopTime = 0;
+ _cdEndTime = 0;
+ }
+ }
+
+ return (_cdrom != NULL);
+}
+
+void SdlAudioCDManager::stopCD() { /* Stop CD Audio in 1/10th of a second */
+ _cdStopTime = SDL_GetTicks() + 100;
+ _cdNumLoops = 0;
+}
+
+void SdlAudioCDManager::playCD(int track, int num_loops, int start_frame, int duration) {
+ if (!num_loops && !start_frame)
+ return;
+
+ if (!_cdrom)
+ return;
+
+ if (duration > 0)
+ duration += 5;
+
+ _cdTrack = track;
+ _cdNumLoops = num_loops;
+ _cdStartFrame = start_frame;
+
+ SDL_CDStatus(_cdrom);
+ if (start_frame == 0 && duration == 0)
+ SDL_CDPlayTracks(_cdrom, track, 0, 1, 0);
+ else
+ SDL_CDPlayTracks(_cdrom, track, start_frame, 0, duration);
+ _cdDuration = duration;
+ _cdStopTime = 0;
+ _cdEndTime = SDL_GetTicks() + _cdrom->track[track].length * 1000 / CD_FPS;
+}
+
+bool SdlAudioCDManager::pollCD() const {
+ if (!_cdrom)
+ return false;
+
+ return (_cdNumLoops != 0 && (SDL_GetTicks() < _cdEndTime || SDL_CDStatus(_cdrom) == CD_PLAYING));
+}
+
+void SdlAudioCDManager::updateCD() {
+ if (!_cdrom)
+ return;
+
+ if (_cdStopTime != 0 && SDL_GetTicks() >= _cdStopTime) {
+ SDL_CDStop(_cdrom);
+ _cdNumLoops = 0;
+ _cdStopTime = 0;
+ return;
+ }
+
+ if (_cdNumLoops == 0 || SDL_GetTicks() < _cdEndTime)
+ return;
+
+ if (_cdNumLoops != 1 && SDL_CDStatus(_cdrom) != CD_STOPPED) {
+ // Wait another second for it to be done
+ _cdEndTime += 1000;
+ return;
+ }
+
+ if (_cdNumLoops > 0)
+ _cdNumLoops--;
+
+ if (_cdNumLoops != 0) {
+ if (_cdStartFrame == 0 && _cdDuration == 0)
+ SDL_CDPlayTracks(_cdrom, _cdTrack, 0, 1, 0);
+ else
+ SDL_CDPlayTracks(_cdrom, _cdTrack, _cdStartFrame, 0, _cdDuration);
+ _cdEndTime = SDL_GetTicks() + _cdrom->track[_cdTrack].length * 1000 / CD_FPS;
+ }
+}
+
+#endif
diff --git a/backends/audiocd/sdl/sdl-audiocd.h b/backends/audiocd/sdl/sdl-audiocd.h
new file mode 100644
index 0000000000..1681f65d2e
--- /dev/null
+++ b/backends/audiocd/sdl/sdl-audiocd.h
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef BACKENDS_AUDIOCD_SDL_H
+#define BACKENDS_AUDIOCD_SDL_H
+
+#include "backends/audiocd/default/default-audiocd.h"
+
+#if defined(__SYMBIAN32__)
+#include <esdl\SDL.h>
+#else
+#include <SDL.h>
+#endif
+
+class SdlAudioCDManager : DefaultAudioCDManager {
+public:
+ SdlAudioCDManager();
+ ~SdlAudioCDManager();
+
+protected:
+ bool openCD(int drive);
+ void updateCD();
+ bool pollCD() const;
+ void playCD(int track, int num_loops, int start_frame, int duration);
+ void stopCD();
+
+ SDL_CD *_cdrom;
+ int _cdTrack, _cdNumLoops, _cdStartFrame, _cdDuration;
+ uint32 _cdEndTime, _cdStopTime;
+};
+
+#endif