diff options
| author | Max Horn | 2003-08-05 02:05:37 +0000 | 
|---|---|---|
| committer | Max Horn | 2003-08-05 02:05:37 +0000 | 
| commit | 1eaf41eda40f1777a5e99c19a027ea025cbaeb4c (patch) | |
| tree | 66c67f0f994ee3f64c2fee33269d7d21d6a9ad24 | |
| parent | 2bc604081e4ef7ac8cf39cdde3a89dd494fbb6e1 (diff) | |
| download | scummvm-rg350-1eaf41eda40f1777a5e99c19a027ea025cbaeb4c.tar.gz scummvm-rg350-1eaf41eda40f1777a5e99c19a027ea025cbaeb4c.tar.bz2 scummvm-rg350-1eaf41eda40f1777a5e99c19a027ea025cbaeb4c.zip | |
more cleanup (like the previous two, I just moved around code, to clearly separate the old and the new mixer code)
svn-id: r9479
| -rw-r--r-- | sound/mixer.cpp | 345 | 
1 files changed, 190 insertions, 155 deletions
| diff --git a/sound/mixer.cpp b/sound/mixer.cpp index fbeef67d6d..1cd63ea5b2 100644 --- a/sound/mixer.cpp +++ b/sound/mixer.cpp @@ -30,31 +30,22 @@  #ifdef NEW_MIXER_CODE  #include "rate.h" -#endif  class Channel {  protected:  	SoundMixer *_mixer;  	PlayingSoundHandle *_handle; -#ifdef NEW_MIXER_CODE  	RateConverter *_converter;  	AudioInputStream *_input; -#endif  public:  	int _id;  	Channel(SoundMixer *mixer, PlayingSoundHandle *handle) -		: _mixer(mixer), _handle(handle), -#ifdef NEW_MIXER_CODE -		_converter(0), _input(0),  -#endif -		_id(-1) { +		: _mixer(mixer), _handle(handle), _converter(0), _input(0), _id(-1) {  		assert(mixer);  	}  	virtual ~Channel() { -#ifdef NEW_MIXER_CODE  		delete _converter;  		delete _input; -#endif  		if (_handle)  			*_handle = 0;  	} @@ -63,7 +54,6 @@ public:  	   10 means that the buffer contains twice 10 sample, each  	   16 bits, for a total of 40 bytes.  	 */ -#ifdef NEW_MIXER_CODE  	virtual void mix(int16 *data, uint len) {  		assert(_input);  		assert(_converter); @@ -77,9 +67,79 @@ public:  		const int volume = isMusicChannel() ? _mixer->getMusicVolume() : _mixer->getVolume();  		_converter->flow(*_input, data, len, volume);  	} -#else -	virtual void mix(int16 *data, uint len) = 0; +	void destroy() { +		for (int i = 0; i != SoundMixer::NUM_CHANNELS; i++) +			if (_mixer->_channels[i] == this) +				_mixer->_channels[i] = 0; +		delete this; +	} +	virtual bool isMusicChannel() const	= 0; +}; + +class ChannelRaw : public Channel { +	byte *_ptr; +public: +	ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, uint32 loopStart, uint32 loopEnd); +	~ChannelRaw(); +	bool isMusicChannel() const		{ return false; } +}; + +class ChannelStream : public Channel { +	bool _finished; +public: +	ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, uint32 buffer_size); +	void mix(int16 *data, uint len); +	void append(void *sound, uint32 size); +	bool isMusicChannel() const		{ return true; } +	void finish()					{ _finished = true; } +}; + +#ifdef USE_MAD +class ChannelMP3 : public Channel { +public: +	ChannelMP3(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, uint size); +	bool isMusicChannel() const		{ return false; } +}; + +class ChannelMP3CDMusic : public Channel { +public: +	ChannelMP3CDMusic(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, mad_timer_t duration); +	bool isMusicChannel() const		{ return true; } +}; +#endif // USE_MAD + +#ifdef USE_VORBIS +class ChannelVorbis : public Channel { +	bool _is_cd_track; +public: +	ChannelVorbis(SoundMixer *mixer, PlayingSoundHandle *handle, OggVorbis_File *ov_file, int duration, bool is_cd_track); +	bool isMusicChannel() const		{ return _is_cd_track; } +};  #endif + + +#else // NEW_MIXER_CODE + +class Channel { +protected: +	SoundMixer *_mixer; +	PlayingSoundHandle *_handle; +public: +	int _id; +	Channel(SoundMixer *mixer, PlayingSoundHandle *handle) +		: _mixer(mixer), _handle(handle), _id(-1) { +		assert(mixer); +	} +	virtual ~Channel() { +		if (_handle) +			*_handle = 0; +	} +	 +	/* len indicates the number of sample *pairs*. So a value of +	   10 means that the buffer contains twice 10 sample, each +	   16 bits, for a total of 40 bytes. +	 */ +	virtual void mix(int16 *data, uint len) = 0;  	void destroy() {  		for (int i = 0; i != SoundMixer::NUM_CHANNELS; i++)  			if (_mixer->_channels[i] == this) @@ -91,7 +151,6 @@ public:  class ChannelRaw : public Channel {  	byte *_ptr; -#ifndef NEW_MIXER_CODE  	byte _flags;  	uint32 _pos;  	uint32 _size; @@ -100,20 +159,16 @@ class ChannelRaw : public Channel {  	uint32 _realSize, _rate;  	byte *_loop_ptr;  	uint32 _loop_size; -#endif  public:  	ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, uint32 loopStart, uint32 loopEnd);  	~ChannelRaw(); -#ifndef NEW_MIXER_CODE  	void mix(int16 *data, uint len); -#endif  	bool isMusicChannel() const		{ return false; }  };  class ChannelStream : public Channel { -#ifndef NEW_MIXER_CODE  	byte *_ptr;  	byte *_endOfData;  	byte *_endOfBuffer; @@ -123,7 +178,6 @@ class ChannelStream : public Channel {  	uint32 _bufferSize;  	uint32 _rate;  	byte _flags; -#endif  	bool _finished;  public: @@ -136,24 +190,7 @@ public:  	void finish()					{ _finished = true; }  }; -  #ifdef USE_MAD - -#ifdef NEW_MIXER_CODE - -class ChannelMP3 : public Channel { -public: -	ChannelMP3(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, uint size); -	bool isMusicChannel() const		{ return false; } -}; - -class ChannelMP3CDMusic : public Channel { -public: -	ChannelMP3CDMusic(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, mad_timer_t duration); -	bool isMusicChannel() const		{ return true; } -}; - -#else // NEW_MIXER_CODE  class ChannelMP3Common : public Channel {  protected:  	byte *_ptr; @@ -190,29 +227,22 @@ public:  	void mix(int16 *data, uint len);  	bool isMusicChannel() const		{ return true; }  }; -#endif // NEW_MIXER_CODE -  #endif // USE_MAD -  #ifdef USE_VORBIS  class ChannelVorbis : public Channel { -#ifndef NEW_MIXER_CODE  	OggVorbis_File *_ov_file;  	int _end_pos; -#endif  	bool _is_cd_track; -  public:  	ChannelVorbis(SoundMixer *mixer, PlayingSoundHandle *handle, OggVorbis_File *ov_file, int duration, bool is_cd_track); - -#ifndef NEW_MIXER_CODE  	void mix(int16 *data, uint len); -#endif  	bool isMusicChannel() const		{ return _is_cd_track; }  };  #endif +#endif +  SoundMixer::SoundMixer() {  	_syst = 0; @@ -460,8 +490,116 @@ void SoundMixer::setMusicVolume(int volume) {  }  #ifdef NEW_MIXER_CODE -#define clamped_add_16(a, b)	clampedAdd(a, b) -#else + +/* RAW mixer */ +ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, uint32 loopStart, uint32 loopEnd) +	: Channel(mixer, handle) { +	_id = id; +	_ptr = (byte *)sound; +	 +	// Create the input stream +	if (flags & SoundMixer::FLAG_LOOP) { +		if (loopEnd == 0) { +			_input = makeLinearInputStream(flags, _ptr, size, 0, size); +		} else { +			assert(loopStart < loopEnd && loopEnd <= size); +			_input = makeLinearInputStream(flags, _ptr, size, loopStart, loopEnd - loopStart); +		} +	} else { +		_input = makeLinearInputStream(flags, _ptr, size, 0, 0); +	} + +	// Get a rate converter instance +	_converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo(), (flags & SoundMixer::FLAG_REVERSE_STEREO) != 0); + +	if (!(flags & SoundMixer::FLAG_AUTOFREE)) +		_ptr = 0; +} + +ChannelRaw::~ChannelRaw() { +	free(_ptr); +} + +ChannelStream::ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle, +                             void *sound, uint32 size, uint rate, +                             byte flags, uint32 buffer_size) +	: Channel(mixer, handle) { +	assert(size <= buffer_size); + +	// Create the input stream +	_input = makeWrappedInputStream(flags, buffer_size); +	 +	// Append the initial data +	((WrappedAudioInputStream *)_input)->append((const byte *)sound, size); + +	// Get a rate converter instance +	_converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo(), (flags & SoundMixer::FLAG_REVERSE_STEREO) != 0); + +	_finished = false; +} + +void ChannelStream::append(void *data, uint32 len) { +	((WrappedAudioInputStream *)_input)->append((const byte *)data, len); +} + +void ChannelStream::mix(int16 *data, uint len) { +	assert(_input); +	assert(_converter); + +	if (_input->eos()) { +		// TODO: call drain method + +		// Normally, the stream stays around even if all its data is used up. +		// This is in case more data is streamed into it. To make the stream +		// go away, one can either stop() it (which takes effect immediately, +		// ignoring any remaining sound data), or finish() it, which means +		// it will finish playing before it terminates itself. +		if (_finished) { +			destroy(); +		} + +		return; +	} + +	const int volume = _mixer->getVolume();	// FIXME: Shouldn't this be music volume instead?? +//	const int volume = isMusicChannel() ? _mixer->getMusicVolume() : _mixer->getVolume(); +	_converter->flow(*_input, data, len, volume); +} + +#ifdef USE_MAD +ChannelMP3::ChannelMP3(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, uint size) +	: Channel(mixer, handle) { +	// Create the input stream +	_input = makeMP3Stream(file, mad_timer_zero, size); + +	// Get a rate converter instance +	_converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo()); +} + +ChannelMP3CDMusic::ChannelMP3CDMusic(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, mad_timer_t duration)  +	: Channel(mixer, handle) { +	// Create the input stream +	_input = makeMP3Stream(file, duration, 0); + +	// Get a rate converter instance +	_converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo()); +} +#endif // USE_MAD + +#ifdef USE_VORBIS +ChannelVorbis::ChannelVorbis(SoundMixer *mixer, PlayingSoundHandle *handle, OggVorbis_File *ov_file, int duration, bool is_cd_track) +	: Channel(mixer, handle) { +	// Create the input stream +	_input = makeVorbisStream(ov_file, duration); + +	// Get a rate converter instance +	_converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo()); +	_is_cd_track = is_cd_track; +} +#endif // USE_VORBIS + +#else // NEW_MIXER_CODE +  /*   * Class that performs cubic interpolation on integer data.   * It is expected that the data is equidistant, i.e. all have the same @@ -674,7 +812,6 @@ static int16 mixer_element_size[] = {  	2, 2,  	4, 4  }; -#endif  /* RAW mixer */  ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, uint32 loopStart, uint32 loopEnd) @@ -682,25 +819,6 @@ ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *soun  	_id = id;  	_ptr = (byte *)sound; -#ifdef NEW_MIXER_CODE -	// Create the input stream -	if (flags & SoundMixer::FLAG_LOOP) { -		if (loopEnd == 0) { -			_input = makeLinearInputStream(flags, _ptr, size, 0, size); -		} else { -			assert(loopStart < loopEnd && loopEnd <= size); -			_input = makeLinearInputStream(flags, _ptr, size, loopStart, loopEnd - loopStart); -		} -	} else { -		_input = makeLinearInputStream(flags, _ptr, size, 0, 0); -	} - -	// Get a rate converter instance -	_converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo(), (flags & SoundMixer::FLAG_REVERSE_STEREO) != 0); - -	if (!(flags & SoundMixer::FLAG_AUTOFREE)) -		_ptr = 0; -#else  	_flags = flags;  	_pos = 0;  	_fpPos = 0; @@ -722,19 +840,13 @@ ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *soun  		_loop_ptr = _ptr;  		_loop_size = _size;  	} -#endif  }  ChannelRaw::~ChannelRaw() { -#ifdef NEW_MIXER_CODE -	free(_ptr); -#else  	if (_flags & SoundMixer::FLAG_AUTOFREE)  		free(_ptr); -#endif  } -#ifndef NEW_MIXER_CODE  void ChannelRaw::mix(int16 *data, uint len) {  	byte *s, *end; @@ -760,26 +872,15 @@ void ChannelRaw::mix(int16 *data, uint len) {  		}  	}  } -#endif  #define WARP_WORKAROUND 50000 -ChannelStream::ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, -										 byte flags, uint32 buffer_size) +ChannelStream::ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle, +                             void *sound, uint32 size, uint rate, +                             byte flags, uint32 buffer_size)  	: Channel(mixer, handle) {  	assert(size <= buffer_size); -#ifdef NEW_MIXER_CODE -	 -	// Create the input stream -	_input = makeWrappedInputStream(flags, buffer_size); -	 -	// Append the initial data -	((WrappedAudioInputStream *)_input)->append((const byte *)sound, size); - -	// Get a rate converter instance -	_converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo(), (flags & SoundMixer::FLAG_REVERSE_STEREO) != 0); -#else  	_flags = flags;  	_bufferSize = buffer_size;  	_ptr = (byte *)malloc(_bufferSize + WARP_WORKAROUND); @@ -795,20 +896,14 @@ ChannelStream::ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle, void  		size >>= 1, rate = (rate >> 1) + 1;  	_rate = rate; -#endif  	_finished = false;  }  ChannelStream::~ChannelStream() { -#ifndef NEW_MIXER_CODE  	free(_ptr); -#endif  }  void ChannelStream::append(void *data, uint32 len) { -#ifdef NEW_MIXER_CODE -	((WrappedAudioInputStream *)_input)->append((const byte *)data, len); -#else  	if (_endOfData + len > _endOfBuffer) {  		/* Wrap-around case */  		uint32 size_to_end_of_buffer = _endOfBuffer - _endOfData; @@ -828,33 +923,9 @@ void ChannelStream::append(void *data, uint32 len) {  		memcpy(_endOfData, data, len);  		_endOfData += len;  	} -#endif  }  void ChannelStream::mix(int16 *data, uint len) { -#ifdef NEW_MIXER_CODE -	assert(_input); -	assert(_converter); - -	if (_input->eos()) { -		// TODO: call drain method - -		// Normally, the stream stays around even if all its data is used up. -		// This is in case more data is streamed into it. To make the stream -		// go away, one can either stop() it (which takes effect immediately, -		// ignoring any remaining sound data), or finish() it, which means -		// it will finish playing before it terminates itself. -		if (_finished) { -			destroy(); -		} - -		return; -	} - -	const int volume = _mixer->getVolume();	// FIXME: Shouldn't this be music volume instead?? -//	const int volume = isMusicChannel() ? _mixer->getMusicVolume() : _mixer->getVolume(); -	_converter->flow(*_input, data, len, volume); -#else  	if (_pos == _endOfData) {  		// Normally, the stream stays around even if all its data is used up.  		// This is in case more data is streamed into it. To make the stream @@ -902,32 +973,9 @@ void ChannelStream::mix(int16 *data, uint len) {  			mixProc(data, len, _pos, _fpPos, _fpSpeed, _mixer->getVolume(), _endOfData, (_flags & SoundMixer::FLAG_REVERSE_STEREO) ? true : false);  		}  	} -#endif  }  #ifdef USE_MAD - -#ifdef NEW_MIXER_CODE -ChannelMP3::ChannelMP3(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, uint size) -	: Channel(mixer, handle) { -	// Create the input stream -	_input = makeMP3Stream(file, mad_timer_zero, size); - -	// Get a rate converter instance -	_converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo()); -} - -ChannelMP3CDMusic::ChannelMP3CDMusic(SoundMixer *mixer, PlayingSoundHandle *handle, File *file, mad_timer_t duration)  -	: Channel(mixer, handle) { -	// Create the input stream -	_input = makeMP3Stream(file, duration, 0); - -	// Get a rate converter instance -	_converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo()); -} - -#else // NEW_MIXER_CODE -  ChannelMP3Common::ChannelMP3Common(SoundMixer *mixer, PlayingSoundHandle *handle)  	: Channel(mixer, handle) {  	mad_stream_init(&_stream); @@ -1137,23 +1185,9 @@ void ChannelMP3CDMusic::mix(int16 *data, uint len) {  		_posInFrame = 0;  	}  } -#endif // NEW_MIXER_CODE -  #endif // USE_MAD  #ifdef USE_VORBIS - -#ifdef NEW_MIXER_CODE -ChannelVorbis::ChannelVorbis(SoundMixer *mixer, PlayingSoundHandle *handle, OggVorbis_File *ov_file, int duration, bool is_cd_track) -	: Channel(mixer, handle) { -	// Create the input stream -	_input = makeVorbisStream(ov_file, duration); - -	// Get a rate converter instance -	_converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo()); -	_is_cd_track = is_cd_track; -} -#else // NEW_MIXER_CODE  ChannelVorbis::ChannelVorbis(SoundMixer *mixer, PlayingSoundHandle *handle, OggVorbis_File *ov_file, int duration, bool is_cd_track)  	: Channel(mixer, handle) {  	_ov_file = ov_file; @@ -1222,6 +1256,7 @@ void ChannelVorbis::mix(int16 *data, uint len) {  	if (eof_flag)  		destroy();  } +#endif // USE_VORBIS +  #endif // NEW_MIXER_CODE -#endif // USE_VORBIS | 
