diff options
Diffstat (limited to 'engines/kyra/sound_intern.h')
-rw-r--r-- | engines/kyra/sound_intern.h | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/engines/kyra/sound_intern.h b/engines/kyra/sound_intern.h new file mode 100644 index 0000000000..cb33c66f47 --- /dev/null +++ b/engines/kyra/sound_intern.h @@ -0,0 +1,353 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef KYRA_SOUND_INTERN_H +#define KYRA_SOUND_INTERN_H + +#include "kyra/sound.h" + +#include "common/mutex.h" + +#include "sound/softsynth/ym2612.h" +#include "sound/softsynth/emumidi.h" +#include "sound/midiparser.h" + +namespace Audio { +class PCSpeaker; +} // end of namespace Audio + +namespace Kyra { +class AdlibDriver; + +/** + * AdLib implementation of the sound output device. + * + * It uses a special sound file format special to + * Dune II, Kyrandia 1 and 2. While Dune II and + * Kyrandia 1 are using exact the same format, the + * one of Kyrandia 2 slightly differs. + * + * See AdlibDriver for more information. + * @see AdlibDriver + */ +class SoundAdlibPC : public Sound { +public: + SoundAdlibPC(KyraEngine_v1 *vm, Audio::Mixer *mixer); + ~SoundAdlibPC(); + + kType getMusicType() const { return kAdlib; } + + bool init(); + void process(); + + void loadSoundFile(uint file); + void loadSoundFile(Common::String file); + + void playTrack(uint8 track); + void haltTrack(); + bool isPlaying(); + + void playSoundEffect(uint8 track); + + void beginFadeOut(); +private: + void internalLoadFile(Common::String file); + + void play(uint8 track); + + void unk1(); + void unk2(); + + AdlibDriver *_driver; + + bool _v2; + uint8 _trackEntries[500]; + uint8 *_soundDataPtr; + int _sfxPlayingSound; + + Common::String _soundFileLoaded; + + uint8 _sfxPriority; + uint8 _sfxFourthByteOfSong; + + int _numSoundTriggers; + const int *_soundTriggers; + + static const int _kyra1NumSoundTriggers; + static const int _kyra1SoundTriggers[]; +}; + +class MidiOutput; + +/** + * MIDI output device. + * + * This device supports both MT-32 MIDI, as used in + * Kyrandia 1 and 2, and GM MIDI, as used in Kyrandia 2. + */ +class SoundMidiPC : public Sound { +public: + SoundMidiPC(KyraEngine_v1 *vm, Audio::Mixer *mixer, MidiDriver *driver, kType type); + ~SoundMidiPC(); + + kType getMusicType() const { return _type; } + + bool init(); + + void updateVolumeSettings(); + + void loadSoundFile(uint file); + void loadSoundFile(Common::String file); + void loadSfxFile(Common::String file); + + void playTrack(uint8 track); + void haltTrack(); + bool isPlaying(); + + void playSoundEffect(uint8 track); + void stopAllSoundEffects(); + + void beginFadeOut(); +private: + static void onTimer(void *data); + + // Our channel handling + int _musicVolume, _sfxVolume; + + uint32 _fadeStartTime; + bool _fadeMusicOut; + + // Midi file related + Common::String _mFileName, _sFileName; + byte *_musicFile, *_sfxFile; + + MidiParser *_music; + MidiParser *_sfx[3]; + + // misc + kType _type; + Common::String getFileName(const Common::String &str); + + bool _nativeMT32; + MidiDriver *_driver; + MidiOutput *_output; + + Common::Mutex _mutex; +}; + +class Towns_EuphonyDriver; +class TownsPC98_OpnDriver; + +class SoundTowns : public MidiDriver, public Sound { +public: + SoundTowns(KyraEngine_v1 *vm, Audio::Mixer *mixer); + ~SoundTowns(); + + kType getMusicType() const { return kTowns; } + + bool init(); + void process(); + + void loadSoundFile(uint file); + void loadSoundFile(Common::String) {} + + void playTrack(uint8 track); + void haltTrack(); + + void playSoundEffect(uint8); + + void beginFadeOut(); + + //MidiDriver interface implementation + int open(); + void close(); + void send(uint32 b); + void metaEvent(byte type, byte *data, uint16 length) {} + + void setTimerCallback(void *timerParam, void (*timerProc)(void *)) { } + uint32 getBaseTempo(void); + + //Channel allocation functions + MidiChannel *allocateChannel() { return 0; } + MidiChannel *getPercussionChannel() { return 0; } + + static float calculatePhaseStep(int8 semiTone, int8 semiToneRootkey, + uint32 sampleRate, uint32 outputRate, int32 pitchWheel); + +private: + bool loadInstruments(); + void playEuphonyTrack(uint32 offset, int loop); + + static void onTimer(void *data); + + int _lastTrack; + Audio::AudioStream *_currentSFX; + Audio::SoundHandle _sfxHandle; + + uint _sfxFileIndex; + uint8 *_sfxFileData; + + Towns_EuphonyDriver * _driver; + MidiParser * _parser; + + Common::Mutex _mutex; + + const uint8 *_sfxBTTable; + const uint8 *_sfxWDTable; +}; + +class SoundPC98 : public Sound { +public: + SoundPC98(KyraEngine_v1 *vm, Audio::Mixer *mixer); + ~SoundPC98(); + + virtual kType getMusicType() const { return kPC98; } + + bool init(); + + void process() {} + void loadSoundFile(uint file) {} + void loadSoundFile(Common::String) {} + + void playTrack(uint8 track); + void haltTrack(); + void beginFadeOut(); + + int32 voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume, bool isSfx) { return -1; } + void playSoundEffect(uint8); + +protected: + int _lastTrack; + uint8 *_musicTrackData; + uint8 *_sfxTrackData; + TownsPC98_OpnDriver *_driver; +}; + +class SoundTownsPC98_v2 : public Sound { +public: + SoundTownsPC98_v2(KyraEngine_v1 *vm, Audio::Mixer *mixer); + ~SoundTownsPC98_v2(); + + kType getMusicType() const { return _vm->gameFlags().platform == Common::kPlatformFMTowns ? kTowns : kPC98; } + + bool init(); + void process(); + + void loadSoundFile(uint file) {} + void loadSoundFile(Common::String file); + + void playTrack(uint8 track); + void haltTrack(); + void beginFadeOut(); + + int32 voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume, bool isSfx); + void playSoundEffect(uint8 track); + +protected: + Audio::AudioStream *_currentSFX; + int _lastTrack; + bool _useFmSfx; + + uint8 *_musicTrackData; + uint8 *_sfxTrackData; + TownsPC98_OpnDriver *_driver; +}; + +// PC Speaker MIDI driver +class MidiDriver_PCSpeaker : public MidiDriver_Emulated { +public: + MidiDriver_PCSpeaker(Audio::Mixer *mixer); + ~MidiDriver_PCSpeaker(); + + // MidiDriver interface + void close() {} + + void send(uint32 data); + + MidiChannel *allocateChannel() { return 0; } + MidiChannel *getPercussionChannel() { return 0; } + + // MidiDriver_Emulated interface + void generateSamples(int16 *buffer, int numSamples); + + // AudioStream interface + bool isStereo() const { return false; } + int getRate() const { return _rate; } +private: + Common::Mutex _mutex; + Audio::PCSpeaker *_speaker; + int _rate; + + struct Channel { + uint8 volume; + uint8 pitchBendLow, pitchBendHigh; + uint8 expression; + uint8 hold; + uint8 modulation; + uint8 voiceProtect; + uint8 noteCount; + } _channel[16]; + + void resetController(int channel); + + struct Note { + bool enabled; + uint8 hardwareChannel; + uint8 midiChannel; + uint8 note1, note2; + uint8 velocity; + bool processHold; + uint8 flags; + uint8 hardwareFlags; + uint16 priority; + int16 modulation; + uint16 precedence; + } _note[2]; + + void noteOn(int channel, int note, int velocity); + void noteOff(int channel, int note); + + void turnNoteOn(int note); + void overwriteNote(int note); + void turnNoteOff(int note); + + void setupTone(int note); + + uint16 _countdown; + uint8 _hardwareChannel[1]; + bool _modulationFlag; + + uint8 _timerValue; + void onTimer(); + + static const uint8 _velocityTable[]; + static const uint8 _noteTable1[]; + static const uint8 _noteTable2[]; +}; + +} // end of namespace Kyra + +#endif + |