1 // YM2612 FM sound chip emulator
3 // Game_Music_Emu 0.6-pre
7 #include "blargg_common.h"
9 enum { ym2612_out_chan_count
= 2 }; // stereo
10 enum { ym2612_channel_count
= 6 };
11 enum { ym2612_disabled_time
= -1 };
15 const int *DT
; // parametre detune
16 int MUL
; // parametre "multiple de frequence"
17 int TL
; // Total Level = volume lorsque l'enveloppe est au plus haut
18 int TLL
; // Total Level ajusted
19 int SLL
; // Sustin Level (ajusted) = volume où l'enveloppe termine sa premiere phase de regression
20 int KSR_S
; // Key Scale Rate Shift = facteur de prise en compte du KSL dans la variations de l'enveloppe
21 int KSR
; // Key Scale Rate = cette valeur est calculee par rapport à la frequence actuelle, elle va influer
22 // sur les differents parametres de l'enveloppe comme l'attaque, le decay ... comme dans la realite !
23 int SEG
; // Type enveloppe SSG
27 const int *AR
; // Attack Rate (table pointeur) = Taux d'attaque (AR [KSR])
28 const int *DR
; // Decay Rate (table pointeur) = Taux pour la regression (DR [KSR])
29 const int *SR
; // Sustin Rate (table pointeur) = Taux pour le maintien (SR [KSR])
30 const int *RR
; // Release Rate (table pointeur) = Taux pour le rel'chement (RR [KSR])
31 int Fcnt
; // Frequency Count = compteur-frequence pour determiner l'amplitude actuelle (SIN [Finc >> 16])
32 int Finc
; // frequency step = pas d'incrementation du compteur-frequence
33 // plus le pas est grand, plus la frequence est aïgu (ou haute)
34 int Ecurp
; // Envelope current phase = cette variable permet de savoir dans quelle phase
35 // de l'enveloppe on se trouve, par exemple phase d'attaque ou phase de maintenue ...
36 // en fonction de la valeur de cette variable, on va appeler une fonction permettant
37 // de mettre à jour l'enveloppe courante.
38 int Ecnt
; // Envelope counter = le compteur-enveloppe permet de savoir où l'on se trouve dans l'enveloppe
39 int Einc
; // Envelope step courant
40 int Ecmp
; // Envelope counter limite pour la prochaine phase
41 int EincA
; // Envelope step for Attack = pas d'incrementation du compteur durant la phase d'attaque
42 // cette valeur est egal à AR [KSR]
43 int EincD
; // Envelope step for Decay = pas d'incrementation du compteur durant la phase de regression
44 // cette valeur est egal à DR [KSR]
45 int EincS
; // Envelope step for Sustain = pas d'incrementation du compteur durant la phase de maintenue
46 // cette valeur est egal à SR [KSR]
47 int EincR
; // Envelope step for Release = pas d'incrementation du compteur durant la phase de rel'chement
48 // cette valeur est egal à RR [KSR]
49 int *OUTp
; // pointeur of SLOT output = pointeur permettant de connecter la sortie de ce slot à l'entree
50 // d'un autre ou carrement à la sortie de la voie
51 int INd
; // input data of the slot = donnees en entree du slot
52 int ChgEnM
; // Change envelop mask.
53 int AMS
; // AMS depth level of this SLOT = degre de modulation de l'amplitude par le LFO
54 int AMSon
; // AMS enable flag = drapeau d'activation de l'AMS
59 int S0_OUT
[4]; // anciennes sorties slot 0 (pour le feed back)
60 int LEFT
; // LEFT enable flag
61 int RIGHT
; // RIGHT enable flag
62 int ALGO
; // Algorythm = determine les connections entre les operateurs
63 int FB
; // shift count of self feed back = degre de "Feed-Back" du SLOT 1 (il est son unique entree)
64 int FMS
; // Frequency Modulation Sensitivity of channel = degre de modulation de la frequence sur la voie par le LFO
65 int AMS
; // Amplitude Modulation Sensitivity of channel = degre de modulation de l'amplitude sur la voie par le LFO
66 int FNUM
[4]; // hauteur frequence de la voie (+ 3 pour le mode special)
67 int FOCT
[4]; // octave de la voie (+ 3 pour le mode special)
68 int KC
[4]; // Key Code = valeur fonction de la frequence (voir KSR pour les slots, KSR = KC >> KSR_S)
69 struct slot_t SLOT
[4]; // four slot.operators = les 4 slots de la voie
70 int FFlag
; // Frequency step recalculation flag
75 int TimerBase
; // TimerBase calculation
76 int Status
; // YM2612 Status (timer overflow)
77 int TimerA
; // timerA limit = valeur jusqu'à laquelle le timer A doit compter
79 int TimerAcnt
; // timerA counter = valeur courante du Timer A
80 int TimerB
; // timerB limit = valeur jusqu'à laquelle le timer B doit compter
82 int TimerBcnt
; // timerB counter = valeur courante du Timer B
83 int Mode
; // Mode actuel des voie 3 et 6 (normal / special)
84 int DAC
; // DAC enabled flag
85 struct channel_ CHANNEL
[ym2612_channel_count
]; // Les 6 voies du YM2612
86 int REG
[2] [0x100]; // Sauvegardes des valeurs de tout les registres, c'est facultatif
87 // cela nous rend le debuggage plus facile
91 #define PI 3.14159265358979323846
100 // (SIN_LBITS + SIN_HBITS) <= 26
101 // (ENV_LBITS + ENV_HBITS) <= 28
102 // (LFO_LBITS + LFO_HBITS) <= 28
104 #define SIN_HBITS 12 // Sinus phase counter int part
105 #define SIN_LBITS (26 - SIN_HBITS) // Sinus phase counter float part (best setting)
108 #define SIN_LBITS 16 // Can't be greater than 16 bits
111 #define ENV_HBITS 12 // Env phase counter int part
112 #define ENV_LBITS (28 - ENV_HBITS) // Env phase counter float part (best setting)
114 #define LFO_HBITS 10 // LFO phase counter int part
115 #define LFO_LBITS (28 - LFO_HBITS) // LFO phase counter float part (best setting)
117 #define SIN_LENGHT (1 << SIN_HBITS)
118 #define ENV_LENGHT (1 << ENV_HBITS)
119 #define LFO_LENGHT (1 << LFO_HBITS)
121 #define TL_LENGHT (ENV_LENGHT * 3) // Env + TL scaling + LFO
123 #define SIN_MASK (SIN_LENGHT - 1)
124 #define ENV_MASK (ENV_LENGHT - 1)
125 #define LFO_MASK (LFO_LENGHT - 1)
127 #define ENV_STEP (96.0 / ENV_LENGHT) // ENV_MAX = 96 dB
129 #define ENV_ATTACK ((ENV_LENGHT * 0) << ENV_LBITS)
130 #define ENV_DECAY ((ENV_LENGHT * 1) << ENV_LBITS)
131 #define ENV_END ((ENV_LENGHT * 2) << ENV_LBITS)
133 #define MAX_OUT_BITS (SIN_HBITS + SIN_LBITS + 2) // Modulation = -4 <--> +4
134 #define MAX_OUT ((1 << MAX_OUT_BITS) - 1)
136 #define PG_CUT_OFF ((int) (78.0 / ENV_STEP))
137 //#define ENV_CUT_OFF ((int) (68.0 / ENV_STEP))
139 #define AR_RATE 399128
140 #define DR_RATE 5514396
142 //#define AR_RATE 426136
143 //#define DR_RATE (AR_RATE * 12)
145 #define LFO_FMS_LBITS 9 // FIXED (LFO_FMS_BASE gives somethink as 1)
146 #define LFO_FMS_BASE ((int) (0.05946309436 * 0.0338 * (double) (1 << LFO_FMS_LBITS)))
148 #define S0 0 // Stupid typo of the YM2612
155 short SIN_TAB
[SIN_LENGHT
]; // SINUS TABLE (offset into TL TABLE)
156 int LFOcnt
; // LFO counter = compteur-frequence pour le LFO
157 int LFOinc
; // LFO step counter = pas d'incrementation du compteur-frequence du LFO
158 // plus le pas est grand, plus la frequence est grande
159 unsigned int AR_TAB
[128]; // Attack rate table
160 unsigned int DR_TAB
[96]; // Decay rate table
161 unsigned int DT_TAB
[8] [32]; // Detune table
162 unsigned int SL_TAB
[16]; // Substain level table
163 unsigned int NULL_RATE
[32]; // Table for NULL rate
164 int LFO_INC_TAB
[8]; // LFO step table
166 short ENV_TAB
[2 * ENV_LENGHT
+ 8]; // ENV CURVE TABLE (attack & decay)
168 short LFO_ENV_TAB
[LFO_LENGHT
]; // LFO AMS TABLE (adjusted for 11.8 dB)
169 short LFO_FREQ_TAB
[LFO_LENGHT
]; // LFO FMS TABLE
170 int TL_TAB
[TL_LENGHT
* 2]; // TOTAL LEVEL TABLE (positif and minus)
171 unsigned int DECAY_TO_ATTACK
[ENV_LENGHT
]; // Conversion from decay to attack phase
172 unsigned int FINC_TAB
[2048]; // Frequency step table
177 struct state_t YM2612
;
182 void impl_reset( struct Ym2612_Impl
* impl
);
185 struct Ym2612_Impl impl
;
194 static inline void Ym2612_init( struct Ym2612_Emu
* this_
)
196 this_
->last_time
= ym2612_disabled_time
; this_
->out
= 0;
197 this_
->impl
.mute_mask
= 0;
200 // Sets sample rate and chip clock rate, in Hz. Returns non-zero
201 // if error. If clock_rate=0, uses sample_rate*144
202 const char* Ym2612_set_rate( struct Ym2612_Emu
* this_
, double sample_rate
, double clock_rate
);
204 // Resets to power-up state
205 void Ym2612_reset( struct Ym2612_Emu
* this_
);
207 // Mutes voice n if bit n (1 << n) of mask is set
208 void Ym2612_mute_voices( struct Ym2612_Emu
* this_
, int mask
);
210 // Writes addr to register 0 then data to register 1
211 void Ym2612_write0( struct Ym2612_Emu
* this_
, int addr
, int data
) ICODE_ATTR
;
213 // Writes addr to register 2 then data to register 3
214 void Ym2612_write1( struct Ym2612_Emu
* this_
, int addr
, int data
) ICODE_ATTR
;
216 // Runs and adds pair_count*2 samples into current output buffer contents
217 void Ym2612_run( struct Ym2612_Emu
* this_
, int pair_count
, short* out
) ICODE_ATTR
;
219 static inline void Ym2612_enable( struct Ym2612_Emu
* this_
, bool b
) { this_
->last_time
= b
? 0 : ym2612_disabled_time
; }
220 static inline bool Ym2612_enabled( struct Ym2612_Emu
* this_
) { return this_
->last_time
!= ym2612_disabled_time
; }
221 static inline void Ym2612_begin_frame( struct Ym2612_Emu
* this_
, short* buf
) { this_
->out
= buf
; this_
->last_time
= 0; }
223 static inline int Ym2612_run_until( struct Ym2612_Emu
* this_
, int time
)
225 int count
= time
- this_
->last_time
;
228 if ( this_
->last_time
< 0 )
230 this_
->last_time
= time
;
231 short* p
= this_
->out
;
232 this_
->out
+= count
* ym2612_out_chan_count
;
233 Ym2612_run( this_
, count
, p
);