diff options
author | Jonathan Gray | 2002-10-27 01:12:10 +0000 |
---|---|---|
committer | Jonathan Gray | 2002-10-27 01:12:10 +0000 |
commit | d93e63908659a9601ee29269606500ded088175e (patch) | |
tree | 420f1bb6c9a364cf25317622984381d9ae94aeec /sound/mixer.cpp | |
parent | f89b40f0276601fb279dd2db03eed30c650df22a (diff) | |
download | scummvm-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.cpp | 100 |
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 |