aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra/sound.cpp
diff options
context:
space:
mode:
authorJohannes Schickel2008-11-30 01:53:32 +0000
committerJohannes Schickel2008-11-30 01:53:32 +0000
commit893a79b01dd02ebc7475b7cdd0f5ec154229f51c (patch)
tree4e5888179f175d8660eab8c9828c25703affb2e2 /engines/kyra/sound.cpp
parentfead4f304f2034de410564e113cef20563018d26 (diff)
downloadscummvm-rg350-893a79b01dd02ebc7475b7cdd0f5ec154229f51c.tar.gz
scummvm-rg350-893a79b01dd02ebc7475b7cdd0f5ec154229f51c.tar.bz2
scummvm-rg350-893a79b01dd02ebc7475b7cdd0f5ec154229f51c.zip
Initial version of proper MIDI support for KYRA.
svn-id: r35174
Diffstat (limited to 'engines/kyra/sound.cpp')
-rw-r--r--engines/kyra/sound.cpp319
1 files changed, 0 insertions, 319 deletions
diff --git a/engines/kyra/sound.cpp b/engines/kyra/sound.cpp
index 073639e4ca..63a97185c8 100644
--- a/engines/kyra/sound.cpp
+++ b/engines/kyra/sound.cpp
@@ -159,325 +159,6 @@ uint32 Sound::voicePlayedTime(const char *file) {
#pragma mark -
-SoundMidiPC::SoundMidiPC(KyraEngine_v1 *vm, Audio::Mixer *mixer, MidiDriver *driver) : Sound(vm, mixer) {
- _driver = driver;
- _passThrough = false;
-
- _musicParser = _sfxParser = 0;
- _isMusicPlaying = _isSfxPlaying = false;
- _eventFromMusic = false;
-
- _nativeMT32 = _useC55 = false;
-
- _fadeStartTime = 0;
- _fadeMusicOut = false;
-
- memset(_channel, 0, sizeof(_channel));
- memset(_channelVolume, 50, sizeof(_channelVolume));
- _channelVolume[10] = 100;
- for (int i = 0; i < 16; ++i)
- _virChannel[i] = i;
-
- int ret = open();
- if (ret != MERR_ALREADY_OPEN && ret != 0)
- error("Couldn't open midi driver");
-}
-
-SoundMidiPC::~SoundMidiPC() {
- Common::StackLock lock(_mutex);
-
- delete _musicParser;
- delete _sfxParser;
-
- _driver->setTimerCallback(0, 0);
- close();
-}
-
-bool SoundMidiPC::init() {
- _musicParser = MidiParser::createParser_XMIDI();
- _sfxParser = MidiParser::createParser_XMIDI();
-
- if (!_musicParser || !_sfxParser)
- return false;
-
- _musicParser->setMidiDriver(this);
- _sfxParser->setMidiDriver(this);
-
- return true;
-}
-
-void SoundMidiPC::updateVolumeSettings() {
- _musicVolume = CLIP(ConfMan.getInt("music_volume"), 0, 255);
- _sfxVolume = CLIP(ConfMan.getInt("sfx_volume"), 0, 255);
-
- updateChannelVolume(_musicVolume);
-}
-
-void SoundMidiPC::hasNativeMT32(bool nativeMT32) {
- _nativeMT32 = nativeMT32;
-
- // C55 appears to be XMIDI for General MIDI instruments
- if (!_nativeMT32 && _vm->game() == GI_KYRA2)
- _useC55 = true;
- else
- _useC55 = false;
-}
-
-void SoundMidiPC::updateChannelVolume(uint8 volume) {
- for (int i = 0; i < 32; ++i) {
- if (_channel[i]) {
- if (i >= 16)
- _channel[i]->volume(_channelVolume[i - 16] * volume / 255);
- else
- _channel[i]->volume(_channelVolume[i] * volume / 255);
- }
- }
-}
-
-int SoundMidiPC::open() {
- // Don't ever call open without first setting the output driver!
- if (!_driver)
- return 255;
-
- int ret = _driver->open();
- if (ret)
- return ret;
-
- _driver->setTimerCallback(this, &onTimer);
- return 0;
-}
-
-void SoundMidiPC::close() {
- if (_driver) {
- _driver->close();
- delete _driver;
- }
- _driver = 0;
-}
-
-void SoundMidiPC::send(uint32 b) {
- if (_passThrough) {
- if ((b & 0xFFF0) == 0x007BB0)
- return;
- _driver->send(b);
- return;
- }
-
- const int volume = /*_eventFromMusic ? */_musicVolume/* : _sfxVolume*/;
-
- uint8 channel = (byte)(b & 0x0F);
- if (((b & 0xFFF0) == 0x6FB0 || (b & 0xFFF0) == 0x6EB0) && channel != 9) {
- if (_virChannel[channel] == channel) {
- _virChannel[channel] = channel + 16;
- if (!_channel[_virChannel[channel]])
- _channel[_virChannel[channel]] = _driver->allocateChannel();
- if (_channel[_virChannel[channel]])
- _channel[_virChannel[channel]]->volume(_channelVolume[channel] * volume / 255);
- }
- return;
- }
-
- if ((b & 0xFFF0) == 0x07B0) {
- // Adjust volume changes by master volume
- uint8 vol = (uint8)((b >> 16) & 0x7F);
- _channelVolume[channel] = vol;
- vol = vol * volume / 255;
- b = (b & 0xFF00FFFF) | (vol << 16);
- } else if ((b & 0xF0) == 0xC0 && !_nativeMT32 && !_useC55) {
- b = (b & 0xFFFF00FF) | (MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8);
- } else if ((b & 0xFFF0) == 0x007BB0) {
- //Only respond to All Notes Off if this channel
- //has currently been allocated
- if (!_channel[/*_virChannel[channel]*/channel])
- return;
- }
-
- if (!_channel[_virChannel[channel]]) {
- _channel[_virChannel[channel]] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
- if (_channel[_virChannel[channel]])
- _channel[_virChannel[channel]]->volume(_channelVolume[channel] * volume / 255);
- }
- if (_channel[_virChannel[channel]])
- _channel[_virChannel[channel]]->send(b);
-}
-
-void SoundMidiPC::metaEvent(byte type, byte *data, uint16 length) {
- switch (type) {
- case 0x2F: // End of Track
- if (_eventFromMusic) {
- // remap all channels
- for (int i = 0; i < 16; ++i)
- _virChannel[i] = i;
- } else {
- _isSfxPlaying = false;
- }
- break;
- default:
- _driver->metaEvent(type, data, length);
- break;
- }
-}
-
-
-struct DeleterArray {
- void operator ()(byte *ptr) {
- delete[] ptr;
- }
-};
-
-void SoundMidiPC::loadSoundFile(uint file) {
- Common::StackLock lock(_mutex);
-
- internalLoadFile(fileListEntry(file));
-}
-
-void SoundMidiPC::loadSoundFile(Common::String file) {
- Common::StackLock lock(_mutex);
-
- internalLoadFile(file);
-}
-
-void SoundMidiPC::internalLoadFile(Common::String file) {
- Common::String filename = file;
- filename += ".";
- filename += _useC55 ? "C55" : "XMI";
-
- if (filename == _currentTrack) {
- _isMusicPlaying = _isSfxPlaying = false;
- _fadeStartTime = 0;
- _fadeMusicOut = false;
- updateChannelVolume(_musicVolume);
- _musicParser->setTempo(0);
- _sfxParser->setTempo(0);
- _musicParser->property(MidiParser::mpAutoLoop, false);
- _sfxParser->property(MidiParser::mpAutoLoop, false);
- return;
- }
-
- uint32 size;
- uint8 *data = (_vm->resource())->fileData(filename.c_str(), &size);
-
- if (!data) {
- warning("Couldn't load soundfile '%s'", filename.c_str());
- return;
- }
-
- _currentTrack = filename;
-
- _musicParser->unloadMusic();
- _sfxParser->unloadMusic();
- _midiFile = Common::SharedPtr<byte>(data, DeleterArray());
-
- _isMusicPlaying = _isSfxPlaying = false;
- _fadeStartTime = 0;
- _fadeMusicOut = false;
- updateChannelVolume(_musicVolume);
-
- if (_musicParser->loadMusic(_midiFile.get(), size)) {
- _musicParser->setTimerRate(getBaseTempo());
- _musicParser->setTempo(0);
- _musicParser->property(MidiParser::mpAutoLoop, false);
- } else {
- warning("Error parsing music track '%s'", filename.c_str());
- }
-
- if (_sfxParser->loadMusic(_midiFile.get(), size)) {
- _sfxParser->setTimerRate(getBaseTempo());
- _sfxParser->setTempo(0);
- _sfxParser->property(MidiParser::mpAutoLoop, false);
- } else {
- warning("Error parsing sfx track '%s'", filename.c_str());
- }
-}
-
-void SoundMidiPC::onTimer(void *refCon) {
- SoundMidiPC *sound = (SoundMidiPC *)refCon;
- Common::StackLock lock(sound->_mutex);
-
- // this should be set to the fadeToBlack value
- static const uint32 musicFadeTime = 1 * 1000;
-
- if (sound->_fadeMusicOut) {
- if (sound->_fadeStartTime + musicFadeTime > sound->_vm->_system->getMillis()) {
- byte volume = (byte)((musicFadeTime - (sound->_vm->_system->getMillis() - sound->_fadeStartTime)) * sound->_musicVolume / musicFadeTime);
- sound->updateChannelVolume(volume);
- } else {
- sound->_fadeStartTime = 0;
- sound->_fadeMusicOut = false;
- sound->_isMusicPlaying = false;
-
- sound->_eventFromMusic = true;
- // from sound/midiparser.cpp
- for (int i = 0; i < 128; ++i) {
- for (int j = 0; j < 16; ++j) {
- sound->send(0x80 | j | i << 8);
- }
- }
-
- for (int i = 0; i < 16; ++i)
- sound->send(0x007BB0 | i);
- }
- }
-
- if (sound->_isMusicPlaying) {
- sound->_eventFromMusic = true;
- sound->_musicParser->onTimer();
- }
-
- if (sound->_isSfxPlaying) {
- sound->_eventFromMusic = false;
- sound->_sfxParser->onTimer();
- }
-}
-
-void SoundMidiPC::playTrack(uint8 track) {
- Common::StackLock lock(_mutex);
-
- if (_musicParser && (track != 0 || _nativeMT32) && _musicEnabled) {
- _isMusicPlaying = true;
- _fadeMusicOut = false;
- _fadeStartTime = 0;
- updateChannelVolume(_musicVolume);
- _musicParser->setTrack(track);
- _musicParser->jumpToTick(0);
- _musicParser->setTempo(1);
- _musicParser->property(MidiParser::mpAutoLoop, false);
- }
-}
-
-void SoundMidiPC::haltTrack() {
- Common::StackLock lock(_mutex);
-
- if (_musicParser) {
- _isMusicPlaying = false;
- _fadeMusicOut = false;
- _fadeStartTime = 0;
- updateChannelVolume(_musicVolume);
- _musicParser->setTrack(0);
- _musicParser->jumpToTick(0);
- _musicParser->setTempo(0);
- }
-}
-
-void SoundMidiPC::playSoundEffect(uint8 track) {
- Common::StackLock lock(_mutex);
-
- if (_sfxParser && _sfxEnabled) {
- _isSfxPlaying = true;
- _sfxParser->setTrack(track);
- _sfxParser->jumpToTick(0);
- _sfxParser->setTempo(1);
- _sfxParser->property(MidiParser::mpAutoLoop, false);
- }
-}
-
-void SoundMidiPC::beginFadeOut() {
- _fadeMusicOut = true;
- _fadeStartTime = _vm->_system->getMillis();
-}
-
-#pragma mark -
-
void KyraEngine_v1::snd_playTheme(int file, int track) {
debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine_v1::snd_playTheme(%d, %d)", file, track);
if (_curMusicTheme == file)