Ticket #8281: ym2612.diff

File ym2612.diff, 23.3 KB (added by SF/jamieson630, 21 years ago)

YM2612 implementation, rev 1

  • scummvm/backends/midi/ym2612.cpp

    RCS file: /cvsroot/scummvm/scummvm/backends/midi/ym2612.cpp,v
    retrieving revision 1.1
    diff -u -r1.1 ym2612.cpp
     
    1919 * along with this program; if not, write to the Free Software
    2020 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    2121 *
    22  * $Header: /cvsroot/scummvm/scummvm/backends/midi/ym2612.cpp,v 1.1 2003/10/05 15:34:53 jamieson630 Exp $
     22 * $Header: /cvsroot/scummvm/scummvm/backends/midi/adlib.cpp,v 1.51 2003/09/28 21:08:47 fingolfin Exp $
    2323 */
    2424
    25 // Real implementation coming soon! :)
    26 
     25#include <math.h>
     26#include <string>
     27#include "common/util.h"
    2728#include "sound/mididrv.h"
     29#include "sound/mixer.h"
    2830
    29 MidiDriver *MidiDriver_YM2612_create(SoundMixer *mixer) {
     31////////////////////////////////////////
     32//
     33// Miscellaneous
     34//
     35////////////////////////////////////////
     36
     37#define BASE_FREQ 250
     38#define FIXP_SHIFT  16
     39
     40#define CHECK_CHANNEL_NUM(funcname, channel) \
     41        if (channel < 0 || ARRAYSIZE(_channel) <= channel) { return; } \
     42        (void)false
     43
     44typedef __int64 int64;
     45
     46static int *sintbl = 0;
     47static int *powtbl = 0;
     48static int *frequencyTable = 0;
     49static int *keycodeTable = 0;
     50static int *keyscaleTable = 0;
     51static int *attackOut = 0;
     52
     53////////////////////////////////////////
     54//
     55// Class declarations
     56//
     57////////////////////////////////////////
     58
     59class Operator2612;
     60class Voice2612;
     61class MidiChannel_YM2612;
     62class MidiDriver_YM2612_Internal;
     63
     64class Operator2612 {
     65protected:
     66        enum State { _s_ready, _s_attacking, _s_decaying, _s_sustaining, _s_releasing };
     67        State _state;
     68        int64 _currentLevel;
     69        int _frequency;
     70        int _phase;
     71        int _lastOutput;
     72        int _feedbackLevel;
     73        int _detune;
     74        int _multiple;
     75        int64 _totalLevel;
     76        int _keyScale;
     77        int _velocity;
     78        int _specifiedTotalLevel;
     79        int _specifiedAttackRate;
     80        int _specifiedDecayRate;
     81        int _specifiedSustainLevel;
     82        int _specifiedSustainRate;
     83        int _specifiedReleaseRate;
     84        int _tickCount;
     85        int _attackTime;
     86        int64 _decayRate;
     87        int64 _sustainLevel;
     88        int64 _sustainRate;
     89        int64 _releaseRate;
     90
     91public:
     92        Operator2612();
     93        ~Operator2612();
     94        void feedbackLevel(int level);
     95        void setInstrument(byte const *instrument);
     96        void velocity(int velo);
     97        void keyOn();
     98        void keyOff();
     99        void frequency(int freq);
     100        int nextTick(int rate, int phaseShift);
     101};
     102
     103class Voice2612 {
     104protected:
     105        enum { _numOfOperators = 4 };
     106        Operator2612 *_opr;
     107        int _rate;
     108        int _velocity;
     109        int _control7;
     110        int _note;
     111        int _frequencyOffs;
     112        int _frequency;
     113        int _algorithm;
     114
     115public:
     116        Voice2612();
     117        ~Voice2612();
     118        void setControlParameter(int control, int value);
     119        void setInstrument(byte const *instrument);
     120        void rate(int r) { _rate = r;}
     121        void velocity(int velo);
     122        void nextTick(int *outbuf, int buflen);
     123        void noteOn(int n, int onVelo);
     124        bool noteOff(int note);
     125        void pitchBend(int value);
     126        void recalculateFrequency();
     127};
     128
     129class MidiChannel_YM2612 : public MidiChannel {
     130protected:
     131        Voice2612 *_voice;
     132
     133public:
     134        MidiChannel_YM2612();
     135        ~MidiChannel_YM2612();
     136
     137        // MidiChannel interface
     138        MidiDriver *device() { return 0; }
     139        byte getNumber() { return 0; }
     140        void release() { }
     141        void send (uint32 b) { }
     142        void noteOff(byte note);
     143        void noteOn(byte note, byte onVelo);
     144        void programChange(byte program) { }
     145        void pitchBend(int16 value);
     146        void controlChange(byte control, byte value);
     147        void pitchBendFactor(byte value) { }
     148        void sysEx_customInstrument (uint32 type, byte *instr);
     149
     150        void nextTick(int *outbuf, int buflen);
     151        void rate(int r);
     152};
     153
     154class MidiDriver_YM2612 : public MidiDriver {
     155protected:
     156        MidiChannel_YM2612 *_channel[16];
     157        int _volume;
     158        int _rate;
     159        bool _outputSampleUnsigned;
     160        int _outputSampleSize;
     161        bool _outputSampleLSBFirst;
     162
     163        bool _isOpen;
     164        SoundMixer *_mixer;
     165        typedef void TimerCallback (void *);
     166        TimerCallback *_timer_proc;
     167        void *_timer_param;
     168        int _next_tick;
     169        int _samples_per_tick;
     170
     171protected:
     172        static void createLookupTables();
     173        void outputSampleUnsigned(bool u) { _outputSampleUnsigned = u; }
     174        void outputSampleSize(int l) { _outputSampleSize = l; }
     175        void outputSampleLSBFirst(bool l) { _outputSampleLSBFirst = l; }
     176        void nextTick (byte *buf1, int buflen);
     177        int volume(int val = -1) { if (val >= 0) _volume = val; return _volume; }
     178        void rate(int r);
     179
     180        void generate_samples(int16 *buf, int len);
     181        static void premix_proc(void *param, int16 *buf, uint len);
     182
     183public:
     184        MidiDriver_YM2612(SoundMixer *mixer);
     185        virtual ~MidiDriver_YM2612();
     186
     187        int open();
     188        void close();
     189        void send(uint32 b);
     190        void send (byte channel, uint32 b); // Supports higher than channel 15
     191        uint32 property(int prop, uint32 param) { return 0; }
     192
     193        void setPitchBendRange(byte channel, uint range) { }
     194        void sysEx (byte *msg, uint16 length);
     195
     196        void setTimerCallback(void *timer_param, void (*timer_proc) (void *));
     197        uint32 getBaseTempo() { return 1000000 / BASE_FREQ; }
     198
     199        MidiChannel *allocateChannel() { return 0; }
     200        MidiChannel *getPercussionChannel() { return 0; }
     201};
     202
     203////////////////////////////////////////
     204//
     205// Operator2612 implementation
     206//
     207////////////////////////////////////////
     208
     209Operator2612::Operator2612() {
     210        _state = _s_ready;
     211        _currentLevel = ((int64)0x7f << 31);
     212        _phase = 0;
     213        _lastOutput = 0;
     214        _feedbackLevel = 0;
     215        _detune = 0;
     216        _multiple = 1;
     217        _specifiedTotalLevel = 127;
     218        _keyScale = 0;
     219        _specifiedAttackRate = 0;
     220        _specifiedDecayRate = 0;
     221        _specifiedSustainRate = 0;
     222        _specifiedReleaseRate = 15;
     223        velocity(0);
     224}
     225
     226Operator2612::~Operator2612()
     227{ }
     228
     229void Operator2612::velocity(int velo) {
     230        _velocity = velo;
     231        _totalLevel = (((int64)_specifiedTotalLevel << 31) +
     232                      ((int64)(127-_velocity) << 29));
     233        _sustainLevel = ((int64)_specifiedSustainLevel << (31+2));
     234}
     235
     236void Operator2612::feedbackLevel(int level) {
     237        _feedbackLevel = level;
     238}
     239
     240void Operator2612::setInstrument(byte const *instrument) {
     241        _detune = (instrument[8] >> 4) & 7;
     242        _multiple = instrument[8] & 15;
     243        _specifiedTotalLevel = instrument[12] & 127;
     244        _keyScale = (instrument[16] >> 6) & 3;
     245        _specifiedAttackRate = instrument[16] & 31;
     246        _specifiedDecayRate = instrument[20] & 31;
     247        _specifiedSustainRate = instrument[24] & 31;
     248        _specifiedSustainLevel = (instrument[28] >> 4) & 15;
     249        _specifiedReleaseRate = instrument[28] & 15;
     250        _state = _s_ready; // ËÜʪ¤Ç¤Ï¤É¤¦¤Ê¤Î¤«¤Ê?
     251        velocity(_velocity);
     252}
     253
     254void Operator2612::keyOn() {
     255        _state = _s_attacking;
     256        _tickCount = 0;
     257        _phase = 0;                     // ¤É¤¦¤â¡¢¼ÂºÝ¤³¤¦¤é¤·¤¤
     258        _currentLevel = ((int64)0x7f << 31); // ¤³¤ì¤â¡¢¼ÂºÝ¤³¤¦¤é¤·¤¤
     259}
     260
     261void Operator2612::keyOff() {
     262        if (_state != _s_ready)
     263                _state = _s_releasing;
     264}
     265
     266void Operator2612::frequency(int freq) {
     267        int r;
     268
     269        _frequency = freq;
     270
     271        r = _specifiedAttackRate;
     272        if (r != 0) {
     273                r = r * 2 + (keyscaleTable[freq/262205] >> (3-_keyScale));
     274                if (r >= 64)
     275                r = 63; // ¤¹¤ë¤Ù¤­¤Ê¤ó¤À¤í¤¦¤È¤Ï»×¤¦¤ó¤À¤±¤É (ÀÖp.207)
     276        }
     277#if 0
     278        _attackRate = 0x80;
     279        _attackRate *= powtbl[(r&3) << 7];
     280        _attackRate <<= 16 + (r >> 2);
     281        _attackRate >>= 1;
     282        _attackRate /= 9;  // r == 4 ¤Î¤È¤­¡¢0-96db ¤¬ 8970.24ms
     283        //_attackRate /= 4;  // r == 4 ¤Î¤È¤­¡¢0-96db ¤¬ 8970.24ms
     284#else
     285        {
     286                r = 63 - r;
     287                int64 t;
     288                if (_specifiedTotalLevel >= 128)
     289                        t = 0;
     290                else {
     291                        t = powtbl[(r&3) << 7];
     292                        t <<= (r >> 2);
     293                        t *= 41;                        // r == 20 ¤Î¤È¤­¡¢0-96[db] ¤¬ 10.01[ms] == 41.00096
     294                        t >>= (15 + 5);
     295                        t *= 127 - _specifiedTotalLevel;
     296                        t /= 127;
     297                }
     298                _attackTime = t;                // 1 ÉÃ == (1 << 12)
     299        }
     300#endif
     301
     302        r = _specifiedDecayRate;
     303        if (r != 0) {
     304                r = r * 2 + (keyscaleTable[freq/262205] >> (3-_keyScale));
     305                if (r >= 64)
     306                        r = 63;
     307        }
     308        _decayRate = 0x80;
     309        _decayRate *= powtbl[(r&3) << 7];
     310        _decayRate <<= 16 + (r >> 2);
     311        _decayRate >>= 1;
     312        _decayRate /= 124;      // r == 4 ¤Î¤È¤­¡¢0-96db ¤¬ 123985.92ms
     313
     314        r = _specifiedSustainRate;
     315        if (r != 0) {
     316                r = r * 2 + (keyscaleTable[freq/262205] >> (3-_keyScale));
     317                if (r >= 64)
     318                        r = 63;
     319        }
     320        _sustainRate = 0x80;
     321        _sustainRate *= powtbl[(r&3) << 7];
     322        _sustainRate <<= 16 + (r >> 2);
     323        _sustainRate >>= 1;
     324        _sustainRate /= 124;
     325
     326        r = _specifiedReleaseRate;
     327        if (r != 0) {
     328                r = r * 2 + 1;          // ¤³¤Î¥¿¥¤¥ß¥ó¥°¤ÇÎɤ¤¤Î¤«¤ï¤«¤é¤ó
     329                r = r * 2 + (keyscaleTable[freq/262205] >> (3-_keyScale));
     330                // KS ¤Ë¤è¤ëÊäÀµ¤Ï¤¢¤ë¤é¤·¤¤¡£ÀÖp.206 ¤Ç¤Ïµ­½Ò¤µ¤ì¤Æ¤Ê¤¤¤±¤É¡£
     331                if (r >= 64)
     332                        r = 63;
     333        }
     334        _releaseRate = 0x80;
     335        _releaseRate *= powtbl[(r&3) << 7];
     336        _releaseRate <<= 16 + (r >> 2);
     337        _releaseRate >>= 1;
     338        _releaseRate /= 124;
     339}
     340
     341int Operator2612::nextTick(int rate, int phaseShift) {
     342        // sampling ¤Ò¤È¤Äʬ¿Ê¤á¤ë
     343        switch (_state) {
     344        case _s_ready:
     345                return 0;
     346                break;
     347        case _s_attacking:
     348                ++_tickCount;
     349                if (_attackTime <= 0) {
     350                        _currentLevel = 0;
     351                        _state = _s_decaying;
     352                } else {
     353                        int i = ((int64)_tickCount << (12+10)) / ((int64)rate * _attackTime);
     354                        if (i >= 1024) {
     355                                _currentLevel = 0;
     356                                _state = _s_decaying;
     357                        } else {
     358                                _currentLevel = attackOut[i];
     359                                _currentLevel <<= 31 - 8;
     360                        }
     361                }
     362                break;
     363        case _s_decaying:
     364                _currentLevel += _decayRate / rate;
     365                if (_currentLevel >= _sustainLevel) {
     366                        _currentLevel = _sustainLevel;
     367                        _state = _s_sustaining;
     368                }
     369                break;
     370        case _s_sustaining:
     371                _currentLevel += _sustainRate / rate;
     372                if (_currentLevel >= ((int64)0x7f << 31)) {
     373                        _currentLevel = ((int64)0x7f << 31);
     374                        _state = _s_ready;
     375                }
     376                break;
     377        case _s_releasing:
     378                _currentLevel += _releaseRate / rate;
     379                if (_currentLevel >= ((int64)0x7f << 31)) {
     380                        _currentLevel = ((int64)0x7f << 31);
     381                        _state = _s_ready;
     382                }
     383                break;
     384        default:
     385                // ¤³¤³¤Ë¤ÏÍè¤Ê¤¤¤Ï¤º
     386                break;
     387        };
     388
     389        int64 level = _currentLevel + _totalLevel;
     390        int64 output = 0;
     391        if (level < ((int64)0x7f << 31)) {
     392                int const feedback[] = {
     393                        0,
     394                        0x400 / 16,
     395                        0x400 / 8,
     396                        0x400 / 4,
     397                        0x400 / 2,
     398                        0x400,
     399                        0x400 * 2,
     400                        0x400 * 4,
     401                };
     402
     403                _phase &= 0x3ffff;
     404                phaseShift >>= 2;               // Àµ¤·¤¤ÊÑÄ´Î̤Ï?  3 ¤¸¤ã¾®¤µ¤¹¤®¤Ç 2 ¤¸¤ãÂ礭¤¤¤è¤¦¤Ê¡£
     405                phaseShift += (((int64)(_lastOutput) * feedback[_feedbackLevel]) >> 16); // Àµ¤·¤¤ÊÑÄ´Î̤Ï?  16¤«¤é17¤Î´Ö¤Î¤è¤¦¤À¤±¤É¡£
     406                output = sintbl[((_phase >> 7) + phaseShift) & 0x7ff];
     407                output >>= (level >> 34);       // Àµ¤·¤¤¸º¿êÎ̤Ï?
     408                output *= powtbl[511 - ((level>>25)&511)];
     409                output >>= 16;
     410                output >>= 1;
     411
     412                if (_multiple > 0)
     413                        _phase += (_frequency * _multiple) / rate;
     414                else
     415                        _phase += _frequency / (rate << 1);
     416        }
     417
     418        _lastOutput = output;
     419        return output;
     420}
     421
     422////////////////////////////////////////
     423//
     424// Voice2612 implementation
     425//
     426////////////////////////////////////////
     427
     428Voice2612::Voice2612() {
     429        _control7 = 127;
     430        _note = 40;
     431        _frequency = 440;
     432        _frequencyOffs = 0x2000;
     433        _algorithm = 7;
     434        _opr = new Operator2612[_numOfOperators];
     435        velocity(0);
     436}
     437
     438Voice2612::~Voice2612() {
     439        delete [] _opr;
     440}
     441
     442void Voice2612::velocity(int velo) {
     443        _velocity = velo;
     444#if 0
     445        int v = (velo * _control7) >> 7; // ¤³¤ì¤À¤ÈÀºÅÙÎɤ¯¤Ê¤¤¤Ç¤¹¤Í
     446#else
     447        int v = velo + (_control7 - 127) * 4;
     448#endif
     449        bool iscarrier[8][4] = {
     450                { false, false, false,  true, }, //0
     451                { false, false, false,  true, }, //1
     452                { false, false, false,  true, }, //2
     453                { false, false, false,  true, }, //3
     454                { false,  true, false,  true, }, //4
     455                { false,  true,  true,  true, }, //5
     456                { false,  true,  true,  true, }, //6
     457                {  true,  true,  true,  true, }, //7
     458        };
     459        int opr;
     460        for (opr = 0; opr < 4; opr++)
     461                if (iscarrier[_algorithm][opr])
     462                        _opr[opr].velocity(v);
     463                else
     464                        _opr[opr].velocity(127);
     465}
     466
     467void Voice2612::setControlParameter(int control, int value) {
     468        switch (control) {
     469        case 7:
     470                _control7 = value;
     471                velocity(_velocity);
     472                break;
     473        case 10:
     474                // panpot
     475                break;
     476        };
     477}
     478
     479void Voice2612::setInstrument(byte const *instrument) {
     480        if (instrument == NULL)
     481                return;
     482
     483        _algorithm = instrument[32] & 7;
     484        _opr[0].feedbackLevel((instrument[32] >> 3) & 7);
     485        _opr[1].feedbackLevel(0);
     486        _opr[2].feedbackLevel(0);
     487        _opr[3].feedbackLevel(0);
     488        _opr[0].setInstrument(instrument + 0);
     489        _opr[1].setInstrument(instrument + 2);
     490        _opr[2].setInstrument(instrument + 1);
     491        _opr[3].setInstrument(instrument + 3);
     492}
     493
     494void Voice2612::nextTick(int *outbuf, int buflen) {
     495        if (_velocity == 0)
     496                return;
     497
     498        int i;
     499        for (i = 0; i < buflen; i++) {
     500                int d = 0;
     501                int d1, d2, d3, d4;
     502                switch (_algorithm) {
     503                case 0:
     504                        d1 = _opr[0].nextTick(_rate, 0);
     505                        d2 = _opr[1].nextTick(_rate, d1);
     506                        d3 = _opr[2].nextTick(_rate, d2);
     507                        d4 = _opr[3].nextTick(_rate, d3);
     508                        d = d4;
     509                        break;
     510                case 1:
     511                        d1 = _opr[0].nextTick(_rate, 0);
     512                        d2 = _opr[1].nextTick(_rate, 0);
     513                        d3 = _opr[2].nextTick(_rate, d1+d2);
     514                        d4 = _opr[3].nextTick(_rate, d3);
     515                        d = d4;
     516                        break;
     517                case 2:
     518                        d1 = _opr[0].nextTick(_rate, 0);
     519                        d2 = _opr[1].nextTick(_rate, 0);
     520                        d3 = _opr[2].nextTick(_rate, d2);
     521                        d4 = _opr[3].nextTick(_rate, d1+d3);
     522                        d = d4;
     523                        break;
     524                case 3:
     525                        d1 = _opr[0].nextTick(_rate, 0);
     526                        d2 = _opr[1].nextTick(_rate, d1);
     527                        d3 = _opr[2].nextTick(_rate, 0);
     528                        d4 = _opr[3].nextTick(_rate, d2+d3);
     529                        d = d4;
     530                        break;
     531                case 4:
     532                        d1 = _opr[0].nextTick(_rate, 0);
     533                        d2 = _opr[1].nextTick(_rate, d1);
     534                        d3 = _opr[2].nextTick(_rate, 0);
     535                        d4 = _opr[3].nextTick(_rate, d3);
     536                        d = d2 + d4;
     537                        break;
     538                case 5:
     539                        d1 = _opr[0].nextTick(_rate, 0);
     540                        d2 = _opr[1].nextTick(_rate, d1);
     541                        d3 = _opr[2].nextTick(_rate, d1);
     542                        d4 = _opr[3].nextTick(_rate, d1);
     543                        d = d2 + d3 + d4;
     544                        break;
     545                case 6:
     546                        d1 = _opr[0].nextTick(_rate, 0);
     547                        d2 = _opr[1].nextTick(_rate, d1);
     548                        d3 = _opr[2].nextTick(_rate, 0);
     549                        d4 = _opr[3].nextTick(_rate, 0);
     550                        d = d2 + d3 + d4;
     551                        break;
     552                case 7:
     553                        d1 = _opr[0].nextTick(_rate, 0);
     554                        d2 = _opr[1].nextTick(_rate, 0);
     555                        d3 = _opr[2].nextTick(_rate, 0);
     556                        d4 = _opr[3].nextTick(_rate, 0);
     557                        d = d1 + d2 + d3 + d4;
     558                        break;
     559                default:
     560                        break;
     561                };
     562
     563                outbuf[i] += d;
     564        }
     565}
     566
     567void Voice2612::noteOn(int n, int onVelo) {
     568        _note = n;
     569        velocity(onVelo);
     570        recalculateFrequency();
     571        int i;
     572        for (i = 0; i < _numOfOperators; i++)
     573                _opr[i].keyOn();
     574}
     575
     576bool Voice2612::noteOff(int note) {
     577        if (_note != note)
     578                return false;
     579        int i;
     580        for (i = 0; i < _numOfOperators; i++)
     581                _opr[i].keyOff();
     582        return true;
     583}
     584
     585void Voice2612::pitchBend(int value) {
     586        _frequencyOffs = value;
     587        recalculateFrequency();
     588}
     589
     590void Voice2612::recalculateFrequency() {
     591        // MIDI ¤È¤â°ã¤¦¤·....
     592        // ¤É¤¦¤¤¤¦»ÅÍͤʤó¤À¤í¤¦¤«?
     593        // ¤È»×¤Ã¤¿¤é¡¢¤Ê¤ó¤È¡¢¤³¤ì (¢­) ¤¬Àµ²ò¤é¤·¤¤¡£
     594        int64 basefreq = frequencyTable[_note];
     595        int cfreq = frequencyTable[_note - (_note % 12)];
     596        int oct = _note / 12;
     597        int fnum = (basefreq << 13) / cfreq; // OPL ¤Î fnum ¤ÈƱ¤¸¤è¤¦¤Ê¤â¤Î¡£
     598        fnum += _frequencyOffs - 0x2000;
     599        if (fnum < 0x2000) {
     600                fnum += 0x2000;
     601                oct--;
     602        }
     603        if (fnum >= 0x4000) {
     604                fnum -= 0x2000;
     605                oct++;
     606        }
     607
     608        // _frequency ¤ÏºÇ½ªÅª¤Ë¥Ð¥¤¥¢¥¹ 256*1024 ÇÜ
     609        _frequency = (frequencyTable[oct*12] * (int64)fnum) >> (13 - 10);
     610
     611        int i;
     612        for (i = 0; i < _numOfOperators; i++)
     613                _opr[i].frequency(_frequency);
     614}
     615
     616////////////////////////////////////////
     617//
     618// MidiChannel_YM2612
     619//
     620////////////////////////////////////////
     621
     622MidiChannel_YM2612::MidiChannel_YM2612() {
     623        _voice = new Voice2612;
     624}
     625
     626MidiChannel_YM2612::~MidiChannel_YM2612() {
     627        delete _voice;
     628}
     629
     630void MidiChannel_YM2612::noteOn(byte note, byte onVelo) {
     631        _voice->noteOn(note, onVelo);
     632}
     633
     634void MidiChannel_YM2612::noteOff(byte note) {
     635        _voice->noteOff(note);
     636}
     637
     638void MidiChannel_YM2612::controlChange(byte control, byte value) {
     639  // ¤¤¤¤¤Î¤«¤³¤ì¤Ç?
     640        _voice->setControlParameter(control, value);
     641}
     642
     643void MidiChannel_YM2612::sysEx_customInstrument(uint32 type, byte *fmInst) {
     644        if (type == 'EUP ')
     645                _voice->setInstrument(fmInst);
     646}
     647
     648void MidiChannel_YM2612::pitchBend(int16 value) {
     649  // ¤¤¤¤¤Î¤«¤³¤ì¤Ç?
     650        _voice->pitchBend(value);
     651}
     652
     653void MidiChannel_YM2612::nextTick(int *outbuf, int buflen) {
     654        _voice->nextTick(outbuf, buflen);
     655}
     656
     657void MidiChannel_YM2612::rate(int r) {
     658        _voice->rate(r);
     659}
     660
     661////////////////////////////////////////
     662//
     663// MidiDriver_YM2612
     664//
     665////////////////////////////////////////
     666
     667MidiDriver_YM2612::MidiDriver_YM2612(SoundMixer *mixer) :
     668_mixer(mixer)
     669{
     670        _isOpen = false;
     671        _timer_proc = 0;
     672        _timer_param = 0;
     673        _next_tick = 0;
     674        _samples_per_tick = (_mixer->getOutputRate() << FIXP_SHIFT) / BASE_FREQ;
     675
     676        createLookupTables();
     677        _volume = 256;
     678        int i;
     679        for (i = 0; i < ARRAYSIZE(_channel); i++)
     680                _channel[i] = new MidiChannel_YM2612;
     681
     682        outputSampleUnsigned(false);
     683        outputSampleSize(2);
     684        outputSampleLSBFirst(false);
     685        rate (_mixer->getOutputRate());
     686}
     687
     688MidiDriver_YM2612::~MidiDriver_YM2612() {
     689        int i;
     690        for (i = 0; i < ARRAYSIZE(_channel); i++)
     691                delete _channel[i];
     692        delete sintbl;
     693        delete powtbl;
     694        delete frequencyTable;
     695        delete keycodeTable;
     696        delete keyscaleTable;
     697        delete attackOut;
     698        sintbl = powtbl = frequencyTable = keycodeTable = keyscaleTable = attackOut = 0;
     699}
     700
     701int MidiDriver_YM2612::open() {
     702        if (_isOpen)
     703                return MERR_ALREADY_OPEN;
     704        _mixer->setupPremix(premix_proc, this);
     705        _isOpen = true;
    30706        return 0;
     707}
     708
     709void MidiDriver_YM2612::close() {
     710        if (!_isOpen)
     711                return;
     712        _isOpen = false;
     713
     714        // Detach the premix callback handler
     715        _mixer->setupPremix(0, 0);
     716}
     717
     718void MidiDriver_YM2612::setTimerCallback(void *timer_param, void (*timer_proc) (void *)) {
     719        _timer_proc = (TimerCallback *) timer_proc;
     720        _timer_param = timer_param;
     721}
     722
     723void MidiDriver_YM2612::send (uint32 b) {
     724        send (b & 0xF, b & 0xFFFFFFF0);
     725}
     726
     727void MidiDriver_YM2612::send (byte chan, uint32 b) {
     728        //byte param3 = (byte) ((b >> 24) & 0xFF);
     729        byte param2 = (byte) ((b >> 16) & 0xFF);
     730        byte param1 = (byte) ((b >>  8) & 0xFF);
     731        byte cmd    = (byte) (b & 0xF0);
     732        if (chan > ARRAYSIZE(_channel))
     733                return;
     734
     735        switch (cmd) {
     736        case 0x80:// Note Off
     737                _channel[chan]->noteOff(param1);
     738                break;
     739        case 0x90: // Note On
     740                _channel[chan]->noteOn(param1, param2);
     741                break;
     742        case 0xA0: // Aftertouch
     743                break; // Not supported.
     744        case 0xB0: // Control Change
     745                _channel[chan]->controlChange(param1, param2);
     746                break;
     747        case 0xC0: // Program Change
     748                _channel[chan]->programChange(param1);
     749                break;
     750        case 0xD0: // Channel Pressure
     751                break; // Not supported.
     752        case 0xE0: // Pitch Bend
     753                _channel[chan]->pitchBend((param1 | (param2 << 7)) - 0x2000);
     754                break;
     755        case 0xF0: // SysEx
     756                // We should never get here! SysEx information has to be
     757                // sent via high-level semantic methods.
     758                warning("MidiDriver_YM2612: Receiving SysEx command on a send() call");
     759                break;
     760
     761        default:
     762                warning("MidiDriver_YM2612: Unknown send() command 0x%02X", cmd);
     763        }
     764}
     765
     766void MidiDriver_YM2612::sysEx (byte *msg, uint16 length) {
     767        if (msg[0] != 0x7C || msg[1] >= ARRAYSIZE(_channel))
     768                return;
     769        _channel[msg[1]]->sysEx_customInstrument('EUP ', &msg[2]);
     770}
     771
     772void MidiDriver_YM2612::premix_proc(void *param, int16 *buf, uint len) {
     773        ((MidiDriver_YM2612 *) param)->generate_samples(buf, len);
     774}
     775
     776void MidiDriver_YM2612::generate_samples(int16 *data, int len) {
     777        int step;
     778
     779        int16 *origData = data;
     780        uint origLen = len;
     781
     782        do {
     783                step = len;
     784                if (step > (_next_tick >> FIXP_SHIFT))
     785                        step = (_next_tick >> FIXP_SHIFT);
     786                nextTick ((byte *) data, step);
     787
     788                _next_tick -= step << FIXP_SHIFT;
     789                if (!(_next_tick >> FIXP_SHIFT)) {
     790                        if (_timer_proc)
     791                                (*_timer_proc)(_timer_param);
     792                        _next_tick += _samples_per_tick;
     793                }
     794                data += step;
     795                len -= step;
     796        } while (len);
     797
     798        // Convert mono data to stereo
     799        int i;
     800        for (i = (origLen - 1); i >= 0; i--) {
     801                origData[2 * i] = origData[2 * i + 1] = origData[i];
     802        }
     803}
     804
     805void MidiDriver_YM2612::nextTick (byte *buf1, int buflen) {
     806        // steptime ¤Ò¤È¤Äʬ¿Ê¤á¤ë
     807        int *buf0 = new int [buflen];
     808        memset(buf0, 0, sizeof(buf0[0]) * buflen);
     809
     810        int i;
     811        for (i = 0; i < ARRAYSIZE(_channel); i++)
     812                _channel[i]->nextTick(buf0, buflen);
     813
     814        if (_outputSampleSize == 1) {
     815                for (i = 0; i < buflen; i++) {
     816                        int d = buf0[i];
     817                        d *= volume();
     818                        d >>= 10;                       // ¤¤¤¤¤«¤²¤ó¤À¤Ê¤¡
     819                        d ^= _outputSampleUnsigned?0x8000:0;
     820                        buf1[i] = ((d >> 8) & 0xff);
     821                }
     822        } else {
     823                for (i = 0; i < buflen; i++) {
     824                        int d = buf0[i];
     825                        d *= volume();
     826                        d >>= 10;                       // ¤¤¤¤¤«¤²¤ó¤À¤Ê¤¡
     827                        d ^= _outputSampleUnsigned?0x8000:0;
     828                        if (_outputSampleLSBFirst) {
     829                                buf1[i*2+0] = ((d >> 8) & 0xff);
     830                                buf1[i*2+1] = ((d >> 0) & 0xff);
     831                        } else {
     832                                buf1[i*2+1] = ((d >> 8) & 0xff);
     833                                buf1[i*2+0] = ((d >> 0) & 0xff);
     834                        }
     835                }
     836        }
     837        delete [] buf0;
     838}
     839
     840void MidiDriver_YM2612::rate(int r)
     841{
     842        _rate = r;
     843        int i;
     844        for (i = 0; i < ARRAYSIZE(_channel); i++)
     845                _channel[i]->rate(r);
     846}
     847
     848#define M_PI 3.14159265358979323846
     849void MidiDriver_YM2612::createLookupTables() {
     850        {
     851                int i;
     852                sintbl = new int [2048];
     853                for (i = 0; i < 2048; i++)
     854                        sintbl[i] = (int)(0xffff * sin(i/2048.0*2.0*M_PI));
     855        }
     856
     857        {
     858                int i;
     859                powtbl = new int [1025];
     860                for (i = 0; i <= 1024; i++)
     861                        powtbl[i] = (int)(0x10000 * pow(2.0, (i-512)/512.0));
     862        }
     863
     864        {
     865                int i;
     866                int block;
     867
     868                int const fnum[] = {
     869                        0x026a, 0x028f, 0x02b6, 0x02df,
     870                        0x030b, 0x0339, 0x036a, 0x039e,
     871                        0x03d5, 0x0410, 0x044e, 0x048f,
     872                };
     873
     874                // (int)(880.0 * 256.0 * pow(2.0, (note-0x51)/12.0)); // ¥Ð¥¤¥¢¥¹ 256 ÇÜ
     875                // 0x45 ¤¬ 440Hz (a4)¡¢0x51 ¤¬ 880Hz (a5) ¤é¤·¤¤
     876                frequencyTable = new int [120];
     877                for (block = -1; block < 9; block++) {
     878                        for (i = 0; i < 12; i++) {
     879                                double freq = fnum[i] * (166400.0 / 3) * pow(2.0, block-21);
     880                                frequencyTable[(block+1)*12+i] = (int)(256.0 * freq);
     881                        }
     882                }
     883
     884                keycodeTable = new int [120];
     885                // detune Î̤η׻»¤ä KS ¤Ë¤è¤ë rate ÊÑ´¹¤Ë»È¤¦¤ó¤¸¤ã¤Ê¤¤¤«¤Ê
     886                for (block = -1; block < 9; block++) {
     887                        for (i = 0; i < 12; i++) {
     888                                // see p.204
     889                                int  f8 = (fnum[i] >>  7) & 1;
     890                                int  f9 = (fnum[i] >>  8) & 1;
     891                                int f10 = (fnum[i] >>  9) & 1;
     892                                int f11 = (fnum[i] >> 10) & 1;
     893                                int  n4 = f11;
     894                                int  n3 = f11&(f10|f9|f8) | (~f11&f10&f9&f8);
     895                                int note = n4*2 + n3;
     896                                // see p.207
     897                                keycodeTable[(block+1)*12+i] = block*4 + note;
     898                        }
     899                }
     900        }
     901
     902        {
     903                int freq;
     904                keyscaleTable = new int [8192];
     905                keyscaleTable[0] = 0;
     906                for (freq = 1; freq < 8192; freq++) {
     907                        keyscaleTable[freq] = (int)(log((double)freq) / 9.03 * 32.0) - 1;
     908                        // 8368[Hz] (o9c) ¤Ç 32¤¯¤é¤¤¡£9.03 =:= ln 8368
     909                }
     910        }
     911
     912        {
     913                int i;
     914                attackOut = new int [1024];
     915                for (i = 0; i < 1024; i++)
     916                        attackOut[i] = (int)(((0x7fff+0x03a5)*30.0) / (30.0+i)) - 0x03a5;
     917        }
     918}
     919
     920////////////////////////////////////////
     921//
     922// MidiDriver_YM2612 factory
     923//
     924////////////////////////////////////////
     925
     926MidiDriver *MidiDriver_YM2612_create(SoundMixer *mixer) {
     927        return new MidiDriver_YM2612(mixer);
    31928}