view fmgen/opna.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 __OPNA_H__
#define __OPNA_H__

#include <stdint.h>
#include "op.h"
#include "psg.h"

//  YM2608 (OPNA) ------------------------------------------------------
typedef struct _OPNA
{
    int fmvolume;
    uint32_t    clock;
    uint32_t    rate;
    uint32_t    psgrate;
    uint32_t    status;
    Channel4  ch[6];
    Channel4* csmch;
    
    int32_t mixdelta;
    int     mpratio;
    uint8_t    interpolation;
    
    uint8_t timer_status;
    uint8_t regtc;
    uint8_t regta[2];

    int32_t timera, timera_count;
    int32_t timerb, timerb_count;
    int32_t timer_step;
    uint8_t prescale;
    uint8_t devmask;
    
    PSG     psg;

    Rhythm  rhythm[6];
    int8_t  rhythmtl;
    int     rhythmtvol;     
    uint8_t rhythmkey;

    int32_t mixl, mixl1;
    uint8_t pan[6];
    uint8_t fnum2[9];
    
    uint8_t reg22;
    uint32_t    reg29;
    uint32_t    statusnext;

    uint32_t    lfocount;
    uint32_t    lfodcount;
    
    uint32_t    fnum[6];
    uint32_t    fnum3[3];
} OPNA;

#ifdef __cplusplus
extern "C" {
#endif

// ---------------------------------------------------------------------------
uint8_t OPNAInit(OPNA *opna, uint c, uint r, uint8_t ipflag);
void OPNAReset(OPNA *opna);
void SetVolumeFM(OPNA *opna, int db);
void SetVolumeRhythmTotal(OPNA *opna, int db);
uint8_t OPNASetRate(OPNA *opna, uint r, uint8_t ipflag);
void OPNASetChannelMask(OPNA *opna, uint mask);
void OPNASetReg(OPNA *opna, uint addr, uint data);
uint8_t OPNATimerCount(OPNA *opna, int32_t us);
void OPNAMix(OPNA *opna, Sample* buffer, uint32_t nsamples);

// ---------------------------------------------------------------------------
static inline uint32_t ReadStatus(OPNA *opna) { return opna->status & 0x03; }
static inline void SetVolumeRhythm(OPNA *opna, int index, int db)
{
    db = Min(db, 20);
    opna->rhythm[index].volume = -(db * 2 / 3);
}   

static inline int32_t OPNAGetNextEvent(OPNA *opna)
{
    uint32_t ta = ((opna->timera_count + 0xffff) >> 16) - 1;
    uint32_t tb = ((opna->timerb_count + 0xfff) >> 12) - 1;
    return (ta < tb ? ta : tb) + 1;
}

#ifdef __cplusplus
};
#endif

#endif // FM_OPNA_H