handle volume and pan by SoundMixer not SmushMixer

svn-id: r12287
This commit is contained in:
Paweł Kołodziejski 2004-01-09 23:33:46 +00:00
parent 9d7d23a7c6
commit 1f04d5a7cd
5 changed files with 32 additions and 62 deletions

View File

@ -41,7 +41,7 @@ public:
virtual void getSoundData(int16 *sound_buffer, int32 size) = 0;
virtual void getSoundData(int8 *sound_buffer, int32 size) = 0;
virtual int32 getRate() = 0;
virtual bool getParameters(int32 &rate, bool &stereo, bool &is_16bit) = 0;
virtual bool getParameters(int32 &rate, bool &stereo, bool &is_16bit, int32 &vol, int32 &pan) = 0;
virtual int32 getTrackIdentifier() const = 0;
};
@ -55,9 +55,8 @@ private:
bool _markReached;
int32 _flags;
int32 _volume;
int32 _balance;
int32 _pan;
int32 _index;
int16 _voltable[2][256];
byte *_tbuffer;
int32 _tbufferSize;
byte *_sbuffer;
@ -70,7 +69,6 @@ protected:
void handleShdr(Chunk &c);
bool handleSubTags(int32 &offset);
bool processBuffer();
void recalcVolumeTable();
public:
SaudChannel(int32 track, int32 freq);
@ -83,10 +81,12 @@ public:
void getSoundData(int16 *sound_buffer, int32 size);
void getSoundData(int8 *sound_buffer, int32 size) { error("8bit request for SAUD channel should never happen"); };
int32 getRate() { return _frequency; }
bool getParameters(int32 &rate, bool &stereo, bool &is_16bit) {
bool getParameters(int32 &rate, bool &stereo, bool &is_16bit, int32 &vol, int32 &pan) {
rate = _frequency;
stereo = true;
is_16bit = true;
vol = _volume;
pan = _pan;
return true;
};
virtual int32 getTrackIdentifier() const { return _track; };
@ -104,6 +104,7 @@ private:
int32 _dataSize; //!< remaining size of sound data in the iMUS buffer
bool _inData;
int32 _volume;
int32 _pan;
int32 _bitsize; //!< the bitsize of the original data
int32 _rate; //!< the sampling rate of the original data
@ -131,10 +132,12 @@ public:
void getSoundData(int16 *sound_buffer, int32 size);
void getSoundData(int8 *sound_buffer, int32 size);
int32 getRate() { return _rate; }
bool getParameters(int32 &rate, bool &stereo, bool &is_16bit) {
bool getParameters(int32 &rate, bool &stereo, bool &is_16bit, int32 &vol, int32 &pan) {
rate = _rate;
stereo = (_channels == 2);
is_16bit = (_bitsize > 8);
vol = _volume;
pan = _pan;
return true;
};
virtual int32 getTrackIdentifier() const { return _track; };

View File

@ -63,6 +63,7 @@ bool ImuseChannel::setParameters(int32 nb, int32 size, int32 flags, int32 unk1,
} else {
error("ImuseChannel::setParameters(): bad flags: %d", flags);
}
_pan = 0;
return true;
}
@ -324,15 +325,9 @@ int32 ImuseChannel::availableSoundData(void) const {
void ImuseChannel::getSoundData(int16 *snd, int32 size) {
if (_dataSize <= 0 || _bitsize <= 8) error("invalid call to imuse_channel::read_sound_data()");
if (_channels == 2) size *= 2;
byte * buf = (byte*)snd;
for (int32 i = 0; i < size; i++){
byte sample1 = *(_sbuffer + i * 2);
byte sample2 = *(_sbuffer + i * 2 + 1);
uint16 sample = (uint16)(((int16)((sample1 << 8) | sample2) * _volume) >> 8);
buf[i * 2 + 0] = (byte)(sample >> 8);
buf[i * 2 + 1] = (byte)(sample & 0xff);
}
memcpy(snd, _sbuffer, size * 2);
delete []_sbuffer;
assert(_sbufferSize == 2 * size);
_sbuffer = 0;
@ -344,9 +339,8 @@ void ImuseChannel::getSoundData(int8 *snd, int32 size) {
if (_dataSize <= 0 || _bitsize > 8) error("invalid call to imuse_channel::read_sound_data()");
if (_channels == 2) size *= 2;
for (int32 i = 0; i < size; i++){
snd[i] = (int8)(((int8)(_sbuffer[i] ^ 0x80) * _volume) >> 8) ^ 0x80;
}
memcpy(snd, _sbuffer, size);
delete []_sbuffer;
_sbuffer = 0;
_sbufferSize = 0;

View File

@ -183,59 +183,30 @@ bool SaudChannel::isTerminated() const {
return (_markReached && _dataSize == 0 && _sbuffer == 0);
}
void SaudChannel::recalcVolumeTable() {
const int MAX_BALANCE = 100;
int volume_left, volume_right;
if (_balance < -MAX_BALANCE || _balance > MAX_BALANCE) {
warning("balance is out of range ! : %d", _balance);
return;
}
int left_multiplier = MAX_BALANCE - _balance;
int right_multiplier = MAX_BALANCE + _balance;
volume_left = _volume * left_multiplier / (MAX_BALANCE * 2);
volume_right = _volume * right_multiplier / (MAX_BALANCE * 2);
if (volume_left < 0)
volume_left = 0;
if (volume_left > 128)
volume_left = 128;
if (volume_right < 0)
volume_right = 0;
if (volume_right > 128)
volume_right = 128;
for (int i = 0; i < 256; i++) {
int16 value = volume_left * (int8)i;
_voltable[0][i] = TO_BE_16(value);
value = volume_right * (int8)i;
_voltable[1][i] = TO_BE_16(value);
}
}
bool SaudChannel::setParameters(int32 nb, int32 flags, int32 volume, int32 balance, int32 index) {
bool SaudChannel::setParameters(int32 nb, int32 flags, int32 volume, int32 pan, int32 index) {
_nbframes = nb;
_flags = flags; // bit 7 == IS_VOICE, bit 6 == IS_BACKGROUND_MUSIC, other ??
_volume = volume;
_balance = balance;
_pan = pan;
_index = index;
if (index != 0) {
_dataSize = -2;
_keepSize = true;
_inData = true;
}
recalcVolumeTable();
return true;
}
bool SaudChannel::checkParameters(int32 index, int32 nb, int32 flags, int32 volume, int32 balance) {
bool SaudChannel::checkParameters(int32 index, int32 nb, int32 flags, int32 volume, int32 pan) {
if (++_index != index)
error("invalid index in SaudChannel::checkParameters()");
if (_nbframes != nb)
error("invalid duration in SaudChannel::checkParameters()");
if (_flags != flags)
error("invalid flags in SaudChannel::checkParameters()");
if (_volume != volume || _balance != balance) {
if (_volume != volume || _pan != pan) {
_volume = volume;
_balance = balance;
recalcVolumeTable();
_pan = pan;
}
return true;
}
@ -277,8 +248,8 @@ int32 SaudChannel::availableSoundData(void) const {
void SaudChannel::getSoundData(int16 *snd, int32 size) {
for (int32 i = 0; i < size; i++) {
snd[2 * i] = _voltable[0][_sbuffer[i] ^ 0x80];
snd[2 * i + 1] = _voltable[1][_sbuffer[i] ^ 0x80];
snd[2 * i] = _sbuffer[i] ^ 0x80;
snd[2 * i + 1] = _sbuffer[i] ^ 0x80;
}
if (!_keepSize)
_dataSize -= size;

View File

@ -95,11 +95,11 @@ bool SmushMixer::handleFrame() {
_channels[i].chan = NULL;
_mixer->endStream(_channels[i].handle);
} else {
int32 rate;
int32 rate, vol, pan;
bool stereo, is_16bit;
void *data;
_channels[i].chan->getParameters(rate, stereo, is_16bit);
_channels[i].chan->getParameters(rate, stereo, is_16bit, vol, pan);
int32 size = _channels[i].chan->availableSoundData();
byte flags = stereo ? SoundMixer::FLAG_STEREO : 0;
@ -121,6 +121,8 @@ bool SmushMixer::handleFrame() {
if (_mixer->isReady()) {
if (!_channels[i].handle.isActive())
_mixer->newStream(&_channels[i].handle, rate, flags, 400000);
_mixer->setChannelVolume(_channels[i].handle, vol);
_mixer->setChannelPan(_channels[i].handle, pan);
_mixer->appendStream(_channels[i].handle, data, size);
}
free(data);

View File

@ -298,7 +298,7 @@ void SmushPlayer::checkBlock(const Chunk &b, Chunk::type type_expected, uint32 m
}
}
void SmushPlayer::handleSoundBuffer(int32 track_id, int32 index, int32 max_frames, int32 flags, int32 vol, int32 bal, Chunk &b, int32 size) {
void SmushPlayer::handleSoundBuffer(int32 track_id, int32 index, int32 max_frames, int32 flags, int32 vol, int32 pan, Chunk &b, int32 size) {
debug(6, "SmushPlayer::handleSoundBuffer(%d, %d)", track_id, index);
// if ((flags & 128) == 128) {
// return;
@ -313,11 +313,11 @@ void SmushPlayer::handleSoundBuffer(int32 track_id, int32 index, int32 max_frame
}
if ((_middleAudio) && (index != 0)) {
c->setParameters(max_frames, flags, vol, bal, index);
c->setParameters(max_frames, flags, vol, pan, index);
} else if (index == 0) {
c->setParameters(max_frames, flags, vol, bal, index);
c->setParameters(max_frames, flags, vol, pan, index);
} else {
c->checkParameters(index, max_frames, flags, vol, bal);
c->checkParameters(index, max_frames, flags, vol, pan);
}
_middleAudio = false;
c->appendData(b, size);
@ -332,12 +332,12 @@ void SmushPlayer::handleSoundFrame(Chunk &b) {
int32 max_frames = b.getWord();
int32 flags = b.getWord();
int32 vol = b.getByte();
int32 bal = b.getChar();
int32 pan = b.getChar();
if (index == 0) {
debug(5, "track_id == %d, max_frames == %d, %d, %d, %d", track_id, max_frames, flags, vol, bal);
debug(5, "track_id:%d, max_frames:%d, flags:%d, vol:%d, pan:%d", track_id, max_frames, flags, vol, pan);
}
int32 size = b.getSize() - 10;
handleSoundBuffer(track_id, index, max_frames, flags, vol, bal, b, size);
handleSoundBuffer(track_id, index, max_frames, flags, vol, pan, b, size);
}
void SmushPlayer::handleSkip(Chunk &b) {