-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #86 from jpcima/pmdwin
add PMDWin emulator
- Loading branch information
Showing
13 changed files
with
7,422 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
#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_LFOENTS (1 << FM_LFOBITS) | ||
#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 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); | ||
} | ||
|
||
static inline int16_t Limit16(int a) | ||
{ | ||
if ((a+0x8000) & ~0xFFFF) return (a>>31) ^ 0x7FFF; | ||
else return a; | ||
} | ||
|
||
/* ------------------------------------------------------------------------- */ | ||
struct _OPNA; | ||
struct Channel4; | ||
|
||
/* Operator ---------------------------------------------------------------- */ | ||
typedef struct _FMOperator | ||
{ | ||
struct Channel4 *master; | ||
|
||
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 | ||
{ | ||
struct _OPNA *master; | ||
uint32_t fb; | ||
int buf[4]; | ||
uint8_t idx[6]; | ||
int *pms; | ||
uint16_t panl; | ||
uint16_t panr; | ||
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 OperatorInit(Channel4 *ch4, 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 |
Oops, something went wrong.