#ifndef _YM2612_H_ #define _YM2612_H_ // Change it if you need to do long update //#define MAX_UPDATE_LENGHT 4000 #define MAX_UPDATE_LENGHT 0x100 //#define MAX_UPDATE_LENGHT 1 // for in_vgm // Gens always uses 16 bits sound (in 32 bits buffer) and do the convertion later if needed. #define OUTPUT_BITS 15 // OUTPUT_BITS 15 is MAME's volume level #define DAC_SHIFT (OUTPUT_BITS - 9) // DAC_SHIFT makes sure that FM and DAC volume has the same volume // VC++ inline #ifndef INLINE #define INLINE __inline #endif typedef struct slot__ { int *DT; // paramètre detune int MUL; // paramètre "multiple de fréquence" int TL; // Total Level = volume lorsque l'enveloppe est au plus haut int TLL; // Total Level ajusted int SLL; // Sustin Level (ajusted) = volume où l'enveloppe termine sa première phase de régression int KSR_S; // Key Scale Rate Shift = facteur de prise en compte du KSL dans la variations de l'enveloppe int KSR; // Key Scale Rate = cette valeur est calculée par rapport à la fréquence actuelle, elle va influer // sur les différents paramètres de l'enveloppe comme l'attaque, le decay ... comme dans la réalité ! int SEG; // Type enveloppe SSG int *AR; // Attack Rate (table pointeur) = Taux d'attaque (AR[KSR]) int *DR; // Decay Rate (table pointeur) = Taux pour la régression (DR[KSR]) int *SR; // Sustin Rate (table pointeur) = Taux pour le maintien (SR[KSR]) int *RR; // Release Rate (table pointeur) = Taux pour le relâchement (RR[KSR]) int Fcnt; // Frequency Count = compteur-fréquence pour déterminer l'amplitude actuelle (SIN[Finc >> 16]) int Finc; // frequency step = pas d'incrémentation du compteur-fréquence // plus le pas est grand, plus la fréquence est aïgu (ou haute) int Ecurp; // Envelope current phase = cette variable permet de savoir dans quelle phase // de l'enveloppe on se trouve, par exemple phase d'attaque ou phase de maintenue ... // en fonction de la valeur de cette variable, on va appeler une fonction permettant // de mettre à jour l'enveloppe courante. int Ecnt; // Envelope counter = le compteur-enveloppe permet de savoir où l'on se trouve dans l'enveloppe int Einc; // Envelope step courant int Ecmp; // Envelope counter limite pour la prochaine phase int EincA; // Envelope step for Attack = pas d'incrémentation du compteur durant la phase d'attaque // cette valeur est égal à AR[KSR] int EincD; // Envelope step for Decay = pas d'incrémentation du compteur durant la phase de regression // cette valeur est égal à DR[KSR] int EincS; // Envelope step for Sustain = pas d'incrémentation du compteur durant la phase de maintenue // cette valeur est égal à SR[KSR] int EincR; // Envelope step for Release = pas d'incrémentation du compteur durant la phase de relâchement // cette valeur est égal à RR[KSR] int *OUTp; // pointeur of SLOT output = pointeur permettant de connecter la sortie de ce slot à l'entrée // d'un autre ou carrement à la sortie de la voie int INd; // input data of the slot = données en entrée du slot int ChgEnM; // Change envelop mask. int AMS; // AMS depth level of this SLOT = degré de modulation de l'amplitude par le LFO int AMSon; // AMS enable flag = drapeau d'activation de l'AMS } slot_; typedef struct channel__ { int S0_OUT[4]; // anciennes sorties slot 0 (pour le feed back) int Old_OUTd; // ancienne sortie de la voie (son brut) int OUTd; // sortie de la voie (son brut) int LEFT; // LEFT enable flag int RIGHT; // RIGHT enable flag int ALGO; // Algorythm = détermine les connections entre les opérateurs int FB; // shift count of self feed back = degré de "Feed-Back" du SLOT 1 (il est son unique entrée) int FMS; // Fréquency Modulation Sensitivity of channel = degré de modulation de la fréquence sur la voie par le LFO int AMS; // Amplitude Modulation Sensitivity of channel = degré de modulation de l'amplitude sur la voie par le LFO int FNUM[4]; // hauteur fréquence de la voie (+ 3 pour le mode spécial) int FOCT[4]; // octave de la voie (+ 3 pour le mode spécial) int KC[4]; // Key Code = valeur fonction de la fréquence (voir KSR pour les slots, KSR = KC >> KSR_S) struct slot__ SLOT[4]; // four slot.operators = les 4 slots de la voie int FFlag; // Frequency step recalculation flag int Mute; // Maxim: channel mute flag } channel_; typedef struct ym2612__ { int Clock; // Horloge YM2612 int Rate; // Sample Rate (11025/22050/44100) int TimerBase; // TimerBase calculation int Status; // YM2612 Status (timer overflow) int OPNAadr; // addresse pour l'écriture dans l'OPN A (propre à l'émulateur) int OPNBadr; // addresse pour l'écriture dans l'OPN B (propre à l'émulateur) int LFOcnt; // LFO counter = compteur-fréquence pour le LFO int LFOinc; // LFO step counter = pas d'incrémentation du compteur-fréquence du LFO // plus le pas est grand, plus la fréquence est grande int TimerA; // timerA limit = valeur jusqu'à laquelle le timer A doit compter int TimerAL; int TimerAcnt; // timerA counter = valeur courante du Timer A int TimerB; // timerB limit = valeur jusqu'à laquelle le timer B doit compter int TimerBL; int TimerBcnt; // timerB counter = valeur courante du Timer B int Mode; // Mode actuel des voie 3 et 6 (normal / spécial) int DAC; // DAC enabled flag int DACdata; // DAC data long dac_highpass; double Frequence; // Fréquence de base, se calcul par rapport à l'horlage et au sample rate unsigned int Inter_Cnt; // Interpolation Counter unsigned int Inter_Step; // Interpolation Step struct channel__ CHANNEL[6]; // Les 6 voies du YM2612 int REG[2][0x100]; // Sauvegardes des valeurs de tout les registres, c'est facultatif // cela nous rend le débuggage plus facile int LFO_ENV_UP[MAX_UPDATE_LENGHT]; // Temporary calculated LFO AMS (adjusted for 11.8 dB) * int LFO_FREQ_UP[MAX_UPDATE_LENGHT]; // Temporary calculated LFO FMS * int in0, in1, in2, in3; // current phase calculation * int en0, en1, en2, en3; // current enveloppe calculation * int DAC_Mute; } ym2612_; /* Gens */ //extern int YM2612_Enable; //extern int YM2612_Improv; //extern int DAC_Enable; //extern int *YM_Buf[2]; //extern int YM_Len; /* end */ ym2612_ *YM2612_Init(int clock, int rate, int interpolation); int YM2612_End(ym2612_ *YM2612); int YM2612_Reset(ym2612_ *YM2612); int YM2612_Read(ym2612_ *YM2612); int YM2612_Write(ym2612_ *YM2612, unsigned char adr, unsigned char data); void YM2612_ClearBuffer(int **buffer, int length); void YM2612_Update(ym2612_ *YM2612, int **buf, int length); /*int YM2612_Save(ym2612_ *YM2612, unsigned char SAVE[0x200]); int YM2612_Restore(ym2612_ *YM2612, unsigned char SAVE[0x200]);*/ /* Maxim: muting (bits 0-5 for channels 0-5) */ int YM2612_GetMute(ym2612_ *YM2612); void YM2612_SetMute(ym2612_ *YM2612, int val); void YM2612_SetOptions(int Flags); /* Gens */ void YM2612_DacAndTimers_Update(ym2612_ *YM2612, int **buffer, int length); void YM2612_Special_Update(ym2612_ *YM2612); /* end */ // used for foward... void Update_Chan_Algo0(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo1(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo2(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo3(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo4(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo5(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo6(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo7(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo0_LFO(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo1_LFO(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo2_LFO(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo3_LFO(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo4_LFO(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo5_LFO(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo6_LFO(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo7_LFO(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo0_Int(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo1_Int(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo2_Int(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo3_Int(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo4_Int(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo5_Int(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo6_Int(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo7_Int(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo0_LFO_Int(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo1_LFO_Int(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo2_LFO_Int(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo3_LFO_Int(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo4_LFO_Int(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo5_LFO_Int(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo6_LFO_Int(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); void Update_Chan_Algo7_LFO_Int(ym2612_ *YM2612, channel_ *CH, int **buf, int lenght); // used for foward... void Env_Attack_Next(slot_ *SL); void Env_Decay_Next(slot_ *SL); void Env_Substain_Next(slot_ *SL); void Env_Release_Next(slot_ *SL); void Env_NULL_Next(slot_ *SL); #endif