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
This commit is contained in:
parent
c57402160d
commit
e01c3e1b1d
2 changed files with 54 additions and 41 deletions
|
@ -47,31 +47,23 @@ private:
|
||||||
byte _volume;
|
byte _volume;
|
||||||
int8 _pan;
|
int8 _pan;
|
||||||
bool _paused;
|
bool _paused;
|
||||||
|
int _id;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RateConverter *_converter;
|
RateConverter *_converter;
|
||||||
AudioInputStream *_input;
|
AudioInputStream *_input;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int _id;
|
|
||||||
|
|
||||||
Channel(SoundMixer *mixer, PlayingSoundHandle *handle, bool isMusic, byte volume, int8 pan, int id = -1)
|
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) {
|
Channel(SoundMixer *mixer, PlayingSoundHandle *handle, AudioInputStream *input, bool isMusic, byte volume, int8 pan, bool reverseStereo = false, int id = -1);
|
||||||
assert(mixer);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// Get a rate converter instance
|
|
||||||
_converter = makeRateConverter(_input->getRate(), mixer->getOutputRate(), _input->isStereo(), reverseStereo);
|
|
||||||
}
|
|
||||||
virtual ~Channel();
|
virtual ~Channel();
|
||||||
void destroy();
|
|
||||||
virtual void mix(int16 *data, uint len);
|
|
||||||
|
|
||||||
|
void mix(int16 *data, uint len);
|
||||||
|
|
||||||
|
bool isFinished() const {
|
||||||
|
return _input->endOfStream();
|
||||||
|
}
|
||||||
bool isMusicChannel() const {
|
bool isMusicChannel() const {
|
||||||
return _isMusic;
|
return _isMusic;
|
||||||
}
|
}
|
||||||
|
@ -90,6 +82,9 @@ public:
|
||||||
int getVolume() const {
|
int getVolume() const {
|
||||||
return isMusicChannel() ? _mixer->getMusicVolume() : _mixer->getVolume();
|
return isMusicChannel() ? _mixer->getMusicVolume() : _mixer->getVolume();
|
||||||
}
|
}
|
||||||
|
int getId() const {
|
||||||
|
return _id;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ChannelStream : public Channel {
|
class ChannelStream : public Channel {
|
||||||
|
@ -121,7 +116,7 @@ SoundMixer::SoundMixer() {
|
||||||
_paused = false;
|
_paused = false;
|
||||||
|
|
||||||
for (i = 0; i != NUM_CHANNELS; i++)
|
for (i = 0; i != NUM_CHANNELS; i++)
|
||||||
_channels[i] = NULL;
|
_channels[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundMixer::~SoundMixer() {
|
SoundMixer::~SoundMixer() {
|
||||||
|
@ -208,9 +203,10 @@ void SoundMixer::endStream(PlayingSoundHandle handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundMixer::insertChannel(PlayingSoundHandle *handle, Channel *chan) {
|
void SoundMixer::insertChannel(PlayingSoundHandle *handle, Channel *chan) {
|
||||||
|
|
||||||
int index = -1;
|
int index = -1;
|
||||||
for (int i = 0; i != NUM_CHANNELS; i++) {
|
for (int i = 0; i != NUM_CHANNELS; i++) {
|
||||||
if (_channels[i] == NULL) {
|
if (_channels[i] == 0) {
|
||||||
index = i;
|
index = i;
|
||||||
break;
|
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) {
|
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);
|
Common::StackLock lock(_mutex);
|
||||||
|
|
||||||
|
const bool autoFreeMemory = (flags & SoundMixer::FLAG_AUTOFREE) != 0;
|
||||||
|
|
||||||
// Prevent duplicate sounds
|
// Prevent duplicate sounds
|
||||||
if (id != -1) {
|
if (id != -1) {
|
||||||
for (int i = 0; i != NUM_CHANNELS; i++)
|
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;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the input stream
|
// Create the input stream
|
||||||
AudioInputStream *input;
|
AudioInputStream *input;
|
||||||
const bool autoFreeMemory = (flags & SoundMixer::FLAG_AUTOFREE) != 0;
|
|
||||||
if (flags & SoundMixer::FLAG_LOOP) {
|
if (flags & SoundMixer::FLAG_LOOP) {
|
||||||
if (loopEnd == 0) {
|
if (loopEnd == 0) {
|
||||||
input = makeLinearInputStream(rate, flags, (byte *)sound, size, 0, size, autoFreeMemory);
|
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
|
// now mix all channels
|
||||||
for (int i = 0; i != NUM_CHANNELS; i++)
|
for (int i = 0; i != NUM_CHANNELS; i++)
|
||||||
if (_channels[i] && !_channels[i]->isPaused())
|
if (_channels[i]) {
|
||||||
_channels[i]->mix(buf, len);
|
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() {
|
void SoundMixer::stopAll() {
|
||||||
Common::StackLock lock(_mutex);
|
Common::StackLock lock(_mutex);
|
||||||
for (int i = 0; i != NUM_CHANNELS; i++)
|
for (int i = 0; i != NUM_CHANNELS; i++)
|
||||||
if (_channels[i])
|
if (_channels[i] != 0) {
|
||||||
_channels[i]->destroy();
|
delete _channels[i];
|
||||||
|
_channels[i] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundMixer::stopID(int id) {
|
void SoundMixer::stopID(int id) {
|
||||||
Common::StackLock lock(_mutex);
|
Common::StackLock lock(_mutex);
|
||||||
for (int i = 0; i != NUM_CHANNELS; i++) {
|
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]->destroy();
|
delete _channels[i];
|
||||||
return;
|
_channels[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,8 +352,10 @@ void SoundMixer::stopHandle(PlayingSoundHandle handle) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_channels[index])
|
if (_channels[index]) {
|
||||||
_channels[index]->destroy();
|
delete _channels[index];
|
||||||
|
_channels[index] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundMixer::setChannelVolume(PlayingSoundHandle handle, byte volume) {
|
void SoundMixer::setChannelVolume(PlayingSoundHandle handle, byte volume) {
|
||||||
|
@ -390,7 +399,7 @@ void SoundMixer::pauseAll(bool paused) {
|
||||||
void SoundMixer::pauseID(int id, bool paused) {
|
void SoundMixer::pauseID(int id, bool paused) {
|
||||||
Common::StackLock lock(_mutex);
|
Common::StackLock lock(_mutex);
|
||||||
for (int i = 0; i != NUM_CHANNELS; i++) {
|
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);
|
_channels[i]->pause(paused);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -453,6 +462,20 @@ void SoundMixer::setMusicVolume(int volume) {
|
||||||
#pragma mark -
|
#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() {
|
Channel::~Channel() {
|
||||||
delete _converter;
|
delete _converter;
|
||||||
delete _input;
|
delete _input;
|
||||||
|
@ -460,13 +483,6 @@ Channel::~Channel() {
|
||||||
*_handle = 0;
|
*_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
|
/* len indicates the number of sample *pairs*. So a value of
|
||||||
10 means that the buffer contains twice 10 sample, each
|
10 means that the buffer contains twice 10 sample, each
|
||||||
16 bits, for a total of 40 bytes.
|
16 bits, for a total of 40 bytes.
|
||||||
|
@ -474,9 +490,7 @@ void Channel::destroy() {
|
||||||
void Channel::mix(int16 *data, uint len) {
|
void Channel::mix(int16 *data, uint len) {
|
||||||
assert(_input);
|
assert(_input);
|
||||||
|
|
||||||
if (_input->endOfStream()) {
|
if (_input->endOfData()) {
|
||||||
destroy();
|
|
||||||
} else if (_input->endOfData()) {
|
|
||||||
// TODO: call drain method
|
// TODO: call drain method
|
||||||
} else {
|
} else {
|
||||||
assert(_converter);
|
assert(_converter);
|
||||||
|
|
|
@ -42,7 +42,6 @@ class Channel;
|
||||||
class File;
|
class File;
|
||||||
|
|
||||||
class SoundMixer {
|
class SoundMixer {
|
||||||
friend class Channel;
|
|
||||||
public:
|
public:
|
||||||
typedef void PremixProc (void *param, int16 *data, uint len);
|
typedef void PremixProc (void *param, int16 *data, uint len);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue