aboutsummaryrefslogtreecommitdiff
path: root/sound/mixer.cpp
diff options
context:
space:
mode:
authorMax Horn2003-12-22 19:08:19 +0000
committerMax Horn2003-12-22 19:08:19 +0000
commite01c3e1b1d04188e4aca270d3e5fd715fdffba2c (patch)
treeaf81b66da26b1fac86edcfafec42a9d6b624148c /sound/mixer.cpp
parentc57402160d900e134c3fcb1d03de73d4278a2e26 (diff)
downloadscummvm-rg350-e01c3e1b1d04188e4aca270d3e5fd715fdffba2c.tar.gz
scummvm-rg350-e01c3e1b1d04188e4aca270d3e5fd715fdffba2c.tar.bz2
scummvm-rg350-e01c3e1b1d04188e4aca270d3e5fd715fdffba2c.zip
o Got rid of Channel::destroy() method (no more evil 'delete this', plus
slightly more efficient) o Fixed potential memory leak in SoundMixer::playRaw o Channel not anymore friend class of SoundMixer o misc cleanup svn-id: r11857
Diffstat (limited to 'sound/mixer.cpp')
-rw-r--r--sound/mixer.cpp92
1 files changed, 53 insertions, 39 deletions
diff --git a/sound/mixer.cpp b/sound/mixer.cpp
index 4c3e9ca277..772f38e9bd 100644
--- a/sound/mixer.cpp
+++ b/sound/mixer.cpp
@@ -47,31 +47,23 @@ private:
byte _volume;
int8 _pan;
bool _paused;
+ int _id;
protected:
RateConverter *_converter;
AudioInputStream *_input;
public:
- int _id;
- Channel(SoundMixer *mixer, PlayingSoundHandle *handle, bool isMusic, byte volume, int8 pan, int id = -1)
- : _mixer(mixer), _handle(handle), _isMusic(isMusic), _volume(volume), _pan(pan), _paused(false), _converter(0), _input(0), _id(id) {
- assert(mixer);
- }
+ Channel(SoundMixer *mixer, PlayingSoundHandle *handle, bool isMusic, byte volume, int8 pan, int id = -1);
+ Channel(SoundMixer *mixer, PlayingSoundHandle *handle, AudioInputStream *input, bool isMusic, byte volume, int8 pan, bool reverseStereo = false, int id = -1);
+ virtual ~Channel();
- Channel(SoundMixer *mixer, PlayingSoundHandle *handle, AudioInputStream *input, bool isMusic, byte volume, int8 pan, bool reverseStereo = false, int id = -1)
- : _mixer(mixer), _handle(handle), _isMusic(isMusic), _volume(volume), _pan(pan), _paused(false), _converter(0), _input(input), _id(id) {
- assert(mixer);
- assert(input);
+ void mix(int16 *data, uint len);
- // Get a rate converter instance
- _converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo(), reverseStereo);
+ bool isFinished() const {
+ return _input->endOfStream();
}
- virtual ~Channel();
- void destroy();
- virtual void mix(int16 *data, uint len);
-
bool isMusicChannel() const {
return _isMusic;
}
@@ -90,6 +82,9 @@ public:
int getVolume() const {
return isMusicChannel() ? _mixer->getMusicVolume() : _mixer->getVolume();
}
+ int getId() const {
+ return _id;
+ }
};
class ChannelStream : public Channel {
@@ -121,7 +116,7 @@ SoundMixer::SoundMixer() {
_paused = false;
for (i = 0; i != NUM_CHANNELS; i++)
- _channels[i] = NULL;
+ _channels[i] = 0;
}
SoundMixer::~SoundMixer() {
@@ -208,9 +203,10 @@ void SoundMixer::endStream(PlayingSoundHandle handle) {
}
void SoundMixer::insertChannel(PlayingSoundHandle *handle, Channel *chan) {
+
int index = -1;
for (int i = 0; i != NUM_CHANNELS; i++) {
- if (_channels[i] == NULL) {
+ if (_channels[i] == 0) {
index = i;
break;
}
@@ -229,16 +225,20 @@ void SoundMixer::insertChannel(PlayingSoundHandle *handle, Channel *chan) {
void SoundMixer::playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, byte volume, int8 pan, uint32 loopStart, uint32 loopEnd) {
Common::StackLock lock(_mutex);
+ const bool autoFreeMemory = (flags & SoundMixer::FLAG_AUTOFREE) != 0;
+
// Prevent duplicate sounds
if (id != -1) {
for (int i = 0; i != NUM_CHANNELS; i++)
- if (_channels[i] != NULL && _channels[i]->_id == id)
+ if (_channels[i] != 0 && _channels[i]->getId() == id) {
+ if (autoFreeMemory)
+ free(sound);
return;
+ }
}
// Create the input stream
AudioInputStream *input;
- const bool autoFreeMemory = (flags & SoundMixer::FLAG_AUTOFREE) != 0;
if (flags & SoundMixer::FLAG_LOOP) {
if (loopEnd == 0) {
input = makeLinearInputStream(rate, flags, (byte *)sound, size, 0, size, autoFreeMemory);
@@ -301,8 +301,13 @@ void SoundMixer::mix(int16 *buf, uint len) {
// now mix all channels
for (int i = 0; i != NUM_CHANNELS; i++)
- if (_channels[i] && !_channels[i]->isPaused())
- _channels[i]->mix(buf, len);
+ if (_channels[i]) {
+ if (_channels[i]->isFinished()) {
+ delete _channels[i];
+ _channels[i] = 0;
+ } else if (!_channels[i]->isPaused())
+ _channels[i]->mix(buf, len);
+ }
}
}
@@ -317,16 +322,18 @@ void SoundMixer::mixCallback(void *s, byte *samples, int len) {
void SoundMixer::stopAll() {
Common::StackLock lock(_mutex);
for (int i = 0; i != NUM_CHANNELS; i++)
- if (_channels[i])
- _channels[i]->destroy();
+ if (_channels[i] != 0) {
+ delete _channels[i];
+ _channels[i] = 0;
+ }
}
void SoundMixer::stopID(int id) {
Common::StackLock lock(_mutex);
for (int i = 0; i != NUM_CHANNELS; i++) {
- if (_channels[i] != NULL && _channels[i]->_id == id) {
- _channels[i]->destroy();
- return;
+ if (_channels[i] != 0 && _channels[i]->getId() == id) {
+ delete _channels[i];
+ _channels[i] = 0;
}
}
}
@@ -345,8 +352,10 @@ void SoundMixer::stopHandle(PlayingSoundHandle handle) {
return;
}
- if (_channels[index])
- _channels[index]->destroy();
+ if (_channels[index]) {
+ delete _channels[index];
+ _channels[index] = 0;
+ }
}
void SoundMixer::setChannelVolume(PlayingSoundHandle handle, byte volume) {
@@ -390,7 +399,7 @@ void SoundMixer::pauseAll(bool paused) {
void SoundMixer::pauseID(int id, bool paused) {
Common::StackLock lock(_mutex);
for (int i = 0; i != NUM_CHANNELS; i++) {
- if (_channels[i] != NULL && _channels[i]->_id == id) {
+ if (_channels[i] != 0 && _channels[i]->getId() == id) {
_channels[i]->pause(paused);
return;
}
@@ -453,6 +462,20 @@ void SoundMixer::setMusicVolume(int volume) {
#pragma mark -
+Channel::Channel(SoundMixer *mixer, PlayingSoundHandle *handle, bool isMusic, byte volume, int8 pan, int id)
+ : _mixer(mixer), _handle(handle), _isMusic(isMusic), _volume(volume), _pan(pan), _paused(false), _converter(0), _input(0), _id(id) {
+ assert(mixer);
+}
+
+Channel::Channel(SoundMixer *mixer, PlayingSoundHandle *handle, AudioInputStream *input, bool isMusic, byte volume, int8 pan, bool reverseStereo, int id)
+ : _mixer(mixer), _handle(handle), _isMusic(isMusic), _volume(volume), _pan(pan), _paused(false), _converter(0), _input(input), _id(id) {
+ assert(mixer);
+ assert(input);
+
+ // Get a rate converter instance
+ _converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo(), reverseStereo);
+}
+
Channel::~Channel() {
delete _converter;
delete _input;
@@ -460,13 +483,6 @@ Channel::~Channel() {
*_handle = 0;
}
-void Channel::destroy() {
- for (int i = 0; i != SoundMixer::NUM_CHANNELS; i++)
- if (_mixer->_channels[i] == this)
- _mixer->_channels[i] = 0;
- delete this;
-}
-
/* 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.
@@ -474,9 +490,7 @@ void Channel::destroy() {
void Channel::mix(int16 *data, uint len) {
assert(_input);
- if (_input->endOfStream()) {
- destroy();
- } else if (_input->endOfData()) {
+ if (_input->endOfData()) {
// TODO: call drain method
} else {
assert(_converter);