Mercurial > pmdwin
diff fmgen/op.h @ 0:c55ea9478c80
Hello Gensokyo!
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Tue, 21 May 2013 10:29:21 +0200 |
parents | |
children |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/fmgen/op.h @@ -0,0 +1,135 @@ +#ifndef FM_OP_H +#define FM_OP_H + +#include <stdint.h> +#define false 0 +#define true 1 +#define Max(a,b) ((a>b)?a:b) +#define Min(a,b) ((a<b)?a:b) + +// Types ---------------------------------------------------------------- +typedef int32_t Sample; +typedef int32_t ISample; + +// --------------------------------------------------------------------------- +// Various implementation-specific constants. +// Most are used to either define the bit-width of counters, or the size +// of various constant tables. +// +#define FM_LFOBITS 8 +#define FM_TLBITS 7 +#define FM_TLENTS (1 << FM_TLBITS) +#define FM_LFOENTS (1 << FM_LFOBITS) +#define FM_TLPOS (FM_TLENTS/4) +#define FM_CLENTS (0xc00 << 2) +#define FM_OPSINBITS 10 +#define FM_OPSINENTS (1 << FM_OPSINBITS) +#define FM_EGBITS 16 +#define FM_EGCBITS 18 +#define FM_LFOCBITS 14 +#define FM_PGBITS 9 +#define FM_RATIOBITS 12 + +typedef uint32_t uint; +typedef enum _EGPhase { next, attack, decay, sustain, release, off } EGPhase; + +static inline int Limit(int v, int max, int min) +{ + return v > max ? max : (v < min ? min : v); +} + +// Operator ---------------------------------------------------------------- +typedef struct _FMOperator +{ + int32_t out, out2; + + // Phase Generator ----------------------------------------------------- + uint32_t dp; // Octave (used to define note in conjunction with bn, below). + uint8_t detune; // Detune + uint8_t multiple; // Multiple + uint32_t pgcount; // Phase generator sweep value. Only the top 9 bits are relevant/used. + uint32_t pgdcount; // Phase generator increment-per-clock value. Hopefully self-explanatory. + uint32_t pgdcountl; // Phase generator detune increment value. Used in the implementation of vibrato. + // Equal to pgdcount >> 11. + + // Envelope Generator -------------------------------------------------- + uint32_t bn; // Block/Note + uint32_t egout; + int eglevel; // EG ¤Î½ÐÎÏÃÍ + int eglvnext; // ¼¡¤Î phase ¤Ë°Ü¤ëÃÍ + int32_t egstep; // EG ¤Î¼¡¤ÎÊѰܤޤǤλþ´Ö + int32_t egstepd; // egstep ¤Î»þ´Öº¹Ê¬ + uint8_t egtransa; // EG ÊѲ½¤Î³ä¹ç (for attack) + uint8_t egtransd; // EG ÊѲ½¤Î³ä¹ç (for decay) + + uint32_t ksr; // key scale rate + EGPhase phase; + uint8_t ams; + uint8_t ms; + + uint8_t keyon; // current key state + + uint8_t tl; // Total Level (0-127) + uint8_t tll; // Total Level Latch (for CSM mode) + uint8_t ar; // Attack Rate (0-63) + uint8_t dr; // Decay Rate (0-63) + uint8_t sr; // Sustain Rate (0-63) + uint8_t sl; // Sustain Level (0-127) + uint8_t rr; // Release Rate (0-63) + uint8_t ks; // Keyscale (0-3) + uint8_t ssgtype; // SSG-Type Envelope Control + + uint8_t amon; // enable Amplitude Modulation + uint8_t paramchanged; // Set whenever f-number or any ADSR constants + // are set in OPNASetReg(), as well as upon + // chip reset and chip "DAC" samplerate change. + // Causes the envelope generator to reset its + // internal state, also sets correct increments + // for the phase generator. + uint8_t mute; +} FMOperator; + +// 4-op Channel ------------------------------------------------------------ +typedef struct Channel4 +{ + uint32_t fb; + int buf[4]; + uint8_t idx[6]; + int *pms; + FMOperator op[4]; +} Channel4; + +// OPNA Rhythm Generator --------------------------------------------------- +typedef struct Rhythm { + uint8_t pan; + int8_t level; + int8_t volume; + int8_t* sample; // Rhythm sample data + uint32_t size; // Rhythm sample data size + uint32_t pos; // Current index into rhytm sample data array + uint32_t step; // Amount to increment the above by every time + // RhythmMix() gets called. + uint32_t rate; // Samplerate of rhythm sample data + // (44100Hz in this implementation). +} Rhythm; + +#ifdef __cplusplus +extern "C" { +#endif + +// -------------------------------------------------------------------------- +// Miscellaneous and probably irrelevant function prototypes. +void MakeTable(void); +void OperatorInit(FMOperator *op); +void OperatorReset(FMOperator *op); +void OperatorPrepare(FMOperator *op); + +static inline uint32_t IsOn(FMOperator *op) { + return (op->phase - off); +} + +#ifdef __cplusplus +}; +#endif + +#endif