diff options
-rw-r--r-- | backends/midi/adlib.cpp | 10 | ||||
-rw-r--r-- | scumm/player_v2.cpp | 14 | ||||
-rw-r--r-- | sky/music/adlibmusic.cpp | 40 | ||||
-rw-r--r-- | sound/mixer.cpp | 7 | ||||
-rw-r--r-- | sound/mixer.h | 10 |
5 files changed, 52 insertions, 29 deletions
diff --git a/backends/midi/adlib.cpp b/backends/midi/adlib.cpp index 2205c56589..efd412235e 100644 --- a/backends/midi/adlib.cpp +++ b/backends/midi/adlib.cpp @@ -866,7 +866,7 @@ int MidiDriver_ADLIB::open() { _samples_per_tick = (_mixer->getOutputRate() << FIXP_SHIFT) / BASE_FREQ; - _mixer->setupPremix(this, premix_proc); + _mixer->setupPremix(premix_proc, this); return 0; } @@ -1014,6 +1014,9 @@ void MidiDriver_ADLIB::adlib_write(byte port, byte value) { void MidiDriver_ADLIB::generate_samples(int16 *data, int len) { int step; + int16 *origData = data; + uint origLen = len; + do { step = len; if (step > (_next_tick >> FIXP_SHIFT)) @@ -1030,6 +1033,11 @@ void MidiDriver_ADLIB::generate_samples(int16 *data, int len) { data += step; len -= step; } while (len); + + // Convert mono data to stereo + for (int i = (origLen - 1); i >= 0; i--) { + origData[2 * i] = origData[2 * i + 1] = origData[i]; + } } void MidiDriver_ADLIB::reset_tick() { diff --git a/scumm/player_v2.cpp b/scumm/player_v2.cpp index d8910ebf63..b1f7be623c 100644 --- a/scumm/player_v2.cpp +++ b/scumm/player_v2.cpp @@ -381,7 +381,7 @@ Player_V2::Player_V2(Scumm *scumm) { set_pcjr(scumm->_midiDriver != MD_PCSPK); setMasterVolume(255); - _mixer->setupPremix(this, premix_proc); + _mixer->setupPremix(premix_proc, this); } Player_V2::~Player_V2() { @@ -820,10 +820,12 @@ void Player_V2::next_freqs(ChannelInfo *channel) { } } -void Player_V2::do_mix (int16 *data, uint len) { +void Player_V2::do_mix(int16 *data, uint len) { mutex_up(); uint step; + int16 *origData = data; + uint origLen = len; do { step = len; if (step > (_next_tick >> FIXP_SHIFT)) @@ -848,6 +850,12 @@ void Player_V2::do_mix (int16 *data, uint len) { } } } while (len -= step); + + // Convert mono data to stereo + for (int i = (origLen - 1); i >= 0; i--) { + origData[2 * i] = origData[2 * i + 1] = origData[i]; + } + mutex_down(); } @@ -911,7 +919,7 @@ void Player_V2::generateSpkSamples(int16 *data, uint len) { } } - memset (data, 0, sizeof(int16) * len); + memset(data, 0, sizeof(int16) * len); if (winning_channel != -1) { squareGenerator(0, _channels[winning_channel].d.freq, 0, 0, data, len); diff --git a/sky/music/adlibmusic.cpp b/sky/music/adlibmusic.cpp index 7aaf6e8c0e..52e0a7ed94 100644 --- a/sky/music/adlibmusic.cpp +++ b/sky/music/adlibmusic.cpp @@ -39,7 +39,7 @@ SkyAdlibMusic::SkyAdlibMusic(SoundMixer *pMixer, SkyDisk *pSkyDisk, OSystem *sys OPLBuildTables((env_bits ? env_bits : FMOPL_ENV_BITS_HQ), (eg_ent ? eg_ent : FMOPL_EG_ENT_HQ)); _opl = OPLCreate(OPL_TYPE_YM3812, 3579545, _sampleRate); - _mixer->setupPremix(this, passMixerFunc); + _mixer->setupPremix(passMixerFunc, this); } SkyAdlibMusic::~SkyAdlibMusic(void) { @@ -55,30 +55,36 @@ void SkyAdlibMusic::setVolume(uint8 volume) { _channels[cnt]->updateVolume(volume | 128); } -void SkyAdlibMusic::premixerCall(int16 *buf, uint len) { +void SkyAdlibMusic::premixerCall(int16 *data, uint len) { if (_musicData == NULL) { // no music loaded - memset(buf, 0, len * sizeof(int16)); - return; + memset(data, 0, 2 * len * sizeof(int16)); } else if ((_currentMusic == 0) || (_numberOfChannels == 0)) { // music loaded but not played as of yet - memset(buf, 0, len * sizeof(int16)); + memset(data, 0, 2 * len * sizeof(int16)); // poll anyways as pollMusic() can activate the music pollMusic(); _nextMusicPoll = _sampleRate/50; - return; - } - uint32 render; - while (len) { - render = (len > _nextMusicPoll) ? (_nextMusicPoll) : (len); - len -= render; - _nextMusicPoll -= render; - YM3812UpdateOne (_opl, buf, render); - buf += render; - if (_nextMusicPoll == 0) { - pollMusic(); - _nextMusicPoll = _sampleRate/50; + } else { + uint32 render; + int16 *origData = data; + uint origLen = len; + while (len) { + render = (len > _nextMusicPoll) ? (_nextMusicPoll) : (len); + len -= render; + _nextMusicPoll -= render; + YM3812UpdateOne(_opl, data, render); + data += render; + if (_nextMusicPoll == 0) { + pollMusic(); + _nextMusicPoll = _sampleRate/50; + } + } + + // Convert mono data to stereo + for (int i = (origLen - 1); i >= 0; i--) { + origData[2 * i] = origData[2 * i + 1] = origData[i]; } } } diff --git a/sound/mixer.cpp b/sound/mixer.cpp index da5952ecf4..a8d611588f 100644 --- a/sound/mixer.cpp +++ b/sound/mixer.cpp @@ -160,7 +160,7 @@ bool SoundMixer::bindToSystem(OSystem *syst) { return syst->set_sound_proc(mixCallback, this, OSystem::SOUND_16BIT); } -void SoundMixer::setupPremix(void *param, PremixProc *proc) { +void SoundMixer::setupPremix(PremixProc *proc, void *param) { StackLock lock(_mutex); _premixParam = param; _premixProc = proc; @@ -279,12 +279,7 @@ void SoundMixer::mix(int16 *buf, uint len) { StackLock lock(_mutex); if (_premixProc && !_paused) { - int i; _premixProc(_premixParam, buf, len); - // Convert mono data from the premix proc to stereo - for (i = (len - 1); i >= 0; i--) { - buf[2 * i] = buf[2 * i + 1] = buf[i]; - } } else { // zero the buf out memset(buf, 0, 2 * len * sizeof(int16)); diff --git a/sound/mixer.h b/sound/mixer.h index 0e7e89bddf..6c9e9a4671 100644 --- a/sound/mixer.h +++ b/sound/mixer.h @@ -83,8 +83,14 @@ public: * to be generated */ bool bindToSystem(OSystem *syst); - /** Premix procedure, useful when using fmopl adlib */ - void setupPremix(void * param, PremixProc * proc); + /** + * Set the premix procedure. This is mainly used for the adlib music, but is not limited + * to it. The premix proc is invoked by the mixer whenever it needs to generate any + * data, before any other mixing takes place. The premixer than has a chanve to fill + * the mix buffer with data (usually music samples). It should generate the specified + * number of 16bit stereo samples (i.e. len * 4 bytes). + */ + void setupPremix(PremixProc *proc, void *param); // start playing a raw sound int playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, |