Ticket #8620: kyra_fmtowns_music.patch

File kyra_fmtowns_music.patch, 43.3 KB (added by lordhoto, 17 years ago)

updated patch

  • sound/softsynth/ym2612.cpp

     
    2323 * $Id$
    2424 */
    2525
    26 #include "sound/softsynth/emumidi.h"
    27 
    2826#include <math.h>
    2927
     28#include "sound/softsynth/ym2612.h"
    3029#include "common/util.h"
    3130
    3231////////////////////////////////////////
     
    4241static int *keyscaleTable = 0;
    4342static int *attackOut = 0;
    4443
    45 ////////////////////////////////////////
    46 //
    47 // Class declarations
    48 //
    49 ////////////////////////////////////////
    5044
    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 
    19345////////////////////////////////////////
    19446//
    19547// Operator2612 implementation
     
    726578        int i;
    727579        for (i = 0; i < ARRAYSIZE(_channel); i++)
    728580                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;
     581        removeLookupTables();
    736582}
    737583
    738584int MidiDriver_YM2612::open() {
     
    896742        }
    897743}
    898744
     745void MidiDriver_YM2612::removeLookupTables() {
     746        delete [] sintbl;
     747        delete [] powtbl;
     748        delete [] frequencyTable;
     749        delete [] keycodeTable;
     750        delete [] keyscaleTable;
     751        delete [] attackOut;
     752        sintbl = powtbl = frequencyTable = keycodeTable = keyscaleTable = attackOut = 0;
     753}
     754
    899755////////////////////////////////////////
    900756//
    901757// MidiDriver_YM2612 factory
     
    905761MidiDriver *MidiDriver_YM2612_create(Audio::Mixer *mixer) {
    906762        return new MidiDriver_YM2612(mixer);
    907763}
     764
  • 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();
     145
     146        bool loadMusic (byte *data, uint32 unused = 0);
     147        void setTempo(uint32 tempo);
     148protected:
     149        void parseNextEvent (EventInfo &info);
     150        void resetTracking();
     151
     152        byte * _enable;
     153        byte * _mode;
     154        byte * _channel;
     155        byte * _adjVelo;
     156        int8 * _adjNote;
     157
     158        uint8 _firstBaseTickStep;
     159        uint8 _nextBaseTickStep;
     160        uint8 _initialTempo;
     161        uint32 _baseTick;
     162};
     163
     164class FMT_EuphonyDriver : public MidiDriver_Emulated {
     165public:
     166        FMT_EuphonyDriver(Audio::Mixer *mixer);
     167        virtual ~FMT_EuphonyDriver();
     168
     169        int open();
     170        void close();
     171        void send(uint32 b);
     172        void send(byte channel, uint32 b);
     173        uint32 property(int prop, uint32 param) { return 0; }
     174
     175        void setPitchBendRange(byte channel, uint range) { }
     176        //void sysEx(const byte *msg, uint16 length);
     177        void loadFmInstruments(const byte *instr);
     178        void loadWaveInstruments(const byte *instr);
     179
     180        MidiChannel *allocateChannel() { return 0; }
     181        MidiChannel *getPercussionChannel() { return 0; }
     182
     183        void assignFmChannel(uint8 midiChannelNumber, uint8 fmChannelNumber);
     184        void assignWaveChannel(uint8 midiChannelNumber, uint8 waveChannelNumber);
     185        void removeChannel(uint8 midiChannelNumber);
     186
     187        // AudioStream API
     188        bool isStereo() const { return true; }
     189        int getRate() const { return _mixer->getOutputRate(); }
     190
     191protected:
     192        void nextTick(int16 *buf1, int buflen);
     193        int volume(int val = -1) { if (val >= 0) _volume = val; return _volume; }
     194        void rate(uint16 r);
     195
     196        void generateSamples(int16 *buf, int len);
     197
     198        MidiChannel_EuD_FM *_fChannel[6];
     199        MidiChannel_EuD_WAVE *_wChannel[8];
     200        MidiChannel_EuD * _channel[16];
     201
     202        int _volume;
     203
     204        uint8 *_fmInstruments;
     205        uint8 *_waveInstruments;
     206        int8 * _waveSounds[10];
     207};
     208
     209MidiChannel_EuD_FM::MidiChannel_EuD_FM() {
     210        _voice = new Voice2612;
     211}
     212
     213MidiChannel_EuD_FM::~MidiChannel_EuD_FM() {
     214        delete _voice;
     215}
     216
     217void MidiChannel_EuD_FM::noteOn(byte note, byte onVelo) {
     218        _voice->noteOn(note, onVelo);
     219}
     220
     221void MidiChannel_EuD_FM::noteOff(byte note) {
     222        _voice->noteOff(note);
     223}
     224
     225void MidiChannel_EuD_FM::controlChange(byte control, byte value) {
     226        if (control == 121) {
     227                // Reset controller
     228                delete _voice;
     229                _voice = new Voice2612;
     230        } else if (control == 10) {
     231                // pan position
     232        } else {
     233                _voice->setControlParameter(control, value);
     234        }
     235}
     236
     237void MidiChannel_EuD_FM::sysEx_customInstrument(uint32, const byte *fmInst) {
     238        _voice->_rate = _rate;
     239        _voice->setInstrument(fmInst);
     240}
     241
     242void MidiChannel_EuD_FM::pitchBend(int16 value) {
     243        _voice->pitchBend(value);
     244}
     245
     246void MidiChannel_EuD_FM::nextTick(int32 *outbuf, int buflen) {
     247        _voice->nextTick((int*) outbuf, buflen);
     248}
     249
     250void MidiChannel_EuD_FM::rate(uint16 r) {
     251        _rate = r;
     252        _voice->_rate = r;
     253}
     254
     255MidiChannel_EuD_WAVE::MidiChannel_EuD_WAVE() {
     256        _voice = new Voice;
     257        for (uint8 i = 0; i < 8; i++) {
     258                _voice->_env[i] = new Voice::Env;
     259                _voice->_snd[i] = 0;
     260        }
     261
     262        _ctrl7_volume = 127;
     263        velocity(0);
     264        _frequencyOffs = 0x2000;
     265        _current = -1;
     266}
     267
     268MidiChannel_EuD_WAVE::~MidiChannel_EuD_WAVE() {
     269        for (uint8 i = 0; i < 8; i++) {
     270                if (_voice->_snd[i])
     271                        delete _voice->_snd[i];
     272                delete _voice->_env[i];
     273        }
     274        delete _voice;
     275}
     276
     277void MidiChannel_EuD_WAVE::noteOn(byte note, byte onVelo) {
     278        _note = note;
     279        velocity(onVelo);
     280        _phase = 0;
     281
     282        for (_current = 0; _current < 7; _current++) {
     283                if (note <=     _voice->split[_current])
     284                        break;
     285        }
     286
     287        _voice->_env[_current]->state = _s_attacking;
     288        _voice->_env[_current]->currentLevel = 0;
     289        _voice->_env[_current]->rate = _rate;
     290        _voice->_env[_current]->tickCount = 0;
     291}
     292
     293void MidiChannel_EuD_WAVE::noteOff(byte note) {
     294    if (_current == -1)
     295                return;
     296        if (_voice->_env[_current]->state == _s_ready)
     297                return;
     298
     299        _voice->_env[_current]->state = _s_releasing;
     300        _voice->_env[_current]->releaseLevel = _voice->_env[_current]->currentLevel;
     301        _voice->_env[_current]->tickCount = 0;
     302}
     303
     304void MidiChannel_EuD_WAVE::controlChange(byte control, byte value) {
     305        switch (control) {
     306                case 0x07:
     307                        // volume
     308                        _ctrl7_volume = value;
     309                        break;
     310                case 0x0A:
     311                        // pan position
     312                        break;
     313                case 0x79:
     314                // Reset controller
     315                        for (uint8 i = 0; i < 8; i++) {
     316                                if (_voice->_snd[i])
     317                                        delete _voice->_snd[i];
     318                                delete _voice->_env[i];
     319                        }
     320                        delete _voice;
     321                        _voice = new Voice;
     322                        for (uint8 i = 0; i < 8; i++) {
     323                                _voice->_env[i] = new Voice::Env;
     324                                _voice->_snd[i] = 0;
     325                        }
     326                        break;
     327                case 0x7B:
     328                        noteOff(_note);
     329                        break;
     330                default:
     331                        break;
     332        }
     333}
     334
     335void MidiChannel_EuD_WAVE::sysEx_customInstrument(uint32 type, const byte *fmInst) {
     336        if (type == 0x80) {
     337                for (uint8 i = 0; i < 8; i++) {
     338                        byte ** pos = (byte **) fmInst;
     339                        for (uint8 ii = 0; ii < 10; ii++) {
     340                                if (_voice->id[i] == *(pos[ii] + 8)) {
     341                                        if (!_voice->_snd[i])
     342                                                _voice->_snd[i] = new Voice::Snd;
     343                                        memset (_voice->_snd[i]->name, 0, 9);
     344                                        memcpy (_voice->_snd[i]->name, (const char*) pos[ii], 8);
     345                                        _voice->_snd[i]->id = READ_LE_UINT32(pos[ii] + 8);
     346                                        _voice->_snd[i]->numSamples = READ_LE_UINT32(pos[ii] + 12);
     347                                        _voice->_snd[i]->loopStart = READ_LE_UINT32(pos[ii] + 16);
     348                                        _voice->_snd[i]->loopLength = READ_LE_UINT32(pos[ii] + 20);
     349                                        _voice->_snd[i]->samplingRate = READ_LE_UINT16(pos[ii] + 24);
     350                                        _voice->_snd[i]->keyOffset = READ_LE_UINT16(pos[ii] + 26);
     351                                        _voice->_snd[i]->keyNote = *(uint8*)(pos[ii] + 28);
     352                                        _voice->_snd[i]->_samples = (int8*)(pos[ii] + 32);
     353                                }
     354                        }
     355                }
     356        } else {
     357                memset (_voice->name, 0, 9);
     358                memcpy (_voice->name, (const char*) fmInst, 8);
     359
     360                for (uint8 i = 0; i < 8; i++) {
     361                        _voice->split[i] = READ_LE_UINT16(fmInst + 16 + 2 * i);
     362                        _voice->id[i] = READ_LE_UINT32(fmInst + 32 + 4 * i);
     363                        _voice->_snd[i] = 0;
     364                        _voice->_env[i]->state = _s_ready;
     365                        _voice->_env[i]->currentLevel = 0;
     366                        _voice->_env[i]->totalLevel = *(fmInst + 64 + 8 * i);
     367                        _voice->_env[i]->attackRate = *(fmInst + 65 + 8 * i) * 10;
     368                        _voice->_env[i]->decayRate = *(fmInst + 66 + 8 * i) * 10;
     369                        _voice->_env[i]->sustainLevel = *(fmInst + 67 + 8 * i);
     370                        _voice->_env[i]->sustainRate = *(fmInst + 68 + 8 * i) * 20;
     371                        _voice->_env[i]->releaseRate = *(fmInst + 69 + 8 * i) * 10;
     372                        _voice->_env[i]->rootKeyOffset = *(fmInst + 70 + 8 * i);
     373                }
     374        }
     375}
     376
     377void MidiChannel_EuD_WAVE::pitchBend(int16 value) {
     378        _frequencyOffs = value;
     379}
     380
     381void MidiChannel_EuD_WAVE::nextTick(int32 *outbuf, int buflen) {
     382        if (_current == -1 || !_voice->_snd[_current] || !_voice->_env[_current]->state || !_velocity) {
     383                velocity(0);
     384                _current = -1;
     385                return;
     386        }
     387
     388        float phaseStep = SoundTowns::semitoneAndSampleRate_to_sampleStep(_note, _voice->_snd[_current]->keyNote -
     389                _voice->_env[_current]->rootKeyOffset, _voice->_snd[_current]->samplingRate, _rate, _frequencyOffs);
     390
     391        int32 looplength = _voice->_snd[_current]->loopLength;
     392        int32 numsamples = _voice->_snd[_current]->numSamples;
     393        int8 * samples = _voice->_snd[_current]->_samples;
     394
     395        for (int i = 0; i < buflen; i++) {
     396                if (looplength > 0) {
     397                        while (_phase >= numsamples)
     398                                _phase -= looplength;
     399                } else {
     400                        if (_phase >= numsamples) {
     401                                velocity(0);
     402                                _current = -1;
     403                                break;
     404                        }
     405                }
     406
     407                int32 output;
     408
     409                int32 phase0 = int32(_phase);
     410                int32 phase1 = int32(_phase + 1);
     411                if (phase1 >= numsamples)
     412                        phase1 -= looplength;
     413                float weight0 = _phase - phase0;
     414                float weight1 = phase1 - _phase;
     415                output = int32(samples[phase0] * weight0 + samples[phase1] * weight1);
     416
     417                output *= _velocity;
     418                output <<= 1;
     419
     420                evpNextTick();
     421                output *= _voice->_env[_current]->currentLevel;
     422                output >>= 7;
     423                output *= _ctrl7_volume;
     424                output >>= 7;
     425
     426                output *= 185;
     427                output >>= 8;
     428                outbuf[i] += output;
     429                _phase += phaseStep;
     430        }
     431}
     432
     433void MidiChannel_EuD_WAVE::evpNextTick() {
     434        switch (_voice->_env[_current]->state) {
     435                case _s_ready:
     436                        _voice->_env[_current]->currentLevel = 0;
     437                        return;
     438
     439                case _s_attacking:
     440                        if (_voice->_env[_current]->attackRate == 0)
     441                                _voice->_env[_current]->currentLevel = _voice->_env[_current]->totalLevel;
     442                        else if (_voice->_env[_current]->attackRate >= 1270)
     443                                _voice->_env[_current]->currentLevel = 0;
     444                        else
     445                                _voice->_env[_current]->currentLevel = (_voice->_env[_current]->totalLevel *
     446                                        _voice->_env[_current]->tickCount++ * 1000) /
     447                                                (_voice->_env[_current]->attackRate * _voice->_env[_current]->rate);
     448
     449                        if (_voice->_env[_current]->currentLevel >= _voice->_env[_current]->totalLevel) {
     450                                _voice->_env[_current]->currentLevel = _voice->_env[_current]->totalLevel;
     451                                _voice->_env[_current]->state = _s_decaying;
     452                                _voice->_env[_current]->tickCount = 0;
     453                        }
     454                        break;
     455
     456                case _s_decaying:
     457                        if (_voice->_env[_current]->decayRate == 0)
     458                                _voice->_env[_current]->currentLevel = _voice->_env[_current]->sustainLevel;
     459                        else if (_voice->_env[_current]->decayRate >= 1270)
     460                                _voice->_env[_current]->currentLevel = _voice->_env[_current]->totalLevel;
     461                        else {
     462                                _voice->_env[_current]->currentLevel = _voice->_env[_current]->totalLevel;
     463                                _voice->_env[_current]->currentLevel -= ((_voice->_env[_current]->totalLevel -
     464                                        _voice->_env[_current]->sustainLevel) * _voice->_env[_current]->tickCount++ * 1000) /
     465                                                (_voice->_env[_current]->decayRate * _voice->_env[_current]->rate);
     466                        }
     467
     468                        if (_voice->_env[_current]->currentLevel <= _voice->_env[_current]->sustainLevel) {
     469                                _voice->_env[_current]->currentLevel = _voice->_env[_current]->sustainLevel;
     470                                _voice->_env[_current]->state = _s_sustaining;
     471                                _voice->_env[_current]->tickCount = 0;
     472                        }
     473                        break;
     474
     475                        case _s_sustaining:
     476                                if (_voice->_env[_current]->sustainRate == 0)
     477                                        _voice->_env[_current]->currentLevel = 0;
     478                                else if (_voice->_env[_current]->sustainRate >= 2540)
     479                                        _voice->_env[_current]->currentLevel = _voice->_env[_current]->sustainLevel;
     480                                else {
     481                                        _voice->_env[_current]->currentLevel = _voice->_env[_current]->sustainLevel;
     482                                        _voice->_env[_current]->currentLevel -= (_voice->_env[_current]->sustainLevel *
     483                                                _voice->_env[_current]->tickCount++ * 1000) / (_voice->_env[_current]->sustainRate *
     484                                                        _voice->_env[_current]->rate);
     485                                }
     486
     487                                if (_voice->_env[_current]->currentLevel <= 0) {
     488                                        _voice->_env[_current]->currentLevel = 0;
     489                                        _voice->_env[_current]->state = _s_ready;
     490                                        _voice->_env[_current]->tickCount = 0;
     491                                }
     492                                break;
     493
     494                        case _s_releasing:
     495                                if (_voice->_env[_current]->releaseRate == 0)
     496                                        _voice->_env[_current]->currentLevel = 0;
     497                                else if (_voice->_env[_current]->releaseRate >= 1270)
     498                                        _voice->_env[_current]->currentLevel = _voice->_env[_current]->releaseLevel;
     499                                else {
     500                                        _voice->_env[_current]->currentLevel = _voice->_env[_current]->releaseLevel;
     501                                        _voice->_env[_current]->currentLevel -= (_voice->_env[_current]->releaseLevel *
     502                                                _voice->_env[_current]->tickCount++ * 1000) / (_voice->_env[_current]->releaseRate *
     503                                                        _voice->_env[_current]->rate);
     504                                }
     505
     506                                if (_voice->_env[_current]->currentLevel <= 0) {
     507                                        _voice->_env[_current]->currentLevel = 0;
     508                                        _voice->_env[_current]->state = _s_ready;
     509                                }
     510                                break;
     511
     512                        default:
     513                        break;
     514        }
     515}
     516
     517void MidiChannel_EuD_WAVE::rate(uint16 r) {
     518        _rate = r;
     519}
     520
     521void MidiChannel_EuD_WAVE::velocity(int velo) {
     522        _velocity = velo;
     523}
     524
     525FMT_EuphonyDriver::FMT_EuphonyDriver(Audio::Mixer *mixer)
     526        : MidiDriver_Emulated(mixer) {
     527
     528        MidiDriver_YM2612::createLookupTables();
     529
     530        _volume = 255;
     531        for (uint8 i = 0; i < 6; i++)
     532                _channel[i] = _fChannel[i] = new MidiChannel_EuD_FM;
     533        for (uint8 i = 0; i < 8; i++)
     534                _channel[i + 6] = _wChannel[i] = new MidiChannel_EuD_WAVE;
     535        _channel[14] = _channel[15] = 0;
     536
     537        _fmInstruments = _waveInstruments = 0;
     538        memset(_waveSounds, 0, sizeof(uint8*) * 10);
     539
     540        rate(getRate());
     541}
     542
     543FMT_EuphonyDriver::~FMT_EuphonyDriver() {
     544        for (int i = 0; i < 6; i++)
     545                delete _fChannel[i];
     546        for (int i = 0; i < 8; i++)
     547                delete _wChannel[i];
     548
     549        MidiDriver_YM2612::removeLookupTables();
     550
     551        if (_fmInstruments) {
     552                delete [] _fmInstruments;
     553                _fmInstruments = 0;
     554        }
     555
     556        if (_waveInstruments) {
     557                delete [] _waveInstruments;
     558                _waveInstruments = 0;
     559        }
     560
     561        for (int i = 0; i < 10; i++) {
     562                if (_waveSounds[i]) {
     563                        delete [] _waveSounds[i];
     564                        _waveSounds[i] = 0;
     565                }
     566        }
     567}
     568
     569int FMT_EuphonyDriver::open() {
     570        if (_isOpen)
     571                return MERR_ALREADY_OPEN;
     572
     573        MidiDriver_Emulated::open();
     574
     575        _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_mixerSoundHandle,
     576                this, -1, Audio::Mixer::kMaxChannelVolume, 0, false, true);
     577        return 0;
     578}
     579
     580void FMT_EuphonyDriver::close() {
     581        if (!_isOpen)
     582                return;
     583        _isOpen = false;
     584        _mixer->stopHandle(_mixerSoundHandle);
     585}
     586
     587void FMT_EuphonyDriver::send(uint32 b) {
     588        send(b & 0xF, b & 0xFFFFFFF0);
     589}
     590
     591void FMT_EuphonyDriver::send(byte chan, uint32 b) {
     592        //byte param3 = (byte) ((b >> 24) & 0xFF);
     593
     594        byte param2 = (byte) ((b >> 16) & 0xFF);
     595        byte param1 = (byte) ((b >>  8) & 0xFF);
     596        byte cmd    = (byte) (b & 0xF0);
     597        if (chan > ARRAYSIZE(_channel))
     598                return;
     599
     600        switch (cmd) {
     601        case 0x80:// Note Off
     602                if (_channel[chan])
     603                        _channel[chan]->noteOff(param1);
     604                break;
     605        case 0x90: // Note On
     606                if (_channel[chan])
     607                        _channel[chan]->noteOn(param1, param2);
     608                break;
     609        case 0xA0: // Aftertouch
     610                break; // Not supported.
     611        case 0xB0: // Control Change
     612                if (param1 == 0x79) {
     613                        for (int i = 0; i < 15; i++) {
     614                                if (_channel[i]) {
     615                                        _channel[i]->controlChange(param1, param2);
     616                                        _channel[i]->programChange(0);
     617                                }
     618                        }
     619                } else if (param1 == 0x7B) {
     620                        for (int i = 0; i < 15; i++) {
     621                                if (_channel[i])
     622                                        _channel[i]->controlChange(param1, param2);
     623                        }
     624                } else {
     625                        if (_channel[chan])
     626                                _channel[chan]->controlChange(param1, param2);
     627                }
     628                break;
     629        case 0xC0: // Program Change
     630        for (int i = 0; i < 6; i++) {
     631                        if (_channel[chan] == _fChannel[i]) {
     632                                _channel[chan]->sysEx_customInstrument(0, _fmInstruments + param1 * 0x30);
     633                                break;
     634                        }
     635                }
     636                for (int i = 0; i < 8; i++) {
     637                        if (_channel[chan] == _wChannel[i]) {
     638                                _channel[chan]->sysEx_customInstrument(0, _waveInstruments + param1 * 0x80);
     639                                _channel[chan]->sysEx_customInstrument(0x80, (const byte*) _waveSounds);
     640                                break;
     641                        }
     642                }
     643                break;
     644        case 0xD0: // Channel Pressure
     645                break; // Not supported.
     646        case 0xE0: // Pitch Bend
     647                if (_channel[chan])
     648                        _channel[chan]->pitchBend((param1 | (param2 << 7)) - 0x2000);
     649                break;
     650        default:
     651                warning("FMT_EuphonyDriver: Unknown send() command 0x%02X", cmd);
     652        }
     653}
     654
     655void FMT_EuphonyDriver::loadFmInstruments(const byte *instr) {
     656        if (_fmInstruments)
     657                delete [] _fmInstruments;
     658        _fmInstruments = new uint8[0x1800];
     659        memcpy(_fmInstruments, instr, 0x1800);
     660}
     661
     662void FMT_EuphonyDriver::loadWaveInstruments(const byte *instr) {
     663        if (_waveInstruments)
     664                delete [] _waveInstruments;
     665        _waveInstruments = new uint8[0x1000];
     666        memcpy(_waveInstruments, instr, 0x1000);
     667
     668        const uint8 *pos = (const uint8 *)(instr + 0x1000);
     669
     670        for (uint8 i = 0; i < 10; i++) {
     671                if (_waveSounds[i])
     672                        delete [] _waveSounds[i];
     673                uint32 numsamples = READ_LE_UINT32(pos + 0x0C);
     674                _waveSounds[i] = new int8[numsamples + 0x20];
     675        memcpy(_waveSounds[i], pos, 0x20);
     676                pos += 0x20;
     677                for (uint32 ii = 0; ii < numsamples; ii++) {
     678                        uint8 s = *(pos + ii);
     679                        s = (s < 0x80) ? 0x80 - s : s;
     680                        _waveSounds[i][ii + 0x20] = s ^ 0x80;
     681                }
     682                pos += numsamples;
     683        }
     684}
     685
     686
     687void FMT_EuphonyDriver::assignFmChannel(uint8 midiChannelNumber, uint8 fmChannelNumber) {
     688        _channel[midiChannelNumber] = _fChannel[fmChannelNumber];
     689}
     690
     691void FMT_EuphonyDriver::assignWaveChannel(uint8 midiChannelNumber, uint8 waveChannelNumber) {
     692        _channel[midiChannelNumber] = _wChannel[waveChannelNumber];
     693}
     694
     695void FMT_EuphonyDriver::removeChannel(uint8 midiChannelNumber) {
     696        _channel[midiChannelNumber] = 0;
     697}
     698
     699void FMT_EuphonyDriver::generateSamples(int16 *data, int len) {
     700        memset(data, 0, 2 * sizeof(int16) * len);
     701        nextTick(data, len);
     702}
     703
     704void FMT_EuphonyDriver::nextTick(int16 *buf1, int buflen) {
     705        int32 *buf0 = (int32 *)buf1;
     706
     707        for (int i = 0; i < ARRAYSIZE(_channel); i++) {
     708                if (_channel[i])
     709                        _channel[i]->nextTick(buf0, buflen);
     710        }
     711
     712        for (int i = 0; i < buflen; ++i) {
     713                buf1[i*2] = buf1[i*2+1] =((buf0[i] * volume()) >> 9) & 0xffff;
     714        }
     715}
     716
     717void FMT_EuphonyDriver::rate(uint16 r)
     718{
     719        for (uint8 i = 0; i < 16; i++) {
     720                if (_channel[i])
     721                        _channel[i]->rate(r);
     722        }
     723}
     724
     725MidiParser_EuD::MidiParser_EuD() : MidiParser() {
     726}
     727
     728void MidiParser_EuD::parseNextEvent(EventInfo &info) {
     729        byte *pos = _position._play_pos;
     730
     731        while (true) {
     732                byte cmd = *pos;
     733                byte evt = (cmd & 0xF0);
     734
     735                if (evt == 0x90) {
     736                        byte chan = pos[1];
     737
     738                        if (_enable[chan]) {
     739                                uint16 tick = (pos[2] | ((uint16) pos[3] << 7)) + _baseTick;
     740                                info.start = pos + 6;
     741                                uint32 last = _position._last_event_tick;
     742                                info.delta = (tick < last) ? 0 : (tick - last);
     743
     744                                info.event = 0x90 | _channel[chan];
     745                                info.length = pos[7] | (pos[8] << 4);
     746
     747                                int8 note = (int8) pos[4];
     748                                if (_adjNote[chan]) {
     749                                        note = (note & 0x7f) & _adjNote[chan];
     750                                        if (note > 0x7c)
     751                                                note -= 0x0c;
     752                                        else if (note < 0)
     753                                                note += 0x0c;
     754                                }
     755                                info.basic.param1 = (byte) note;
     756
     757                                uint8 onVelo = (pos[5] & 0x7f) + _adjVelo[chan];
     758                                if (onVelo > 0x7f)
     759                                        onVelo = 0x7f;
     760                                if (onVelo < 1)
     761                                        onVelo = 1;
     762                                info.basic.param2 = onVelo;
     763
     764                                pos += 12;
     765                                break;
     766                        } else {
     767                                pos += 6;
     768                        }
     769                } else if (evt == 0xB0 || evt == 0xC0 || evt == 0xe0) {
     770                        byte chan = pos[1];
     771
     772                        if (_enable[chan]) {
     773                                info.start = pos;
     774                                uint16 tick = (pos[2] | ((uint16) pos[3] << 7)) + _baseTick;
     775                                uint32 last = _position._last_event_tick;
     776                                info.delta = (tick < last) ? 0 : (tick - last);
     777                                info.event = evt | _channel[chan];
     778                                info.length = 0;
     779                                info.basic.param1 = pos[4];
     780                                info.basic.param2 = pos[5];
     781                                pos += 6;
     782                                break;
     783                        } else {
     784                                pos += 6;
     785                        }
     786                } else if (cmd == 0xF2) {
     787                        static uint16 tickTable [] = { 0x180, 0xC0, 0x80, 0x60, 0x40, 0x30, 0x20, 0x18 };
     788                        _baseTick += tickTable[_nextBaseTickStep >> 4] * ((_nextBaseTickStep & 0x0f) + 1);
     789                        _nextBaseTickStep = pos[1];
     790                        pos += 6;
     791                } else if (cmd == 0xF8) {
     792                        uint16 tempo = pos[4] | (pos[5] << 7);
     793                        setTempo(tempo);
     794                        pos += 6;
     795                } else if (cmd == 0xFD || cmd == 0xFE) {
     796                        // End of track.
     797                        if (_autoLoop)
     798                                pos = info.start = _tracks[0];
     799                        else
     800                                info.start = pos;
     801
     802                        uint32 last = _position._last_event_tick;
     803                        uint16 tick = (pos[2] | ((uint16) pos[3] << 7)) + _baseTick;
     804                        info.delta = (tick < last) ? 0 : (tick - last);
     805                        info.event = 0xFF;
     806                        info.ext.type = 0x2F;
     807                        info.ext.data = pos;
     808                        break;
     809                } else {
     810                        error("Unknown Euphony music event 0x%02X", (int) cmd);
     811                        memset(&info, 0, sizeof(info));
     812                        pos = 0;
     813                        break;
     814                }
     815        }
     816        _position._play_pos = pos;
     817}
     818
     819bool MidiParser_EuD::loadMusic(byte *data, uint32) {
     820        unloadMusic();
     821
     822        _enable = data + 0x354;
     823        _mode = data + 0x374;
     824        _channel = data + 0x394;
     825        _adjVelo = data + 0x3B4;
     826        _adjNote = (int8*) data + 0x3D4;
     827
     828        _firstBaseTickStep = data[0x804];
     829        _initialTempo = (data[0x805] > 0xfc) ? 0x5a : data[0x805];
     830
     831        _num_tracks = 1;
     832        _ppqn = 120;
     833        _tracks[0] = data + 0x806;
     834
     835        resetTracking();
     836        setTrack (0);
     837
     838        return true;
     839}
     840
     841void MidiParser_EuD::setTempo(uint32 tempo) {
     842        if (tempo)
     843                MidiParser::setTempo(60000000 / tempo);
     844}
     845
     846void MidiParser_EuD::resetTracking() {
     847        MidiParser::resetTracking();
     848
     849        _nextBaseTickStep = _firstBaseTickStep;
     850        _baseTick = 0;
     851        setTempo(_initialTempo);
     852}
     853
    34854SoundTowns::SoundTowns(KyraEngine *engine, Audio::Mixer *mixer) : Sound(engine, mixer), _lastTrack(-1),
    35         _currentSFX(0), _sfxFileData(0), _sfxFileIndex((uint)-1), _sfxWDTable(0) {
     855         _currentSFX(0), _sfxFileData(0), _sfxFileIndex((uint)-1), _sfxWDTable(0), _parser(0), _musicTrackData(0) {
     856
     857        _driver = new FMT_EuphonyDriver(_mixer);
     858        int ret = open();
     859        if (ret != MERR_ALREADY_OPEN && ret != 0) {
     860                error("couldn't open midi driver");
     861        }
    36862}
    37863
    38864SoundTowns::~SoundTowns() {
    39865        AudioCD.stop();
     866        haltTrack();
    40867        delete [] _sfxFileData;
    41         stopSoundEffect();
     868
     869        Common::StackLock lock(_mutex);
     870        _driver->setTimerCallback(0, 0);
     871        close();
     872
     873        if (_musicTrackData)
     874                delete [] _musicTrackData;
     875
     876        _driver = 0;
    42877}
    43878
    44879bool SoundTowns::init() {
    45880        _engine->checkCD();
    46881        int unused = 0;
    47882        _sfxWDTable = _engine->staticres()->loadRawData(kKyra1TownsSFXTable, unused);
    48         return true;
     883
     884        return loadInstruments();
    49885}
    50886
    51887void SoundTowns::process() {
     
    131967
    132968        int trackNum = tTable[track].track;
    133969        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)
     970
     971        if (track == _lastTrack && _musicEnabled)
    137972                return;
    138973
    139974        haltTrack();
    140         AudioCD.play(trackNum+1, loop ? -1 : 1, 0, 0);
    141         AudioCD.updateCD();
    142975
    143         _lastTrack = trackNum;
     976        if (_musicEnabled == 2 && trackNum != -1) {
     977                AudioCD.play(trackNum+1, loop ? -1 : 1, 0, 0);
     978                AudioCD.updateCD();
     979        } else if (_musicEnabled) {
     980                playEuphonyTrack(tTable[track].fileOffset, loop);
     981        }
     982
     983        _lastTrack = track;
    144984}
    145985
    146986void SoundTowns::haltTrack() {
    147987        _lastTrack = -1;
    148988        AudioCD.stop();
    149989        AudioCD.updateCD();
     990        if (_parser) {
     991                Common::StackLock lock(_mutex);
     992
     993                _parser->setTrack(0);
     994                _parser->jumpToTick(0);
     995
     996                _parser->unloadMusic();
     997                delete _parser;
     998                _parser = 0;
     999
     1000                setVolume(255);
     1001        }
    1501002}
    1511003
    1521004void SoundTowns::loadSoundFile(uint file) {
     
    1571009        _sfxFileData = _engine->resource()->fileData(soundFilename(file), 0);
    1581010}
    1591011
    160 void SoundTowns::stopSoundEffect() {
    161         _sfxIsPlaying = false; 
    162         _mixer->stopHandle(_sfxHandle);
    163 }
    164 
    1651012void SoundTowns::playSoundEffect(uint8 track) {
    1661013        if (!_sfxEnabled || !_sfxFileData)
    1671014                return;
    1681015
    169         _sfxIsPlaying = true;
    170        
    171         uint8 pitch = 0x3c;
    172         if (_sfxFileIndex == 5) {               
     1016        if (track == 0 || track == 10) {
     1017                _mixer->stopHandle(_sfxHandle);
     1018                return;
     1019        } else if (track == 1) {
     1020                // sfx fadeout
     1021                _mixer->stopHandle(_sfxHandle);
     1022                return;
     1023        }
     1024
     1025        uint8 note = 0x3c;
     1026        if (_sfxFileIndex == 5) {
    1731027                if (track == 0x10) {
    174                         pitch = 0x3e;
     1028                        note = 0x3e;
    1751029                        track = 0x0f;
    1761030                } else if (track == 0x11) {
    177                         pitch = 0x40;
     1031                        note = 0x40;
    1781032                        track = 0x0f;
    1791033                } else if (track == 0x12) {
    180                         pitch = 0x41;
     1034                        note = 0x41;
    1811035                        track = 0x0f;
    1821036                }
    1831037        }
     
    1941048                uint32 outBufferSize;
    1951049                uint32 unused2;
    1961050                uint32 unused3;
    197                 uint32 unknown1;
    198                 uint32 pitch;
     1051                uint32 rate;
     1052                uint32 rootNoteOffs;
    1991053        } *sfxHeader = (SfxHeader*)(fileBody + offset);
    2001054
    2011055        uint32 sfxHeaderID = TO_LE_32(sfxHeader->id);
    2021056        uint32 sfxHeaderInBufferSize = TO_LE_32(sfxHeader->inBufferSize);
    2031057        uint32 sfxHeaderOutBufferSize = TO_LE_32(sfxHeader->outBufferSize);
    204         sfxHeader->pitch = TO_LE_32(sfxHeader->pitch);
     1058        uint32 sfxRootNoteOffs = TO_LE_32(sfxHeader->rootNoteOffs);
     1059        uint32 sfxRate = TO_LE_32(sfxHeader->rate);
    2051060
    2061061        uint32 playbackBufferSize = (sfxHeaderID == 1) ? sfxHeaderInBufferSize : sfxHeaderOutBufferSize;
    2071062
    208         stopSoundEffect();
    2091063        uint8 *sfxPlaybackBuffer = (uint8 *)malloc(playbackBufferSize);
    2101064        memset(sfxPlaybackBuffer, 0x80, playbackBufferSize);
    2111065
     
    2201074                uint32 sfx_BtTable_Offset = 0;
    2211075                uint32 sfx_WdTable_Offset = 0;
    2221076                uint32 sfx_WdTable_Number = 5;
    223                
     1077
    2241078                for (uint32 i = 0; i < sfxHeaderInBufferSize; i++) {
    2251079                        sfx_WdTable_Offset = (sfx_WdTable_Number * 3 << 9) + sfxBody[i] * 6;
    2261080                        sfx_WdTable_Number = READ_LE_UINT16(_sfxWDTable + sfx_WdTable_Offset);
     
    2331087                }
    2341088        }
    2351089
    236         for (uint32 i = 0; i < playbackBufferSize; i++) {               
     1090        for (uint32 i = 0; i < playbackBufferSize; i++) {
    2371091                if (sfxPlaybackBuffer[i] < 0x80)
    2381092                        sfxPlaybackBuffer[i] = 0x80 - sfxPlaybackBuffer[i];
    2391093        }
    2401094
    2411095        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);
     1096        uint32 outputRate = uint32(11025 * semitoneAndSampleRate_to_sampleStep(note, sfxRootNoteOffs, sfxRate, 11025, 0x2000));
     1097
     1098        _currentSFX = Audio::makeLinearInputStream(sfxPlaybackBuffer, playbackBufferSize,
     1099                outputRate, Audio::Mixer::FLAG_UNSIGNED | Audio::Mixer::FLAG_LITTLE_ENDIAN | Audio::Mixer::FLAG_AUTOFREE, 0, 0);
    2481100        _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_sfxHandle, _currentSFX);
    2491101}
    2501102
    251 void SoundTowns::setPitch(uint8 *&data, uint32 &size, int8 sourcePitch, int8 targetPitch) {
    252         if (sourcePitch == targetPitch)
    253                 return;
     1103void SoundTowns::beginFadeOut() {
     1104        //int vol = 255;
     1105        haltTrack();
     1106}
    2541107
    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        
     1108int SoundTowns::open() {
     1109        if (!_driver)
     1110                return 255;
     1111
     1112        int ret = _driver->open();
     1113        if (ret)
     1114                return ret;
     1115
     1116        _driver->setTimerCallback(this, &onTimer);
     1117        return 0;
     1118}
     1119
     1120void SoundTowns::close() {
     1121        if (_driver)
     1122                _driver->close();
     1123}
     1124
     1125void SoundTowns::send(uint32 b) {
     1126        _driver->send(b);
     1127}
     1128
     1129uint32 SoundTowns::getBaseTempo(void) {
     1130        return _driver ? _driver->getBaseTempo() : 0;
     1131}
     1132
     1133bool SoundTowns::loadInstruments() {
     1134        if (!_musicTrackData)
     1135                _musicTrackData = new uint8[0xC58A];
     1136
     1137        memset(_musicTrackData, 0, 0xC58A);
     1138        uint8 * twm = _engine->resource()->fileData("twmusic.pak", 0);
     1139        if (!twm)
     1140                return false;
     1141        Screen::decodeFrame4(twm, _musicTrackData, 0x8BF0);
     1142        _driver->loadFmInstruments(_musicTrackData + 8);
     1143
     1144        memset (_musicTrackData, 0, 0xC58A);
     1145        Screen::decodeFrame4(twm + 0x0CA0, _musicTrackData, 0xC58A);
     1146        delete [] twm;
     1147        _driver->loadWaveInstruments(_musicTrackData + 8);
     1148
     1149        return true;
     1150}
     1151
     1152void SoundTowns::playEuphonyTrack(uint32 offset, int loop) {
     1153        if (!_musicTrackData)
     1154                _musicTrackData = new uint8[0xC58A];
     1155
     1156        memset(_musicTrackData, 0, 0xC58A);
     1157        uint8 * twm = _engine->resource()->fileData("twmusic.pak", 0);
     1158        Screen::decodeFrame4(twm + 0x4b70 + offset, _musicTrackData, 0xC58A);
     1159        delete [] twm;
     1160
     1161        Common::StackLock lock(_mutex);
     1162
     1163        uint8 * used = _musicTrackData + 0x374;
     1164        uint8 * fchan = _musicTrackData + 0x6d4;
     1165        uint8 * wchan = _musicTrackData + 0x6dA;
     1166
     1167        for (uint8 i = 0; i < 6; i++) {
     1168                if (used[fchan[i]])
     1169                        _driver->assignFmChannel(fchan[i], i);
     1170        }
     1171
     1172        for (uint8 i = 0; i < 8; i++) {
     1173                if (used[wchan[i]])
     1174                        _driver->assignWaveChannel(wchan[i], i);
     1175        }
     1176
     1177        for (uint8 i = 0; i < 16; i++) {
     1178                if (!used[i])
     1179                        _driver->removeChannel(i);
     1180        }
     1181        _driver->send(0x79B0);
     1182
     1183        if (_parser)
     1184                delete _parser;
     1185
     1186        _parser = new MidiParser_EuD;
     1187        _parser->property(MidiParser::mpAutoLoop, loop);
     1188        _parser->loadMusic(_musicTrackData, 0);
     1189        _parser->jumpToTick(0);
     1190
     1191        _parser->setMidiDriver(this);
     1192        _parser->setTimerRate(getBaseTempo());
     1193}
     1194
     1195void SoundTowns::onTimer(void * data) {
     1196        SoundTowns *music = (SoundTowns *)data;
     1197        Common::StackLock lock(music->_mutex);
     1198        if (music->_parser)
     1199                music->_parser->onTimer();
     1200}
     1201
     1202float SoundTowns::semitoneAndSampleRate_to_sampleStep(int8 semiTone, int8 semiToneRootkey,
     1203        uint32 sampleRate, uint32 outputRate, int32 pitchWheel) {
     1204        if (semiTone < 0)
     1205                semiTone = 0;
     1206        if (semiTone > 119)
     1207                semiTone = 119;
     1208        if (semiTone < 0)
     1209                semiTone = 0;
     1210        if (semiTone > 119)
     1211                semiTone = 119;
     1212
    2641213        static const float noteFrq[] = {
    2651214                0004.13f, 0004.40f, 0004.64f, 0004.95f, 0005.16f, 0005.50f, 0005.80f, 0006.19f, 0006.60f, 0006.86f,
    2661215                0007.43f, 0007.73f, 0008.25f, 0008.80f, 0009.28f, 0009.90f, 0010.31f, 0011.00f, 0011.60f, 0012.38f,
     
    2761225                2376.00f, 2534.40f, 2640.00f, 2816.00f, 2970.40f, 3168.00f, 3379.20f, 3520.00f, 3801.60f, 3960.00f
    2771226        };
    2781227
    279         const float inc = noteFrq[targetPitch] / noteFrq[sourcePitch];
     1228        float pwModifier = (pitchWheel - 0x2000) / 0x2000;
     1229        int8 d = pwModifier ? (pwModifier < 0 ? -1 : 1) : 0;
     1230        float rateshift = (noteFrq[semiTone] - ((noteFrq[semiTone] -
     1231                noteFrq[semiTone + d]) * pwModifier * d)) / noteFrq[semiToneRootkey];
    2801232
    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;
     1233        return (float) sampleRate * 10.0f * rateshift / outputRate;
    3011234}
    3021235
    3031236const uint8 SoundTowns::_sfxBTTable[256] = {
  • 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") && _flags.platform == Common::kPlatformFMTowns) ? 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.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/ym2612.h"
    5555
    5656#include "kyra/kyra.h"
    5757
     
    8484
    8585        virtual void beginFadeOut() = 0;
    8686
    87         void enableMusic(bool enable) { _musicEnabled = enable; }
    88         bool musicEnabled() const { return _musicEnabled; }
     87        void enableMusic(int enable) { _musicEnabled = enable; }
     88        int musicEnabled() const { return _musicEnabled; }
    8989        void enableSFX(bool enable) { _sfxEnabled = enable; }
    9090        bool sfxEnabled() const { return _sfxEnabled; }
    9191
     
    9393        void voiceUnload() {}
    9494        bool voiceIsPlaying();
    9595        void voiceStop();
    96        
     96
    9797protected:
    9898        const char *soundFilename(uint file) { return (file < _soundFileListSize) ? _soundFileList[file] : ""; }
    99         bool _musicEnabled;
     99        int _musicEnabled;
    100100        bool _sfxEnabled;
    101101
    102102        KyraEngine *_engine;
     
    129129
    130130        void setVolume(int volume);
    131131        int getVolume();
    132        
     132
    133133        void loadSoundFile(uint file);
    134        
     134
    135135        void playTrack(uint8 track);
    136136        void haltTrack();
    137        
     137
    138138        void playSoundEffect(uint8 track);
    139        
     139
    140140        void beginFadeOut();
    141141private:
    142142        void play(uint8 track);
     
    231231        Common::Mutex _mutex;
    232232};
    233233
    234 class SoundTowns : public Sound {
     234class FMT_EuphonyDriver;
     235class SoundTowns : public MidiDriver, public Sound {
    235236public:
    236237        SoundTowns(KyraEngine *engine, Audio::Mixer *mixer);
    237238        ~SoundTowns();
     
    249250
    250251        void playSoundEffect(uint8);
    251252
    252         void beginFadeOut() { /* TODO */ }
     253        void beginFadeOut();
     254
     255        //MidiDriver interface implementation
     256        int open();
     257        void close();
     258        void send(uint32 b);
     259        void metaEvent(byte type, byte *data, uint16 length) {}
     260
     261        void setTimerCallback(void *timerParam, void (*timerProc)(void *)) { }
     262        uint32 getBaseTempo(void);
     263
     264        //Channel allocation functions
     265        MidiChannel *allocateChannel()          { return 0; }
     266        MidiChannel *getPercussionChannel()     { return 0; }
     267
     268        static float semitoneAndSampleRate_to_sampleStep(int8 semiTone, int8 semiToneRootkey,
     269                uint32 sampleRate, uint32 outputRate, int32 pitchWheel);
    253270private:
    254         void stopSoundEffect();
    255         void setPitch(uint8 *&data, uint32 &size, int8 sourcePitch, int8 targetPitch);
     271        bool loadInstruments();
     272        void playEuphonyTrack(uint32 offset, int loop);
    256273
     274        static void onTimer(void *data);
     275
    257276        int _lastTrack;
    258277        Audio::AudioStream *_currentSFX;
    259278        Audio::SoundHandle _sfxHandle;
     279
    260280        int _currentTrackTable;
    261         bool _sfxIsPlaying;
    262281        uint _sfxFileIndex;
    263282        uint8 *_sfxFileData;
    264283
     284        FMT_EuphonyDriver * _driver;
     285        MidiParser * _parser;
     286        uint8 *_musicTrackData;
     287
     288        Common::Mutex _mutex;
     289
    265290        static const char *_sfxFiles[];
    266291        static const int _sfxFilenum;
    267292        static const uint8 _sfxBTTable[256];
    268         const uint8 *_sfxWDTable;       
     293        const uint8 *_sfxWDTable;
    269294};
    270295
    271296class MixedSoundDriver : public Sound {
     
    300325        ~SoundDigital();
    301326
    302327        bool init();
    303        
     328
    304329        int playSound(Common::File *fileHandle, bool loop = false, bool fadeIn = false, int channel = -1);
    305330        bool isPlaying(int channel);
    306331        void stopSound(int channel);
  • engines/kyra/kyra.h

     
    790790
    791791        uint8 _configTextspeed;
    792792        uint8 _configWalkspeed;
    793         bool _configMusic;
     793        int _configMusic;
    794794        bool _configSounds;
    795795        uint8 _configVoice;
    796796
     
    891891        const char *_textSpeedString;
    892892        const char *_onString;
    893893        const char *_offString;
     894        const char *_onCDString;
    894895               
    895896        int _itemList_Size;
    896897        int _takenList_Size;
  • engines/kyra/resource.cpp

     
    8888                for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
    8989                        Common::String filename = file->name();
    9090                        filename.toUppercase();
     91
     92                        // No real PAK file!
     93                        if (filename == "TWMUSIC.PAK")
     94                                continue;
     95
    9196                        if (filename.hasSuffix("PAK") || filename.hasSuffix("APK")) {
    9297                                if (!loadPakFile(file->name())) {
    9398                                        error("couldn't open pakfile '%s'", file->name().c_str());
  • 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}