aboutsummaryrefslogtreecommitdiff
path: root/sound/mixer.cpp
diff options
context:
space:
mode:
authorJonathan Gray2002-10-27 01:12:10 +0000
committerJonathan Gray2002-10-27 01:12:10 +0000
commitd93e63908659a9601ee29269606500ded088175e (patch)
tree420f1bb6c9a364cf25317622984381d9ae94aeec /sound/mixer.cpp
parentf89b40f0276601fb279dd2db03eed30c650df22a (diff)
downloadscummvm-rg350-d93e63908659a9601ee29269606500ded088175e.tar.gz
scummvm-rg350-d93e63908659a9601ee29269606500ded088175e.tar.bz2
scummvm-rg350-d93e63908659a9601ee29269606500ded088175e.zip
patch #628997 support for ogg vorbis instead of cd tracks by Daniel Schepler. Uncomment the relevant lines in the makefile to use
svn-id: r5320
Diffstat (limited to 'sound/mixer.cpp')
-rw-r--r--sound/mixer.cpp100
1 files changed, 98 insertions, 2 deletions
diff --git a/sound/mixer.cpp b/sound/mixer.cpp
index c742fb153e..e79a91aa98 100644
--- a/sound/mixer.cpp
+++ b/sound/mixer.cpp
@@ -120,7 +120,7 @@ void SoundMixer::beginSlots(int index) {
_beginSlots = index;
}
-#ifdef COMPRESSED_SOUND_FILE
+#ifdef USE_MAD
int SoundMixer::playMP3(PlayingSoundHandle * handle, void *sound, uint32 size, byte flags) {
for (int i = _beginSlots; i != NUM_CHANNELS; i++) {
if (_channels[i] == NULL) {
@@ -144,6 +144,19 @@ int SoundMixer::playMP3CDTrack(PlayingSoundHandle * handle, File * file, mad_tim
}
#endif
+#ifdef USE_VORBIS
+int SoundMixer::playVorbisCDTrack(PlayingSoundHandle * handle, OggVorbis_File * ov_file, double duration) {
+ for (int i = _beginSlots; i != NUM_CHANNELS; i++) {
+ if (_channels[i] == NULL) {
+ return insertAt(handle, i, new ChannelVorbis(this, ov_file, duration));
+ }
+ }
+
+ warning("SoundMixer::out of mixer slots");
+ return -1;
+}
+#endif
+
void SoundMixer::mix(int16 *buf, uint len) {
if (_paused) {
memset(buf, 0, 2 * len * sizeof(int16));
@@ -713,7 +726,7 @@ void SoundMixer::ChannelStream::realDestroy() {
delete this;
}
-#ifdef COMPRESSED_SOUND_FILE
+#ifdef USE_MAD
SoundMixer::ChannelMP3::ChannelMP3(SoundMixer * mixer, void * sound, uint size, byte flags) {
_mixer = mixer;
_flags = flags;
@@ -962,3 +975,86 @@ void SoundMixer::ChannelMP3CDMusic::realDestroy() {
}
#endif
+
+#ifdef USE_VORBIS
+SoundMixer::ChannelVorbis::ChannelVorbis(SoundMixer * mixer, OggVorbis_File * ov_file, double duration) {
+ _mixer = mixer;
+ _ov_file = ov_file;
+
+ if (duration)
+ _end_pos = ov_time_tell(ov_file) + duration;
+ else
+ _end_pos = 0;
+
+ _eof_flag = false;
+ _toBeDestroyed = false;
+}
+
+void SoundMixer::ChannelVorbis::mix(int16 * data, uint len) {
+ if (_toBeDestroyed) {
+ realDestroy();
+ return;
+ }
+
+ if (_eof_flag) {
+ memset(data, 0, sizeof(int16) * 2 * len);
+ return;
+ }
+
+ int channels = ov_info(_ov_file, -1)->channels;
+ uint len_left = len * channels * 2;
+ int16 *samples = new int16[len_left / 2];
+ char *read_pos = (char *) samples;
+ int volume = _mixer->_musicVolume;
+
+ // Read the samples
+ while (len_left > 0) {
+ long result = ov_read(_ov_file, read_pos, len_left,
+#ifdef SCUMM_BIG_ENDIAN
+ 1,
+#else
+ 0,
+#endif
+ 2, 1, NULL);
+ if (result == 0) {
+ _eof_flag = true;
+ memset(read_pos, 0, len_left);
+ break;
+ }
+ else if (result < 0) {
+ debug(1, "Decode error %d in Vorbis file", result);
+ // Don't delete it yet, that causes problems in
+ // the CD player emulation code.
+ _eof_flag = true;
+ memset(read_pos, 0, len_left);
+ break;
+ }
+ else {
+ len_left -= result;
+ read_pos += result;
+ }
+ }
+
+ // Mix the samples in
+ for (uint i = 0; i < len; i++) {
+ int16 sample = (int16) ((int32) samples[i * channels] * volume / 256);
+ *data++ += sample;
+ if (channels > 1)
+ sample = (int16) ((int32) samples[i * channels + 1] * volume / 256);
+ *data++ += sample;
+ }
+
+ delete [] samples;
+}
+
+void SoundMixer::ChannelVorbis::realDestroy() {
+ _mixer->unInsert(this);
+ delete this;
+}
+
+bool SoundMixer::ChannelVorbis::soundFinished() {
+ return _eof_flag || (_end_pos > 0 &&
+ ov_time_tell(_ov_file) >= _end_pos);
+}
+
+#endif