view 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 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