12a6a4076SMarkus Armbruster #ifndef FMOPL_H 22a6a4076SMarkus Armbruster #define FMOPL_H 347b43a1fSPaolo Bonzini 44a796e97SJuan Quintela 5c57fbf50SHervé Poussineau typedef void (*OPL_TIMERHANDLER)(void *param, int channel, double interval_Sec); 647b43a1fSPaolo Bonzini 747b43a1fSPaolo Bonzini /* !!!!! here is private section , do not access there member direct !!!!! */ 847b43a1fSPaolo Bonzini 947b43a1fSPaolo Bonzini /* Saving is necessary for member of the 'R' mark for suspend/resume */ 1047b43a1fSPaolo Bonzini /* ---------- OPL one of slot ---------- */ 1147b43a1fSPaolo Bonzini typedef struct fm_opl_slot { 127f643fb5SJuan Quintela int32_t TL; /* total level :TL << 8 */ 137f643fb5SJuan Quintela int32_t TLL; /* adjusted now TL */ 144a796e97SJuan Quintela uint8_t KSR; /* key scale rate :(shift down bit) */ 157f643fb5SJuan Quintela int32_t *AR; /* attack rate :&AR_TABLE[AR<<2] */ 167f643fb5SJuan Quintela int32_t *DR; /* decay rate :&DR_TALBE[DR<<2] */ 177f643fb5SJuan Quintela int32_t SL; /* sustin level :SL_TALBE[SL] */ 187f643fb5SJuan Quintela int32_t *RR; /* release rate :&DR_TABLE[RR<<2] */ 194a796e97SJuan Quintela uint8_t ksl; /* keyscale level :(shift down bits) */ 204a796e97SJuan Quintela uint8_t ksr; /* key scale rate :kcode>>KSR */ 213795f180SJuan Quintela uint32_t mul; /* multiple :ML_TABLE[ML] */ 223795f180SJuan Quintela uint32_t Cnt; /* frequency count : */ 233795f180SJuan Quintela uint32_t Incr; /* frequency step : */ 2447b43a1fSPaolo Bonzini /* envelope generator state */ 254a796e97SJuan Quintela uint8_t eg_typ; /* envelope type flag */ 264a796e97SJuan Quintela uint8_t evm; /* envelope phase */ 277f643fb5SJuan Quintela int32_t evc; /* envelope counter */ 287f643fb5SJuan Quintela int32_t eve; /* envelope counter end point */ 297f643fb5SJuan Quintela int32_t evs; /* envelope counter step */ 307f643fb5SJuan Quintela int32_t evsa; /* envelope step for AR :AR[ksr] */ 317f643fb5SJuan Quintela int32_t evsd; /* envelope step for DR :DR[ksr] */ 327f643fb5SJuan Quintela int32_t evsr; /* envelope step for RR :RR[ksr] */ 3347b43a1fSPaolo Bonzini /* LFO */ 344a796e97SJuan Quintela uint8_t ams; /* ams flag */ 354a796e97SJuan Quintela uint8_t vib; /* vibrate flag */ 3647b43a1fSPaolo Bonzini /* wave selector */ 377f643fb5SJuan Quintela int32_t **wavetable; 3847b43a1fSPaolo Bonzini }OPL_SLOT; 3947b43a1fSPaolo Bonzini 4047b43a1fSPaolo Bonzini /* ---------- OPL one of channel ---------- */ 4147b43a1fSPaolo Bonzini typedef struct fm_opl_channel { 4247b43a1fSPaolo Bonzini OPL_SLOT SLOT[2]; 434a796e97SJuan Quintela uint8_t CON; /* connection type */ 444a796e97SJuan Quintela uint8_t FB; /* feed back :(shift down bit) */ 457f643fb5SJuan Quintela int32_t *connect1; /* slot1 output pointer */ 467f643fb5SJuan Quintela int32_t *connect2; /* slot2 output pointer */ 477f643fb5SJuan Quintela int32_t op1_out[2]; /* slot1 output for selfeedback */ 4847b43a1fSPaolo Bonzini /* phase generator state */ 493795f180SJuan Quintela uint32_t block_fnum; /* block+fnum : */ 504a796e97SJuan Quintela uint8_t kcode; /* key code : KeyScaleCode */ 513795f180SJuan Quintela uint32_t fc; /* Freq. Increment base */ 523795f180SJuan Quintela uint32_t ksl_base; /* KeyScaleLevel Base step */ 534a796e97SJuan Quintela uint8_t keyon; /* key on/off flag */ 5447b43a1fSPaolo Bonzini } OPL_CH; 5547b43a1fSPaolo Bonzini 5647b43a1fSPaolo Bonzini /* OPL state */ 5747b43a1fSPaolo Bonzini typedef struct fm_opl_f { 5847b43a1fSPaolo Bonzini int clock; /* master clock (Hz) */ 5947b43a1fSPaolo Bonzini int rate; /* sampling rate (Hz) */ 6047b43a1fSPaolo Bonzini double freqbase; /* frequency base */ 6147b43a1fSPaolo Bonzini double TimerBase; /* Timer base time (==sampling time) */ 624a796e97SJuan Quintela uint8_t address; /* address register */ 634a796e97SJuan Quintela uint8_t status; /* status flag */ 644a796e97SJuan Quintela uint8_t statusmask; /* status mask */ 653795f180SJuan Quintela uint32_t mode; /* Reg.08 : CSM , notesel,etc. */ 6647b43a1fSPaolo Bonzini /* Timer */ 6747b43a1fSPaolo Bonzini int T[2]; /* timer counter */ 684a796e97SJuan Quintela uint8_t st[2]; /* timer enable */ 6947b43a1fSPaolo Bonzini /* FM channel slots */ 7047b43a1fSPaolo Bonzini OPL_CH *P_CH; /* pointer of CH */ 7147b43a1fSPaolo Bonzini int max_ch; /* maximum channel */ 72*528ea579SMichael Tokarev /* Rhythm section */ 734a796e97SJuan Quintela uint8_t rhythm; /* Rhythm mode , key flag */ 7447b43a1fSPaolo Bonzini /* time tables */ 7557ac4a7aSGerd Hoffmann int32_t AR_TABLE[76]; /* attack rate tables */ 7657ac4a7aSGerd Hoffmann int32_t DR_TABLE[76]; /* decay rate tables */ 773795f180SJuan Quintela uint32_t FN_TABLE[1024]; /* fnumber -> increment counter */ 7847b43a1fSPaolo Bonzini /* LFO */ 797f643fb5SJuan Quintela int32_t *ams_table; 807f643fb5SJuan Quintela int32_t *vib_table; 817f643fb5SJuan Quintela int32_t amsCnt; 827f643fb5SJuan Quintela int32_t amsIncr; 837f643fb5SJuan Quintela int32_t vibCnt; 847f643fb5SJuan Quintela int32_t vibIncr; 8547b43a1fSPaolo Bonzini /* wave selector enable flag */ 864a796e97SJuan Quintela uint8_t wavesel; 8747b43a1fSPaolo Bonzini /* external event callback handler */ 8847b43a1fSPaolo Bonzini OPL_TIMERHANDLER TimerHandler; /* TIMER handler */ 89c57fbf50SHervé Poussineau void *TimerParam; /* TIMER parameter */ 9047b43a1fSPaolo Bonzini } FM_OPL; 9147b43a1fSPaolo Bonzini 9247b43a1fSPaolo Bonzini /* ---------- Generic interface section ---------- */ 938f7e2c2cSJuan Quintela FM_OPL *OPLCreate(int clock, int rate); 9447b43a1fSPaolo Bonzini void OPLDestroy(FM_OPL *OPL); 95c57fbf50SHervé Poussineau void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler, 96c57fbf50SHervé Poussineau void *param); 9747b43a1fSPaolo Bonzini 9847b43a1fSPaolo Bonzini int OPLWrite(FM_OPL *OPL,int a,int v); 9947b43a1fSPaolo Bonzini unsigned char OPLRead(FM_OPL *OPL,int a); 10047b43a1fSPaolo Bonzini int OPLTimerOver(FM_OPL *OPL,int c); 10147b43a1fSPaolo Bonzini 1027bf10b1dSJuan Quintela void YM3812UpdateOne(FM_OPL *OPL, int16_t *buffer, int length); 10347b43a1fSPaolo Bonzini #endif 104