Mercurial > pmdwin
view fmgen/op.h @ 8:a7e3a45d3002
Remove the embedded memcpy implementation.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Mon, 08 Sep 2014 17:24:29 +0200 |
parents | c55ea9478c80 |
children |
line wrap: on
line source
#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