| 1 | #ifndef FMOPL_H |
| 2 | #define FMOPL_H |
| 3 | |
| 4 | |
| 5 | typedef void (*OPL_TIMERHANDLER)(void *param, int channel, double interval_Sec); |
| 6 | |
| 7 | /* !!!!! here is private section , do not access there member direct !!!!! */ |
| 8 | |
| 9 | /* Saving is necessary for member of the 'R' mark for suspend/resume */ |
| 10 | /* ---------- OPL one of slot ---------- */ |
| 11 | typedef struct fm_opl_slot { |
| 12 | int32_t TL; /* total level :TL << 8 */ |
| 13 | int32_t TLL; /* adjusted now TL */ |
| 14 | uint8_t KSR; /* key scale rate :(shift down bit) */ |
| 15 | int32_t *AR; /* attack rate :&AR_TABLE[AR<<2] */ |
| 16 | int32_t *DR; /* decay rate :&DR_TALBE[DR<<2] */ |
| 17 | int32_t SL; /* sustin level :SL_TALBE[SL] */ |
| 18 | int32_t *RR; /* release rate :&DR_TABLE[RR<<2] */ |
| 19 | uint8_t ksl; /* keyscale level :(shift down bits) */ |
| 20 | uint8_t ksr; /* key scale rate :kcode>>KSR */ |
| 21 | uint32_t mul; /* multiple :ML_TABLE[ML] */ |
| 22 | uint32_t Cnt; /* frequency count : */ |
| 23 | uint32_t Incr; /* frequency step : */ |
| 24 | /* envelope generator state */ |
| 25 | uint8_t eg_typ; /* envelope type flag */ |
| 26 | uint8_t evm; /* envelope phase */ |
| 27 | int32_t evc; /* envelope counter */ |
| 28 | int32_t eve; /* envelope counter end point */ |
| 29 | int32_t evs; /* envelope counter step */ |
| 30 | int32_t evsa; /* envelope step for AR :AR[ksr] */ |
| 31 | int32_t evsd; /* envelope step for DR :DR[ksr] */ |
| 32 | int32_t evsr; /* envelope step for RR :RR[ksr] */ |
| 33 | /* LFO */ |
| 34 | uint8_t ams; /* ams flag */ |
| 35 | uint8_t vib; /* vibrate flag */ |
| 36 | /* wave selector */ |
| 37 | int32_t **wavetable; |
| 38 | }OPL_SLOT; |
| 39 | |
| 40 | /* ---------- OPL one of channel ---------- */ |
| 41 | typedef struct fm_opl_channel { |
| 42 | OPL_SLOT SLOT[2]; |
| 43 | uint8_t CON; /* connection type */ |
| 44 | uint8_t FB; /* feed back :(shift down bit) */ |
| 45 | int32_t *connect1; /* slot1 output pointer */ |
| 46 | int32_t *connect2; /* slot2 output pointer */ |
| 47 | int32_t op1_out[2]; /* slot1 output for selfeedback */ |
| 48 | /* phase generator state */ |
| 49 | uint32_t block_fnum; /* block+fnum : */ |
| 50 | uint8_t kcode; /* key code : KeyScaleCode */ |
| 51 | uint32_t fc; /* Freq. Increment base */ |
| 52 | uint32_t ksl_base; /* KeyScaleLevel Base step */ |
| 53 | uint8_t keyon; /* key on/off flag */ |
| 54 | } OPL_CH; |
| 55 | |
| 56 | /* OPL state */ |
| 57 | typedef struct fm_opl_f { |
| 58 | int clock; /* master clock (Hz) */ |
| 59 | int rate; /* sampling rate (Hz) */ |
| 60 | double freqbase; /* frequency base */ |
| 61 | double TimerBase; /* Timer base time (==sampling time) */ |
| 62 | uint8_t address; /* address register */ |
| 63 | uint8_t status; /* status flag */ |
| 64 | uint8_t statusmask; /* status mask */ |
| 65 | uint32_t mode; /* Reg.08 : CSM , notesel,etc. */ |
| 66 | /* Timer */ |
| 67 | int T[2]; /* timer counter */ |
| 68 | uint8_t st[2]; /* timer enable */ |
| 69 | /* FM channel slots */ |
| 70 | OPL_CH *P_CH; /* pointer of CH */ |
| 71 | int max_ch; /* maximum channel */ |
| 72 | /* Rhythm section */ |
| 73 | uint8_t rhythm; /* Rhythm mode , key flag */ |
| 74 | /* time tables */ |
| 75 | int32_t AR_TABLE[76]; /* attack rate tables */ |
| 76 | int32_t DR_TABLE[76]; /* decay rate tables */ |
| 77 | uint32_t FN_TABLE[1024]; /* fnumber -> increment counter */ |
| 78 | /* LFO */ |
| 79 | int32_t *ams_table; |
| 80 | int32_t *vib_table; |
| 81 | int32_t amsCnt; |
| 82 | int32_t amsIncr; |
| 83 | int32_t vibCnt; |
| 84 | int32_t vibIncr; |
| 85 | /* wave selector enable flag */ |
| 86 | uint8_t wavesel; |
| 87 | /* external event callback handler */ |
| 88 | OPL_TIMERHANDLER TimerHandler; /* TIMER handler */ |
| 89 | void *TimerParam; /* TIMER parameter */ |
| 90 | } FM_OPL; |
| 91 | |
| 92 | /* ---------- Generic interface section ---------- */ |
| 93 | FM_OPL *OPLCreate(int clock, int rate); |
| 94 | void OPLDestroy(FM_OPL *OPL); |
| 95 | void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler, |
| 96 | void *param); |
| 97 | |
| 98 | int OPLWrite(FM_OPL *OPL,int a,int v); |
| 99 | unsigned char OPLRead(FM_OPL *OPL,int a); |
| 100 | int OPLTimerOver(FM_OPL *OPL,int c); |
| 101 | |
| 102 | void YM3812UpdateOne(FM_OPL *OPL, int16_t *buffer, int length); |
| 103 | #endif |