diff options
author | Max Horn | 2003-06-21 23:29:34 +0000 |
---|---|---|
committer | Max Horn | 2003-06-21 23:29:34 +0000 |
commit | bd4370c25166ad0e49c78d9e4407d39358e17b91 (patch) | |
tree | ae1acc56b83cdb642da285be7373ab116f3efd1f /sound | |
parent | 7281ac690732a93e9407f56e61976ea4b7c54fad (diff) | |
download | scummvm-rg350-bd4370c25166ad0e49c78d9e4407d39358e17b91.tar.gz scummvm-rg350-bd4370c25166ad0e49c78d9e4407d39358e17b91.tar.bz2 scummvm-rg350-bd4370c25166ad0e49c78d9e4407d39358e17b91.zip |
lots of mixer cleanup / refactoring / reengineering
svn-id: r8594
Diffstat (limited to 'sound')
-rw-r--r-- | sound/mixer.cpp | 134 | ||||
-rw-r--r-- | sound/mixer.h | 16 |
2 files changed, 44 insertions, 106 deletions
diff --git a/sound/mixer.cpp b/sound/mixer.cpp index fffb623257..cdcba77d34 100644 --- a/sound/mixer.cpp +++ b/sound/mixer.cpp @@ -53,16 +53,14 @@ class ChannelStream : public Channel { uint32 _fpPos; uint32 _bufferSize; uint32 _rate; - int32 _timeOut; - int32 _setTimeOut; byte _flags; public: - ChannelStream(SoundMixer *mixer, void *sound, uint32 size, uint rate, byte flags, int32 timout, int32 buffer_size); + ChannelStream(SoundMixer *mixer, void *sound, uint32 size, uint rate, byte flags, int32 buffer_size); - void append(void *sound, uint32 size); void mix(int16 *data, uint len); void realDestroy(); + void append(void *sound, uint32 size); }; #ifdef USE_MAD @@ -129,7 +127,6 @@ SoundMixer::SoundMixer() { memset(this,0,sizeof(SoundMixer)); // palmos _volumeTable = (int16 *)calloc(256 * sizeof(int16), 1); - _beginSlots = 0; for (int i = 0; i != NUM_CHANNELS; i++) { _channels[i] = NULL; } @@ -143,20 +140,6 @@ SoundMixer::~SoundMixer() { } } -void SoundMixer::unInsert(Channel *chan) { - for (int i = 0; i != NUM_CHANNELS; i++) { - if (_channels[i] == chan) { - if (_handles[i]) { - *_handles[i] = 0; - _handles[i] = NULL; - } - _channels[i] = NULL; - return; - } - } - error("SoundMixer::channel_deleted chan not found"); -} - int SoundMixer::append(int index, void *sound, uint32 size) { _syst->lock_mutex(_mutex); @@ -173,8 +156,11 @@ int SoundMixer::append(int index, void *sound, uint32 size) { int SoundMixer::insertAt(PlayingSoundHandle *handle, int index, Channel *chan) { if(index == -1) { - for (int i = _beginSlots; i != NUM_CHANNELS; i++) - if (_channels[i] == NULL) { index = i; break; } + for (int i = 0; i != NUM_CHANNELS; i++) + if (_channels[i] == NULL) { + index = i; + break; + } if(index == -1) { warning("SoundMixer::out of mixer slots"); return -1; @@ -191,7 +177,7 @@ int SoundMixer::insertAt(PlayingSoundHandle *handle, int index, Channel *chan) { } int SoundMixer::playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id) { - for (int i = _beginSlots; i != NUM_CHANNELS; i++) { + for (int i = 0; i != NUM_CHANNELS; i++) { if (_channels[i] == NULL) { return insertAt(handle, i, new ChannelRaw(this, sound, size, rate, flags, id)); } @@ -201,22 +187,13 @@ int SoundMixer::playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, ui return -1; } -int SoundMixer::playStream(int idx, void *sound, uint32 size, - uint rate, byte flags, int32 timeout, int32 buffer_size) { - return insertAt(NULL, idx, new ChannelStream(this, sound, size, rate, flags, timeout, buffer_size)); -} - -void SoundMixer::beginSlots(int index) { - if ((index < 0) && (index >= NUM_CHANNELS)) { - warning("soundMixer::beginSlots has invalid index %d", index); - return; - } - _beginSlots = index; +int SoundMixer::playStream(void *sound, uint32 size, uint rate, byte flags, int32 buffer_size) { + return insertAt(NULL, -1, new ChannelStream(this, sound, size, rate, flags, buffer_size)); } #ifdef USE_MAD int SoundMixer::playMP3(PlayingSoundHandle *handle, void *sound, uint32 size, byte flags) { - for (int i = _beginSlots; i != NUM_CHANNELS; i++) { + for (int i = 0; i != NUM_CHANNELS; i++) { if (_channels[i] == NULL) { return insertAt(handle, i, new ChannelMP3(this, sound, size, flags)); } @@ -227,7 +204,7 @@ int SoundMixer::playMP3(PlayingSoundHandle *handle, void *sound, uint32 size, by } int SoundMixer::playMP3CDTrack(PlayingSoundHandle *handle, File *file, mad_timer_t duration) { /* Stop the previously playing CD track (if any) */ - for (int i = _beginSlots; i != NUM_CHANNELS; i++) { + for (int i = 0; i != NUM_CHANNELS; i++) { if (_channels[i] == NULL) { return insertAt(handle, i, new ChannelMP3CDMusic(this, file, duration)); } @@ -240,7 +217,7 @@ int SoundMixer::playMP3CDTrack(PlayingSoundHandle *handle, File *file, mad_timer #ifdef USE_VORBIS int SoundMixer::playVorbis(PlayingSoundHandle *handle, OggVorbis_File *ov_file, int duration, bool is_cd_track) { - for (int i = _beginSlots; i != NUM_CHANNELS; i++) { + for (int i = 0; i != NUM_CHANNELS; i++) { if (_channels[i] == NULL) { return insertAt(handle, i, new ChannelVorbis(this, ov_file, duration, is_cd_track)); } @@ -266,10 +243,20 @@ void SoundMixer::mix(int16 *buf, uint len) { } if (!_paused) { - /* now mix all channels */ + // now mix all channels for (int i = 0; i != NUM_CHANNELS; i++) - if (_channels[i]) - _channels[i]->mix(buf, len); + if (_channels[i]) { + if (_channels[i]->_toBeDestroyed) { + if (_handles[i]) { + *_handles[i] = 0; + _handles[i] = NULL; + } + _channels[i]->realDestroy(); + delete _channels[i]; + _channels[i] = NULL; + } else + _channels[i]->mix(buf, len); + } } _syst->unlock_mutex(_mutex); @@ -309,7 +296,7 @@ void SoundMixer::stop(int index) { void SoundMixer::stopID(int id) { - for (int i = _beginSlots; i != NUM_CHANNELS; i++) { + for (int i = 0; i != NUM_CHANNELS; i++) { if (_channels[i] != NULL && _channels[i]->_id == id) { _channels[i]->destroy(); return; @@ -322,7 +309,7 @@ void SoundMixer::pause(bool paused) { } bool SoundMixer::hasActiveChannel() { - for (int i = _beginSlots; i != NUM_CHANNELS; i++) + for (int i = 0; i != NUM_CHANNELS; i++) if (_channels[i]) return true; return false; @@ -653,7 +640,6 @@ ChannelRaw::ChannelRaw(SoundMixer *mixer, void *sound, uint32 size, uint rate, b _pos = 0; _fpPos = 0; _fpSpeed = (1 << 16) * rate / mixer->_outputRate; - _toBeDestroyed = false; _realSize = size; // adjust the magnitude to prevent division error @@ -676,11 +662,6 @@ ChannelRaw::ChannelRaw(SoundMixer *mixer, void *sound, uint32 size, uint rate, b void ChannelRaw::mix(int16 *data, uint len) { byte *s, *end; - if (_toBeDestroyed) { - realDestroy(); - return; - } - if (len > _size) len = _size; _size -= len; @@ -702,7 +683,7 @@ void ChannelRaw::mix(int16 *data, uint len) { _pos = 0; _fpPos = 0; } else { - realDestroy(); + _toBeDestroyed = true; } } @@ -711,14 +692,12 @@ void ChannelRaw::mix(int16 *data, uint len) { void ChannelRaw::realDestroy() { if (_flags & SoundMixer::FLAG_AUTOFREE) free(_ptr); - _mixer->unInsert(this); - delete this; } #define WARP_WORKAROUND 50000 ChannelStream::ChannelStream(SoundMixer *mixer, void *sound, uint32 size, uint rate, - byte flags, int32 timeout, int32 buffer_size) { + byte flags, int32 buffer_size) { _mixer = mixer; _flags = flags; _bufferSize = buffer_size; @@ -729,8 +708,6 @@ ChannelStream::ChannelStream(SoundMixer *mixer, void *sound, uint32 size, uint r _pos = _ptr; _fpPos = 0; _fpSpeed = (1 << 16) * rate / mixer->_outputRate; - _toBeDestroyed = false; - _setTimeOut = timeout; // adjust the magnitude to prevent division error while (size & 0xFFFF0000) @@ -769,18 +746,7 @@ void ChannelStream::mix(int16 *data, uint len) { const int16 *vol_tab = _mixer->_volumeTable; byte *end_of_data = _endOfData; - if (_toBeDestroyed) { - realDestroy(); - return; - } - if (_pos == end_of_data) { - if (_timeOut == -1) { - return; - } - if (--_timeOut == 0) { - realDestroy(); - } return; } @@ -813,14 +779,11 @@ void ChannelStream::mix(int16 *data, uint len) { mixer_helper_table[_flags & 0x07] (data, &len, &_pos, &fp_pos, fp_speed, vol_tab, end_of_data, (_flags & SoundMixer::FLAG_REVERSE_STEREO) ? true : false); } } - _timeOut = _setTimeOut; _fpPos = fp_pos; } void ChannelStream::realDestroy() { free(_ptr); - _mixer->unInsert(this); - delete this; } #ifdef USE_MAD @@ -831,7 +794,6 @@ ChannelMP3::ChannelMP3(SoundMixer *mixer, void *sound, uint size, byte flags) { _position = 0; _size = size; _ptr = (byte *)sound; - _toBeDestroyed = false; mad_stream_init(&_stream); #ifdef _WIN32_WCE @@ -875,11 +837,6 @@ void ChannelMP3::mix(int16 *data, uint len) { const int16 * vol_tab = _mixer->_volumeTable; unsigned char volume = ((int)vol_tab[1]) / 8; - if (_toBeDestroyed) { - realDestroy(); - return; - } - while (1) { ch = _synth.pcm.samples[0] + _posInFrame; @@ -908,7 +865,7 @@ void ChannelMP3::mix(int16 *data, uint len) { return; if (_position >= _size) { - realDestroy(); + _toBeDestroyed = true; return; } @@ -918,7 +875,7 @@ void ChannelMP3::mix(int16 *data, uint len) { if (mad_frame_decode(&_frame, &_stream) == -1) { /* End of audio... */ if (_stream.error == MAD_ERROR_BUFLEN) { - realDestroy(); + _toBeDestroyed = true; return; } else if (!MAD_RECOVERABLE(_stream.error)) { error("MAD frame decode error !"); @@ -933,12 +890,9 @@ void ChannelMP3::mix(int16 *data, uint len) { void ChannelMP3::realDestroy() { if (_flags & SoundMixer::FLAG_AUTOFREE) free(_ptr); - _mixer->unInsert(this); mad_synth_finish(&_synth); mad_frame_finish(&_frame); mad_stream_finish(&_stream); - - delete this; } #define MP3CD_BUFFERING_SIZE 131072 @@ -951,7 +905,6 @@ ChannelMP3CDMusic::ChannelMP3CDMusic(SoundMixer *mixer, File *file, _initialized = false; _bufferSize = MP3CD_BUFFERING_SIZE; _ptr = (byte *)malloc(MP3CD_BUFFERING_SIZE); - _toBeDestroyed = false; mad_stream_init(&_stream); #ifdef _WIN32_WCE @@ -968,18 +921,13 @@ void ChannelMP3CDMusic::mix(int16 *data, uint len) { mad_timer_t frame_duration; unsigned char volume = _mixer->_musicVolume / 8; - if (_toBeDestroyed) { - realDestroy(); - return; - } - if (!_initialized) { int skip_loop; // just skipped memset(_ptr, 0, _bufferSize); _size = _file->read(_ptr, _bufferSize); if (!_size) { - realDestroy(); + _toBeDestroyed = true; return; } // Resync @@ -995,7 +943,7 @@ void ChannelMP3CDMusic::mix(int16 *data, uint len) { } else { if (!MAD_RECOVERABLE(_stream.error)) { debug(1, "Unrecoverable error while skipping !"); - realDestroy(); + _toBeDestroyed = true; return; } } @@ -1009,7 +957,7 @@ void ChannelMP3CDMusic::mix(int16 *data, uint len) { _initialized = true; } else { debug(1, "Cannot resume decoding"); - realDestroy(); + _toBeDestroyed = true; return; } } @@ -1069,12 +1017,9 @@ bool ChannelMP3CDMusic::soundFinished() { void ChannelMP3CDMusic::realDestroy() { free(_ptr); - _mixer->unInsert(this); mad_synth_finish(&_synth); mad_frame_finish(&_frame); mad_stream_finish(&_stream); - - delete this; } #endif @@ -1091,14 +1036,9 @@ ChannelVorbis::ChannelVorbis(SoundMixer *mixer, OggVorbis_File *ov_file, int dur _eof_flag = false; _is_cd_track = is_cd_track; - _toBeDestroyed = false; } void ChannelVorbis::mix(int16 *data, uint len) { - if (_toBeDestroyed) { - realDestroy(); - return; - } if (_eof_flag) { memset(data, 0, sizeof(int16) * 2 * len); @@ -1158,12 +1098,10 @@ void ChannelVorbis::mix(int16 *data, uint len) { delete [] samples; if (_eof_flag && ! _is_cd_track) - realDestroy(); + _toBeDestroyed = true; } void ChannelVorbis::realDestroy() { - _mixer->unInsert(this); - delete this; } bool ChannelVorbis::soundFinished() { diff --git a/sound/mixer.h b/sound/mixer.h index 1abfcc4935..afe6560a73 100644 --- a/sound/mixer.h +++ b/sound/mixer.h @@ -39,9 +39,14 @@ typedef uint32 PlayingSoundHandle; +class Channel; class File; class SoundMixer; +// TODO: class Channel should really be declared non-public, inside mixer.cpp +// However, right now Sound::updateMP3CD directly calls soundFinished. That +// should be changed, by adding proper API abstraction to SoundMixer for +// MP3/Vorbis "CD" playback. class Channel { protected: SoundMixer *_mixer; @@ -86,16 +91,10 @@ public: Channel *_channels[NUM_CHANNELS]; - int _beginSlots; - public: SoundMixer(); ~SoundMixer(); - int insertAt(PlayingSoundHandle *handle, int index, Channel *chan); - void unInsert(Channel *chan); - void beginSlots(int index); - // start playing a raw sound enum { // Do *NOT* change any of these flags without looking at the code in mixer.cpp @@ -107,8 +106,7 @@ public: FLAG_LOOP = 1 << 5 // loop the audio }; int playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id = -1); - int playStream(int index, void *sound, uint32 size, uint rate, - byte flags, int32 timeout = 3, int32 buffer_size = 2000000); + int playStream(void *sound, uint32 size, uint rate, byte flags, int32 buffer_size); #ifdef USE_MAD int playMP3(PlayingSoundHandle *handle, void *sound, uint32 size, byte flags); int playMP3CDTrack(PlayingSoundHandle *handle, File *file, mad_timer_t duration); @@ -150,6 +148,8 @@ public: /** pause - unpause */ void pause(bool paused); +private: + int insertAt(PlayingSoundHandle *handle, int index, Channel *chan); }; #endif |