Ticket #8620: kyra_fmt_music.patch

File kyra_fmt_music.patch, 46.1 KB (added by athrxx, 17 years ago)

kyra fm-towns music patch

  • engines/kyra/gui.cpp

     
    3838        // Most settings already have sensible defaults. This one, however, is
    3939        // specific to the Kyra engine.
    4040        ConfMan.registerDefault("walkspeed", 2);
     41        ConfMan.registerDefault("cdaudio", _flags.platform == Common::kPlatformFMTowns);
    4142}
    4243
    4344void KyraEngine::readSettings() {
     
    5556                _configTextspeed = 2;   // Fast
    5657
    5758        _configWalkspeed = ConfMan.getInt("walkspeed");
    58         _configMusic = ConfMan.getBool("music_mute") ? 0 : 1;
     59        _configMusic = ConfMan.getBool("music_mute") ? 0 : (ConfMan.getBool("cdaudio") ? 2 : 1);       
    5960        _configSounds = ConfMan.getBool("sfx_mute") ? 0 : 1;
    6061
    6162        _sound->enableMusic(_configMusic);
     
    9697        ConfMan.setInt("talkspeed", talkspeed);
    9798        ConfMan.setInt("walkspeed", _configWalkspeed);
    9899        ConfMan.setBool("music_mute", _configMusic == 0);
     100        ConfMan.setBool("cdaudio", _configMusic & 2);
    99101        ConfMan.setBool("sfx_mute", _configSounds == 0);
    100102
    101103        switch (_configVoice) {
     
    563565        _textSpeedString = _guiStrings[25 + offsetOptions];
    564566        _onString =  _guiStrings[20 + offsetOn];
    565567        _offString =  _guiStrings[21 + offset];
     568        _onCDString = _guiStrings[21];
    566569}
    567570
    568571int KyraEngine::buttonMenuCallback(Button *caller) {
     
    12141217void KyraEngine::gui_setupControls(Menu &menu) {
    12151218        debugC(9, kDebugLevelGUI, "KyraEngine::gui_setupControls()");
    12161219
    1217         if (_configMusic)
    1218                 menu.item[0].itemString = _onString; //"On"
    1219         else
    1220                 menu.item[0].itemString = _offString; //"Off"
     1220        switch (_configMusic) {
     1221                case 0:
     1222                        menu.item[0].itemString = _offString; //"Off"
     1223                        break;
     1224                case 1:
     1225                        menu.item[0].itemString = _onString; //"On"
     1226                        break;
     1227                case 2:
     1228                        menu.item[0].itemString = _onCDString; //"On + CD"
     1229                        break;
     1230        }
    12211231
    12221232        if (_configSounds)
    12231233                menu.item[1].itemString = _onString; //"On"
     
    12991309        debugC(9, kDebugLevelGUI, "KyraEngine::gui_controlsChangeMusic()");
    13001310        processMenuButton(button);
    13011311
    1302         _configMusic = !_configMusic;
     1312        _configMusic = ++_configMusic % (_flags.platform == Common::kPlatformFMTowns ? 3 : 2);
    13031313        gui_setupControls(_menu[5]);
    13041314        return 0;
    13051315}
  • engines/kyra/sound.cpp

     
    3737
    3838Sound::Sound(KyraEngine *engine, Audio::Mixer *mixer)
    3939        : _engine(engine), _mixer(mixer), _currentVocFile(0), _vocHandle(), _compressHandle(),
    40         _musicEnabled(true), _sfxEnabled(true), _soundFileList(0), _soundFileListSize(0) {
     40        _musicEnabled(1), _sfxEnabled(true), _soundFileList(0), _soundFileListSize(0) {
    4141}
    4242
    4343Sound::~Sound() {
     
    450450
    451451void KyraEngine::snd_playSoundEffect(int track) {
    452452        debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine::snd_playSoundEffect(%d)", track);
    453         if (_flags.platform == Common::kPlatformFMTowns) {
    454                 if (track == 49) {
    455                         snd_playWanderScoreViaMap(56, 1);
    456                         return;
    457                 } else if (track == 0 || track == 1 || track == 10) {
    458                         // I don't know what's supposed to happen here, but calling playSoundEffect will lead to crash
    459                         return;
    460                 }
     453        if (_flags.platform == Common::kPlatformFMTowns && track == 49) {
     454                snd_playWanderScoreViaMap(56, 1);
     455                return;
    461456        }
    462457        _sound->playSoundEffect(track);
    463458}
  • engines/kyra/sound.h

     
    4141 *
    4242 */
    4343
    44 #ifndef KYRA_SOUND_H
    45 #define KYRA_SOUND_H
     44#ifndef SOUND_H
     45#define SOUND_H
    4646
    4747#include "common/stdafx.h"
    4848#include "common/scummsys.h"
    4949#include "common/file.h"
    5050#include "common/mutex.h"
    5151
    52 #include "sound/mididrv.h"
    5352#include "sound/midiparser.h"
    5453#include "sound/mixer.h"
     54#include "sound/softsynth/emumidi.h"
     55#include "sound/softsynth/ym2612.h"
    5556
    5657#include "kyra/kyra.h"
    5758
     
    8485
    8586        virtual void beginFadeOut() = 0;
    8687
    87         void enableMusic(bool enable) { _musicEnabled = enable; }
    88         bool musicEnabled() const { return _musicEnabled; }
     88        void enableMusic(int enable) { _musicEnabled = enable; }
     89        int musicEnabled() const { return _musicEnabled; }
    8990        void enableSFX(bool enable) { _sfxEnabled = enable; }
    9091        bool sfxEnabled() const { return _sfxEnabled; }
    9192
     
    9394        void voiceUnload() {}
    9495        bool voiceIsPlaying();
    9596        void voiceStop();
    96        
     97
    9798protected:
    9899        const char *soundFilename(uint file) { return (file < _soundFileListSize) ? _soundFileList[file] : ""; }
    99         bool _musicEnabled;
     100        int _musicEnabled;
    100101        bool _sfxEnabled;
    101102
    102103        KyraEngine *_engine;
     
    129130
    130131        void setVolume(int volume);
    131132        int getVolume();
    132        
     133
    133134        void loadSoundFile(uint file);
    134        
     135
    135136        void playTrack(uint8 track);
    136137        void haltTrack();
    137        
     138
    138139        void playSoundEffect(uint8 track);
    139        
     140
    140141        void beginFadeOut();
    141142private:
    142143        void play(uint8 track);
     
    231232        Common::Mutex _mutex;
    232233};
    233234
    234 class SoundTowns : public Sound {
     235class FMT_EuphonyDriver;
     236class SoundTowns : public MidiDriver, public Sound {
    235237public:
    236238        SoundTowns(KyraEngine *engine, Audio::Mixer *mixer);
    237239        ~SoundTowns();
     
    249251
    250252        void playSoundEffect(uint8);
    251253
    252         void beginFadeOut() { /* TODO */ }
     254        void beginFadeOut();
     255
     256        //MidiDriver interface implementation
     257        int open();
     258        void close();
     259        void send(uint32 b);
     260        void metaEvent(byte type, byte *data, uint16 length) {}
     261
     262        void setTimerCallback(void *timerParam, void (*timerProc)(void *)) { }
     263        uint32 getBaseTempo(void);
     264
     265        //Channel allocation functions
     266        MidiChannel *allocateChannel()          { return 0; }
     267        MidiChannel *getPercussionChannel()     { return 0; }
     268
     269        static float semitoneAndSampleRate_to_sampleStep(int8 semiTone, int8 semiToneRootkey,
     270                uint32 sampleRate, uint32 outputRate, int32 pitchWheel);
    253271private:
    254         void stopSoundEffect();
    255         void setPitch(uint8 *&data, uint32 &size, int8 sourcePitch, int8 targetPitch);
     272        bool loadInstruments();
     273        void playEuphonyTrack(uint32 offset, int loop);
    256274
     275        static void onTimer(void *data);
     276
    257277        int _lastTrack;
    258278        Audio::AudioStream *_currentSFX;
    259279        Audio::SoundHandle _sfxHandle;
    260         int _currentTrackTable;
    261         bool _sfxIsPlaying;
     280
     281    int _currentTrackTable;
    262282        uint _sfxFileIndex;
    263283        uint8 *_sfxFileData;
    264284
     285        FMT_EuphonyDriver * _driver;
     286        MidiParser * _parser;
     287        uint8 *_musicTrackData;
     288
     289        Common::Mutex _mutex;
     290
    265291        static const char *_sfxFiles[];
    266292        static const int _sfxFilenum;
    267293        static const uint8 _sfxBTTable[256];
    268         const uint8 *_sfxWDTable;       
     294        const uint8 *_sfxWDTable;
    269295};
    270296
    271297class MixedSoundDriver : public Sound {
     
    300326        ~SoundDigital();
    301327
    302328        bool init();
    303        
     329
    304330        int playSound(Common::File *fileHandle, bool loop = false, bool fadeIn = false, int channel = -1);
    305331        bool isPlaying(int channel);
    306332        void stopSound(int channel);
  • engines/kyra/sound_towns.cpp

     
    2929#include "sound/audiocd.h"
    3030#include "sound/audiostream.h"
    3131
     32#include "common/util.h"
     33#include <math.h>
     34
    3235namespace Kyra {
    3336
     37enum EuD_ChannelState { _s_ready, _s_attacking, _s_decaying, _s_sustaining, _s_releasing };
     38
     39class MidiChannel_EuD : public MidiChannel {
     40public:
     41        MidiChannel_EuD() {}
     42        ~MidiChannel_EuD() {}
     43
     44        virtual void nextTick(int32 *outbuf, int buflen) = 0;
     45        virtual void rate(uint16 r) = 0;
     46
     47protected:
     48        uint16 _rate;
     49};
     50
     51class MidiChannel_EuD_FM : public MidiChannel_EuD {
     52public:
     53        MidiChannel_EuD_FM();
     54        virtual ~MidiChannel_EuD_FM();
     55
     56        void nextTick(int32 *outbuf, int buflen);
     57        void rate(uint16 r);
     58
     59        // MidiChannel interface
     60        MidiDriver *device() { return 0; }
     61        byte getNumber() { return 0; }
     62        void release() { }
     63        void send(uint32 b) { }
     64        void noteOff(byte note);
     65        void noteOn(byte note, byte onVelo);
     66        void programChange(byte program) {}
     67        void pitchBend(int16 value);
     68        void controlChange(byte control, byte value);
     69        void pitchBendFactor(byte value) { }
     70        void sysEx_customInstrument(uint32 unused, const byte *instr);
     71
     72protected:
     73        Voice2612 *_voice;
     74};
     75
     76class MidiChannel_EuD_WAVE : public MidiChannel_EuD {
     77public:
     78        void nextTick(int32 *outbuf, int buflen);
     79        void rate(uint16 r);
     80
     81        MidiChannel_EuD_WAVE();
     82        virtual ~MidiChannel_EuD_WAVE();
     83
     84        // MidiChannel interface
     85        MidiDriver *device() { return 0; }
     86        byte getNumber() { return 0; }
     87        void release() { }
     88        void send(uint32 b) { }
     89        void noteOff(byte note);
     90        void noteOn(byte note, byte onVelo);
     91        void programChange(byte program) {}
     92        void pitchBend(int16 value);
     93        void controlChange(byte control, byte value);
     94        void pitchBendFactor(byte value) { }
     95        void sysEx_customInstrument(uint32 type, const byte *instr);
     96
     97protected:
     98        void velocity(int velo);
     99        void panPosition(int8 pan);
     100        void evpNextTick();
     101
     102        int _ctrl7_volume;
     103        int16 _velocity;
     104        int16 _note;
     105        int32 _frequencyOffs;
     106        float _phase;
     107        int8 _current;
     108
     109        struct Voice {
     110                char name[9];
     111                uint16 split[8];
     112                uint32 id[8];
     113                struct Snd {
     114                        char name[9];
     115                        int32 id;
     116                        int32 numSamples;
     117                        int32 loopStart;
     118                        int32 loopLength;
     119                        int32 samplingRate;
     120                        int32 keyOffset;
     121                        int32 keyNote;
     122                        int8 *_samples;
     123                } * _snd[8];
     124                struct Env {
     125                        EuD_ChannelState state;
     126                        int32 currentLevel;
     127                        int32 rate;
     128                        int32 tickCount;
     129                        int32 totalLevel;
     130                        int32 attackRate;
     131                        int32 decayRate;
     132                        int32 sustainLevel;
     133                        int32 sustainRate;
     134                        int32 releaseLevel;
     135                        int32 releaseRate;
     136                        int32 rootKeyOffset;
     137                        int32 size;
     138                } * _env[8];
     139        } * _voice;
     140};
     141
     142class MidiParser_EuD : public MidiParser {
     143public:
     144        MidiParser_EuD::MidiParser_EuD();
     145        MidiParser_EuD::~MidiParser_EuD() {}
     146
     147        bool loadMusic (byte *data, uint32 unused = 0);
     148        void setTempo(uint32 tempo);
     149
     150protected:
     151        void parseNextEvent (EventInfo &info);
     152        void resetTracking();
     153
     154        byte * _enable;
     155        byte * _mode;
     156        byte * _channel;
     157        byte * _adjVelo;
     158        int8 * _adjNote;
     159
     160        uint8 _firstBaseTickStep;
     161        uint8 _nextBaseTickStep;
     162        uint8 _initialTempo;
     163        uint32 _baseTick;
     164};
     165
     166class FMT_EuphonyDriver : public MidiDriver_Emulated {
     167public:
     168        FMT_EuphonyDriver(Audio::Mixer *mixer);
     169        virtual ~FMT_EuphonyDriver();
     170
     171        int open();
     172        void close();
     173        void send(uint32 b);
     174        void send(byte channel, uint32 b);
     175        uint32 property(int prop, uint32 param) { return 0; }
     176
     177        void setPitchBendRange(byte channel, uint range) { }
     178        //void sysEx(const byte *msg, uint16 length);
     179        void loadFmInstruments(const byte *instr);
     180        void loadWaveInstruments(const byte *instr);
     181
     182        MidiChannel *allocateChannel() { return 0; }
     183        MidiChannel *getPercussionChannel() { return 0; }
     184
     185        void assignFmChannel(uint8 midiChannelNumber, uint8 fmChannelNumber);
     186        void assignWaveChannel(uint8 midiChannelNumber, uint8 waveChannelNumber);
     187        void removeChannel(uint8 midiChannelNumber);
     188
     189        // AudioStream API
     190        bool isStereo() const { return true; }
     191        int getRate() const { return _mixer->getOutputRate(); }
     192
     193protected:
     194        void nextTick(int16 *buf1, int buflen);
     195        int volume(int val = -1) { if (val >= 0) _volume = val; return _volume; }
     196        void rate(uint16 r);
     197
     198        void generateSamples(int16 *buf, int len);
     199
     200        MidiChannel_EuD_FM *_fChannel[6];
     201        MidiChannel_EuD_WAVE *_wChannel[8];
     202        MidiChannel_EuD * _channel[16];
     203
     204        int _volume;
     205
     206        uint8 *_fmInstruments;
     207        uint8 *_waveInstruments;
     208        int8 * _waveSounds[10];
     209};
     210
     211MidiChannel_EuD_FM::MidiChannel_EuD_FM() {
     212        _voice = new Voice2612;
     213}
     214
     215MidiChannel_EuD_FM::~MidiChannel_EuD_FM() {
     216        delete _voice;
     217}
     218
     219void MidiChannel_EuD_FM::noteOn(byte note, byte onVelo) {
     220        _voice->noteOn(note, onVelo);
     221}
     222
     223void MidiChannel_EuD_FM::noteOff(byte note) {
     224        _voice->noteOff(note);
     225}
     226
     227void MidiChannel_EuD_FM::controlChange(byte control, byte value) {
     228        if (control == 121) {
     229                // Reset controller
     230                delete _voice;
     231                _voice = new Voice2612;
     232        } else if (control == 10) {
     233                // pan position
     234        } else {
     235                _voice->setControlParameter(control, value);
     236        }
     237}
     238
     239void MidiChannel_EuD_FM::sysEx_customInstrument(uint32, const byte *fmInst) {
     240        _voice->_rate = _rate;
     241        _voice->setInstrument(fmInst);
     242}
     243
     244void MidiChannel_EuD_FM::pitchBend(int16 value) {
     245        _voice->pitchBend(value);
     246}
     247
     248void MidiChannel_EuD_FM::nextTick(int32 *outbuf, int buflen) {
     249        _voice->nextTick((int*) outbuf, buflen);
     250}
     251
     252void MidiChannel_EuD_FM::rate(uint16 r) {
     253        _rate = r;
     254        _voice->_rate = r;
     255}
     256
     257MidiChannel_EuD_WAVE::MidiChannel_EuD_WAVE() {
     258        _voice = new Voice;
     259        for (uint8 i = 0; i < 8; i++) {
     260                _voice->_env[i] = new Voice::Env;
     261                _voice->_snd[i] = 0;
     262        }
     263
     264        int _buflen = 0;
     265        _ctrl7_volume = 127;
     266        velocity(0);
     267        _frequencyOffs = 0x2000;
     268        _current = -1;
     269}
     270
     271MidiChannel_EuD_WAVE::~MidiChannel_EuD_WAVE() {
     272        for (uint8 i = 0; i < 8; i++) {
     273                if (_voice->_snd[i])
     274                        delete _voice->_snd[i];
     275                delete _voice->_env[i];
     276        }
     277        delete _voice;
     278}
     279
     280void MidiChannel_EuD_WAVE::noteOn(byte note, byte onVelo) {
     281        _note = note;
     282        velocity(onVelo);
     283        _phase = 0;
     284
     285        for (_current = 0; _current < 7; _current++) {
     286                if (note <=     _voice->split[_current])
     287                        break;
     288        }
     289
     290        _voice->_env[_current]->state = _s_attacking;
     291        _voice->_env[_current]->currentLevel = 0;
     292        _voice->_env[_current]->rate = _rate;
     293        _voice->_env[_current]->tickCount = 0;
     294}
     295
     296void MidiChannel_EuD_WAVE::noteOff(byte note) {
     297    if (_current == -1)
     298                return;
     299        if (_voice->_env[_current]->state == _s_ready)
     300                return;
     301
     302        _voice->_env[_current]->state = _s_releasing;
     303        _voice->_env[_current]->releaseLevel = _voice->_env[_current]->currentLevel;
     304        _voice->_env[_current]->tickCount = 0;
     305}
     306
     307void MidiChannel_EuD_WAVE::controlChange(byte control, byte value) {
     308        switch (control) {
     309                case 0x07:
     310                        // volume
     311                        _ctrl7_volume = value;
     312                        break;
     313                case 0x0A:
     314                        // pan position
     315                        break;
     316                case 0x79:
     317                // Reset controller
     318                        for (uint8 i = 0; i < 8; i++) {
     319                                if (_voice->_snd[i])
     320                                        delete _voice->_snd[i];
     321                                delete _voice->_env[i];
     322                        }
     323                        delete _voice;
     324                        _voice = new Voice;
     325                        for (uint8 i = 0; i < 8; i++) {
     326                                _voice->_env[i] = new Voice::Env;
     327                                _voice->_snd[i] = 0;
     328                        }
     329                        break;
     330                case 0x7B:
     331                        noteOff(_note);
     332                        break;
     333                default:
     334                        break;
     335        }
     336}
     337
     338void MidiChannel_EuD_WAVE::sysEx_customInstrument(uint32 type, const byte *fmInst) {
     339        if (type == 0x80) {
     340                for (uint8 i = 0; i < 8; i++) {
     341                        byte ** pos = (byte **) fmInst;
     342                        for (uint8 ii = 0; ii < 10; ii++) {
     343                                if (_voice->id[i] == *(pos[ii] + 8)) {
     344                                        if (!_voice->_snd[i])
     345                                                _voice->_snd[i] = new Voice::Snd;
     346                                        memset (_voice->_snd[i]->name, 0, 9);
     347                                        memcpy (_voice->_snd[i]->name, (const char*) pos[ii], 8);
     348                                        _voice->_snd[i]->id = READ_LE_UINT32(pos[ii] + 8);
     349                                        _voice->_snd[i]->numSamples = READ_LE_UINT32(pos[ii] + 12);
     350                                        _voice->_snd[i]->loopStart = READ_LE_UINT32(pos[ii] + 16);
     351                                        _voice->_snd[i]->loopLength = READ_LE_UINT32(pos[ii] + 20);
     352                                        _voice->_snd[i]->samplingRate = READ_LE_UINT16(pos[ii] + 24);
     353                                        _voice->_snd[i]->keyOffset = READ_LE_UINT16(pos[ii] + 26);
     354                                        _voice->_snd[i]->keyNote = *(uint8*)(pos[ii] + 28);
     355                                        _voice->_snd[i]->_samples = (int8*) (pos[ii] + 32);
     356                                }
     357                        }
     358                }
     359        } else {
     360                memset (_voice->name, 0, 9);
     361                memcpy (_voice->name, (const char*) fmInst, 8);
     362
     363                for (uint8 i = 0; i < 8; i++) {
     364                        _voice->split[i] = READ_LE_UINT16(fmInst + 16 + 2 * i);
     365                        _voice->id[i] = READ_LE_UINT32(fmInst + 32 + 4 * i);
     366                        _voice->_snd[i] = 0;
     367                        _voice->_env[i]->state = _s_ready;
     368                        _voice->_env[i]->currentLevel = 0;
     369                        _voice->_env[i]->totalLevel = *(uint8*)(fmInst + 64 + 8 * i);
     370                        _voice->_env[i]->attackRate = *(uint8*)(fmInst + 65 + 8 * i) * 10;
     371                        _voice->_env[i]->decayRate = *(uint8*)(fmInst + 66 + 8 * i) * 10;
     372                        _voice->_env[i]->sustainLevel = *(uint8*)(fmInst + 67 + 8 * i);
     373                        _voice->_env[i]->sustainRate = *(uint8*)(fmInst + 68 + 8 * i) * 20;
     374                        _voice->_env[i]->releaseRate = *(uint8*)(fmInst + 69 + 8 * i) * 10;
     375                        _voice->_env[i]->rootKeyOffset = *(int8*)(fmInst + 70 + 8 * i);
     376                }
     377        }
     378}
     379
     380void MidiChannel_EuD_WAVE::pitchBend(int16 value) {
     381        _frequencyOffs = value;
     382}
     383
     384void MidiChannel_EuD_WAVE::nextTick(int32 *outbuf, int buflen) {
     385        if (_current == -1 || !_voice->_snd[_current] || !_voice->_env[_current]->state || !_velocity) {
     386                velocity(0);
     387                _current = -1;
     388                return;
     389        }
     390
     391        float phaseStep = SoundTowns::semitoneAndSampleRate_to_sampleStep(_note, _voice->_snd[_current]->keyNote -
     392                _voice->_env[_current]->rootKeyOffset, _voice->_snd[_current]->samplingRate, _rate, _frequencyOffs);
     393
     394        int32 looplength = _voice->_snd[_current]->loopLength;
     395        int32 numsamples = _voice->_snd[_current]->numSamples;
     396        int8 * samples = _voice->_snd[_current]->_samples;
     397
     398        for (int i = 0; i < buflen; i++) {
     399                if (looplength > 0) {
     400                        while (_phase >= numsamples)
     401                                _phase -= looplength;
     402                } else {
     403                        if (_phase >= numsamples) {
     404                                velocity(0);
     405                                _current = -1;
     406                                break;
     407                        }
     408                }
     409
     410                int32 output;
     411
     412                int32 phase0 = _phase;
     413                int32 phase1 = _phase + 1;
     414                if (phase1 >= numsamples)
     415                        phase1 -= looplength;
     416                float weight0 = _phase - phase0;
     417                float weight1 = phase1 - _phase;
     418                output = samples[phase0] * weight0 + samples[phase1] * weight1;
     419
     420                output *= _velocity;
     421                output <<= 1;
     422
     423                evpNextTick();
     424                output *= _voice->_env[_current]->currentLevel;
     425                output >>= 7;
     426                output *= _ctrl7_volume;
     427                output >>= 7;
     428
     429                output *= 185;
     430                output >>= 8;
     431                outbuf[i] += output;
     432                _phase += phaseStep;
     433        }
     434}
     435
     436void MidiChannel_EuD_WAVE::evpNextTick() {
     437        switch (_voice->_env[_current]->state) {
     438                case _s_ready:
     439                        _voice->_env[_current]->currentLevel = 0;
     440                        return;
     441
     442                case _s_attacking:
     443                        if (_voice->_env[_current]->attackRate == 0)
     444                                _voice->_env[_current]->currentLevel = _voice->_env[_current]->totalLevel;
     445                        else if (_voice->_env[_current]->attackRate >= 1270)
     446                                _voice->_env[_current]->currentLevel = 0;
     447                        else
     448                                _voice->_env[_current]->currentLevel = (_voice->_env[_current]->totalLevel *
     449                                        _voice->_env[_current]->tickCount++ * 1000) /
     450                                                (_voice->_env[_current]->attackRate * _voice->_env[_current]->rate);
     451
     452                        if (_voice->_env[_current]->currentLevel >= _voice->_env[_current]->totalLevel) {
     453                                _voice->_env[_current]->currentLevel = _voice->_env[_current]->totalLevel;
     454                                _voice->_env[_current]->state = _s_decaying;
     455                                _voice->_env[_current]->tickCount = 0;
     456                        }
     457                        break;
     458
     459                case _s_decaying:
     460                        if (_voice->_env[_current]->decayRate == 0)
     461                                _voice->_env[_current]->currentLevel = _voice->_env[_current]->sustainLevel;
     462                        else if (_voice->_env[_current]->decayRate >= 1270)
     463                                _voice->_env[_current]->currentLevel = _voice->_env[_current]->totalLevel;
     464                        else {
     465                                _voice->_env[_current]->currentLevel = _voice->_env[_current]->totalLevel;
     466                                _voice->_env[_current]->currentLevel -= ((_voice->_env[_current]->totalLevel -
     467                                        _voice->_env[_current]->sustainLevel) * _voice->_env[_current]->tickCount++ * 1000) /
     468                                                (_voice->_env[_current]->decayRate * _voice->_env[_current]->rate);
     469                        }
     470
     471                        if (_voice->_env[_current]->currentLevel <= _voice->_env[_current]->sustainLevel) {
     472                                _voice->_env[_current]->currentLevel = _voice->_env[_current]->sustainLevel;
     473                                _voice->_env[_current]->state = _s_sustaining;
     474                                _voice->_env[_current]->tickCount = 0;
     475                        }
     476                        break;
     477
     478                        case _s_sustaining:
     479                                if (_voice->_env[_current]->sustainRate == 0)
     480                                        _voice->_env[_current]->currentLevel = 0;
     481                                else if (_voice->_env[_current]->sustainRate >= 2540)
     482                                        _voice->_env[_current]->currentLevel = _voice->_env[_current]->sustainLevel;
     483                                else {
     484                                        _voice->_env[_current]->currentLevel = _voice->_env[_current]->sustainLevel;
     485                                        _voice->_env[_current]->currentLevel -= (_voice->_env[_current]->sustainLevel *
     486                                                _voice->_env[_current]->tickCount++ * 1000) / (_voice->_env[_current]->sustainRate *
     487                                                        _voice->_env[_current]->rate);
     488                                }
     489
     490                                if (_voice->_env[_current]->currentLevel <= 0) {
     491                                        _voice->_env[_current]->currentLevel = 0;
     492                                        _voice->_env[_current]->state = _s_ready;
     493                                        _voice->_env[_current]->tickCount = 0;
     494                                }
     495                                break;
     496
     497                        case _s_releasing:
     498                                if (_voice->_env[_current]->releaseRate == 0)
     499                                        _voice->_env[_current]->currentLevel = 0;
     500                                else if (_voice->_env[_current]->releaseRate >= 1270)
     501                                        _voice->_env[_current]->currentLevel = _voice->_env[_current]->releaseLevel;
     502                                else {
     503                                        _voice->_env[_current]->currentLevel = _voice->_env[_current]->releaseLevel;
     504                                        _voice->_env[_current]->currentLevel -= (_voice->_env[_current]->releaseLevel *
     505                                                _voice->_env[_current]->tickCount++ * 1000) / (_voice->_env[_current]->releaseRate *
     506                                                        _voice->_env[_current]->rate);
     507                                }
     508
     509                                if (_voice->_env[_current]->currentLevel <= 0) {
     510                                        _voice->_env[_current]->currentLevel = 0;
     511                                        _voice->_env[_current]->state = _s_ready;
     512                                }
     513                                break;
     514
     515                        default:
     516                        break;
     517        }
     518}
     519
     520void MidiChannel_EuD_WAVE::rate(uint16 r) {
     521        _rate = r;
     522}
     523
     524void MidiChannel_EuD_WAVE::velocity(int velo) {
     525        _velocity = velo;
     526}
     527
     528FMT_EuphonyDriver::FMT_EuphonyDriver(Audio::Mixer *mixer)
     529        : MidiDriver_Emulated(mixer) {
     530
     531        MidiDriver_YM2612::createLookupTables();
     532
     533        _volume = 255;
     534        for (uint8 i = 0; i < 6; i++)
     535                _channel[i] = _fChannel[i] = new MidiChannel_EuD_FM;
     536        for (uint8 i = 0; i < 8; i++)
     537                _channel[i + 6] = _wChannel[i] = new MidiChannel_EuD_WAVE;
     538        _channel[14] = _channel[15] = 0;
     539
     540        _fmInstruments = _waveInstruments = 0;
     541        memset(_waveSounds, 0, sizeof(uint8*) * 10);
     542
     543        rate(getRate());
     544}
     545
     546FMT_EuphonyDriver::~FMT_EuphonyDriver() {
     547        uint8 i;
     548        for (i = 0; i < 6; i++)
     549                delete _fChannel[i];
     550        for (i = 0; i < 8; i++)
     551                delete _wChannel[i];
     552
     553        MidiDriver_YM2612::removeLookupTables();
     554
     555        if (_fmInstruments) {
     556                delete [] _fmInstruments;
     557                _fmInstruments = 0;
     558        }
     559        if (_waveInstruments) {
     560                delete [] _waveInstruments;
     561                _waveInstruments = 0;
     562        }
     563        for (int i = 0; i < 10; i++) {
     564                if (_waveSounds[i]) {
     565                        delete [] _waveSounds[i];
     566                        _waveSounds[i] = 0;
     567                }
     568        }
     569}
     570
     571int FMT_EuphonyDriver::open() {
     572        if (_isOpen)
     573                return MERR_ALREADY_OPEN;
     574
     575        MidiDriver_Emulated::open();
     576
     577        _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_mixerSoundHandle,
     578                this, -1, Audio::Mixer::kMaxChannelVolume, 0, false, true);
     579        return 0;
     580}
     581
     582void FMT_EuphonyDriver::close() {
     583        if (!_isOpen)
     584                return;
     585        _isOpen = false;
     586        _mixer->stopHandle(_mixerSoundHandle);
     587}
     588
     589void FMT_EuphonyDriver::send(uint32 b) {
     590        send(b & 0xF, b & 0xFFFFFFF0);
     591}
     592
     593void FMT_EuphonyDriver::send(byte chan, uint32 b) {
     594        //byte param3 = (byte) ((b >> 24) & 0xFF);
     595
     596        byte param2 = (byte) ((b >> 16) & 0xFF);
     597        byte param1 = (byte) ((b >>  8) & 0xFF);
     598        byte cmd    = (byte) (b & 0xF0);
     599        if (chan > ARRAYSIZE(_channel))
     600                return;
     601
     602        switch (cmd) {
     603        case 0x80:// Note Off
     604                if (_channel[chan])
     605                        _channel[chan]->noteOff(param1);
     606                break;
     607        case 0x90: // Note On
     608                if (_channel[chan])
     609                        _channel[chan]->noteOn(param1, param2);
     610                break;
     611        case 0xA0: // Aftertouch
     612                break; // Not supported.
     613        case 0xB0: // Control Change
     614                if (param1 == 0x79) {
     615                        for (int i = 0; i < 15; i++) {
     616                                if (_channel[i]) {
     617                                        _channel[i]->controlChange(param1, param2);
     618                                        _channel[i]->programChange(0);
     619                                }
     620                        }
     621                } else if (param1 == 0x7B) {
     622                        for (int i = 0; i < 15; i++) {
     623                                if (_channel[i])
     624                                        _channel[i]->controlChange(param1, param2);
     625                        }
     626                } else {
     627                        if (_channel[chan])
     628                                _channel[chan]->controlChange(param1, param2);
     629                }
     630                break;
     631        case 0xC0: // Program Change
     632        for (int i = 0; i < 6; i++) {
     633                        if (_channel[chan] == _fChannel[i]) {
     634                                _channel[chan]->sysEx_customInstrument(0, _fmInstruments + param1 * 0x30);
     635                                break;
     636                        }
     637                }
     638                for (int i = 0; i < 8; i++) {
     639                        if (_channel[chan] == _wChannel[i]) {
     640                                _channel[chan]->sysEx_customInstrument(0, _waveInstruments + param1 * 0x80);
     641                                _channel[chan]->sysEx_customInstrument(0x80, (const byte*) _waveSounds);
     642                                break;
     643                        }
     644                }
     645                break;
     646        case 0xD0: // Channel Pressure
     647                break; // Not supported.
     648        case 0xE0: // Pitch Bend
     649                if (_channel[chan])
     650                        _channel[chan]->pitchBend((param1 | (param2 << 7)) - 0x2000);
     651                break;
     652        default:
     653                warning("FMT_EuphonyDriver: Unknown send() command 0x%02X", cmd);
     654        }
     655}
     656
     657void FMT_EuphonyDriver::loadFmInstruments(const byte *instr) {
     658        if (_fmInstruments)
     659                delete [] _fmInstruments;
     660        _fmInstruments = new uint8[0x1800];
     661        memcpy(_fmInstruments, instr, 0x1800);
     662}
     663
     664void FMT_EuphonyDriver::loadWaveInstruments(const byte *instr) {
     665        if (_waveInstruments)
     666                delete [] _waveInstruments;
     667        _waveInstruments = new uint8[0x1000];
     668        memcpy(_waveInstruments, instr, 0x1000);
     669
     670        uint8 * pos = (uint8 *)(instr + 0x1000);
     671
     672        for (uint8 i = 0; i < 10; i++) {
     673                if (_waveSounds[i])
     674                        delete [] _waveSounds[i];
     675                uint32 numsamples = READ_LE_UINT32(pos + 0x0C);
     676                _waveSounds[i] = new int8[numsamples + 0x20];
     677        memcpy(_waveSounds[i], pos, 0x20);
     678                pos += 0x20;
     679                for (uint32 ii = 0; ii < numsamples; ii++) {
     680                        uint8 s = *(uint8*)(pos + ii);
     681                        s = (s < 0x80) ? 0x80 - s : s;
     682                        _waveSounds[i][ii + 0x20] = s ^ 0x80;
     683                }
     684                pos += numsamples;
     685        }
     686}
     687
     688
     689void FMT_EuphonyDriver::assignFmChannel(uint8 midiChannelNumber, uint8 fmChannelNumber) {
     690        _channel[midiChannelNumber] = _fChannel[fmChannelNumber];
     691}
     692
     693void FMT_EuphonyDriver::assignWaveChannel(uint8 midiChannelNumber, uint8 waveChannelNumber) {
     694        _channel[midiChannelNumber] = _wChannel[waveChannelNumber];
     695}
     696
     697void FMT_EuphonyDriver::removeChannel(uint8 midiChannelNumber) {
     698        _channel[midiChannelNumber] = 0;
     699}
     700
     701void FMT_EuphonyDriver::generateSamples(int16 *data, int len) {
     702        memset(data, 0, 2 * sizeof(int16) * len);
     703        nextTick(data, len);
     704}
     705
     706void FMT_EuphonyDriver::nextTick(int16 *buf1, int buflen) {
     707        int32 *buf0 = (int32 *)buf1;
     708
     709        for (int i = 0; i < ARRAYSIZE(_channel); i++) {
     710                if (_channel[i])
     711                        _channel[i]->nextTick(buf0, buflen);
     712        }
     713
     714        for (int i = 0; i < buflen; ++i) {
     715                buf1[i*2] = buf1[i*2+1] =((buf0[i] * volume()) >> 9) & 0xffff;
     716        }
     717}
     718
     719void FMT_EuphonyDriver::rate(uint16 r)
     720{
     721        for (uint8 i = 0; i < 16; i++) {
     722                if (_channel[i])
     723                        _channel[i]->rate(r);
     724        }
     725}
     726
     727MidiParser_EuD::MidiParser_EuD() : MidiParser() {
     728}
     729
     730void MidiParser_EuD::parseNextEvent (EventInfo &info) {
     731        byte *pos = _position._play_pos;
     732
     733        while (true) {
     734                byte cmd = *pos;
     735                byte evt = (cmd & 0xF0);
     736
     737                if (evt == 0x90) {
     738                        byte chan = pos[1];
     739
     740                        if (_enable[chan]) {
     741                                uint16 tick = (pos[2] | ((uint16) pos[3] << 7)) + _baseTick;
     742                                info.start = pos + 6;
     743                                uint32 last = _position._last_event_tick;
     744                                info.delta = (tick < last) ? 0 : (tick - last);
     745
     746                                info.event = 0x90 | _channel[chan];
     747                                info.length = pos[7] | (pos[8] << 4);
     748
     749                                int8 note = (int8) pos[4];
     750                                if (_adjNote[chan]) {
     751                                        note = (note & 0x7f) & _adjNote[chan];
     752                                        if (note > 0x7c)
     753                                                note -= 0x0c;
     754                                        else if (note < 0)
     755                                                note += 0x0c;
     756                                }
     757                                info.basic.param1 = (byte) note;
     758
     759                                uint8 onVelo = (pos[5] & 0x7f) + _adjVelo[chan];
     760                                if (onVelo > 0x7f)
     761                                        onVelo = 0x7f;
     762                                if (onVelo < 1)
     763                                        onVelo = 1;
     764                                info.basic.param2 = onVelo;
     765
     766                                pos += 12;
     767                                break;
     768                        } else {
     769                                pos += 6;
     770                        }
     771                } else if (evt == 0xB0 || evt == 0xC0 || evt == 0xe0) {
     772                        byte chan = pos[1];
     773
     774                        if (_enable[chan]) {
     775                                info.start = pos;
     776                                uint16 tick = (pos[2] | ((uint16) pos[3] << 7)) + _baseTick;
     777                                uint32 last = _position._last_event_tick;
     778                                info.delta = (tick < last) ? 0 : (tick - last);
     779                                info.event = evt | _channel[chan];
     780                                info.length = 0;
     781                                info.basic.param1 = pos[4];
     782                                info.basic.param2 = pos[5];
     783                                pos += 6;
     784                                break;
     785                        } else {
     786                                pos += 6;
     787                        }
     788                } else if (cmd == 0xF2) {
     789                        static uint16 tickTable [] = { 0x180, 0xC0, 0x80, 0x60, 0x40, 0x30, 0x20, 0x18 };
     790                        _baseTick += tickTable[_nextBaseTickStep >> 4] * ((_nextBaseTickStep & 0x0f) + 1);
     791                        _nextBaseTickStep = pos[1];
     792                        pos += 6;
     793                } else if (cmd == 0xF8) {
     794                        uint16 tempo = pos[4] | (pos[5] << 7);
     795                        setTempo (tempo);
     796                        pos += 6;
     797                } else if (cmd == 0xFD || cmd == 0xFE) {
     798                        // End of track.
     799                        if (_autoLoop)
     800                                pos = info.start = _tracks[0];
     801                        else
     802                                info.start = pos;
     803
     804                        uint32 last = _position._last_event_tick;
     805                        uint16 tick = (pos[2] | ((uint16) pos[3] << 7)) + _baseTick;
     806                        info.delta = (tick < last) ? 0 : (tick - last);
     807                        info.event = 0xFF;
     808                        info.ext.type = 0x2F;
     809                        info.ext.data = pos;
     810                        break;
     811                } else {
     812                        error("Unknown Euphony music event 0x%02X", (int) cmd);
     813                        memset(&info, 0, sizeof(info));
     814                        pos = 0;
     815                        break;
     816                }
     817        }
     818        _position._play_pos = pos;
     819}
     820
     821bool MidiParser_EuD::loadMusic (byte *data, uint32) {
     822        unloadMusic();
     823
     824        _enable = data + 0x354;
     825        _mode = data + 0x374;
     826        _channel = data + 0x394;
     827        _adjVelo = data + 0x3B4;
     828        _adjNote = (int8*) data + 0x3D4;
     829
     830        _firstBaseTickStep = data[0x804];
     831        _initialTempo = (data[0x805] > 0xfc) ? 0x5a : data[0x805];
     832
     833        _num_tracks = 1;
     834        _ppqn = 120;
     835        _tracks[0] = data + 0x806;
     836
     837        resetTracking();
     838        setTrack (0);
     839
     840        return true;
     841}
     842
     843void MidiParser_EuD::setTempo(uint32 tempo) {
     844        MidiParser::setTempo(60000000 / tempo);
     845}
     846
     847void MidiParser_EuD::resetTracking() {
     848        MidiParser::resetTracking();
     849
     850        _nextBaseTickStep = _firstBaseTickStep;
     851        _baseTick = 0;
     852        setTempo (_initialTempo);
     853}
     854
    34855SoundTowns::SoundTowns(KyraEngine *engine, Audio::Mixer *mixer) : Sound(engine, mixer), _lastTrack(-1),
    35         _currentSFX(0), _sfxFileData(0), _sfxFileIndex((uint)-1), _sfxWDTable(0) {
     856         _currentSFX(0), _sfxFileData(0), _sfxFileIndex((uint)-1), _sfxWDTable(0), _parser(0), _musicTrackData(0) {
     857
     858        _driver = new FMT_EuphonyDriver(_mixer);
     859        int ret = open();
     860        if (ret != MERR_ALREADY_OPEN && ret != 0) {
     861                error("couldn't open midi driver");
     862        }
    36863}
    37864
    38865SoundTowns::~SoundTowns() {
    39866        AudioCD.stop();
     867        haltTrack();
    40868        delete [] _sfxFileData;
    41         stopSoundEffect();
     869
     870        Common::StackLock lock(_mutex);
     871        _driver->setTimerCallback(0, 0);
     872        close();
     873
     874        if (_musicTrackData)
     875                delete [] _musicTrackData;
     876
     877        _driver = 0;
    42878}
    43879
    44880bool SoundTowns::init() {
    45881        _engine->checkCD();
    46882        int unused = 0;
    47883        _sfxWDTable = _engine->staticres()->loadRawData(kKyra1TownsSFXTable, unused);
    48         return true;
     884
     885        return loadInstruments();
    49886}
    50887
    51888void SoundTowns::process() {
     
    131968
    132969        int trackNum = tTable[track].track;
    133970        bool loop = tTable[track].loop;
    134         // could be that if the trackNum is -1, the music should be stopped
    135         // instead of letting the old music play on
    136         if (trackNum == -1 || trackNum == _lastTrack)
     971
     972        if (track == _lastTrack && _musicEnabled)
    137973                return;
    138974
    139975        haltTrack();
    140         AudioCD.play(trackNum+1, loop ? -1 : 1, 0, 0);
    141         AudioCD.updateCD();
    142976
    143         _lastTrack = trackNum;
     977        if (_musicEnabled == 2 && trackNum != -1) {
     978                AudioCD.play(trackNum+1, loop ? -1 : 1, 0, 0);
     979                AudioCD.updateCD();
     980        } else if (_musicEnabled) {
     981                playEuphonyTrack(tTable[track].fileOffset, loop);
     982        }
     983
     984        _lastTrack = track;
    144985}
    145986
    146987void SoundTowns::haltTrack() {
    147988        _lastTrack = -1;
    148989        AudioCD.stop();
    149990        AudioCD.updateCD();
     991        if (_parser) {
     992                Common::StackLock lock(_mutex);
     993
     994                _parser->setTrack(0);
     995                _parser->jumpToTick(0);
     996                _parser->setTempo(0);
     997
     998                _parser->unloadMusic();
     999                delete _parser;
     1000                _parser = 0;
     1001
     1002                setVolume(255);
     1003        }
    1501004}
    1511005
    1521006void SoundTowns::loadSoundFile(uint file) {
     
    1571011        _sfxFileData = _engine->resource()->fileData(soundFilename(file), 0);
    1581012}
    1591013
    160 void SoundTowns::stopSoundEffect() {
    161         _sfxIsPlaying = false; 
    162         _mixer->stopHandle(_sfxHandle);
    163 }
    164 
    1651014void SoundTowns::playSoundEffect(uint8 track) {
    1661015        if (!_sfxEnabled || !_sfxFileData)
    1671016                return;
    1681017
    169         _sfxIsPlaying = true;
    170        
    171         uint8 pitch = 0x3c;
    172         if (_sfxFileIndex == 5) {               
     1018        if (track == 0 || track == 10) {
     1019                _mixer->stopHandle(_sfxHandle);
     1020                return;
     1021        } else if (track == 1) {
     1022                // sfx fadeout
     1023                _mixer->stopHandle(_sfxHandle);
     1024                return;
     1025        }
     1026
     1027        uint8 note = 0x3c;
     1028        if (_sfxFileIndex == 5) {
    1731029                if (track == 0x10) {
    174                         pitch = 0x3e;
     1030                        note = 0x3e;
    1751031                        track = 0x0f;
    1761032                } else if (track == 0x11) {
    177                         pitch = 0x40;
     1033                        note = 0x40;
    1781034                        track = 0x0f;
    1791035                } else if (track == 0x12) {
    180                         pitch = 0x41;
     1036                        note = 0x41;
    1811037                        track = 0x0f;
    1821038                }
    1831039        }
     
    1941050                uint32 outBufferSize;
    1951051                uint32 unused2;
    1961052                uint32 unused3;
    197                 uint32 unknown1;
    198                 uint32 pitch;
     1053                uint32 rate;
     1054                uint32 rootNoteOffs;
    1991055        } *sfxHeader = (SfxHeader*)(fileBody + offset);
    2001056
    2011057        uint32 sfxHeaderID = TO_LE_32(sfxHeader->id);
    2021058        uint32 sfxHeaderInBufferSize = TO_LE_32(sfxHeader->inBufferSize);
    2031059        uint32 sfxHeaderOutBufferSize = TO_LE_32(sfxHeader->outBufferSize);
    204         sfxHeader->pitch = TO_LE_32(sfxHeader->pitch);
     1060        uint32 sfxRootNoteOffs = TO_LE_32(sfxHeader->rootNoteOffs);
     1061        uint32 sfxRate = TO_LE_32(sfxHeader->rate);
    2051062
    2061063        uint32 playbackBufferSize = (sfxHeaderID == 1) ? sfxHeaderInBufferSize : sfxHeaderOutBufferSize;
    2071064
    208         stopSoundEffect();
    2091065        uint8 *sfxPlaybackBuffer = (uint8 *)malloc(playbackBufferSize);
    2101066        memset(sfxPlaybackBuffer, 0x80, playbackBufferSize);
    2111067
     
    2201076                uint32 sfx_BtTable_Offset = 0;
    2211077                uint32 sfx_WdTable_Offset = 0;
    2221078                uint32 sfx_WdTable_Number = 5;
    223                
     1079
    2241080                for (uint32 i = 0; i < sfxHeaderInBufferSize; i++) {
    2251081                        sfx_WdTable_Offset = (sfx_WdTable_Number * 3 << 9) + sfxBody[i] * 6;
    2261082                        sfx_WdTable_Number = READ_LE_UINT16(_sfxWDTable + sfx_WdTable_Offset);
     
    2331089                }
    2341090        }
    2351091
    236         for (uint32 i = 0; i < playbackBufferSize; i++) {               
     1092        for (uint32 i = 0; i < playbackBufferSize; i++) {
    2371093                if (sfxPlaybackBuffer[i] < 0x80)
    2381094                        sfxPlaybackBuffer[i] = 0x80 - sfxPlaybackBuffer[i];
    2391095        }
    2401096
    2411097        playbackBufferSize -= 0x20;
    242         setPitch(sfxPlaybackBuffer, playbackBufferSize, sfxHeader->pitch, pitch);
    243        
    244         _currentSFX = Audio::makeLinearInputStream(sfxPlaybackBuffer, playbackBufferSize,
    245                 0x2b11,
    246                 Audio::Mixer::FLAG_UNSIGNED | Audio::Mixer::FLAG_LITTLE_ENDIAN | Audio::Mixer::FLAG_AUTOFREE,
    247                 0, 0);
     1098        uint32 outputRate = 11025 * semitoneAndSampleRate_to_sampleStep(note, sfxRootNoteOffs, sfxRate, 11025, 0x2000);
     1099
     1100        _currentSFX = Audio::makeLinearInputStream(sfxPlaybackBuffer, playbackBufferSize,
     1101                outputRate, Audio::Mixer::FLAG_UNSIGNED | Audio::Mixer::FLAG_LITTLE_ENDIAN | Audio::Mixer::FLAG_AUTOFREE, 0, 0);
    2481102        _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_sfxHandle, _currentSFX);
    2491103}
    2501104
    251 void SoundTowns::setPitch(uint8 *&data, uint32 &size, int8 sourcePitch, int8 targetPitch) {
    252         if (sourcePitch == targetPitch)
    253                 return;
     1105void SoundTowns::beginFadeOut() {
     1106        int vol = 255;
     1107        haltTrack();
     1108}
    2541109
    255         if (sourcePitch < 0)
    256                 sourcePitch = 0;
    257         if (sourcePitch > 119)
    258                 sourcePitch = 119;
    259         if (targetPitch < 0)
    260                 targetPitch = 0;
    261         if (targetPitch > 119)
    262                 targetPitch = 119;
    263        
     1110int SoundTowns::open() {
     1111        if (!_driver)
     1112                return 255;
     1113
     1114        int ret = _driver->open();
     1115        if (ret)
     1116                return ret;
     1117
     1118        _driver->setTimerCallback(this, &onTimer);
     1119        return 0;
     1120}
     1121
     1122void SoundTowns::close() {
     1123        if (_driver)
     1124                _driver->close();
     1125}
     1126
     1127void SoundTowns::send(uint32 b) {
     1128        _driver->send(b);
     1129}
     1130
     1131uint32 SoundTowns::getBaseTempo(void) {
     1132        return _driver ? _driver->getBaseTempo() : 0;
     1133}
     1134
     1135bool SoundTowns::loadInstruments() {
     1136        if (!_musicTrackData)
     1137                _musicTrackData = new uint8[0xC58A];
     1138
     1139        memset(_musicTrackData, 0, 0xC58A);
     1140        uint8 * twm = _engine->resource()->fileData("twmusic.pak", 0);
     1141        if (!twm)
     1142                return false;
     1143        Screen::decodeFrame4(twm, _musicTrackData, 0x8BF0);
     1144        _driver->loadFmInstruments(_musicTrackData + 8);
     1145
     1146        memset (_musicTrackData, 0, 0xC58A);
     1147        Screen::decodeFrame4(twm + 0x0CA0, _musicTrackData, 0xC58A);
     1148        delete [] twm;
     1149        _driver->loadWaveInstruments(_musicTrackData + 8);
     1150
     1151        return true;
     1152}
     1153
     1154void SoundTowns::playEuphonyTrack(uint32 offset, int loop) {
     1155        if (!_musicTrackData)
     1156                _musicTrackData = new uint8[0xC58A];
     1157
     1158        memset(_musicTrackData, 0, 0xC58A);
     1159        uint8 * twm = _engine->resource()->fileData("twmusic.pak", 0);
     1160        Screen::decodeFrame4(twm + 0x4b70 + offset, _musicTrackData, 0xC58A);
     1161        delete [] twm;
     1162
     1163        Common::StackLock lock(_mutex);
     1164
     1165        uint8 * used = _musicTrackData + 0x374;
     1166        uint8 * fchan = _musicTrackData + 0x6d4;
     1167        uint8 * wchan = _musicTrackData + 0x6dA;
     1168
     1169        for (uint8 i = 0; i < 6; i++) {
     1170                if (used[fchan[i]])
     1171                        _driver->assignFmChannel(fchan[i], i);
     1172        }
     1173
     1174        for (uint8 i = 0; i < 8; i++) {
     1175                if (used[wchan[i]])
     1176                        _driver->assignWaveChannel(wchan[i], i);
     1177        }
     1178
     1179        for (uint8 i = 0; i < 16; i++) {
     1180                if (!used[i])
     1181                        _driver->removeChannel(i);
     1182        }
     1183        _driver->send(0x79B0);
     1184
     1185        if (_parser)
     1186                delete _parser;
     1187
     1188        _parser = new MidiParser_EuD;
     1189        _parser->property(MidiParser::mpAutoLoop, loop);
     1190        _parser->loadMusic(_musicTrackData, 0);
     1191        _parser->jumpToTick(0);
     1192
     1193        _parser->setMidiDriver(this);
     1194        _parser->setTimerRate(getBaseTempo());
     1195}
     1196
     1197void SoundTowns::onTimer(void * data) {
     1198        SoundTowns *music = (SoundTowns *)data;
     1199        Common::StackLock lock(music->_mutex);
     1200        if (music->_parser)
     1201                music->_parser->onTimer();
     1202}
     1203
     1204float SoundTowns::semitoneAndSampleRate_to_sampleStep(int8 semiTone, int8 semiToneRootkey,
     1205        uint32 sampleRate, uint32 outputRate, int32 pitchWheel) {
     1206        if (semiTone < 0)
     1207                semiTone = 0;
     1208        if (semiTone > 119)
     1209                semiTone = 119;
     1210        if (semiTone < 0)
     1211                semiTone = 0;
     1212        if (semiTone > 119)
     1213                semiTone = 119;
     1214
    2641215        static const float noteFrq[] = {
    2651216                0004.13f, 0004.40f, 0004.64f, 0004.95f, 0005.16f, 0005.50f, 0005.80f, 0006.19f, 0006.60f, 0006.86f,
    2661217                0007.43f, 0007.73f, 0008.25f, 0008.80f, 0009.28f, 0009.90f, 0010.31f, 0011.00f, 0011.60f, 0012.38f,
     
    2761227                2376.00f, 2534.40f, 2640.00f, 2816.00f, 2970.40f, 3168.00f, 3379.20f, 3520.00f, 3801.60f, 3960.00f
    2771228        };
    2781229
    279         const float inc = noteFrq[targetPitch] / noteFrq[sourcePitch];
     1230        float pwModifier = (pitchWheel - 0x2000) / 0x2000;
     1231        int8 d = pwModifier ? (pwModifier < 0 ? -1 : 1) : 0;
     1232        float rateshift = (noteFrq[semiTone] - ((noteFrq[semiTone] -
     1233                noteFrq[semiTone + d]) * pwModifier * d)) / noteFrq[semiToneRootkey];
    2801234
    281         uint32 estimatedSize = (uint32)(((float) size / inc) + 1);
    282         uint32 exactSize = 0;
    283         uint8 * tmp = new uint8[estimatedSize];
    284         memset(tmp, 0x80, estimatedSize);
    285 
    286         int last = 0;
    287         for (float i = 0; i < size; i += inc) {
    288                 int cur = (int) i;
    289                 if (cur == last + 2)
    290                         tmp[exactSize++] = (data[last] + data[cur - 1] + data[cur]) / 3;
    291                 else if (cur == last)
    292                         tmp[exactSize++] = (data[cur] + data[cur + 1]) / 2;
    293                 else
    294                         tmp[exactSize++] = data[cur];
    295                 last = (int) i;
    296         }
    297 
    298     size = MIN(exactSize, estimatedSize);
    299         delete[] data;
    300         data = tmp;
     1235        return (float) sampleRate * 10.0f * rateshift / outputRate;
    3011236}
    3021237
    3031238const uint8 SoundTowns::_sfxBTTable[256] = {
  • sound/softsynth/ym2612.cpp

     
    2828#include <math.h>
    2929
    3030#include "common/util.h"
     31#include "sound/softsynth/ym2612.h"
    3132
    3233////////////////////////////////////////
    3334//
     
    4243static int *keyscaleTable = 0;
    4344static int *attackOut = 0;
    4445
    45 ////////////////////////////////////////
    46 //
    47 // Class declarations
    48 //
    49 ////////////////////////////////////////
    5046
    51 class Operator2612;
    52 class Voice2612;
    53 class MidiChannel_YM2612;
    54 class MidiDriver_YM2612;
    55 
    56 class Operator2612 {
    57 protected:
    58         Voice2612 *_owner;
    59         enum State { _s_ready, _s_attacking, _s_decaying, _s_sustaining, _s_releasing };
    60         State _state;
    61         int32 _currentLevel;
    62         int _frequency;
    63         uint32 _phase;
    64         int _lastOutput;
    65         int _feedbackLevel;
    66         int _detune;
    67         int _multiple;
    68         int32 _totalLevel;
    69         int _keyScale;
    70         int _velocity;
    71         int _specifiedTotalLevel;
    72         int _specifiedAttackRate;
    73         int _specifiedDecayRate;
    74         int _specifiedSustainLevel;
    75         int _specifiedSustainRate;
    76         int _specifiedReleaseRate;
    77         int _tickCount;
    78         int _attackTime;
    79         int32 _decayRate;
    80         int32 _sustainLevel;
    81         int32 _sustainRate;
    82         int32 _releaseRate;
    83 
    84 public:
    85         Operator2612 (Voice2612 *owner);
    86         ~Operator2612();
    87         void feedbackLevel(int level);
    88         void setInstrument(byte const *instrument);
    89         void velocity(int velo);
    90         void keyOn();
    91         void keyOff();
    92         void frequency(int freq);
    93         void nextTick(const int *phaseShift, int *outbuf, int buflen);
    94         bool inUse() { return (_state != _s_ready); }
    95 };
    96 
    97 class Voice2612 {
    98 public:
    99         Voice2612 *next;
    100         uint16 _rate;
    101 
    102 protected:
    103         Operator2612 *_opr[4];
    104         int _velocity;
    105         int _control7;
    106         int _note;
    107         int _frequencyOffs;
    108         int _frequency;
    109         int _algorithm;
    110 
    111         int *_buffer;
    112         int _buflen;
    113 
    114 public:
    115         Voice2612();
    116         ~Voice2612();
    117         void setControlParameter(int control, int value);
    118         void setInstrument(byte const *instrument);
    119         void velocity(int velo);
    120         void nextTick(int *outbuf, int buflen);
    121         void noteOn(int n, int onVelo);
    122         bool noteOff(int note);
    123         void pitchBend(int value);
    124         void recalculateFrequency();
    125 };
    126 
    127 class MidiChannel_YM2612 : public MidiChannel {
    128 protected:
    129         uint16 _rate;
    130         Voice2612 *_voices;
    131         Voice2612 *_next_voice;
    132 
    133 public:
    134         void removeAllVoices();
    135         void nextTick(int *outbuf, int buflen);
    136         void rate(uint16 r);
    137 
    138 public:
    139         MidiChannel_YM2612();
    140         virtual ~MidiChannel_YM2612();
    141 
    142         // MidiChannel interface
    143         MidiDriver *device() { return 0; }
    144         byte getNumber() { return 0; }
    145         void release() { }
    146         void send(uint32 b) { }
    147         void noteOff(byte note);
    148         void noteOn(byte note, byte onVelo);
    149         void programChange(byte program) { }
    150         void pitchBend(int16 value);
    151         void controlChange(byte control, byte value);
    152         void pitchBendFactor(byte value) { }
    153         void sysEx_customInstrument(uint32 type, const byte *instr);
    154 };
    155 
    156 class MidiDriver_YM2612 : public MidiDriver_Emulated {
    157 protected:
    158         MidiChannel_YM2612 *_channel[16];
    159 
    160         int _next_voice;
    161         int _volume;
    162 
    163 protected:
    164         static void createLookupTables();
    165         void nextTick(int16 *buf1, int buflen);
    166         int volume(int val = -1) { if (val >= 0) _volume = val; return _volume; }
    167         void rate(uint16 r);
    168 
    169         void generateSamples(int16 *buf, int len);
    170 
    171 public:
    172         MidiDriver_YM2612(Audio::Mixer *mixer);
    173         virtual ~MidiDriver_YM2612();
    174 
    175         int open();
    176         void close();
    177         void send(uint32 b);
    178         void send(byte channel, uint32 b); // Supports higher than channel 15
    179         uint32 property(int prop, uint32 param) { return 0; }
    180 
    181         void setPitchBendRange(byte channel, uint range) { }
    182         void sysEx(const byte *msg, uint16 length);
    183 
    184         MidiChannel *allocateChannel() { return 0; }
    185         MidiChannel *getPercussionChannel() { return 0; }
    186 
    187 
    188         // AudioStream API
    189         bool isStereo() const { return true; }
    190         int getRate() const { return _mixer->getOutputRate(); }
    191 };
    192 
    19347////////////////////////////////////////
    19448//
    19549// Operator2612 implementation
     
    726580        int i;
    727581        for (i = 0; i < ARRAYSIZE(_channel); i++)
    728582                delete _channel[i];
    729         delete sintbl;
    730         delete powtbl;
    731         delete frequencyTable;
    732         delete keycodeTable;
    733         delete keyscaleTable;
    734         delete attackOut;
    735         sintbl = powtbl = frequencyTable = keycodeTable = keyscaleTable = attackOut = 0;
     583        removeLookupTables();
    736584}
    737585
    738586int MidiDriver_YM2612::open() {
     
    896744        }
    897745}
    898746
     747void MidiDriver_YM2612::removeLookupTables() {
     748        delete [] sintbl;
     749        delete [] powtbl;
     750        delete [] frequencyTable;
     751        delete [] keycodeTable;
     752        delete [] keyscaleTable;
     753        delete [] attackOut;
     754        sintbl = powtbl = frequencyTable = keycodeTable = keyscaleTable = attackOut = 0;
     755}
     756
    899757////////////////////////////////////////
    900758//
    901759// MidiDriver_YM2612 factory
  • sound/softsynth/ym2612.h

     
     1////////////////////////////////////////
     2//
     3// Class declarations
     4//
     5////////////////////////////////////////
     6
     7class Voice2612;
     8class Operator2612 {
     9protected:
     10        Voice2612 *_owner;
     11        enum State { _s_ready, _s_attacking, _s_decaying, _s_sustaining, _s_releasing };
     12        State _state;
     13        int32 _currentLevel;
     14        int _frequency;
     15        uint32 _phase;
     16        int _lastOutput;
     17        int _feedbackLevel;
     18        int _detune;
     19        int _multiple;
     20        int32 _totalLevel;
     21        int _keyScale;
     22        int _velocity;
     23        int _specifiedTotalLevel;
     24        int _specifiedAttackRate;
     25        int _specifiedDecayRate;
     26        int _specifiedSustainLevel;
     27        int _specifiedSustainRate;
     28        int _specifiedReleaseRate;
     29        int _tickCount;
     30        int _attackTime;
     31        int32 _decayRate;
     32        int32 _sustainLevel;
     33        int32 _sustainRate;
     34        int32 _releaseRate;
     35
     36public:
     37        Operator2612 (Voice2612 *owner);
     38        ~Operator2612();
     39        void feedbackLevel(int level);
     40        void setInstrument(byte const *instrument);
     41        void velocity(int velo);
     42        void keyOn();
     43        void keyOff();
     44        void frequency(int freq);
     45        void nextTick(const int *phaseShift, int *outbuf, int buflen);
     46        bool inUse() { return (_state != _s_ready); }
     47};
     48
     49class Voice2612 {
     50public:
     51        Voice2612 *next;
     52        uint16 _rate;
     53
     54protected:
     55        Operator2612 *_opr[4];
     56        int _velocity;
     57        int _control7;
     58        int _note;
     59        int _frequencyOffs;
     60        int _frequency;
     61        int _algorithm;
     62
     63        int *_buffer;
     64        int _buflen;
     65
     66public:
     67        Voice2612();
     68        ~Voice2612();
     69        void setControlParameter(int control, int value);
     70        void setInstrument(byte const *instrument);
     71        void velocity(int velo);
     72        void nextTick(int *outbuf, int buflen);
     73        void noteOn(int n, int onVelo);
     74        bool noteOff(int note);
     75        void pitchBend(int value);
     76        void recalculateFrequency();
     77};
     78
     79class MidiChannel_YM2612 : public MidiChannel {
     80protected:
     81        uint16 _rate;
     82        Voice2612 *_voices;
     83        Voice2612 *_next_voice;
     84
     85public:
     86        void removeAllVoices();
     87        void nextTick(int *outbuf, int buflen);
     88        void rate(uint16 r);
     89
     90public:
     91        MidiChannel_YM2612();
     92        virtual ~MidiChannel_YM2612();
     93
     94        // MidiChannel interface
     95        MidiDriver *device() { return 0; }
     96        byte getNumber() { return 0; }
     97        void release() { }
     98        void send(uint32 b) { }
     99        void noteOff(byte note);
     100        void noteOn(byte note, byte onVelo);
     101        void programChange(byte program) { }
     102        void pitchBend(int16 value);
     103        void controlChange(byte control, byte value);
     104        void pitchBendFactor(byte value) { }
     105        void sysEx_customInstrument(uint32 type, const byte *instr);
     106};
     107
     108class MidiDriver_YM2612 : public MidiDriver_Emulated {
     109protected:
     110        MidiChannel_YM2612 *_channel[16];
     111
     112        int _next_voice;
     113        int _volume;
     114
     115protected:
     116        void nextTick(int16 *buf1, int buflen);
     117        int volume(int val = -1) { if (val >= 0) _volume = val; return _volume; }
     118        void rate(uint16 r);
     119
     120        void generateSamples(int16 *buf, int len);
     121
     122public:
     123        MidiDriver_YM2612(Audio::Mixer *mixer);
     124        virtual ~MidiDriver_YM2612();
     125
     126        static void createLookupTables();
     127        static void removeLookupTables();
     128
     129        int open();
     130        void close();
     131        void send(uint32 b);
     132        void send(byte channel, uint32 b); // Supports higher than channel 15
     133        uint32 property(int prop, uint32 param) { return 0; }
     134
     135        void setPitchBendRange(byte channel, uint range) { }
     136        void sysEx(const byte *msg, uint16 length);
     137
     138        MidiChannel *allocateChannel() { return 0; }
     139        MidiChannel *getPercussionChannel() { return 0; }
     140
     141
     142        // AudioStream API
     143        bool isStereo() const { return true; }
     144        int getRate() const { return _mixer->getOutputRate(); }
     145};
     146 Kein Zeilenvorschub am Ende der Datei