aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaweł Kołodziejski2003-08-31 20:26:21 +0000
committerPaweł Kołodziejski2003-08-31 20:26:21 +0000
commit2533b23a601b053dd5394e8da9e787504d37e8ba (patch)
treeb9f35b8e7044d6ad18cc8917a88fcd58bc742ee2
parent54f5caedc5f93f6a7ae067f1fda08c2dedd79de1 (diff)
downloadscummvm-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
-rw-r--r--scumm/imuse_digi.cpp2
-rw-r--r--scumm/smush/smush_mixer.cpp2
-rw-r--r--scumm/smush/smush_player.cpp2
-rw-r--r--scumm/sound.cpp28
-rw-r--r--simon/sound.cpp6
-rw-r--r--sky/intro.cpp9
-rw-r--r--sky/sound.cpp8
-rw-r--r--sound/mixer.cpp77
-rw-r--r--sound/mixer.h8
-rw-r--r--sword2/driver/d_sound.cpp107
10 files changed, 186 insertions, 63 deletions
diff --git a/scumm/imuse_digi.cpp b/scumm/imuse_digi.cpp
index 90f9f82334..0b79d7aeca 100644
--- a/scumm/imuse_digi.cpp
+++ b/scumm/imuse_digi.cpp
@@ -812,7 +812,7 @@ void IMuseDigital::handler() {
if (_scumm->_silentDigitalImuse == false) {
if (_channel[l]._mixerChannel == -1) {
_channel[l]._mixerChannel = _scumm->_mixer->newStream(buf, mixer_size,
- _channel[l]._freq, _channel[l]._mixerFlags, 100000);
+ _channel[l]._freq, _channel[l]._mixerFlags, 100000, 127, 0);
} else {
_scumm->_mixer->appendStream(_channel[l]._mixerChannel, buf, mixer_size);
}
diff --git a/scumm/smush/smush_mixer.cpp b/scumm/smush/smush_mixer.cpp
index 15b67513f0..c01753e2ab 100644
--- a/scumm/smush/smush_mixer.cpp
+++ b/scumm/smush/smush_mixer.cpp
@@ -137,7 +137,7 @@ bool SmushMixer::handleFrame() {
if (_silentMixer == false) {
if (_channels[i].mixer_index == -1) {
- _channels[i].mixer_index = _mixer->newStream(data, size, rate, flags, 500000);
+ _channels[i].mixer_index = _mixer->newStream(data, size, rate, flags, 500000, 127, 0);
} else {
_mixer->appendStream(_channels[i].mixer_index, data, size);
}
diff --git a/scumm/smush/smush_player.cpp b/scumm/smush/smush_player.cpp
index 44b9a46f3d..e3feacdb41 100644
--- a/scumm/smush/smush_player.cpp
+++ b/scumm/smush/smush_player.cpp
@@ -463,7 +463,7 @@ void SmushPlayer::handleImuseAction(Chunk &b) {
if (_IACTchannel == -1) {
_IACTchannel = _scumm->_mixer->newStream(output_data, 0x1000, 22050,
- SoundMixer::FLAG_STEREO | SoundMixer::FLAG_16BITS, 200000);
+ SoundMixer::FLAG_STEREO | SoundMixer::FLAG_16BITS, 200000, 127, 0);
} else {
_scumm->_mixer->appendStream(_IACTchannel, output_data, 0x1000);
}
diff --git a/scumm/sound.cpp b/scumm/sound.cpp
index 546580a138..9b385053e5 100644
--- a/scumm/sound.cpp
+++ b/scumm/sound.cpp
@@ -214,7 +214,7 @@ void Sound::playSound(int soundID) {
// Allocate a sound buffer, copy the data into it, and play
sound = (char *)malloc(size);
memcpy(sound, ptr, size);
- _scumm->_mixer->playRaw(NULL, sound, size, rate, flags, soundID);
+ _scumm->_mixer->playRaw(NULL, sound, size, rate, flags, 127, 0, soundID);
return;
}
// Support for Putt-Putt sounds - very hackish, too 8-)
@@ -232,7 +232,7 @@ void Sound::playSound(int soundID) {
// Allocate a sound buffer, copy the data into it, and play
sound = (char *)malloc(size);
memcpy(sound, ptr + 8, size);
- _scumm->_mixer->playRaw(NULL, sound, size, rate, flags, soundID);
+ _scumm->_mixer->playRaw(NULL, sound, size, rate, flags, 127, 0, soundID);
return;
}
else if (READ_UINT32(ptr) == MKID('MRAW')) {
@@ -249,7 +249,7 @@ void Sound::playSound(int soundID) {
// Allocate a sound buffer, copy the data into it, and play
sound = (char *)malloc(size);
memcpy(sound, ptr + 8, size);
- _scumm->_mixer->playRaw(NULL, sound, size, rate, flags, soundID);
+ _scumm->_mixer->playRaw(NULL, sound, size, rate, flags, 127, 0, soundID);
return;
}
@@ -318,7 +318,7 @@ void Sound::playSound(int soundID) {
// Allocate a sound buffer, copy the data into it, and play
sound = (char *)malloc(size);
memcpy(sound, ptr + 33, size);
- _scumm->_mixer->playRaw(NULL, sound, size, rate, flags, soundID);
+ _scumm->_mixer->playRaw(NULL, sound, size, rate, flags, 127, 0, soundID);
return;
} else if (_scumm->_features & GF_FMTOWNS) {
size = READ_LE_UINT32(ptr);
@@ -361,7 +361,7 @@ void Sound::playSound(int soundID) {
}
}
- _scumm->_mixer->playRaw(NULL, sound, waveSize, rate, flags, soundID, loopStart, loopEnd);
+ _scumm->_mixer->playRaw(NULL, sound, waveSize, rate, flags, 127, 0, soundID, loopStart, loopEnd);
}
break;
}
@@ -445,9 +445,11 @@ void Sound::playSound(int soundID) {
if ((_scumm->_features & GF_AMIGA) && (READ_BE_UINT16(ptr + 16) || READ_BE_UINT16(ptr + 6))) {
// the first check is for pitch-bending looped sounds (i.e. "pouring liquid", "biplane dive", etc.)
// the second check is for simple looped sounds
- _scumm->_mixer->playRaw(NULL,sound,size,rate,SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_LOOP,soundID,READ_BE_UINT16(ptr + 10) - READ_BE_UINT16(ptr + 8),READ_BE_UINT16(ptr + 14));
+ _scumm->_mixer->playRaw(NULL, sound, size, rate,
+ SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_LOOP, 127, 0, soundID,
+ READ_BE_UINT16(ptr + 10) - READ_BE_UINT16(ptr + 8),READ_BE_UINT16(ptr + 14));
} else {
- _scumm->_mixer->playRaw(NULL,sound,size,rate,SoundMixer::FLAG_AUTOFREE,soundID);
+ _scumm->_mixer->playRaw(NULL, sound, size, rate, SoundMixer::FLAG_AUTOFREE, 127, 0, soundID);
}
return;
}
@@ -460,7 +462,7 @@ void Sound::playSound(int soundID) {
rate = 11000;
sound = (char *)malloc(size);
memcpy(sound,ptr + 100,size);
- _scumm->_mixer->playRaw(NULL,sound,size,rate,SoundMixer::FLAG_AUTOFREE,soundID);
+ _scumm->_mixer->playRaw(NULL, sound, size, rate, SoundMixer::FLAG_AUTOFREE, 127, 0, soundID);
return;
}
}
@@ -559,7 +561,7 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, PlayingSoundHandle
_sfxFile->seek(offset + 48, SEEK_SET);
sound = (byte *)malloc(b - 64);
_sfxFile->read(sound, b - 64);
- _scumm->_mixer->playRaw(handle, sound, b - 64, 11025, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE);
+ _scumm->_mixer->playRaw(handle, sound, b - 64, 11025, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE, 127, 0);
return;
}
@@ -1248,7 +1250,7 @@ void Sound::bundleMusicHandler(Scumm *scumm) {
_bundleMusicPosition += final_size;
if (_bundleMusicTrack == -1) {
_bundleMusicTrack = _scumm->_mixer->newStream(buffer, final_size, rate,
- SoundMixer::FLAG_16BITS | SoundMixer::FLAG_STEREO, 300000);
+ SoundMixer::FLAG_16BITS | SoundMixer::FLAG_STEREO, 300000, 127, 0);
} else {
_scumm->_mixer->appendStream(_bundleMusicTrack, buffer, final_size);
}
@@ -1355,12 +1357,12 @@ void Sound::playBundleSound(char *sound, PlayingSoundHandle *handle) {
_scumm->_mixer->stopHandle(*handle);
if (bits == 8) {
- _scumm->_mixer->playRaw(handle, final, size, rate, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE);
+ _scumm->_mixer->playRaw(handle, final, size, rate, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE, 127, 0);
} else if (bits == 16) {
// FIXME: For some weird reasons, sometimes we get an odd size, even though
// the data is supposed to be in 16 bit format... that makes no sense...
size &= ~1;
- _scumm->_mixer->playRaw(handle, final, size, rate, SoundMixer::FLAG_16BITS | SoundMixer::FLAG_AUTOFREE);
+ _scumm->_mixer->playRaw(handle, final, size, rate, SoundMixer::FLAG_16BITS | SoundMixer::FLAG_AUTOFREE, 127, 0);
} else {
warning("Sound::playBundleSound() to do more options to playRaw...");
}
@@ -1373,7 +1375,7 @@ void Sound::playSfxSound(void *sound, uint32 size, uint rate, bool isUnsigned, P
byte flags = SoundMixer::FLAG_AUTOFREE;
if (isUnsigned)
flags |= SoundMixer::FLAG_UNSIGNED;
- _scumm->_mixer->playRaw(handle, sound, size, rate, flags);
+ _scumm->_mixer->playRaw(handle, sound, size, rate, flags, 127, 0);
}
#ifdef USE_VORBIS
diff --git a/simon/sound.cpp b/simon/sound.cpp
index 2aca4b955c..81df8c1258 100644
--- a/simon/sound.cpp
+++ b/simon/sound.cpp
@@ -174,7 +174,7 @@ int WavSound::playSound(uint sound, PlayingSoundHandle *handle, byte flags) {
byte *buffer = (byte *)malloc(data[1]);
_file->read(buffer, data[1]);
- return _mixer->playRaw(handle, buffer, data[1], FROM_LE_32(wave_hdr.samples_per_sec), flags);
+ return _mixer->playRaw(handle, buffer, data[1], FROM_LE_32(wave_hdr.samples_per_sec), flags, 127, 0);
}
int VocSound::playSound(uint sound, PlayingSoundHandle *handle, byte flags) {
@@ -212,7 +212,7 @@ int VocSound::playSound(uint sound, PlayingSoundHandle *handle, byte flags) {
byte *buffer = (byte *)malloc(size);
_file->read(buffer, size);
- return _mixer->playRaw(handle, buffer, size, samples_per_sec, flags);
+ return _mixer->playRaw(handle, buffer, size, samples_per_sec, flags, 127, 0);
}
int RawSound::playSound(uint sound, PlayingSoundHandle *handle, byte flags) {
@@ -226,7 +226,7 @@ int RawSound::playSound(uint sound, PlayingSoundHandle *handle, byte flags) {
byte *buffer = (byte *)malloc(size);
_file->read(buffer, size);
- return _mixer->playRaw(handle, buffer, size, 22050, flags);
+ return _mixer->playRaw(handle, buffer, size, 22050, flags, 127, 0);
}
#ifdef USE_MAD
diff --git a/sky/intro.cpp b/sky/intro.cpp
index 2d1ced19b4..39b45716e2 100644
--- a/sky/intro.cpp
+++ b/sky/intro.cpp
@@ -717,7 +717,8 @@ bool SkyIntro::nextPart(uint16 *&data) {
// probably use _skySound instead of calling playRaw()
// directly, but this will have to do for now.
memset(vData, 127, sizeof(struct dataFileHeader));
- _mixer->playRaw(&_voice, vData, _skyDisk->_lastLoadedFileSize, 11025, SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_UNSIGNED, SOUND_VOICE);
+ _mixer->playRaw(&_voice, vData, _skyDisk->_lastLoadedFileSize, 11025,
+ SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_UNSIGNED, SOUND_VOICE, 127, 0);
return true;
case WAITVOICE:
while (_voice)
@@ -733,11 +734,13 @@ bool SkyIntro::nextPart(uint16 *&data) {
return true;
case LOOPBG:
_mixer->stopID(SOUND_BG);
- _mixer->playRaw(&_bgSfx, _bgBuf + 256, _bgSize - 768, 11025, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_LOOP, SOUND_BG);
+ _mixer->playRaw(&_bgSfx, _bgBuf + 256, _bgSize - 768, 11025,
+ SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_LOOP, 127, 0, SOUND_BG);
return true;
case PLAYBG:
_mixer->stopID(SOUND_BG);
- _mixer->playRaw(&_bgSfx, _bgBuf + 256, _bgSize - 768, 11025, SoundMixer::FLAG_UNSIGNED, SOUND_BG);
+ _mixer->playRaw(&_bgSfx, _bgBuf + 256, _bgSize - 768, 11025,
+ SoundMixer::FLAG_UNSIGNED, SOUND_BG, 127, 0);
return true;
case STOPBG:
_mixer->stopID(SOUND_BG);
diff --git a/sky/sound.cpp b/sky/sound.cpp
index 0488557506..d13b7db8ca 100644
--- a/sky/sound.cpp
+++ b/sky/sound.cpp
@@ -1054,7 +1054,7 @@ int SkySound::playSound(uint32 id, byte *sound, uint32 size, PlayingSoundHandle
memcpy(buffer, sound+sizeof(struct dataFileHeader), size);
_mixer->stopID(id);
- return _mixer->playRaw(handle, buffer, size, 11025, flags, id);
+ return _mixer->playRaw(handle, buffer, size, 11025, flags, 127, 0, id);
}
void SkySound::loadSection(uint8 pSection) {
@@ -1130,9 +1130,9 @@ void SkySound::playSound(uint16 sound, uint16 volume, uint8 channel) {
_mixer->setVolume(volume);
if (channel == 0)
- _mixer->playRaw(&_ingameSound0, _soundData + dataOfs, dataSize, sampleRate, flags, SOUND_CH0, loopSta, loopEnd);
+ _mixer->playRaw(&_ingameSound0, _soundData + dataOfs, dataSize, sampleRate, flags, 127, 0, SOUND_CH0, loopSta, loopEnd);
else
- _mixer->playRaw(&_ingameSound1, _soundData + dataOfs, dataSize, sampleRate, flags, SOUND_CH1, loopSta, loopEnd);
+ _mixer->playRaw(&_ingameSound1, _soundData + dataOfs, dataSize, sampleRate, flags, 127, 0, SOUND_CH1, loopSta, loopEnd);
}
void SkySound::fnStartFx(uint32 sound, uint8 channel) {
@@ -1251,6 +1251,6 @@ bool SkySound::startSpeech(uint16 textNum) {
free(speechData);
_mixer->stopID(SOUND_SPEECH);
- _mixer->playRaw(&_ingameSpeech, playBuffer, speechSize, 11025, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE, SOUND_SPEECH);
+ _mixer->playRaw(&_ingameSpeech, playBuffer, speechSize, 11025, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE, 127, 0, SOUND_SPEECH);
return true;
}
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);
diff --git a/sword2/driver/d_sound.cpp b/sword2/driver/d_sound.cpp
index 9d708479b5..3bf6c721b2 100644
--- a/sword2/driver/d_sound.cpp
+++ b/sword2/driver/d_sound.cpp
@@ -179,6 +179,12 @@
#define GetdAPower(dA, power) for (power = 15; power > 0 && !((dA) & (1 << power)); power--)
int32 panTable[33] = {
+ -127, -119, -111, -103, -95, -87, -79, -71, -63, -55, -47, -39, -31, -23, -15, -7,
+ 0,
+ 7, 15, 23, 31, 39, 47, 55, 63, 71, 79, 87, 95, 103, 111, 119, 127
+};
+/*
+int32 panTable[33] = {
-10000,
-1500, -1400, -1300, -1200,
-1100, -1000, -900, -800,
@@ -196,7 +202,11 @@ int32 volTable[241] = {
-800, -791, -782, -773, -764, -755, -747, -738, -730, -721, -713, -705, -697, -689, -681, -673, -665, -658, -650, -643, -635, -628, -621, -613, -606, -599, -593, -586, -579, -572, -566, -559, -553, -546, -540, -534, -528, -522, -516, -510, -504, -498, -492, -487, -481, -476, -470, -465, -459, -454, -449, -444, -439, -434, -429, -424, -419, -414, -409, -404,
-400, -362, -328, -297, -269, -244, -221, -200, -181, -164, -148, -134, -122, -110, -100, -90, -82, -74, -67, -61, -55, -50, -45, -41, -37, -33, -30, -27, -25, -22, -20, -18, -16, -15, -13, -12, -11, -10, -9, -8, -7, -6, -6, -5, -5, -4, -4, -3, -3, -3, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0
};
-
+*/
+int32 musicVolTable[17] = {
+ 0, 15, 31, 47, 63, 79, 95, 111, 127, 143, 159, 175, 191, 207, 223, 239, 255
+};
+/*
int32 musicVolTable[17] = {
-10000,
-5000, -3000, -2500, -2250,
@@ -204,7 +214,7 @@ int32 musicVolTable[17] = {
-1000, -750, -500, -350,
-200, -100, -50, 0
};
-
+*/
void sword2_sound_handler (void *engine) {
g_sword2->_sound->FxServer();
}
@@ -460,7 +470,7 @@ int32 Sword2Sound::PreFetchCompSpeech(const char *filename, uint32 speechid, uin
if (GetCompressedSign(data8[i + 1]))
data16[i] = data16[i - 1] - (GetCompressedAmplitude(data8[i + 1]) << GetCompressedShift(data8[i + 1]));
else
- data16[i] = data16[i - 1] + (GetCompressedAmplitude(data8[i + 1])<<GetCompressedShift(data8[i + 1]));
+ data16[i] = data16[i - 1] + (GetCompressedAmplitude(data8[i + 1]) << GetCompressedShift(data8[i + 1]));
i++;
}
@@ -534,11 +544,16 @@ int32 Sword2Sound::PlayCompSpeech(const char *filename, uint32 speechid, uint8 v
free(data8);
// Modify the volume according to the master volume
+ byte volume;
+ int8 p;
if (speechMuted) {
+ volume = 0;
// IDirectSoundBuffer_SetVolume(dsbSpeech, volTable[0]);
} else {
+ volume = vol * speechVol;
// IDirectSoundBuffer_SetVolume(dsbSpeech, volTable[vol*speechVol]);
}
+ p = panTable[pan + 16];
// IDirectSoundBuffer_SetPan(dsbSpeech, panTable[pan+16]);
// Start the speech playing
@@ -552,8 +567,8 @@ int32 Sword2Sound::PlayCompSpeech(const char *filename, uint32 speechid, uint8 v
data16[j] = TO_BE_16(data16[j]);
soundHandleSpeech = 0;
- _mixer->playRaw(&soundHandleSpeech, data16, bufferSize, 22050, flags);
-
+ _mixer->playRaw(&soundHandleSpeech, data16, bufferSize, 22050, flags, volume, pan);
+
speechStatus = 1;
}
@@ -561,7 +576,6 @@ int32 Sword2Sound::PlayCompSpeech(const char *filename, uint32 speechid, uint8 v
return (RD_OK);
}
-
int32 Sword2Sound::StopSpeechSword2(void) {
if (!soundOn)
return(RD_OK);
@@ -593,6 +607,7 @@ int32 Sword2Sound::GetSpeechStatus(void) {
void Sword2Sound::SetSpeechVolume(uint8 volume) {
speechVol = volume;
if ((soundHandleSpeech != 0) && !speechMuted && GetSpeechStatus() == RDSE_SAMPLEPLAYING) {
+ g_engine->_mixer->setChannelVolume(soundHandleSpeech, 16 * speechVol);
// IDirectSoundBuffer_SetVolume(dsbSpeech, volTable[16*speechVol]);
}
}
@@ -606,8 +621,10 @@ void Sword2Sound::MuteSpeech(uint8 mute) {
if (GetSpeechStatus() == RDSE_SAMPLEPLAYING) {
if (mute) {
+ g_engine->_mixer->setChannelVolume(soundHandleSpeech, 0);
// IDirectSoundBuffer_SetVolume(dsbSpeech, volTable[0]);
} else {
+ g_engine->_mixer->setChannelVolume(soundHandleSpeech, 16 * speechVol);
// IDirectSoundBuffer_SetVolume(dsbSpeech, volTable[16*speechVol]);
}
}
@@ -827,14 +844,17 @@ int32 Sword2Sound::PlayFx(int32 id, uint8 *data, uint8 vol, int8 pan, uint8 type
fxLooped[i] = 0;
flagsFx[i] &= ~SoundMixer::FLAG_LOOP;
+ byte volume;
// Start the sound effect playing
if (musicMuted) {
+ volume = 0;
// IDirectSoundBuffer_SetVolume(dsbFx[i], volTable[0]);
} else {
+ volume = musicVolTable[volMusic[0]];
// IDirectSoundBuffer_SetVolume(dsbFx[i], musicVolTable[volMusic[0]]);
}
// IDirectSoundBuffer_SetPan(dsbFx[i], 0);
- g_engine->_mixer->playRaw(&soundHandleFx[i], bufferFx[i], bufferSizeFx[i], fxRate[i], flagsFx[i]);
+ g_engine->_mixer->playRaw(&soundHandleFx[i], bufferFx[i], bufferSizeFx[i], fxRate[i], flagsFx[i], volume, 0);
fxCached[i] = RDSE_FXTOCLEAR;
} else {
@@ -850,15 +870,20 @@ int32 Sword2Sound::PlayFx(int32 id, uint8 *data, uint8 vol, int8 pan, uint8 type
fxVolume[i] = vol;
+ byte volume;
+ int8 p;
// Start the sound effect playing
if (fxMuted) {
+ volume = 0;
// IDirectSoundBuffer_SetVolume(dsbFx[i], volTable[0]);
} else {
+ volume = vol * fxVol;
// IDirectSoundBuffer_SetVolume(dsbFx[i], volTable[vol*fxVol]);
}
+ p = panTable[pan + 16];
// IDirectSoundBuffer_SetPan(dsbFx[i], panTable[pan+16]);
- g_engine->_mixer->playRaw(&soundHandleFx[i], bufferFx[i], bufferSizeFx[i], fxRate[i], flagsFx[i]);
+ g_engine->_mixer->playRaw(&soundHandleFx[i], bufferFx[i], bufferSizeFx[i], fxRate[i], flagsFx[i], volume, p);
if (id == (int32) 0xffffffff) {
fxCached[i] = RDSE_FXTOCLEAR;
}
@@ -875,13 +900,17 @@ int32 Sword2Sound::PlayFx(int32 id, uint8 *data, uint8 vol, int8 pan, uint8 type
return RDERR_FXFUCKED;
}
fxCached[i] = RDSE_FXTOCLEAR;
+
+ byte volume;
if (musicMuted) {
+ volume = 0;
// IDirectSoundBuffer_SetVolume(dsbFx[i], volTable[0]);
} else {
+ volume = musicVolTable[volMusic[0]];
// IDirectSoundBuffer_SetVolume(dsbFx[i], musicVolTable[volMusic[0]]);
}
// IDirectSoundBuffer_SetPan(dsbFx[i], 0);
- g_engine->_mixer->playRaw(&soundHandleFx[i], bufferFx[i], bufferSizeFx[i], fxRate[i], flagsFx[i]);
+ g_engine->_mixer->playRaw(&soundHandleFx[i], bufferFx[i], bufferSizeFx[i], fxRate[i], flagsFx[i], volume, 0);
} else {
hr = OpenFx(id, data);
if (hr != RD_OK) {
@@ -900,14 +929,19 @@ int32 Sword2Sound::PlayFx(int32 id, uint8 *data, uint8 vol, int8 pan, uint8 type
flagsFx[i] &= ~SoundMixer::FLAG_LOOP;
fxVolume[i] = vol;
+ byte volume;
+ int8 p;
// Start the sound effect playing
if (fxMuted) {
+ volume = 0;
// IDirectSoundBuffer_SetVolume(dsbFx[i], volTable[0]);
} else {
+ volume = vol * fxVol;
// IDirectSoundBuffer_SetVolume(dsbFx[i], volTable[vol*fxVol]);
}
+ p = panTable[pan + 16];
// IDirectSoundBuffer_SetPan(dsbFx[i], panTable[pan+16]);
- g_engine->_mixer->playRaw(&soundHandleFx[i], bufferFx[i], bufferSizeFx[i], fxRate[i], flagsFx[i]);
+ g_engine->_mixer->playRaw(&soundHandleFx[i], bufferFx[i], bufferSizeFx[i], fxRate[i], flagsFx[i], volume, p);
}
}
}
@@ -1020,6 +1054,8 @@ int32 Sword2Sound::SetFxVolumePan(int32 id, uint8 vol, int8 pan) {
fxVolume[i] = vol;
if (!fxMuted) {
+ g_engine->_mixer->setChannelVolume(soundHandleFx[i], vol * fxVol);
+ g_engine->_mixer->setChannelPan(soundHandleFx[i], panTable[pan + 16]);
// IDirectSoundBuffer_SetVolume(dsbFx[i], volTable[vol*fxVol]);
// IDirectSoundBuffer_SetPan(dsbFx[i], panTable[pan+16]);
}
@@ -1033,6 +1069,7 @@ int32 Sword2Sound::SetFxIdVolume(int32 id, uint8 vol) {
fxVolume[i] = vol;
if (!fxMuted) {
+ g_engine->_mixer->setChannelVolume(soundHandleFx[i], vol * fxVol);
// IDirectSoundBuffer_SetVolume(dsbFx[i], volTable[vol*fxVol]);
}
return RD_OK;
@@ -1142,6 +1179,7 @@ void Sword2Sound::SetFxVolume(uint8 volume) {
// Now update the volume of any fxs playing
for (fxi = 0; fxi < MAXFX; fxi++) {
if (fxId[fxi] && !fxMuted) {
+ g_engine->_mixer->setChannelVolume(soundHandleFx[fxi], fxVolume[fxi] * fxVol);
// IDirectSoundBuffer_SetVolume(dsbFx[fxi], volTable[fxVolume[fxi]*fxVol]);
}
}
@@ -1156,8 +1194,10 @@ void Sword2Sound::MuteFx(uint8 mute) {
for (fxi = 0; fxi < MAXFX; fxi++) {
if (fxId[fxi]) {
if (mute) {
+ g_engine->_mixer->setChannelVolume(soundHandleFx[fxi], 0);
// IDirectSoundBuffer_SetVolume(dsbFx[fxi], volTable[0]);
} else {
+ g_engine->_mixer->setChannelVolume(soundHandleFx[fxi], fxVolume[fxi] * fxVol);
// IDirectSoundBuffer_SetVolume(dsbFx[fxi], volTable[fxVolume[fxi]*fxVol]);
}
}
@@ -1304,13 +1344,22 @@ int32 Sword2Sound::StreamCompMusic(const char *filename, uint32 musicId, int32 l
v1 = volMusic[1];
}
+ byte volume;
+ int8 pan;
+
if (v0 > v1) {
+ volume = musicVolTable[v0];
+ pan = (musicVolTable[v1 * 16 / v0] / 2) - 127;
// IDirectSoundBuffer_SetVolume(lpDsbMus[primaryStream], musicVolTable[v0]);
// IDirectSoundBuffer_SetPan(lpDsbMus[primaryStream], musicVolTable[v1*16/v0]);
} else if (v1 > v0) {
+ volume = musicVolTable[v1];
+ pan = (musicVolTable[v0 * 16 / v1] / 2) + 127;
// IDirectSoundBuffer_SetVolume(lpDsbMus[primaryStream], musicVolTable[v1]);
// IDirectSoundBuffer_SetPan(lpDsbMus[primaryStream], -musicVolTable[v0*16/v1]);
} else {
+ volume = musicVolTable[v1];
+ pan = 0;
// IDirectSoundBuffer_SetVolume(lpDsbMus[primaryStream], musicVolTable[v1]);
// IDirectSoundBuffer_SetPan(lpDsbMus[primaryStream], 0);
}
@@ -1321,13 +1370,8 @@ int32 Sword2Sound::StreamCompMusic(const char *filename, uint32 musicId, int32 l
data16[i] = TO_BE_16(data16[i]);
}
- if (soundHandleMusic[primaryStream] == 0) {
- soundHandleMusic[primaryStream] = g_engine->_mixer->newStream(data16, bufferSizeMusic, 22050, SoundMixer::FLAG_16BITS, 100000);
- } else {
- g_engine->_mixer->appendStream(soundHandleMusic[primaryStream], data16, bufferSizeMusic);
- }
-
- free(data16);
+ soundHandleMusic[primaryStream] = g_engine->_mixer->newStream(data16, bufferSizeMusic, 22050,
+ SoundMixer::FLAG_16BITS | SoundMixer::FLAG_AUTOFREE, 100000, volume, 0);
// Recorder some last variables
musStreaming[primaryStream] = 1;
@@ -1767,17 +1811,28 @@ void Sword2Sound::UpdateCompSampleStreaming(void) {
v1 = (volMusic[1] * (0 - musFading[i]) / 16);
}
+ byte volume;
+ int8 pan;
+
if (v0 > v1) {
+ volume = musicVolTable[v0];
+ pan = (musicVolTable[v1 * 16 / v0] / 2) - 127;
// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v0]);
// IDirectSoundBuffer_SetPan(lpDsbMus[i], musicVolTable[v1*16/v0]);
} else {
if (v1 > v0) {
+ volume = musicVolTable[v1];
+ pan = (musicVolTable[v0 * 16 / v1] / 2) + 127;
// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
// IDirectSoundBuffer_SetPan(lpDsbMus[i], -musicVolTable[v0*16/v1]);
} else {
+ volume = musicVolTable[v1];
+ pan = 0;
// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
// IDirectSoundBuffer_SetPan(lpDsbMus[i], 0);
}
+ g_engine->_mixer->setChannelVolume(soundHandleMusic[i], volume);
+ g_engine->_mixer->setChannelPan(soundHandleMusic[i], pan);
}
}
}
@@ -1840,15 +1895,12 @@ void Sword2Sound::UpdateCompSampleStreaming(void) {
data16[y] = TO_BE_16(data16[y]);
}
- if (soundHandleMusic[i] == 0) {
- soundHandleMusic[i] = g_engine->_mixer->newStream(data16, bufferSizeMusic, 22050, SoundMixer::FLAG_16BITS, 100000);
- } else {
- // Paranoid check that seems to
- // be necessary.
- if (len & 1)
- len--;
- g_engine->_mixer->appendStream(soundHandleMusic[i], data16, len);
- }
+ // Paranoid check that seems to
+ // be necessary.
+ if (len & 1)
+ len--;
+ assert(soundHandleMusic[i]);
+ g_engine->_mixer->appendStream(soundHandleMusic[i], data16, len);
free(data16);
@@ -2227,6 +2279,7 @@ void Sword2Sound::SetMusicVolume(uint8 volume) {
for (i = 0; i < MAXMUS; i++) {
volMusic[i] = volume;
if (musStreaming[i] && !musFading[i] && !musicMuted) {
+ g_engine->_mixer->setChannelVolume(soundHandleMusic[i], musicVolTable[volume]);
// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[volume]);
}
}
@@ -2249,8 +2302,10 @@ void Sword2Sound::MuteMusic(uint8 mute) {
if (musStreaming[i] && !musFading[i]) {
if (mute) {
+ g_engine->_mixer->setChannelVolume(soundHandleMusic[i], musicVolTable[0]);
// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[0]);
} else {
+ g_engine->_mixer->setChannelVolume(soundHandleMusic[i], musicVolTable[volMusic[i]]);
// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[volMusic[i]]);
}
}