mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-12-12 13:21:51 +00:00
87d46ddd11
## 1.5.0 2020-09-28 * Drum note length expanding is now supported in real-time mode (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!) * Added support for OPNA chip with Neko Project II Kai YM2602 emulator usage (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!) * Added VGM file dumper which allows to output OPN2 commands into VGM file. (A new MIDI to VGM tool is now created with basing on libOPNMIDI) * Fixed an incorrect work of CC-121 (See https://github.com/Wohlstand/libADLMIDI/issues/227 for details) * Internality has been refactored and improved
144 lines
4.9 KiB
C
144 lines
4.9 KiB
C
#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
|