[Scummvm-cvs-logs] CVS: scummvm/sound audiocd.cpp,NONE,1.1 audiocd.h,NONE,1.1 mp3.cpp,NONE,1.1 mp3.h,NONE,1.1 vorbis.cpp,NONE,1.1 vorbis.h,NONE,1.1 module.mk,1.14,1.15
Max Horn
fingolfin at users.sourceforge.net
Sat Nov 29 04:10:03 CET 2003
Update of /cvsroot/scummvm/scummvm/sound
In directory sc8-pr-cvs1:/tmp/cvs-serv6926
Modified Files:
module.mk
Added Files:
audiocd.cpp audiocd.h mp3.cpp mp3.h vorbis.cpp vorbis.h
Log Message:
moved Audio CD (emulation) code from scumm/sound.cpp to sound/, so that it may be reused by other engines in the future
--- NEW FILE: audiocd.cpp ---
/* 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: /cvsroot/scummvm/scummvm/sound/audiocd.cpp,v 1.1 2003/11/29 12:09:51 fingolfin Exp $
*
*/
#include "stdafx.h"
#include "sound/audiocd.h"
#include "sound/mp3.h"
#include "sound/vorbis.h"
#include "base/engine.h"
#include "common/file.h"
#include "common/util.h"
AudioCDManager::AudioCDManager() {
_current_cache = 0;
}
void AudioCDManager::playCDTrack(int track, int numLoops, int startFrame, int duration) {
if (numLoops != 0 || startFrame != 0) {
// Try to load the track from a .mp3/.ogg file, and if found, use
// that. If not found, attempt to do regular Audio CD playback of
// the requested track.
int index = getCachedTrack(track);
if (index >= 0) {
g_engine->_mixer->stopHandle(_cd.handle);
_cd.playing = true;
_cd.track = track;
_cd.numLoops = numLoops;
_cd.start = startFrame;
_cd.duration = duration;
_track_info[index]->play(g_engine->_mixer, &_cd.handle, _cd.start, _cd.duration);
} else {
g_system->play_cdrom(track, numLoops, startFrame, duration);
}
}
}
void AudioCDManager::stopCD() {
if (_cd.playing) {
g_engine->_mixer->stopHandle(_cd.handle);
_cd.playing = false;
} else {
g_system->stop_cdrom();
}
}
int AudioCDManager::pollCD() const {
return _cd.playing || g_system->poll_cdrom();
}
void AudioCDManager::updateCD() {
if (_cd.playing) {
// If the sound handle is 0, then playback stopped.
if (!_cd.handle) {
// If playback just stopped, check if the current track is supposed
// to be repeated, and if that's the case, play it again. Else, stop
// the CD explicitly.
if (_cd.numLoops == -1 || --_cd.numLoops > 0) {
//FIXME _scumm->VAR(_scumm->VAR_MUSIC_TIMER) = 0;
//FIXME if (!_soundsPaused) {
int index = getCachedTrack(_cd.track);
assert(index >= 0);
_track_info[index]->play(g_engine->_mixer, &_cd.handle, _cd.start, _cd.duration);
//FIXME }
} else {
g_engine->_mixer->stopHandle(_cd.handle);
_cd.playing = false;
}
}
} else {
g_system->update_cdrom();
}
}
int AudioCDManager::getCachedTrack(int track) {
int i;
#if defined(USE_MAD) || defined(USE_VORBIS)
char track_name[1024];
File *file = new File();
#endif
int current_index;
// See if we find the track in the cache
for (i = 0; i < CACHE_TRACKS; i++)
if (_cached_tracks[i] == track) {
if (_track_info[i])
return i;
else
return -1;
}
current_index = _current_cache++;
_current_cache %= CACHE_TRACKS;
// Not found, see if it exists
// First, delete the previous track info object
delete _track_info[current_index];
_track_info[current_index] = NULL;
_cached_tracks[current_index] = track;
#ifdef USE_MAD
sprintf(track_name, "track%d.mp3", track);
file->open(track_name, g_engine->getGameDataPath());
if (file->isOpen()) {
_track_info[current_index] = new MP3TrackInfo(file);
if (_track_info[current_index]->error()) {
delete _track_info[current_index];
_track_info[current_index] = NULL;
return -1;
}
return current_index;
}
#endif
#ifdef USE_VORBIS
sprintf(track_name, "track%d.ogg", track);
file->open(track_name, g_engine->getGameDataPath());
if (file->isOpen()) {
_track_info[current_index] = new VorbisTrackInfo(file);
if (_track_info[current_index]->error()) {
delete _track_info[current_index];
_track_info[current_index] = NULL;
return -1;
}
return current_index;
}
#endif
debug(2, "Track %d not available in compressed format", track);
return -1;
}
--- NEW FILE: audiocd.h ---
/* 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: /cvsroot/scummvm/scummvm/sound/audiocd.h,v 1.1 2003/11/29 12:09:51 fingolfin Exp $
*
*/
#ifndef SOUND_AUDIOCD_H
#define SOUND_AUDIOCD_H
#include "stdafx.h"
#include "common/scummsys.h"
#include "common/singleton.h"
#include "sound/mixer.h"
class DigitalTrackInfo {
public:
virtual bool error() = 0;
virtual int play(SoundMixer *mixer, PlayingSoundHandle *handle, int startFrame, int duration) = 0;
virtual ~DigitalTrackInfo() { }
};
class AudioCDManager : public Common::Singleton<AudioCDManager> {
public:
void playCDTrack(int track, int numLoops, int startFrame, int duration);
void stopCD();
int pollCD() const;
void updateCD();
private:
friend class Common::Singleton<AudioCDManager>;
AudioCDManager();
int getCachedTrack(int track);
private:
/* used for emulated CD music */
enum {
CACHE_TRACKS = 10
};
int _cached_tracks[CACHE_TRACKS];
DigitalTrackInfo *_track_info[CACHE_TRACKS];
int _current_cache;
struct {
PlayingSoundHandle handle;
int track;
int start;
int duration;
int numLoops;
bool playing;
} _cd;
};
/** Shortcut for accessing the audio CD manager. */
#define AudioCD AudioCDManager::instance()
#endif
--- NEW FILE: mp3.cpp ---
/* 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: /cvsroot/scummvm/scummvm/sound/mp3.cpp,v 1.1 2003/11/29 12:09:51 fingolfin Exp $
*
*/
#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
--- NEW FILE: mp3.h ---
/* 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: /cvsroot/scummvm/scummvm/sound/mp3.h,v 1.1 2003/11/29 12:09:51 fingolfin Exp $
*
*/
#ifndef SOUND_MP3_H
#define SOUND_MP3_H
#include "sound/audiocd.h"
class File;
#ifdef USE_MAD
class MP3TrackInfo : public DigitalTrackInfo {
private:
struct mad_header _mad_header;
long _size;
File *_file;
bool _error_flag;
public:
MP3TrackInfo(File *file);
~MP3TrackInfo();
bool error() { return _error_flag; }
int play(SoundMixer *mixer, PlayingSoundHandle *handle, int startFrame, int duration);
};
#endif
#endif
--- NEW FILE: vorbis.cpp ---
/* 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: /cvsroot/scummvm/scummvm/sound/vorbis.cpp,v 1.1 2003/11/29 12:09:51 fingolfin Exp $
*
*/
#include "stdafx.h"
#include "sound/vorbis.h"
#include "common/file.h"
#include "common/util.h"
#ifdef USE_VORBIS
// These are wrapper functions to allow using a File object to
// provide data to the OggVorbis_File object.
struct file_info {
File *file;
int start, curr_pos;
size_t len;
};
static size_t read_wrap(void *ptr, size_t size, size_t nmemb, void *datasource) {
file_info *f = (file_info *) datasource;
int result;
nmemb *= size;
if (f->curr_pos > (int) f->len)
nmemb = 0;
else if (nmemb > f->len - f->curr_pos)
nmemb = f->len - f->curr_pos;
result = f->file->read(ptr, nmemb);
if (result == -1) {
f->curr_pos = f->file->pos() - f->start;
return (size_t) -1;
} else {
f->curr_pos += result;
return result / size;
}
}
static int seek_wrap(void *datasource, ogg_int64_t offset, int whence) {
file_info *f = (file_info *) datasource;
if (whence == SEEK_SET)
offset += f->start;
else if (whence == SEEK_END) {
offset += f->start + f->len;
whence = SEEK_SET;
}
f->file->seek(offset, whence);
f->curr_pos = f->file->pos() - f->start;
return f->curr_pos;
}
static int close_wrap(void *datasource) {
file_info *f = (file_info *) datasource;
f->file->close();
delete f;
return 0;
}
static long tell_wrap(void *datasource) {
file_info *f = (file_info *) datasource;
return f->curr_pos;
}
static ov_callbacks g_File_wrap = {
read_wrap, seek_wrap, close_wrap, tell_wrap
};
#endif
#ifdef USE_VORBIS
VorbisTrackInfo::VorbisTrackInfo(File *file) {
file_info *f = new file_info;
f->file = file;
f->start = 0;
f->len = file->size();
f->curr_pos = file->pos();
if (ov_open_callbacks((void *) f, &_ov_file, NULL, 0, g_File_wrap) < 0) {
warning("Invalid file format");
_error_flag = true;
delete f;
delete file;
} else {
_error_flag = false;
_file = file;
}
}
#ifdef CHUNKSIZE
#define VORBIS_TREMOR
#endif
int VorbisTrackInfo::play(SoundMixer *mixer, PlayingSoundHandle *handle, int startFrame, int duration) {
#ifdef VORBIS_TREMOR
ov_time_seek(&_ov_file, (ogg_int64_t)(startFrame / 75.0 * 1000));
#else
ov_time_seek(&_ov_file, startFrame / 75.0);
#endif
return mixer->playVorbis(handle, &_ov_file,
duration * ov_info(&_ov_file, -1)->rate / 75, true);
}
VorbisTrackInfo::~VorbisTrackInfo() {
if (! _error_flag) {
ov_clear(&_ov_file);
delete _file;
}
}
void playSfxSound_Vorbis(SoundMixer *mixer, File *file, uint32 size, PlayingSoundHandle *handle) {
OggVorbis_File *ov_file = new OggVorbis_File;
file_info *f = new file_info;
f->file = file;
f->start = file->pos();
f->len = size;
f->curr_pos = 0;
if (ov_open_callbacks((void *) f, ov_file, NULL, 0, g_File_wrap) < 0) {
warning("Invalid file format");
delete ov_file;
delete f;
} else
mixer->playVorbis(handle, ov_file, 0, false);
}
#endif
--- NEW FILE: vorbis.h ---
/* 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: /cvsroot/scummvm/scummvm/sound/vorbis.h,v 1.1 2003/11/29 12:09:51 fingolfin Exp $
*
*/
#ifndef SOUND_VORBIS_H
#define SOUND_VORBIS_H
#include "sound/audiocd.h"
class File;
#ifdef USE_VORBIS
class VorbisTrackInfo : public DigitalTrackInfo {
private:
File *_file;
OggVorbis_File _ov_file;
bool _error_flag;
public:
VorbisTrackInfo(File *file);
~VorbisTrackInfo();
bool error() { return _error_flag; }
int play(SoundMixer *mixer, PlayingSoundHandle *handle, int startFrame, int duration);
};
void playSfxSound_Vorbis(SoundMixer *mixer, File *file, uint32 size, PlayingSoundHandle *handle);
#endif
#endif
Index: module.mk
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/module.mk,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- module.mk 2 Oct 2003 22:52:56 -0000 1.14
+++ module.mk 29 Nov 2003 12:09:51 -0000 1.15
@@ -1,6 +1,7 @@
MODULE := sound
MODULE_OBJS := \
+ sound/audiocd.o \
sound/audiostream.o \
sound/fmopl.o \
sound/mididrv.o \
@@ -8,9 +9,11 @@
sound/midiparser_smf.o \
sound/midiparser_xmidi.o \
sound/mixer.o \
+ sound/mp3.o \
sound/mpu401.o \
sound/rate.o \
- sound/voc.o
+ sound/voc.o \
+ sound/vorbis.o
# sound/resample.o \
MODULE_DIRS += \
More information about the Scummvm-git-logs
mailing list