diff options
author | Paweł Kołodziejski | 2003-08-31 20:26:21 +0000 |
---|---|---|
committer | Paweł Kołodziejski | 2003-08-31 20:26:21 +0000 |
commit | 2533b23a601b053dd5394e8da9e787504d37e8ba (patch) | |
tree | b9f35b8e7044d6ad18cc8917a88fcd58bc742ee2 /sound | |
parent | 54f5caedc5f93f6a7ae067f1fda08c2dedd79de1 (diff) | |
download | scummvm-rg350-2533b23a601b053dd5394e8da9e787504d37e8ba.tar.gz scummvm-rg350-2533b23a601b053dd5394e8da9e787504d37e8ba.tar.bz2 scummvm-rg350-2533b23a601b053dd5394e8da9e787504d37e8ba.zip |
added mixer features: volume and pan control per channel
svn-id: r9944
Diffstat (limited to 'sound')
-rw-r--r-- | sound/mixer.cpp | 77 | ||||
-rw-r--r-- | sound/mixer.h | 8 |
2 files changed, 74 insertions, 11 deletions
diff --git a/sound/mixer.cpp b/sound/mixer.cpp index 14d8b41808..4e31ac7f0d 100644 --- a/sound/mixer.cpp +++ b/sound/mixer.cpp @@ -44,6 +44,9 @@ protected: PlayingSoundHandle *_handle; RateConverter *_converter; AudioInputStream *_input; + byte _volume; + int8 _pan; + public: int _id; @@ -54,6 +57,12 @@ public: virtual ~Channel(); void destroy(); virtual void mix(int16 *data, uint len); + virtual void setChannelVolume(const byte volume) { + _volume = volume; + } + virtual void setChannelPan(const int8 pan) { + _pan = pan; + } virtual int getVolume() const { return isMusicChannel() ? _mixer->getMusicVolume() : _mixer->getVolume(); } @@ -63,7 +72,7 @@ public: 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(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, byte volume, int8 pan, int id, uint32 loopStart, uint32 loopEnd); ~ChannelRaw(); bool isMusicChannel() const { return false; } }; @@ -71,7 +80,7 @@ public: class ChannelStream : public Channel { bool _finished; public: - ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, uint32 buffer_size); + ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, uint32 buffer_size, byte volume, int8 pan); void mix(int16 *data, uint len); void append(void *sound, uint32 size); bool isMusicChannel() const { return true; } @@ -135,9 +144,9 @@ SoundMixer::~SoundMixer() { _syst->delete_mutex(_mutex); } -int SoundMixer::newStream(void *sound, uint32 size, uint rate, byte flags, uint32 buffer_size) { +int SoundMixer::newStream(void *sound, uint32 size, uint rate, byte flags, uint32 buffer_size, byte volume, int8 pan) { StackLock lock(_mutex); - return insertChannel(NULL, new ChannelStream(this, 0, sound, size, rate, flags, buffer_size)); + return insertChannel(NULL, new ChannelStream(this, 0, sound, size, rate, flags, buffer_size, volume, pan)); } void SoundMixer::appendStream(int index, void *sound, uint32 size) { @@ -195,7 +204,7 @@ int SoundMixer::insertChannel(PlayingSoundHandle *handle, Channel *chan) { return index; } -int SoundMixer::playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, uint32 loopStart, uint32 loopEnd) { +int SoundMixer::playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, byte volume, int8 pan, int id, uint32 loopStart, uint32 loopEnd) { StackLock lock(_mutex); // Prevent duplicate sounds @@ -205,7 +214,7 @@ int SoundMixer::playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, ui return -1; } - return insertChannel(handle, new ChannelRaw(this, handle, sound, size, rate, flags, id, loopStart, loopEnd)); + return insertChannel(handle, new ChannelRaw(this, handle, sound, size, rate, flags, volume, pan, id, loopStart, loopEnd)); } #ifdef USE_MAD @@ -314,6 +323,40 @@ void SoundMixer::stopHandle(PlayingSoundHandle handle) { _channels[index]->destroy(); } +void SoundMixer::setChannelVolume(PlayingSoundHandle handle, byte volume) { + StackLock lock(_mutex); + + if (handle == 0) + return; + + int index = handle - 1; + + if ((index < 0) || (index >= NUM_CHANNELS)) { + warning("soundMixer::setChannelVolume has invalid index %d", index); + return; + } + + if (_channels[index]) + _channels[index]->setChannelVolume(volume); +} + +void SoundMixer::setChannelPan(PlayingSoundHandle handle, int8 pan) { + StackLock lock(_mutex); + + if (handle == 0) + return; + + int index = handle - 1; + + if ((index < 0) || (index >= NUM_CHANNELS)) { + warning("soundMixer::setChannelVolume has invalid index %d", index); + return; + } + + if (_channels[index]) + _channels[index]->setChannelPan(pan); +} + bool SoundMixer::isChannelActive(PlayingSoundHandle handle) { StackLock lock(_mutex); @@ -398,7 +441,17 @@ void Channel::destroy() { delete this; } - +static void changeVolumeAndPan(int16 *data, uint len, byte volume, int8 pan) { + byte volumeLeft = abs(pan - 128); + byte volumeRight = abs(pan + 128); + for (uint32 i = 0; i < len; i++) { + int16 sampleL = data[i * 2 + 0]; + int16 sampleR = data[i * 2 + 1]; + data[i * 2 + 0] = (sampleL * volume * volumeLeft) / (256 * 256); + data[i * 2 + 1] = (sampleR * volume * volumeRight) / (256 * 256); + } +} + /* 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. @@ -412,13 +465,16 @@ void Channel::mix(int16 *data, uint len) { assert(_converter); _converter->flow(*_input, data, len, getVolume()); } + changeVolumeAndPan(data, len, _volume, _pan); } /* RAW mixer */ -ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, uint32 loopStart, uint32 loopEnd) +ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, byte volume, int8 pan, int id, uint32 loopStart, uint32 loopEnd) : Channel(mixer, handle) { _id = id; _ptr = (byte *)sound; + _volume = volume; + _pan = pan; // Create the input stream if (flags & SoundMixer::FLAG_LOOP) { @@ -445,8 +501,10 @@ ChannelRaw::~ChannelRaw() { ChannelStream::ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, - byte flags, uint32 buffer_size) + byte flags, uint32 buffer_size, byte volume, int8 pan) : Channel(mixer, handle) { + _volume = volume; + _pan = pan; assert(size <= buffer_size); // Create the input stream @@ -483,6 +541,7 @@ void ChannelStream::mix(int16 *data, uint len) { assert(_converter); _converter->flow(*_input, data, len, getVolume()); + changeVolumeAndPan(data, len, _volume, _pan); } #ifdef USE_MAD diff --git a/sound/mixer.h b/sound/mixer.h index 3ecc6997ed..4604559f47 100644 --- a/sound/mixer.h +++ b/sound/mixer.h @@ -83,7 +83,7 @@ public: // start playing a raw sound int playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, - int id = -1, uint32 loopStart = 0, uint32 loopEnd = 0); + byte volume, int8 pan, int id = -1, uint32 loopStart = 0, uint32 loopEnd = 0); #ifdef USE_MAD int playMP3(PlayingSoundHandle *handle, File *file, uint32 size); int playMP3CDTrack(PlayingSoundHandle *handle, File *file, mad_timer_t duration); @@ -107,10 +107,14 @@ public: /** stop playing the channel for the given handle */ void stopHandle(PlayingSoundHandle handle); + void setChannelVolume(PlayingSoundHandle handle, byte volume); + + void setChannelPan(PlayingSoundHandle handle, int8 pan); + bool isChannelActive(PlayingSoundHandle handle); /** Start a new stream. */ - int newStream(void *sound, uint32 size, uint rate, byte flags, uint32 buffer_size); + int newStream(void *sound, uint32 size, uint rate, byte flags, uint32 buffer_size, byte volume, int8 pan); /** Append to an existing stream. */ void appendStream(int index, void *sound, uint32 size); |