diff 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 diff
new file mode 100644
--- /dev/null
+++ b/fmgen/opna.h
@@ -0,0 +1,89 @@
+#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