diff --git a/extern/NSFplay/legacy/2413tone.h b/extern/NSFplay/legacy/2413tone.h deleted file mode 100644 index 703979584..000000000 --- a/extern/NSFplay/legacy/2413tone.h +++ /dev/null @@ -1,22 +0,0 @@ -/* YM2413 tone by Mitsutaka Okazaki, 2020 */ -/* https://github.com/digital-sound-antiques/emu2413/blob/d2b9c8dfc5e84b7f8a535fdfee0149ac7bd84ca2/emu2413.c#L34 - */ -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0: Original -0x71, 0x61, 0x1e, 0x17, 0xd0, 0x78, 0x00, 0x17, // 1: Violin -0x13, 0x41, 0x1a, 0x0d, 0xd8, 0xf7, 0x23, 0x13, // 2: Guitar -0x13, 0x01, 0x99, 0x00, 0xf2, 0xc4, 0x21, 0x23, // 3: Piano -0x11, 0x61, 0x0e, 0x07, 0x8d, 0x64, 0x70, 0x27, // 4: Flute -0x32, 0x21, 0x1e, 0x06, 0xe1, 0x76, 0x01, 0x28, // 5: Clarinet -0x31, 0x22, 0x16, 0x05, 0xe0, 0x71, 0x00, 0x18, // 6: Oboe -0x21, 0x61, 0x1d, 0x07, 0x82, 0x81, 0x11, 0x07, // 7: Trumpet -0x33, 0x21, 0x2d, 0x13, 0xb0, 0x70, 0x00, 0x07, // 8: Organ -0x61, 0x61, 0x1b, 0x06, 0x64, 0x65, 0x10, 0x17, // 9: Horn -0x41, 0x61, 0x0b, 0x18, 0x85, 0xf0, 0x81, 0x07, // A: Synthesizer -0x33, 0x01, 0x83, 0x11, 0xea, 0xef, 0x10, 0x04, // B: Harpsichord -0x17, 0xc1, 0x24, 0x07, 0xf8, 0xf8, 0x22, 0x12, // C: Vibraphone -0x61, 0x50, 0x0c, 0x05, 0xd2, 0xf5, 0x40, 0x42, // D: Synthsizer Bass -0x01, 0x01, 0x55, 0x03, 0xe9, 0x90, 0x03, 0x02, // E: Acoustic Bass -0x41, 0x41, 0x89, 0x03, 0xf1, 0xe4, 0xc0, 0x13, // F: Electric Guitar -0x01, 0x01, 0x18, 0x0f, 0xdf, 0xf8, 0x6a, 0x6d, // R: Bass Drum (from VRC7) -0x01, 0x01, 0x00, 0x00, 0xc8, 0xd8, 0xa7, 0x68, // R: High-Hat(M) / Snare Drum(C) (from VRC7) -0x05, 0x01, 0x00, 0x00, 0xf8, 0xaa, 0x59, 0x55, // R: Tom-tom(M) / Top Cymbal(C) (from VRC7) diff --git a/extern/NSFplay/legacy/281btone.h b/extern/NSFplay/legacy/281btone.h deleted file mode 100644 index bb0068bab..000000000 --- a/extern/NSFplay/legacy/281btone.h +++ /dev/null @@ -1,20 +0,0 @@ -/* YMF281B tone by Chabin (4/10/2004) */ -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x62,0x21,0x1a,0x07,0xf0,0x6f,0x00,0x16, -0x00,0x10,0x44,0x02,0xf6,0xf4,0x54,0x23, -0x03,0x01,0x97,0x04,0xf3,0xf3,0x13,0xf3, -0x01,0x61,0x0a,0x0f,0xfa,0x64,0x70,0x17, -0x22,0x21,0x1e,0x06,0xf0,0x76,0x00,0x28, -0x00,0x61,0x8a,0x0e,0xc0,0x61,0x00,0x07, -0x21,0x61,0x1b,0x07,0x84,0x80,0x17,0x17, -0x37,0x32,0xc9,0x01,0x66,0x64,0x40,0x28, -0x01,0x21,0x06,0x03,0xa5,0x71,0x51,0x07, -0x06,0x11,0x5e,0x07,0xf3,0xf2,0xf6,0x11, -0x00,0x20,0x18,0x06,0xf5,0xf3,0x20,0x26, -0x97,0x41,0x20,0x07,0xff,0xf4,0x22,0x22, -0x65,0x61,0x15,0x00,0xf7,0xf3,0x16,0xf4, -0x01,0x31,0x0e,0x07,0xfa,0xf3,0xff,0xff, -0x48,0x61,0x09,0x07,0xf1,0x94,0xf0,0xf5, -0x07,0x21,0x14,0x00,0xee,0xf8,0xff,0xf8, -0x01,0x31,0x00,0x00,0xf8,0xf7,0xf8,0xf7, -0x25,0x11,0x00,0x00,0xf8,0xfa,0xf8,0x55, diff --git a/extern/NSFplay/legacy/emu2149.c b/extern/NSFplay/legacy/emu2149.c deleted file mode 100644 index fa5142f73..000000000 --- a/extern/NSFplay/legacy/emu2149.c +++ /dev/null @@ -1,363 +0,0 @@ -/**************************************************************************** - - emu2149.c -- YM2149/AY-3-8910 emulator by Mitsutaka Okazaki 2001 - - 2001 04-28 : Version 1.00beta -- 1st Beta Release. - 2001 08-14 : Version 1.10 - 2001 10-03 : Version 1.11 -- Added PSG_set_quality(). - 2002 03-02 : Version 1.12 -- Removed PSG_init & PSG_close. - 2002 10-13 : Version 1.14 -- Fixed the envelope unit. - 2003 09-19 : Version 1.15 -- Added PSG_setMask and PSG_toggleMask - 2004 01-11 : Version 1.16 -- Fixed an envelope problem where the envelope - frequency register is written before key-on. - - References: - psg.vhd -- 2000 written by Kazuhiro Tsujikawa. - s_fme7.c -- 1999,2000 written by Mamiya (NEZplug). - ay8910.c -- 1998-2001 Author unknown (MAME). - MSX-Datapack -- 1991 ASCII Corp. - AY-3-8910 data sheet - -*****************************************************************************/ -#include -#include -#include -#include "emu2149.h" - -static e_uint32 voltbl[2][32] = { - {0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, - 0x0B, 0x0D, 0x0F, 0x12, - 0x16, 0x1A, 0x1F, 0x25, 0x2D, 0x35, 0x3F, 0x4C, 0x5A, 0x6A, 0x7F, 0x97, - 0xB4, 0xD6, 0xEB, 0xFF}, - {0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x05, 0x05, 0x07, 0x07, - 0x0B, 0x0B, 0x0F, 0x0F, - 0x16, 0x16, 0x1F, 0x1F, 0x2D, 0x2D, 0x3F, 0x3F, 0x5A, 0x5A, 0x7F, 0x7F, - 0xB4, 0xB4, 0xFF, 0xFF} -}; - -#define GETA_BITS 24 - -static void -internal_refresh (PSG * psg) -{ - if (psg->quality) - { - psg->base_incr = 1 << GETA_BITS; - psg->realstep = (e_uint32) ((1 << 31) / psg->rate); - psg->psgstep = (e_uint32) ((1 << 31) / (psg->clk / 16)); - psg->psgtime = 0; - } - else - { - psg->base_incr = - (e_uint32) ((double) psg->clk * (1 << GETA_BITS) / (16 * psg->rate)); - } -} - -EMU2149_API void -PSG_set_rate (PSG * psg, e_uint32 r) -{ - psg->rate = r ? r : 44100; - internal_refresh (psg); -} - -EMU2149_API void -PSG_set_quality (PSG * psg, e_uint32 q) -{ - psg->quality = q; - internal_refresh (psg); -} - -EMU2149_API PSG * -PSG_new (e_uint32 c, e_uint32 r) -{ - PSG *psg; - - psg = (PSG *) malloc (sizeof (PSG)); - if (psg == NULL) - return NULL; - - PSG_setVolumeMode (psg, EMU2149_VOL_DEFAULT); - psg->clk = c; - psg->rate = r ? r : 44100; - PSG_set_quality (psg, 0); - - return psg; -} - -EMU2149_API void -PSG_setVolumeMode (PSG * psg, int type) -{ - switch (type) - { - case 1: - psg->voltbl = voltbl[EMU2149_VOL_YM2149]; - break; - case 2: - psg->voltbl = voltbl[EMU2149_VOL_AY_3_8910]; - break; - default: - psg->voltbl = voltbl[EMU2149_VOL_DEFAULT]; - break; - } -} - -EMU2149_API e_uint32 -PSG_setMask (PSG *psg, e_uint32 mask) -{ - e_uint32 ret = 0; - if(psg) - { - ret = psg->mask; - psg->mask = mask; - } - return ret; -} - -EMU2149_API e_uint32 -PSG_toggleMask (PSG *psg, e_uint32 mask) -{ - e_uint32 ret = 0; - if(psg) - { - ret = psg->mask; - psg->mask ^= mask; - } - return ret; -} - -EMU2149_API void -PSG_reset (PSG * psg) -{ - int i; - - psg->base_count = 0; - - for (i = 0; i < 3; i++) - { - psg->cout[i] = 0; - psg->count[i] = 0x1000; - psg->freq[i] = 0; - psg->edge[i] = 0; - psg->volume[i] = 0; - } - - psg->mask = 0; - - for (i = 0; i < 16; i++) - psg->reg[i] = 0; - psg->adr = 0; - - psg->noise_seed = 0xffff; - psg->noise_count = 0x40; - psg->noise_freq = 0; - - psg->env_volume = 0; - psg->env_ptr = 0; - psg->env_freq = 0; - psg->env_count = 0; - psg->env_pause = 1; - - psg->out = 0; -} - -EMU2149_API void -PSG_delete (PSG * psg) -{ - free (psg); -} - -EMU2149_API e_uint8 -PSG_readIO (PSG * psg) -{ - return (e_uint8) (psg->reg[psg->adr]); -} - -EMU2149_API e_uint8 -PSG_readReg (PSG * psg, e_uint32 reg) -{ - return (e_uint8) (psg->reg[reg & 0x1f]); - -} - -EMU2149_API void -PSG_writeIO (PSG * psg, e_uint32 adr, e_uint32 val) -{ - if (adr & 1) - PSG_writeReg (psg, psg->adr, val); - else - psg->adr = val & 0x1f; -} - -INLINE static e_int16 -calc (PSG * psg) -{ - - int i, noise; - e_uint32 incr; - e_int32 mix = 0; - - psg->base_count += psg->base_incr; - incr = (psg->base_count >> GETA_BITS); - psg->base_count &= (1 << GETA_BITS) - 1; - - /* Envelope */ - psg->env_count += incr; - while (psg->env_count>=0x10000 && psg->env_freq!=0) - { - if (!psg->env_pause) - { - if(psg->env_face) - psg->env_ptr = (psg->env_ptr + 1) & 0x3f ; - else - psg->env_ptr = (psg->env_ptr + 0x3f) & 0x3f; - } - - if (psg->env_ptr & 0x20) /* if carry or borrow */ - { - if (psg->env_continue) - { - if (psg->env_alternate^psg->env_hold) psg->env_face ^= 1; - if (psg->env_hold) psg->env_pause = 1; - psg->env_ptr = psg->env_face?0:0x1f; - } - else - { - psg->env_pause = 1; - psg->env_ptr = 0; - } - } - - psg->env_count -= psg->env_freq; - } - - /* Noise */ - psg->noise_count += incr; - if (psg->noise_count & 0x40) - { - if (psg->noise_seed & 1) - psg->noise_seed ^= 0x24000; - psg->noise_seed >>= 1; - psg->noise_count -= psg->noise_freq; - } - noise = psg->noise_seed & 1; - - /* Tone */ - for (i = 0; i < 3; i++) - { - psg->count[i] += incr; - if (psg->count[i] & 0x1000) - { - if (psg->freq[i] > 1) - { - psg->edge[i] = !psg->edge[i]; - psg->count[i] -= psg->freq[i]; - } - else - { - psg->edge[i] = 1; - } - } - - psg->cout[i] = 0; // maintaining cout for stereo mix - - if (psg->mask&PSG_MASK_CH(i)) - continue; - - if ((psg->tmask[i] || psg->edge[i]) && (psg->nmask[i] || noise)) - { - if (!(psg->volume[i] & 32)) - psg->cout[i] = psg->voltbl[psg->volume[i] & 31]; - else - psg->cout[i] = psg->voltbl[psg->env_ptr]; - - mix += psg->cout[i]; - } - } - - return (e_int16) mix; -} - -EMU2149_API e_int16 -PSG_calc (PSG * psg) -{ - if (!psg->quality) - return (e_int16) (calc (psg) << 4); - - /* Simple rate converter */ - while (psg->realstep > psg->psgtime) - { - psg->psgtime += psg->psgstep; - psg->out += calc (psg); - psg->out >>= 1; - } - - psg->psgtime = psg->psgtime - psg->realstep; - - return (e_int16) (psg->out << 4); -} - -EMU2149_API void -PSG_writeReg (PSG * psg, e_uint32 reg, e_uint32 val) -{ - int c; - - if (reg > 15) return; - - psg->reg[reg] = (e_uint8) (val & 0xff); - switch (reg) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - c = reg >> 1; - psg->freq[c] = ((psg->reg[c * 2 + 1] & 15) << 8) + psg->reg[c * 2]; - break; - - case 6: - psg->noise_freq = (val == 0) ? 1 : ((val & 31) << 1); - break; - - case 7: - psg->tmask[0] = (val & 1); - psg->tmask[1] = (val & 2); - psg->tmask[2] = (val & 4); - psg->nmask[0] = (val & 8); - psg->nmask[1] = (val & 16); - psg->nmask[2] = (val & 32); - break; - - case 8: - case 9: - case 10: - psg->volume[reg - 8] = val << 1; - - break; - - case 11: - case 12: - psg->env_freq = (psg->reg[12] << 8) + psg->reg[11]; - break; - - case 13: - psg->env_continue = (val >> 3) & 1; - psg->env_attack = (val >> 2) & 1; - psg->env_alternate = (val >> 1) & 1; - psg->env_hold = val & 1; - psg->env_face = psg->env_attack; - psg->env_pause = 0; - psg->env_count = 0x10000 - psg->env_freq; - psg->env_ptr = psg->env_face?0:0x1f; - break; - - case 14: - case 15: - default: - break; - } - - return; -} \ No newline at end of file diff --git a/extern/NSFplay/legacy/emu2149.h b/extern/NSFplay/legacy/emu2149.h deleted file mode 100644 index a2fba126b..000000000 --- a/extern/NSFplay/legacy/emu2149.h +++ /dev/null @@ -1,94 +0,0 @@ -/* emu2149.h */ -#ifndef _EMU2149_H_ -#define _EMU2149_H_ -#include "emutypes.h" - -#ifdef EMU2149_DLL_EXPORTS -#define EMU2149_API __declspec(dllexport) -#elif EMU2149_DLL_IMPORTS -#define EMU2149_API __declspec(dllimport) -#else -#define EMU2149_API -#endif - -#define EMU2149_VOL_DEFAULT 1 -#define EMU2149_VOL_YM2149 0 -#define EMU2149_VOL_AY_3_8910 1 - -#define PSG_MASK_CH(x) (1<<(x)) - -#ifdef __cplusplus -extern "C" -{ -#endif - - typedef struct __PSG - { - - /* Volume Table */ - e_uint32 *voltbl; - - e_uint8 reg[0x20]; - e_int32 out; - e_int32 cout[3]; - - e_uint32 clk, rate, base_incr, quality; - - e_uint32 count[3]; - e_uint32 volume[3]; - e_uint32 freq[3]; - e_uint32 edge[3]; - e_uint32 tmask[3]; - e_uint32 nmask[3]; - e_uint32 mask; - - e_uint32 base_count; - - e_uint32 env_volume; - e_uint32 env_ptr; - e_uint32 env_face; - - e_uint32 env_continue; - e_uint32 env_attack; - e_uint32 env_alternate; - e_uint32 env_hold; - e_uint32 env_pause; - e_uint32 env_reset; - - e_uint32 env_freq; - e_uint32 env_count; - - e_uint32 noise_seed; - e_uint32 noise_count; - e_uint32 noise_freq; - - /* rate converter */ - e_uint32 realstep; - e_uint32 psgtime; - e_uint32 psgstep; - - /* I/O Ctrl */ - e_uint32 adr; - - } - PSG; - - EMU2149_API void PSG_set_quality (PSG * psg, e_uint32 q); - EMU2149_API void PSG_set_rate (PSG * psg, e_uint32 r); - EMU2149_API PSG *PSG_new (e_uint32 clk, e_uint32 rate); - EMU2149_API void PSG_reset (PSG *); - EMU2149_API void PSG_delete (PSG *); - EMU2149_API void PSG_writeReg (PSG *, e_uint32 reg, e_uint32 val); - EMU2149_API void PSG_writeIO (PSG * psg, e_uint32 adr, e_uint32 val); - EMU2149_API e_uint8 PSG_readReg (PSG * psg, e_uint32 reg); - EMU2149_API e_uint8 PSG_readIO (PSG * psg); - EMU2149_API e_int16 PSG_calc (PSG *); - EMU2149_API void PSG_setVolumeMode (PSG * psg, int type); - EMU2149_API e_uint32 PSG_setMask (PSG *, e_uint32 mask); - EMU2149_API e_uint32 PSG_toggleMask (PSG *, e_uint32 mask); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/extern/NSFplay/legacy/emu2212.c b/extern/NSFplay/legacy/emu2212.c deleted file mode 100644 index 88d93382c..000000000 --- a/extern/NSFplay/legacy/emu2212.c +++ /dev/null @@ -1,485 +0,0 @@ -/**************************************************************************** - - emu2212.c -- S.C.C. emulator by Mitsutaka Okazaki 2001 - - 2001 09-30 : Version 1.00 - 2001 10-03 : Version 1.01 -- Added SCC_set_quality(). - 2002 02-14 : Version 1.10 -- Added SCC_writeReg(), SCC_set_type(). - Fixed SCC_write(). - 2002 02-17 : Version 1.11 -- Fixed SCC_write(). - 2002 03-02 : Version 1.12 -- Removed SCC_init & SCC_close. - 2003 09-19 : Version 1.13 -- Added SCC_setMask() and SCC_toggleMask() - 2004 10-21 : Version 1.14 -- Fixed the problem where SCC+ is disabled. - - Registar map for SCC_writeReg() - - $00-1F : WaveTable CH.A - $20-3F : WaveTable CH.B - $40-5F : WaveTable CH.C - $60-7F : WaveTable CH.D&E(SCC), CH.D(SCC+) - $80-9F : WaveTable CH.E - - $C0 : CH.A Freq(L) - $C1 : CH.A Freq(H) - $C2 : CH.B Freq(L) - $C3 : CH.B Freq(H) - $C4 : CH.C Freq(L) - $C5 : CH.C Freq(H) - $C6 : CH.D Freq(L) - $C7 : CH.D Freq(H) - $C8 : CH.E Freq(L) - $C9 : CH.E Freq(H) - - $D0 : CH.A Volume - $D1 : CH.B Volume - $D2 : CH.C Volume - $D3 : CH.D Volume - $D4 : CH.E Volume - - $E0 : Bit0 = 0:SCC, 1:SCC+ - $E1 : CH mask - $E2 : Extra Flags - -*****************************************************************************/ -#include -#include -#include -#include "emu2212.h" - -#define GETA_BITS 22 - -static void -internal_refresh (SCC * scc) -{ - if (scc->quality) - { - scc->base_incr = 2 << GETA_BITS; - scc->realstep = (e_uint32) ((1 << 31) / scc->rate); - scc->sccstep = (e_uint32) ((1 << 31) / (scc->clk / 2)); - scc->scctime = 0; - } - else - { - scc->base_incr = (e_uint32) ((double) scc->clk * (1 << GETA_BITS) / scc->rate); - } -} - -EMU2212_API e_uint32 -SCC_setMask (SCC *scc, e_uint32 mask) -{ - e_uint32 ret = 0; - if(scc) - { - ret = scc->mask; - scc->mask = mask; - } - return ret; -} - -EMU2212_API e_uint32 -SCC_toggleMask (SCC *scc, e_uint32 mask) -{ - e_uint32 ret = 0; - if(scc) - { - ret = scc->mask; - scc->mask ^= mask; - } - return ret; -} - -EMU2212_API void -SCC_set_quality (SCC * scc, e_uint32 q) -{ - scc->quality = q; - internal_refresh (scc); -} - -EMU2212_API void -SCC_set_rate (SCC * scc, e_uint32 r) -{ - scc->rate = r ? r : 44100; - internal_refresh (scc); -} - -EMU2212_API SCC * -SCC_new (e_uint32 c, e_uint32 r) -{ - SCC *scc; - - scc = (SCC *) malloc (sizeof (SCC)); - if (scc == NULL) - return NULL; - memset(scc, 0, sizeof (SCC)); - - scc->clk = c; - scc->rate = r ? r : 44100; - SCC_set_quality (scc, 0); - scc->type = SCC_ENHANCED; - return scc; -} - -EMU2212_API void -SCC_reset (SCC * scc) -{ - int i, j; - - if (scc == NULL) - return; - - scc->mode = 0; - scc->active = 0; - scc->base_adr = 0x9000; - - for (i = 0; i < 5; i++) - { - for (j = 0; j < 5; j++) - scc->wave[i][j] = 0; - scc->count[i] = 0; - scc->freq[i] = 0; - scc->phase[i] = 0; - scc->volume[i] = 0; - scc->offset[i] = 0; - scc->rotate[i] = 0; - } - - memset(scc->reg,0,0x100-0xC0); - - scc->mask = 0; - - scc->ch_enable = 0xff; - scc->ch_enable_next = 0xff; - - scc->cycle_4bit = 0; - scc->cycle_8bit = 0; - scc->refresh = 0; - - scc->out = 0; - scc->prev = 0; - scc->next = 0; - - return; -} - -EMU2212_API void -SCC_delete (SCC * scc) -{ - if (scc != NULL) - free (scc); -} - -INLINE static e_int16 -calc (SCC * scc) -{ - int i; - e_int32 mix = 0; - - for (i = 0; i < 5; i++) - { - scc->count[i] = (scc->count[i] + scc->incr[i]); - - if (scc->count[i] & (1 << (GETA_BITS + 5))) - { - scc->count[i] &= ((1 << (GETA_BITS + 5)) - 1); - scc->offset[i] = (scc->offset[i] + 31) & scc->rotate[i]; - scc->ch_enable &= ~(1 << i); - scc->ch_enable |= scc->ch_enable_next & (1 << i); - } - - if (scc->ch_enable & (1 << i)) - { - scc->phase[i] = ((scc->count[i] >> (GETA_BITS)) + scc->offset[i]) & 0x1F; - if(!(scc->mask&SCC_MASK_CH(i))) - mix += ((((e_int8) (scc->wave[i][scc->phase[i]]) * (e_int8) scc->volume[i]))) >> 4; - } - } - - return (e_int16) (mix << 4); -} - -EMU2212_API e_int16 -SCC_calc (SCC * scc) -{ - if (!scc->quality) - return calc (scc); - - while (scc->realstep > scc->scctime) - { - scc->scctime += scc->sccstep; - scc->prev = scc->next; - scc->next = calc (scc); - } - - scc->scctime -= scc->realstep; - scc->out = (e_int16) (((double) scc->next * (scc->sccstep - scc->scctime) + (double) scc->prev * scc->scctime) / scc->sccstep); - - return (e_int16) (scc->out); -} - -EMU2212_API e_uint32 -SCC_readReg (SCC * scc, e_uint32 adr) -{ - if (adr < 0xA0) - return scc->wave[adr >> 5][adr & 0x1f]; - else if( 0xC0 < adr && adr < 0xF0 ) - return scc->reg[adr-0xC0]; - else - return 0; -} - -EMU2212_API void -SCC_writeReg (SCC * scc, e_uint32 adr, e_uint32 val) -{ - int ch; - e_uint32 freq; - - adr &= 0xFF; - - if (adr < 0xA0) - { - ch = (adr & 0xF0) >> 5; - if (!scc->rotate[ch]) - { - scc->wave[ch][adr & 0x1F] = (e_int8) val; - if (scc->mode == 0 && ch == 3) - scc->wave[4][adr & 0x1F] = (e_int8) val; - } - } - else if (0xC0 <= adr && adr <= 0xC9) - { - scc->reg[adr-0xC0] = val; - ch = (adr & 0x0F) >> 1; - if (adr & 1) - scc->freq[ch] = ((val & 0xF) << 8) | (scc->freq[ch] & 0xFF); - else - scc->freq[ch] = (scc->freq[ch] & 0xF00) | (val & 0xFF); - - if (scc->refresh) - scc->count[ch] = 0; - freq = scc->freq[ch]; - if (scc->cycle_8bit) - freq &= 0xFF; - if (scc->cycle_4bit) - freq >>= 8; - if (freq <= 8) - scc->incr[ch] = 0; - else - scc->incr[ch] = scc->base_incr / (freq + 1); - } - else if (0xD0 <= adr && adr <= 0xD4) - { - scc->reg[adr-0xC0] = val; - scc->volume[adr & 0x0F] = (e_uint8) (val & 0xF); - } - else if (adr == 0xE0) - { - scc->reg[adr-0xC0] = val; - scc->mode = (e_uint8) val & 1; - } - else if (adr == 0xE1) - { - scc->reg[adr-0xC0] = val; - scc->ch_enable_next = (e_uint8) val & 0x1F; - } - else if (adr == 0xE2) - { - scc->reg[adr-0xC0] = val; - scc->cycle_4bit = val & 1; - scc->cycle_8bit = val & 2; - scc->refresh = val & 32; - if (val & 64) - for (ch = 0; ch < 5; ch++) - scc->rotate[ch] = 0x1F; - else - for (ch = 0; ch < 5; ch++) - scc->rotate[ch] = 0; - if (val & 128) - scc->rotate[3] = scc->rotate[4] = 0x1F; - } - - return; -} - -INLINE static void -write_standard (SCC * scc, e_uint32 adr, e_uint32 val) -{ - adr &= 0xFF; - - if (adr < 0x80) /* wave */ - { - SCC_writeReg (scc, adr, val); - } - else if (adr < 0x8A) /* freq */ - { - SCC_writeReg (scc, adr + 0xC0 - 0x80, val); - } - else if (adr < 0x8F) /* volume */ - { - SCC_writeReg (scc, adr + 0xD0 - 0x8A, val); - } - else if (adr == 0x8F) /* ch enable */ - { - SCC_writeReg (scc, 0xE1, val); - } - else if (0xE0 <= adr) /* flags */ - { - SCC_writeReg (scc, 0xE2, val); - } -} - -INLINE static void -write_enhanced (SCC * scc, e_uint32 adr, e_uint32 val) -{ - adr &= 0xFF; - - if (adr < 0xA0) /* wave */ - { - SCC_writeReg (scc, adr, val); - } - else if (adr < 0xAA) /* freq */ - { - SCC_writeReg (scc, adr + 0xC0 - 0xA0, val); - } - else if (adr < 0xAF) /* volume */ - { - SCC_writeReg (scc, adr + 0xD0 - 0xAA, val); - } - else if (adr == 0xAF) /* ch enable */ - { - SCC_writeReg (scc, 0xE1, val); - } - else if (0xC0 <= adr && adr <= 0xDF) /* flags */ - { - SCC_writeReg (scc, 0xE2, val); - } -} - -INLINE static e_uint32 -read_enhanced (SCC * scc, e_uint32 adr) -{ - adr &= 0xFF; - if (adr < 0xA0) - return SCC_readReg (scc, adr); - else if (adr < 0xAA) - return SCC_readReg (scc, adr + 0xC0 - 0xA0); - else if (adr < 0xAF) - return SCC_readReg (scc, adr + 0xD0 - 0xAA); - else if (adr == 0xAF) - return SCC_readReg (scc, 0xE1); - else if (0xC0 <= adr && adr <= 0xDF) - return SCC_readReg (scc, 0xE2); - else - return 0; -} - -INLINE static e_uint32 -read_standard (SCC * scc, e_uint32 adr) -{ - adr &= 0xFF; - if(adr<0x80) - return SCC_readReg (scc, adr); - else if (0xA0<=adr&&adr<=0xBF) - return SCC_readReg (scc, 0x80+(adr&0x1F)); - else if (adr < 0x8A) - return SCC_readReg (scc, adr + 0xC0 - 0x80); - else if (adr < 0x8F) - return SCC_readReg (scc, adr + 0xD0 - 0x8A); - else if (adr == 0x8F) - return SCC_readReg (scc, 0xE1); - else if (0xE0 <= adr) - return SCC_readReg (scc, 0xE2); - else return 0; -} - -EMU2212_API e_uint32 -SCC_read (SCC * scc, e_uint32 adr) -{ - if( scc->type == SCC_ENHANCED && (adr&0xFFFE) == 0xBFFE ) - return (scc->base_adr>>8)&0x20; - - if( adr < scc->base_adr ) return 0; - adr -= scc->base_adr; - - if( adr == 0 ) - { - if(scc->mode) return 0x80; else return 0x3F; - } - - if(!scc->active||adr<0x800||0x8FFtype) - { - case SCC_STANDARD: - return read_standard (scc, adr); - break; - case SCC_ENHANCED: - if(!scc->mode) - return read_standard (scc, adr); - else - return read_enhanced (scc, adr); - break; - default: - break; - } - - return 0; -} - -EMU2212_API void -SCC_write (SCC * scc, e_uint32 adr, e_uint32 val) -{ - val = val & 0xFF; - - if( scc->type == SCC_ENHANCED && (adr&0xFFFE) == 0xBFFE ) - { - scc->base_adr = 0x9000 | ((val&0x20)<<8); - return; - } - - if( adr < scc->base_adr ) return; - adr -= scc->base_adr; - - if(adr == 0) - { - if( val == 0x3F ) - { - scc->mode = 0; - scc->active = 1; - } - else if( val&0x80 && scc->type == SCC_ENHANCED) - { - scc->mode = 1; - scc->active = 1; - } - else - { - scc->mode = 0; - scc->active = 0; - } - return; - } - - if(!scc->active||adr<0x800||0x8FFtype) - { - case SCC_STANDARD: - write_standard (scc, adr, val); - break; - case SCC_ENHANCED: - if(scc->mode) - write_enhanced (scc, adr, val); - else - write_standard (scc, adr, val); - default: - break; - } - - return; -} - -EMU2212_API void -SCC_set_type (SCC * scc, e_uint32 type) -{ - scc->type = type; -} diff --git a/extern/NSFplay/legacy/emu2212.h b/extern/NSFplay/legacy/emu2212.h deleted file mode 100644 index b79e0c360..000000000 --- a/extern/NSFplay/legacy/emu2212.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef _EMU2212_H_ -#define _EMU2212_H_ - -#ifdef EMU2212_DLL_EXPORTS - #define EMU2212_API __declspec(dllexport) -#elif defined(EMU2212_DLL_IMPORTS) - #define EMU2212_API __declspec(dllimport) -#else - #define EMU2212_API -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#include "emutypes.h" - -#define SCC_STANDARD 0 -#define SCC_ENHANCED 1 - -#define SCC_MASK_CH(x) (1<<(x)) - -typedef struct __SCC { - - e_uint32 clk, rate ,base_incr, quality ; - - e_int32 out, prev, next; - e_uint32 type ; - e_uint32 mode ; - e_uint32 active; - e_uint32 base_adr; - e_uint32 mask ; - - e_uint32 realstep ; - e_uint32 scctime ; - e_uint32 sccstep ; - - e_uint32 incr[5] ; - - e_int8 wave[5][32] ; - - e_uint32 count[5] ; - e_uint32 freq[5] ; - e_uint32 phase[5] ; - e_uint32 volume[5] ; - e_uint32 offset[5] ; - e_uint8 reg[0x100-0xC0]; - - int ch_enable ; - int ch_enable_next ; - - int cycle_4bit ; - int cycle_8bit ; - int refresh ; - int rotate[5] ; - -} SCC ; - - -EMU2212_API SCC *SCC_new(e_uint32 c, e_uint32 r) ; -EMU2212_API void SCC_reset(SCC *scc) ; -EMU2212_API void SCC_set_rate(SCC *scc, e_uint32 r); -EMU2212_API void SCC_set_quality(SCC *scc, e_uint32 q) ; -EMU2212_API void SCC_set_type(SCC *scc, e_uint32 type) ; -EMU2212_API void SCC_delete(SCC *scc) ; -EMU2212_API e_int16 SCC_calc(SCC *scc) ; -EMU2212_API void SCC_write(SCC *scc, e_uint32 adr, e_uint32 val) ; -EMU2212_API void SCC_writeReg(SCC *scc, e_uint32 adr, e_uint32 val) ; -EMU2212_API e_uint32 SCC_read(SCC *scc, e_uint32 adr) ; -EMU2212_API e_uint32 SCC_setMask(SCC *scc, e_uint32 adr) ; -EMU2212_API e_uint32 SCC_toggleMask(SCC *scc, e_uint32 adr) ; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/extern/NSFplay/legacy/emu2413.c b/extern/NSFplay/legacy/emu2413.c deleted file mode 100644 index 2ced98f86..000000000 --- a/extern/NSFplay/legacy/emu2413.c +++ /dev/null @@ -1,1461 +0,0 @@ -/** - * emu2413 v1.5.2 - * https://github.com/digital-sound-antiques/emu2413 - * Copyright (C) 2020 Mitsutaka Okazaki - * - * This source refers to the following documents. The author would like to thank all the authors who have - * contributed to the writing of them. - * - [YM2413 notes](http://www.smspower.org/Development/YM2413) by andete - * - ymf262.c by Jarek Burczynski - * - [VRC7 presets](https://siliconpr0n.org/archive/doku.php?id=vendor:yamaha:opl2#opll_vrc7_patch_format) by Nuke.YKT - * - YMF281B presets by Chabin - */ -#include "emu2413.h" -#include -#include -#include -#include - -#ifndef INLINE -#if defined(_MSC_VER) -#define INLINE __inline -#elif defined(__GNUC__) -#define INLINE __inline__ -#else -#define INLINE inline -#endif -#endif - -#define _PI_ 3.14159265358979323846264338327950288 - -#define OPLL_TONE_NUM 9 -static unsigned char default_inst[OPLL_TONE_NUM][(16 + 3) * 8] = { - { -#include "vrc7tone_nuke.h" - }, - { -#include "vrc7tone_rw.h" - }, - { -#include "vrc7tone_ft36.h" - }, - { -#include "vrc7tone_ft35.h" - }, - { -#include "vrc7tone_mo.h" - }, - { -#include "vrc7tone_kt2.h" - }, - { -#include "vrc7tone_kt1.h" - }, - { -#include "2413tone.h" - }, - { -#include "281btone.h" - }, -}; - -/* phase increment counter */ -#define DP_BITS 19 -#define DP_WIDTH (1 << DP_BITS) -#define DP_BASE_BITS (DP_BITS - PG_BITS) - -/* dynamic range of envelope output */ -#define EG_STEP 0.375 -#define EG_BITS 7 -#define EG_MUTE ((1 << EG_BITS) - 1) -#define EG_MAX (EG_MUTE - 3) - -/* dynamic range of total level */ -#define TL_STEP 0.75 -#define TL_BITS 6 - -/* dynamic range of sustine level */ -#define SL_STEP 3.0 -#define SL_BITS 4 - -/* damper speed before key-on. key-scale affects. */ -#define DAMPER_RATE 12 - -#define TL2EG(d) ((d) << 1) - -/* sine table */ -#define PG_BITS 10 /* 2^10 = 1024 length sine table */ -#define PG_WIDTH (1 << PG_BITS) - -/* clang-format off */ -/* exp_table[x] = round((exp2((double)x / 256.0) - 1) * 1024) */ -static uint16_t exp_table[256] = { -0, 3, 6, 8, 11, 14, 17, 20, 22, 25, 28, 31, 34, 37, 40, 42, -45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, -93, 96, 99, 102, 105, 108, 111, 114, 117, 120, 123, 126, 130, 133, 136, 139, -142, 145, 148, 152, 155, 158, 161, 164, 168, 171, 174, 177, 181, 184, 187, 190, -194, 197, 200, 204, 207, 210, 214, 217, 220, 224, 227, 231, 234, 237, 241, 244, -248, 251, 255, 258, 262, 265, 268, 272, 276, 279, 283, 286, 290, 293, 297, 300, -304, 308, 311, 315, 318, 322, 326, 329, 333, 337, 340, 344, 348, 352, 355, 359, -363, 367, 370, 374, 378, 382, 385, 389, 393, 397, 401, 405, 409, 412, 416, 420, -424, 428, 432, 436, 440, 444, 448, 452, 456, 460, 464, 468, 472, 476, 480, 484, -488, 492, 496, 501, 505, 509, 513, 517, 521, 526, 530, 534, 538, 542, 547, 551, -555, 560, 564, 568, 572, 577, 581, 585, 590, 594, 599, 603, 607, 612, 616, 621, -625, 630, 634, 639, 643, 648, 652, 657, 661, 666, 670, 675, 680, 684, 689, 693, -698, 703, 708, 712, 717, 722, 726, 731, 736, 741, 745, 750, 755, 760, 765, 770, -774, 779, 784, 789, 794, 799, 804, 809, 814, 819, 824, 829, 834, 839, 844, 849, -854, 859, 864, 869, 874, 880, 885, 890, 895, 900, 906, 911, 916, 921, 927, 932, -937, 942, 948, 953, 959, 964, 969, 975, 980, 986, 991, 996, 1002, 1007, 1013, 1018 -}; -/* fullsin_table[x] = round(-log2(sin((x + 0.5) * PI / (PG_WIDTH / 4) / 2)) * 256) */ -static uint16_t fullsin_table[PG_WIDTH] = { -2137, 1731, 1543, 1419, 1326, 1252, 1190, 1137, 1091, 1050, 1013, 979, 949, 920, 894, 869, -846, 825, 804, 785, 767, 749, 732, 717, 701, 687, 672, 659, 646, 633, 621, 609, -598, 587, 576, 566, 556, 546, 536, 527, 518, 509, 501, 492, 484, 476, 468, 461, -453, 446, 439, 432, 425, 418, 411, 405, 399, 392, 386, 380, 375, 369, 363, 358, -352, 347, 341, 336, 331, 326, 321, 316, 311, 307, 302, 297, 293, 289, 284, 280, -276, 271, 267, 263, 259, 255, 251, 248, 244, 240, 236, 233, 229, 226, 222, 219, -215, 212, 209, 205, 202, 199, 196, 193, 190, 187, 184, 181, 178, 175, 172, 169, -167, 164, 161, 159, 156, 153, 151, 148, 146, 143, 141, 138, 136, 134, 131, 129, -127, 125, 122, 120, 118, 116, 114, 112, 110, 108, 106, 104, 102, 100, 98, 96, -94, 92, 91, 89, 87, 85, 83, 82, 80, 78, 77, 75, 74, 72, 70, 69, -67, 66, 64, 63, 62, 60, 59, 57, 56, 55, 53, 52, 51, 49, 48, 47, -46, 45, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, -29, 28, 27, 26, 25, 24, 23, 23, 22, 21, 20, 20, 19, 18, 17, 17, -16, 15, 15, 14, 13, 13, 12, 12, 11, 10, 10, 9, 9, 8, 8, 7, -7, 7, 6, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, -2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, -}; -/* clang-format on */ - -static uint16_t halfsin_table[PG_WIDTH]; -static uint16_t *wave_table_map[2] = {fullsin_table, halfsin_table}; - -/* pitch modulator */ -/* offset to fnum, rough approximation of 14 cents depth. */ -static int8_t pm_table[8][8] = { - {0, 0, 0, 0, 0, 0, 0, 0}, // fnum = 000xxxxxx - {0, 0, 1, 0, 0, 0, -1, 0}, // fnum = 001xxxxxx - {0, 1, 2, 1, 0, -1, -2, -1}, // fnum = 010xxxxxx - {0, 1, 3, 1, 0, -1, -3, -1}, // fnum = 011xxxxxx - {0, 2, 4, 2, 0, -2, -4, -2}, // fnum = 100xxxxxx - {0, 2, 5, 2, 0, -2, -5, -2}, // fnum = 101xxxxxx - {0, 3, 6, 3, 0, -3, -6, -3}, // fnum = 110xxxxxx - {0, 3, 7, 3, 0, -3, -7, -3}, // fnum = 111xxxxxx -}; - -/* amplitude lfo table */ -/* The following envelop pattern is verified on real YM2413. */ -/* each element repeates 64 cycles */ -static uint8_t am_table[210] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, // - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, // - 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, // - 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, // - 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, // - 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, // - 12, 12, 12, 12, 12, 12, 12, 12, // - 13, 13, 13, // - 12, 12, 12, 12, 12, 12, 12, 12, // - 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, // - 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, // - 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, // - 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, // - 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, // - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}; - -/* envelope decay increment step table */ -/* based on andete's research */ -static uint8_t eg_step_tables[4][8] = { - {0, 1, 0, 1, 0, 1, 0, 1}, - {0, 1, 0, 1, 1, 1, 0, 1}, - {0, 1, 1, 1, 0, 1, 1, 1}, - {0, 1, 1, 1, 1, 1, 1, 1}, -}; - -enum __OPLL_EG_STATE { ATTACK, DECAY, SUSTAIN, RELEASE, DAMP, UNKNOWN }; - -static uint32_t ml_table[16] = {1, 1 * 2, 2 * 2, 3 * 2, 4 * 2, 5 * 2, 6 * 2, 7 * 2, - 8 * 2, 9 * 2, 10 * 2, 10 * 2, 12 * 2, 12 * 2, 15 * 2, 15 * 2}; - -#define dB2(x) ((x)*2) -static double kl_table[16] = {dB2(0.000), dB2(9.000), dB2(12.000), dB2(13.875), dB2(15.000), dB2(16.125), - dB2(16.875), dB2(17.625), dB2(18.000), dB2(18.750), dB2(19.125), dB2(19.500), - dB2(19.875), dB2(20.250), dB2(20.625), dB2(21.000)}; - -static uint32_t tll_table[8 * 16][1 << TL_BITS][4]; -static int32_t rks_table[8 * 2][2]; - -static OPLL_PATCH null_patch = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -static OPLL_PATCH default_patch[OPLL_TONE_NUM][(16 + 3) * 2]; - -#define min(i, j) (((i) < (j)) ? (i) : (j)) -#define max(i, j) (((i) > (j)) ? (i) : (j)) - -/*************************************************** - - Internal Sample Rate Converter - -****************************************************/ -/* Note: to disable internal rate converter, set clock/72 to output sampling rate. */ - -/* - * LW is truncate length of sinc(x) calculation. - * Lower LW is faster, higher LW results better quality. - * LW must be a non-zero positive even number, no upper limit. - * LW=16 or greater is recommended when upsampling. - * LW=8 is practically okay for downsampling. - */ -#define LW 16 - -/* resolution of sinc(x) table. sinc(x) where 0.0<=x<1.0 corresponds to sinc_table[0...SINC_RESO-1] */ -#define SINC_RESO 256 -#define SINC_AMP_BITS 12 - -// double hamming(double x) { return 0.54 - 0.46 * cos(2 * PI * x); } -static double blackman(double x) { return 0.42 - 0.5 * cos(2 * _PI_ * x) + 0.08 * cos(4 * _PI_ * x); } -static double sinc(double x) { return (x == 0.0 ? 1.0 : sin(_PI_ * x) / (_PI_ * x)); } -static double windowed_sinc(double x) { return blackman(0.5 + 0.5 * x / (LW / 2)) * sinc(x); } - -/* f_inp: input frequency. f_out: output frequencey, ch: number of channels */ -OPLL_RateConv *OPLL_RateConv_new(double f_inp, double f_out, int ch) { - OPLL_RateConv *conv = malloc(sizeof(OPLL_RateConv)); - int i; - - conv->ch = ch; - conv->f_ratio = f_inp / f_out; - conv->buf = malloc(sizeof(void *) * ch); - for (i = 0; i < ch; i++) { - conv->buf[i] = malloc(sizeof(conv->buf[0][0]) * LW); - } - - /* create sinc_table for positive 0 <= x < LW/2 */ - conv->sinc_table = malloc(sizeof(conv->sinc_table[0]) * SINC_RESO * LW / 2); - for (i = 0; i < SINC_RESO * LW / 2; i++) { - const double x = (double)i / SINC_RESO; - if (f_out < f_inp) { - /* for downsampling */ - conv->sinc_table[i] = (int16_t)((1 << SINC_AMP_BITS) * windowed_sinc(x / conv->f_ratio) / conv->f_ratio); - } else { - /* for upsampling */ - conv->sinc_table[i] = (int16_t)((1 << SINC_AMP_BITS) * windowed_sinc(x)); - } - } - - return conv; -} - -static INLINE int16_t lookup_sinc_table(int16_t *table, double x) { - int16_t index = (int16_t)(x * SINC_RESO); - if (index < 0) - index = -index; - return table[min(SINC_RESO * LW / 2 - 1, index)]; -} - -void OPLL_RateConv_reset(OPLL_RateConv *conv) { - int i; - conv->timer = 0; - for (i = 0; i < conv->ch; i++) { - memset(conv->buf[i], 0, sizeof(conv->buf[i][0]) * LW); - } -} - -/* put original data to this converter at f_inp. */ -void OPLL_RateConv_putData(OPLL_RateConv *conv, int ch, int16_t data) { - int16_t *buf = conv->buf[ch]; - int i; - for (i = 0; i < LW - 1; i++) { - buf[i] = buf[i + 1]; - } - buf[LW - 1] = data; -} - -/* get resampled data from this converter at f_out. */ -/* this function must be called f_out / f_inp times per one putData call. */ -int16_t OPLL_RateConv_getData(OPLL_RateConv *conv, int ch) { - int16_t *buf = conv->buf[ch]; - int32_t sum = 0; - int k; - double dn; - conv->timer += conv->f_ratio; - dn = conv->timer - floor(conv->timer); - conv->timer = dn; - - for (k = 0; k < LW; k++) { - double x = ((double)k - (LW / 2 - 1)) - dn; - sum += buf[k] * lookup_sinc_table(conv->sinc_table, x); - } - return sum >> SINC_AMP_BITS; -} - -void OPLL_RateConv_delete(OPLL_RateConv *conv) { - int i; - for (i = 0; i < conv->ch; i++) { - free(conv->buf[i]); - } - free(conv->buf); - free(conv->sinc_table); - free(conv); -} - -/*************************************************** - - Create tables - -****************************************************/ - -static void makeSinTable(void) { - int x; - - for (x = 0; x < PG_WIDTH / 4; x++) { - fullsin_table[PG_WIDTH / 4 + x] = fullsin_table[PG_WIDTH / 4 - x - 1]; - } - - for (x = 0; x < PG_WIDTH / 2; x++) { - fullsin_table[PG_WIDTH / 2 + x] = 0x8000 | fullsin_table[x]; - } - - for (x = 0; x < PG_WIDTH / 2; x++) - halfsin_table[x] = fullsin_table[x]; - - for (x = PG_WIDTH / 2; x < PG_WIDTH; x++) - halfsin_table[x] = 0xfff; -} - -static void makeTllTable(void) { - - int32_t tmp; - int32_t fnum, block, TL, KL; - - for (fnum = 0; fnum < 16; fnum++) { - for (block = 0; block < 8; block++) { - for (TL = 0; TL < 64; TL++) { - for (KL = 0; KL < 4; KL++) { - if (KL == 0) { - tll_table[(block << 4) | fnum][TL][KL] = TL2EG(TL); - } else { - tmp = (int32_t)(kl_table[fnum] - dB2(3.000) * (7 - block)); - if (tmp <= 0) - tll_table[(block << 4) | fnum][TL][KL] = TL2EG(TL); - else - tll_table[(block << 4) | fnum][TL][KL] = (uint32_t)((tmp >> (3 - KL)) / EG_STEP) + TL2EG(TL); - } - } - } - } - } -} - -static void makeRksTable(void) { - int fnum8, block; - for (fnum8 = 0; fnum8 < 2; fnum8++) - for (block = 0; block < 8; block++) { - rks_table[(block << 1) | fnum8][1] = (block << 1) + fnum8; - rks_table[(block << 1) | fnum8][0] = block >> 1; - } -} - -static void makeDefaultPatch() { - int i, j; - for (i = 0; i < OPLL_TONE_NUM; i++) - for (j = 0; j < 19; j++) - OPLL_getDefaultPatch(i, j, &default_patch[i][j * 2]); -} - -static uint8_t table_initialized = 0; - -static void initializeTables() { - makeTllTable(); - makeRksTable(); - makeSinTable(); - makeDefaultPatch(); - table_initialized = 1; -} - -/********************************************************* - - Synthesizing - -*********************************************************/ -#define SLOT_BD1 12 -#define SLOT_BD2 13 -#define SLOT_HH 14 -#define SLOT_SD 15 -#define SLOT_TOM 16 -#define SLOT_CYM 17 - -/* utility macros */ -#define MOD(o, x) (&(o)->slot[(x) << 1]) -#define CAR(o, x) (&(o)->slot[((x) << 1) | 1]) -#define BIT(s, b) (((s) >> (b)) & 1) - -#if OPLL_DEBUG -static void _debug_print_patch(OPLL_SLOT *slot) { - OPLL_PATCH *p = slot->patch; - printf("[slot#%d am:%d pm:%d eg:%d kr:%d ml:%d kl:%d tl:%d ws:%d fb:%d A:%d D:%d S:%d R:%d]\n", slot->number, // - p->AM, p->PM, p->EG, p->KR, p->ML, // - p->KL, p->TL, p->WS, p->FB, // - p->AR, p->DR, p->SL, p->RR); -} - -static char *_debug_eg_state_name(OPLL_SLOT *slot) { - switch (slot->eg_state) { - case ATTACK: - return "attack"; - case DECAY: - return "decay"; - case SUSTAIN: - return "sustain"; - case RELEASE: - return "release"; - case DAMP: - return "damp"; - default: - return "unknown"; - } -} - -static INLINE void _debug_print_slot_info(OPLL_SLOT *slot) { - char *name = _debug_eg_state_name(slot); - printf("[slot#%d state:%s fnum:%03x rate:%d-%d]\n", slot->number, name, slot->blk_fnum, slot->eg_rate_h, - slot->eg_rate_l); - _debug_print_patch(slot); - fflush(stdout); -} -#endif - -static INLINE int get_parameter_rate(OPLL_SLOT *slot) { - - if ((slot->type & 1) == 0 && slot->key_flag == 0) { - return 0; - } - - switch (slot->eg_state) { - case ATTACK: - return slot->patch->AR; - case DECAY: - return slot->patch->DR; - case SUSTAIN: - return slot->patch->EG ? 0 : slot->patch->RR; - case RELEASE: - if (slot->sus_flag) { - return 5; - } else if (slot->patch->EG) { - return slot->patch->RR; - } else { - return 7; - } - case DAMP: - return DAMPER_RATE; - default: - return 0; - } -} - -enum SLOT_UPDATE_FLAG { - UPDATE_WS = 1, - UPDATE_TLL = 2, - UPDATE_RKS = 4, - UPDATE_EG = 8, - UPDATE_ALL = 255, -}; - -static INLINE void request_update(OPLL_SLOT *slot, int flag) { slot->update_requests |= flag; } - -static void commit_slot_update(OPLL_SLOT *slot) { - -#if OPLL_DEBUG - if (slot->last_eg_state != slot->eg_state) { - _debug_print_slot_info(slot); - slot->last_eg_state = slot->eg_state; - } -#endif - - if (slot->update_requests & UPDATE_WS) { - slot->wave_table = wave_table_map[slot->patch->WS]; - } - - if (slot->update_requests & UPDATE_TLL) { - if ((slot->type & 1) == 0) { - slot->tll = tll_table[slot->blk_fnum >> 5][slot->patch->TL][slot->patch->KL]; - } else { - slot->tll = tll_table[slot->blk_fnum >> 5][slot->volume][slot->patch->KL]; - } - } - - if (slot->update_requests & UPDATE_RKS) { - slot->rks = rks_table[slot->blk_fnum >> 8][slot->patch->KR]; - } - - if (slot->update_requests & (UPDATE_RKS | UPDATE_EG)) { - int p_rate = get_parameter_rate(slot); - - if (p_rate == 0) { - slot->eg_shift = 0; - slot->eg_rate_h = 0; - slot->eg_rate_l = 0; - return; - } - - slot->eg_rate_h = min(15, p_rate + (slot->rks >> 2)); - slot->eg_rate_l = slot->rks & 3; - if (slot->eg_state == ATTACK) { - slot->eg_shift = (0 < slot->eg_rate_h && slot->eg_rate_h < 12) ? (13 - slot->eg_rate_h) : 0; - } else { - slot->eg_shift = (slot->eg_rate_h < 13) ? (13 - slot->eg_rate_h) : 0; - } - } - - slot->update_requests = 0; -} - -static void reset_slot(OPLL_SLOT *slot, int number) { - slot->number = number; - slot->type = number % 2; - slot->pg_keep = 0; - slot->wave_table = wave_table_map[0]; - slot->pg_phase = 0; - slot->output[0] = 0; - slot->output[1] = 0; - slot->eg_state = RELEASE; - slot->eg_shift = 0; - slot->rks = 0; - slot->tll = 0; - slot->key_flag = 0; - slot->sus_flag = 0; - slot->blk_fnum = 0; - slot->blk = 0; - slot->fnum = 0; - slot->volume = 0; - slot->pg_out = 0; - slot->eg_out = EG_MUTE; - slot->patch = &null_patch; -} - -static INLINE void slotOn(OPLL *opll, int i) { - OPLL_SLOT *slot = &opll->slot[i]; - slot->key_flag = 1; - slot->eg_state = DAMP; - request_update(slot, UPDATE_EG); -} - -static INLINE void slotOff(OPLL *opll, int i) { - OPLL_SLOT *slot = &opll->slot[i]; - slot->key_flag = 0; - if (slot->type & 1) { - slot->eg_state = RELEASE; - request_update(slot, UPDATE_EG); - } -} - -static INLINE void update_key_status(OPLL *opll) { - const uint8_t r14 = opll->reg[0x0e]; - const uint8_t rhythm_mode = BIT(r14, 5); - uint32_t new_slot_key_status = 0; - uint32_t updated_status; - int ch; - - for (ch = 0; ch < 9; ch++) - if (opll->reg[0x20 + ch] & 0x10) - new_slot_key_status |= 3 << (ch * 2); - - if (rhythm_mode) { - if (r14 & 0x10) - new_slot_key_status |= 3 << SLOT_BD1; - - if (r14 & 0x01) - new_slot_key_status |= 1 << SLOT_HH; - - if (r14 & 0x08) - new_slot_key_status |= 1 << SLOT_SD; - - if (r14 & 0x04) - new_slot_key_status |= 1 << SLOT_TOM; - - if (r14 & 0x02) - new_slot_key_status |= 1 << SLOT_CYM; - } - - updated_status = opll->slot_key_status ^ new_slot_key_status; - - if (updated_status) { - int i; - for (i = 0; i < 18; i++) - if (BIT(updated_status, i)) { - if (BIT(new_slot_key_status, i)) { - slotOn(opll, i); - } else { - slotOff(opll, i); - } - } - } - - opll->slot_key_status = new_slot_key_status; -} - -static INLINE void set_patch(OPLL *opll, int32_t ch, int32_t num) { - opll->patch_number[ch] = num; - MOD(opll, ch)->patch = &opll->patch[num * 2 + 0]; - CAR(opll, ch)->patch = &opll->patch[num * 2 + 1]; - request_update(MOD(opll, ch), UPDATE_ALL); - request_update(CAR(opll, ch), UPDATE_ALL); -} - -static INLINE void set_sus_flag(OPLL *opll, int ch, int flag) { - CAR(opll, ch)->sus_flag = flag; - request_update(CAR(opll, ch), UPDATE_EG); - if (MOD(opll, ch)->type & 1) { - MOD(opll, ch)->sus_flag = flag; - request_update(MOD(opll, ch), UPDATE_EG); - } -} - -/* set volume ( volume : 6bit, register value << 2 ) */ -static INLINE void set_volume(OPLL *opll, int ch, int volume) { - CAR(opll, ch)->volume = volume; - request_update(CAR(opll, ch), UPDATE_TLL); -} - -static INLINE void set_slot_volume(OPLL_SLOT *slot, int volume) { - slot->volume = volume; - request_update(slot, UPDATE_TLL); -} - -/* set f-Nnmber ( fnum : 9bit ) */ -static INLINE void set_fnumber(OPLL *opll, int ch, int fnum) { - OPLL_SLOT *car = CAR(opll, ch); - OPLL_SLOT *mod = MOD(opll, ch); - car->fnum = fnum; - car->blk_fnum = (car->blk_fnum & 0xe00) | (fnum & 0x1ff); - mod->fnum = fnum; - mod->blk_fnum = (mod->blk_fnum & 0xe00) | (fnum & 0x1ff); - request_update(car, UPDATE_EG | UPDATE_RKS | UPDATE_TLL); - request_update(mod, UPDATE_EG | UPDATE_RKS | UPDATE_TLL); -} - -/* set block data (blk : 3bit ) */ -static INLINE void set_block(OPLL *opll, int ch, int blk) { - OPLL_SLOT *car = CAR(opll, ch); - OPLL_SLOT *mod = MOD(opll, ch); - car->blk = blk; - car->blk_fnum = ((blk & 7) << 9) | (car->blk_fnum & 0x1ff); - mod->blk = blk; - mod->blk_fnum = ((blk & 7) << 9) | (mod->blk_fnum & 0x1ff); - request_update(car, UPDATE_EG | UPDATE_RKS | UPDATE_TLL); - request_update(mod, UPDATE_EG | UPDATE_RKS | UPDATE_TLL); -} - -static INLINE void update_rhythm_mode(OPLL *opll) { - const uint8_t new_rhythm_mode = (opll->reg[0x0e] >> 5) & 1; - - if (opll->rhythm_mode != new_rhythm_mode) { - - if (new_rhythm_mode) { - opll->slot[SLOT_HH].type = 3; - opll->slot[SLOT_HH].pg_keep = 1; - opll->slot[SLOT_SD].type = 3; - opll->slot[SLOT_TOM].type = 3; - opll->slot[SLOT_CYM].type = 3; - opll->slot[SLOT_CYM].pg_keep = 1; - set_patch(opll, 6, 16); - set_patch(opll, 7, 17); - set_patch(opll, 8, 18); - set_slot_volume(&opll->slot[SLOT_HH], ((opll->reg[0x37] >> 4) & 15) << 2); - set_slot_volume(&opll->slot[SLOT_TOM], ((opll->reg[0x38] >> 4) & 15) << 2); - } else { - opll->slot[SLOT_HH].type = 0; - opll->slot[SLOT_HH].pg_keep = 0; - opll->slot[SLOT_SD].type = 1; - opll->slot[SLOT_TOM].type = 0; - opll->slot[SLOT_CYM].type = 1; - opll->slot[SLOT_CYM].pg_keep = 0; - set_patch(opll, 6, opll->reg[0x36] >> 4); - set_patch(opll, 7, opll->reg[0x37] >> 4); - set_patch(opll, 8, opll->reg[0x38] >> 4); - } - } - - opll->rhythm_mode = new_rhythm_mode; -} - -static void update_ampm(OPLL *opll) { - if (opll->test_flag & 2) { - opll->pm_phase = 0; - opll->am_phase = 0; - } else { - opll->pm_phase += (opll->test_flag & 8) ? 1024 : 1; - opll->am_phase += (opll->test_flag & 8) ? 64 : 1; - } - opll->lfo_am = am_table[(opll->am_phase >> 6) % sizeof(am_table)]; -} - -static void update_noise(OPLL *opll, int cycle) { - int i; - for (i = 0; i < cycle; i++) { - if (opll->noise & 1) { - opll->noise ^= 0x800200; - } - opll->noise >>= 1; - } -} - -static void update_short_noise(OPLL *opll) { - const uint32_t pg_hh = opll->slot[SLOT_HH].pg_out; - const uint32_t pg_cym = opll->slot[SLOT_CYM].pg_out; - - const uint8_t h_bit2 = BIT(pg_hh, PG_BITS - 8); - const uint8_t h_bit7 = BIT(pg_hh, PG_BITS - 3); - const uint8_t h_bit3 = BIT(pg_hh, PG_BITS - 7); - - const uint8_t c_bit3 = BIT(pg_cym, PG_BITS - 7); - const uint8_t c_bit5 = BIT(pg_cym, PG_BITS - 5); - - opll->short_noise = (h_bit2 ^ h_bit7) | (h_bit3 ^ c_bit5) | (c_bit3 ^ c_bit5); -} - -static INLINE void calc_phase(OPLL_SLOT *slot, int32_t pm_phase, uint8_t reset) { - const int8_t pm = slot->patch->PM ? pm_table[(slot->fnum >> 6) & 7][(pm_phase >> 10) & 7] : 0; - if (reset) { - slot->pg_phase = 0; - } - slot->pg_phase += (((slot->fnum & 0x1ff) * 2 + pm) * ml_table[slot->patch->ML]) << slot->blk >> 2; - slot->pg_phase &= (DP_WIDTH - 1); - slot->pg_out = slot->pg_phase >> DP_BASE_BITS; -} - -static INLINE uint8_t lookup_attack_step(OPLL_SLOT *slot, uint32_t counter) { - int index; - - switch (slot->eg_rate_h) { - case 12: - index = (counter & 0xc) >> 1; - return 4 - eg_step_tables[slot->eg_rate_l][index]; - case 13: - index = (counter & 0xc) >> 1; - return 3 - eg_step_tables[slot->eg_rate_l][index]; - case 14: - index = (counter & 0xc) >> 1; - return 2 - eg_step_tables[slot->eg_rate_l][index]; - case 0: - case 15: - return 0; - default: - index = counter >> slot->eg_shift; - return eg_step_tables[slot->eg_rate_l][index & 7] ? 4 : 0; - } -} - -static INLINE uint8_t lookup_decay_step(OPLL_SLOT *slot, uint32_t counter) { - int index; - - switch (slot->eg_rate_h) { - case 0: - return 0; - case 13: - index = ((counter & 0xc) >> 1) | (counter & 1); - return eg_step_tables[slot->eg_rate_l][index]; - case 14: - index = ((counter & 0xc) >> 1); - return eg_step_tables[slot->eg_rate_l][index] + 1; - case 15: - return 2; - default: - index = counter >> slot->eg_shift; - return eg_step_tables[slot->eg_rate_l][index & 7]; - } -} - -static INLINE void start_envelope(OPLL_SLOT *slot) { - if (min(15, slot->patch->AR + (slot->rks >> 2)) == 15) { - slot->eg_state = DECAY; - slot->eg_out = 0; - } else { - slot->eg_state = ATTACK; - slot->eg_out = EG_MUTE; - } - request_update(slot, UPDATE_EG); -} - -static INLINE void calc_envelope(OPLL_SLOT *slot, OPLL_SLOT *buddy, uint16_t eg_counter, uint8_t test) { - - uint32_t mask = (1 << slot->eg_shift) - 1; - uint8_t s; - - if (slot->eg_state == ATTACK) { - if (0 < slot->eg_out && 0 < slot->eg_rate_h && (eg_counter & mask & ~3) == 0) { - s = lookup_attack_step(slot, eg_counter); - if (0 < s) { - slot->eg_out = max(0, ((int)slot->eg_out - (slot->eg_out >> s) - 1)); - } - } - } else { - if (slot->eg_rate_h > 0 && (eg_counter & mask) == 0) { - slot->eg_out = min(EG_MUTE, slot->eg_out + lookup_decay_step(slot, eg_counter)); - } - } - - switch (slot->eg_state) { - case DAMP: - if (slot->eg_out >= EG_MUTE) { - start_envelope(slot); - if (slot->type & 1) { - if (!slot->pg_keep) { - slot->pg_phase = 0; - } - if (buddy && !buddy->pg_keep) { - buddy->pg_phase = 0; - } - } - } - break; - - case ATTACK: - if (slot->eg_out == 0) { - slot->eg_state = DECAY; - request_update(slot, UPDATE_EG); - } - break; - - case DECAY: - if ((slot->eg_out >> 3) == slot->patch->SL) { - slot->eg_state = SUSTAIN; - request_update(slot, UPDATE_EG); - } - break; - - case SUSTAIN: - case RELEASE: - default: - break; - } - - if (test) { - slot->eg_out = 0; - } -} - -static void update_slots(OPLL *opll) { - int i; - opll->eg_counter++; - - for (i = 0; i < 18; i++) { - OPLL_SLOT *slot = &opll->slot[i]; - OPLL_SLOT *buddy = NULL; - if (slot->type == 0) { - buddy = &opll->slot[i + 1]; - } - if (slot->type == 1) { - buddy = &opll->slot[i - 1]; - } - if (slot->update_requests) { - commit_slot_update(slot); - } - calc_envelope(slot, buddy, opll->eg_counter, opll->test_flag & 1); - calc_phase(slot, opll->pm_phase, opll->test_flag & 4); - } -} - -/* output: -4095...4095 */ -static INLINE int16_t lookup_exp_table(uint16_t i) { - /* from andete's expressoin */ - int16_t t = (exp_table[(i & 0xff) ^ 0xff] + 1024); - int16_t res = t >> ((i & 0x7f00) >> 8); - return ((i & 0x8000) ? ~res : res) << 1; -} - -static INLINE int16_t to_linear(uint16_t h, OPLL_SLOT *slot, int16_t am) { - uint16_t att; - if (slot->eg_out >= EG_MAX) - return 0; - - att = min(EG_MAX, (slot->eg_out + slot->tll + am)) << 4; - return lookup_exp_table(h + att); -} - -static INLINE int16_t calc_slot_car(OPLL *opll, int ch, int16_t fm) { - OPLL_SLOT *slot = CAR(opll, ch); - - uint8_t am = slot->patch->AM ? opll->lfo_am : 0; - - slot->output[1] = slot->output[0]; - slot->output[0] = to_linear(slot->wave_table[(slot->pg_out + 2 * (fm >> 1)) & (PG_WIDTH - 1)], slot, am); - - return slot->output[0]; -} - -static INLINE int16_t calc_slot_mod(OPLL *opll, int ch) { - OPLL_SLOT *slot = MOD(opll, ch); - - int16_t fm = slot->patch->FB > 0 ? (slot->output[1] + slot->output[0]) >> (9 - slot->patch->FB) : 0; - uint8_t am = slot->patch->AM ? opll->lfo_am : 0; - - slot->output[1] = slot->output[0]; - slot->output[0] = to_linear(slot->wave_table[(slot->pg_out + fm) & (PG_WIDTH - 1)], slot, am); - - return slot->output[0]; -} - -static INLINE int16_t calc_slot_tom(OPLL *opll) { - OPLL_SLOT *slot = MOD(opll, 8); - - return to_linear(slot->wave_table[slot->pg_out], slot, 0); -} - -/* Specify phase offset directly based on 10-bit (1024-length) sine table */ -#define _PD(phase) ((PG_BITS < 10) ? (phase >> (10 - PG_BITS)) : (phase << (PG_BITS - 10))) - -static INLINE int16_t calc_slot_snare(OPLL *opll) { - OPLL_SLOT *slot = CAR(opll, 7); - - uint32_t phase; - - if (BIT(slot->pg_out, PG_BITS - 2)) - phase = (opll->noise & 1) ? _PD(0x300) : _PD(0x200); - else - phase = (opll->noise & 1) ? _PD(0x0) : _PD(0x100); - - return to_linear(slot->wave_table[phase], slot, 0); -} - -static INLINE int16_t calc_slot_cym(OPLL *opll) { - OPLL_SLOT *slot = CAR(opll, 8); - - uint32_t phase = opll->short_noise ? _PD(0x300) : _PD(0x100); - - return to_linear(slot->wave_table[phase], slot, 0); -} - -static INLINE int16_t calc_slot_hat(OPLL *opll) { - OPLL_SLOT *slot = MOD(opll, 7); - - uint32_t phase; - - if (opll->short_noise) - phase = (opll->noise & 1) ? _PD(0x2d0) : _PD(0x234); - else - phase = (opll->noise & 1) ? _PD(0x34) : _PD(0xd0); - - return to_linear(slot->wave_table[phase], slot, 0); -} - -#define _MO(x) (-(x) >> 1) -#define _RO(x) (x) - -static void update_output(OPLL *opll) { - int16_t *out; - int i; - - update_ampm(opll); - update_short_noise(opll); - update_slots(opll); - - out = opll->ch_out; - - /* CH1-6 */ - for (i = 0; i < 6; i++) { - if (!(opll->mask & OPLL_MASK_CH(i))) { - out[i] = _MO(calc_slot_car(opll, i, calc_slot_mod(opll, i))); - } - } - - /* CH7 */ - if (!opll->rhythm_mode) { - if (!(opll->mask & OPLL_MASK_CH(6))) { - out[6] = _MO(calc_slot_car(opll, 6, calc_slot_mod(opll, 6))); - } - } else { - if (!(opll->mask & OPLL_MASK_BD)) { - out[9] = _RO(calc_slot_car(opll, 6, calc_slot_mod(opll, 6))); - } - } - update_noise(opll, 14); - - /* CH8 */ - if (!opll->rhythm_mode) { - if (!(opll->mask & OPLL_MASK_CH(7))) { - out[7] = _MO(calc_slot_car(opll, 7, calc_slot_mod(opll, 7))); - } - } else { - if (!(opll->mask & OPLL_MASK_HH)) { - out[10] = _RO(calc_slot_hat(opll)); - } - if (!(opll->mask & OPLL_MASK_SD)) { - out[11] = _RO(calc_slot_snare(opll)); - } - } - update_noise(opll, 2); - - /* CH9 */ - if (!opll->rhythm_mode) { - if (!(opll->mask & OPLL_MASK_CH(8))) { - out[8] = _MO(calc_slot_car(opll, 8, calc_slot_mod(opll, 8))); - } - } else { - if (!(opll->mask & OPLL_MASK_TOM)) { - out[12] = _RO(calc_slot_tom(opll)); - } - if (!(opll->mask & OPLL_MASK_CYM)) { - out[13] = _RO(calc_slot_cym(opll)); - } - } - update_noise(opll, 2); -} - -INLINE static void mix_output(OPLL *opll) { - int16_t out = 0; - int i; - for (i = 0; i < 14; i++) { - out += opll->ch_out[i]; - } - if (opll->conv) { - OPLL_RateConv_putData(opll->conv, 0, out); - } else { - opll->mix_out[0] = out; - } -} - -INLINE static void mix_output_stereo(OPLL *opll) { - int16_t *out = opll->mix_out; - int i; - out[0] = out[1] = 0; - for (i = 0; i < 14; i++) { - if (opll->pan[i] & 2) - out[0] += (int16_t)(opll->ch_out[i] * opll->pan_fine[i][0]); - if (opll->pan[i] & 1) - out[1] += (int16_t)(opll->ch_out[i] * opll->pan_fine[i][1]); - } - if (opll->conv) { - OPLL_RateConv_putData(opll->conv, 0, out[0]); - OPLL_RateConv_putData(opll->conv, 1, out[1]); - } -} - -/*********************************************************** - - External Interfaces - -***********************************************************/ - -OPLL *OPLL_new(uint32_t clk, uint32_t rate) { - OPLL *opll; - int i; - - if (!table_initialized) { - initializeTables(); - } - - opll = (OPLL *)calloc(sizeof(OPLL), 1); - if (opll == NULL) - return NULL; - - for (i = 0; i < 19 * 2; i++) - memcpy(&opll->patch[i], &null_patch, sizeof(OPLL_PATCH)); - - opll->clk = clk; - opll->rate = rate; - opll->mask = 0; - opll->conv = NULL; - opll->mix_out[0] = 0; - opll->mix_out[1] = 0; - - OPLL_reset(opll); - OPLL_setChipType(opll, 0); - OPLL_resetPatch(opll, 0); - return opll; -} - -void OPLL_delete(OPLL *opll) { - if (opll->conv) { - OPLL_RateConv_delete(opll->conv); - opll->conv = NULL; - } - free(opll); -} - -static void reset_rate_conversion_params(OPLL *opll) { - const double f_out = opll->rate; - const double f_inp = opll->clk / 72; - - opll->out_time = 0; - opll->out_step = ((uint32_t)f_inp) << 8; - opll->inp_step = ((uint32_t)f_out) << 8; - - if (opll->conv) { - OPLL_RateConv_delete(opll->conv); - opll->conv = NULL; - } - - if (floor(f_inp) != f_out && floor(f_inp + 0.5) != f_out) { - opll->conv = OPLL_RateConv_new(f_inp, f_out, 2); - } - - if (opll->conv) { - OPLL_RateConv_reset(opll->conv); - } -} - -void OPLL_reset(OPLL *opll) { - int i; - - if (!opll) - return; - - opll->adr = 0; - - opll->pm_phase = 0; - opll->am_phase = 0; - - opll->noise = 0x1; - opll->mask = 0; - - opll->rhythm_mode = 0; - opll->slot_key_status = 0; - opll->eg_counter = 0; - - reset_rate_conversion_params(opll); - - for (i = 0; i < 18; i++) - reset_slot(&opll->slot[i], i); - - for (i = 0; i < 9; i++) { - set_patch(opll, i, 0); - } - - for (i = 0; i < 0x40; i++) - OPLL_writeReg(opll, i, 0); - - for (i = 0; i < 15; i++) { - opll->pan[i] = 3; - opll->pan_fine[i][1] = opll->pan_fine[i][0] = 1.0f; - } - - for (i = 0; i < 14; i++) { - opll->ch_out[i] = 0; - } -} - -void OPLL_forceRefresh(OPLL *opll) { - int i; - - if (opll == NULL) - return; - - for (i = 0; i < 9; i++) { - set_patch(opll, i, opll->patch_number[i]); - } - - for (i = 0; i < 18; i++) { - request_update(&opll->slot[i], UPDATE_ALL); - } -} - -void OPLL_setRate(OPLL *opll, uint32_t rate) { - opll->rate = rate; - reset_rate_conversion_params(opll); -} - -void OPLL_setQuality(OPLL *opll, uint8_t q) {} - -void OPLL_setChipType(OPLL *opll, uint8_t type) { opll->chip_type = type; } - -void OPLL_writeReg(OPLL *opll, uint32_t reg, uint8_t data) { - int ch, i; - - if (reg >= 0x40) - return; - - /* mirror registers */ - if ((0x19 <= reg && reg <= 0x1f) || (0x29 <= reg && reg <= 0x2f) || (0x39 <= reg && reg <= 0x3f)) { - reg -= 9; - } - - opll->reg[reg] = (uint8_t)data; - - switch (reg) { - case 0x00: - opll->patch[0].AM = (data >> 7) & 1; - opll->patch[0].PM = (data >> 6) & 1; - opll->patch[0].EG = (data >> 5) & 1; - opll->patch[0].KR = (data >> 4) & 1; - opll->patch[0].ML = (data)&15; - for (i = 0; i < 9; i++) { - if (opll->patch_number[i] == 0) { - request_update(MOD(opll, i), UPDATE_RKS | UPDATE_EG); - } - } - break; - - case 0x01: - opll->patch[1].AM = (data >> 7) & 1; - opll->patch[1].PM = (data >> 6) & 1; - opll->patch[1].EG = (data >> 5) & 1; - opll->patch[1].KR = (data >> 4) & 1; - opll->patch[1].ML = (data)&15; - for (i = 0; i < 9; i++) { - if (opll->patch_number[i] == 0) { - request_update(CAR(opll, i), UPDATE_RKS | UPDATE_EG); - } - } - break; - - case 0x02: - opll->patch[0].KL = (data >> 6) & 3; - opll->patch[0].TL = (data)&63; - for (i = 0; i < 9; i++) { - if (opll->patch_number[i] == 0) { - request_update(MOD(opll, i), UPDATE_TLL); - } - } - break; - - case 0x03: - opll->patch[1].KL = (data >> 6) & 3; - opll->patch[1].WS = (data >> 4) & 1; - opll->patch[0].WS = (data >> 3) & 1; - opll->patch[0].FB = (data)&7; - for (i = 0; i < 9; i++) { - if (opll->patch_number[i] == 0) { - request_update(MOD(opll, i), UPDATE_WS); - request_update(CAR(opll, i), UPDATE_WS | UPDATE_TLL); - } - } - break; - - case 0x04: - opll->patch[0].AR = (data >> 4) & 15; - opll->patch[0].DR = (data)&15; - for (i = 0; i < 9; i++) { - if (opll->patch_number[i] == 0) { - request_update(MOD(opll, i), UPDATE_EG); - } - } - break; - - case 0x05: - opll->patch[1].AR = (data >> 4) & 15; - opll->patch[1].DR = (data)&15; - for (i = 0; i < 9; i++) { - if (opll->patch_number[i] == 0) { - request_update(CAR(opll, i), UPDATE_EG); - } - } - break; - - case 0x06: - opll->patch[0].SL = (data >> 4) & 15; - opll->patch[0].RR = (data)&15; - for (i = 0; i < 9; i++) { - if (opll->patch_number[i] == 0) { - request_update(MOD(opll, i), UPDATE_EG); - } - } - break; - - case 0x07: - opll->patch[1].SL = (data >> 4) & 15; - opll->patch[1].RR = (data)&15; - for (i = 0; i < 9; i++) { - if (opll->patch_number[i] == 0) { - request_update(CAR(opll, i), UPDATE_EG); - } - } - break; - - case 0x0e: - if (opll->chip_type == 1) - break; - update_rhythm_mode(opll); - update_key_status(opll); - break; - - case 0x0f: - opll->test_flag = data; - break; - - case 0x10: - case 0x11: - case 0x12: - case 0x13: - case 0x14: - case 0x15: - case 0x16: - case 0x17: - case 0x18: - ch = reg - 0x10; - set_fnumber(opll, ch, data + ((opll->reg[0x20 + ch] & 1) << 8)); - break; - - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: - case 0x28: - ch = reg - 0x20; - set_fnumber(opll, ch, ((data & 1) << 8) + opll->reg[0x10 + ch]); - set_block(opll, ch, (data >> 1) & 7); - set_sus_flag(opll, ch, (data >> 5) & 1); - update_key_status(opll); - break; - - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - case 0x38: - if ((opll->reg[0x0e] & 32) && (reg >= 0x36)) { - switch (reg) { - case 0x37: - set_slot_volume(MOD(opll, 7), ((data >> 4) & 15) << 2); - break; - case 0x38: - set_slot_volume(MOD(opll, 8), ((data >> 4) & 15) << 2); - break; - default: - break; - } - } else { - set_patch(opll, reg - 0x30, (data >> 4) & 15); - } - set_volume(opll, reg - 0x30, (data & 15) << 2); - break; - - default: - break; - } -} - -void OPLL_writeIO(OPLL *opll, uint32_t adr, uint8_t val) { - if (adr & 1) - OPLL_writeReg(opll, opll->adr, val); - else - opll->adr = val; -} - -void OPLL_setPan(OPLL *opll, uint32_t ch, uint8_t pan) { opll->pan[ch & 15] = pan; } - -void OPLL_setPanFine(OPLL *opll, uint32_t ch, float pan[2]) { - opll->pan_fine[ch & 15][0] = pan[0]; - opll->pan_fine[ch & 15][1] = pan[1]; -} - -void OPLL_dumpToPatch(const uint8_t *dump, OPLL_PATCH *patch) { - patch[0].AM = (dump[0] >> 7) & 1; - patch[1].AM = (dump[1] >> 7) & 1; - patch[0].PM = (dump[0] >> 6) & 1; - patch[1].PM = (dump[1] >> 6) & 1; - patch[0].EG = (dump[0] >> 5) & 1; - patch[1].EG = (dump[1] >> 5) & 1; - patch[0].KR = (dump[0] >> 4) & 1; - patch[1].KR = (dump[1] >> 4) & 1; - patch[0].ML = (dump[0]) & 15; - patch[1].ML = (dump[1]) & 15; - patch[0].KL = (dump[2] >> 6) & 3; - patch[1].KL = (dump[3] >> 6) & 3; - patch[0].TL = (dump[2]) & 63; - patch[1].TL = 0; - patch[0].FB = (dump[3]) & 7; - patch[1].FB = 0; - patch[0].WS = (dump[3] >> 3) & 1; - patch[1].WS = (dump[3] >> 4) & 1; - patch[0].AR = (dump[4] >> 4) & 15; - patch[1].AR = (dump[5] >> 4) & 15; - patch[0].DR = (dump[4]) & 15; - patch[1].DR = (dump[5]) & 15; - patch[0].SL = (dump[6] >> 4) & 15; - patch[1].SL = (dump[7] >> 4) & 15; - patch[0].RR = (dump[6]) & 15; - patch[1].RR = (dump[7]) & 15; -} - -void OPLL_getDefaultPatch(int32_t type, int32_t num, OPLL_PATCH *patch) { - OPLL_dump2patch(default_inst[type] + num * 8, patch); -} - -void OPLL_setPatch(OPLL *opll, const uint8_t *dump) { - OPLL_PATCH patch[2]; - int i; - for (i = 0; i < 19; i++) { - OPLL_dump2patch(dump + i * 8, patch); - memcpy(&opll->patch[i * 2 + 0], &patch[0], sizeof(OPLL_PATCH)); - memcpy(&opll->patch[i * 2 + 1], &patch[1], sizeof(OPLL_PATCH)); - } -} - -void OPLL_patchToDump(const OPLL_PATCH *patch, uint8_t *dump) { - dump[0] = (uint8_t)((patch[0].AM << 7) + (patch[0].PM << 6) + (patch[0].EG << 5) + (patch[0].KR << 4) + patch[0].ML); - dump[1] = (uint8_t)((patch[1].AM << 7) + (patch[1].PM << 6) + (patch[1].EG << 5) + (patch[1].KR << 4) + patch[1].ML); - dump[2] = (uint8_t)((patch[0].KL << 6) + patch[0].TL); - dump[3] = (uint8_t)((patch[1].KL << 6) + (patch[1].WS << 4) + (patch[0].WS << 3) + patch[0].FB); - dump[4] = (uint8_t)((patch[0].AR << 4) + patch[0].DR); - dump[5] = (uint8_t)((patch[1].AR << 4) + patch[1].DR); - dump[6] = (uint8_t)((patch[0].SL << 4) + patch[0].RR); - dump[7] = (uint8_t)((patch[1].SL << 4) + patch[1].RR); -} - -void OPLL_copyPatch(OPLL *opll, int32_t num, OPLL_PATCH *patch) { - memcpy(&opll->patch[num], patch, sizeof(OPLL_PATCH)); -} - -void OPLL_resetPatch(OPLL *opll, uint8_t type) { - int i; - for (i = 0; i < 19 * 2; i++) - OPLL_copyPatch(opll, i, &default_patch[type % OPLL_TONE_NUM][i]); -} - -int16_t OPLL_calc(OPLL *opll) { - while (opll->out_step > opll->out_time) { - opll->out_time += opll->inp_step; - update_output(opll); - mix_output(opll); - } - opll->out_time -= opll->out_step; - if (opll->conv) { - opll->mix_out[0] = OPLL_RateConv_getData(opll->conv, 0); - } - return opll->mix_out[0]; -} - -void OPLL_calcStereo(OPLL *opll, int32_t out[2]) { - while (opll->out_step > opll->out_time) { - opll->out_time += opll->inp_step; - update_output(opll); - mix_output_stereo(opll); - } - opll->out_time -= opll->out_step; - if (opll->conv) { - out[0] = OPLL_RateConv_getData(opll->conv, 0); - out[1] = OPLL_RateConv_getData(opll->conv, 1); - } else { - out[0] = opll->mix_out[0]; - out[1] = opll->mix_out[1]; - } -} - -uint32_t OPLL_setMask(OPLL *opll, uint32_t mask) { - uint32_t ret; - - if (opll) { - ret = opll->mask; - opll->mask = mask; - return ret; - } else - return 0; -} - -uint32_t OPLL_toggleMask(OPLL *opll, uint32_t mask) { - uint32_t ret; - - if (opll) { - ret = opll->mask; - opll->mask ^= mask; - return ret; - } else - return 0; -} diff --git a/extern/NSFplay/legacy/emu2413.h b/extern/NSFplay/legacy/emu2413.h deleted file mode 100644 index 2804f3fac..000000000 --- a/extern/NSFplay/legacy/emu2413.h +++ /dev/null @@ -1,247 +0,0 @@ -#ifndef _EMU2413_H_ -#define _EMU2413_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define OPLL_DEBUG 0 - -enum OPLL_TONE_ENUM { - OPLL_VRC7_TONE = 0, - OPLL_VRC7_RW_TONE, - OPLL_VRC7_FT36_TONE, - OPLL_VRC7_FT35_TONE, - OPLL_VRC7_MO_TONE, - OPLL_VRC7_KT2_TONE, - OPLL_VRC7_KT1_TONE, - OPLL_2413_TONE, - OPLL_281B_TONE -}; - -/* voice data */ -typedef struct __OPLL_PATCH { - uint32_t TL, FB, EG, ML, AR, DR, SL, RR, KR, KL, AM, PM, WS; -} OPLL_PATCH; - -/* slot */ -typedef struct __OPLL_SLOT { - uint8_t number; - - /* type flags: - * 000000SM - * |+-- M: 0:modulator 1:carrier - * +--- S: 0:normal 1:single slot mode (sd, tom, hh or cym) - */ - uint8_t type; - - OPLL_PATCH *patch; /* voice parameter */ - - /* slot output */ - int32_t output[2]; /* output value, latest and previous. */ - - /* phase generator (pg) */ - uint16_t *wave_table; /* wave table */ - uint32_t pg_phase; /* pg phase */ - uint32_t pg_out; /* pg output, as index of wave table */ - uint8_t pg_keep; /* if 1, pg_phase is preserved when key-on */ - uint16_t blk_fnum; /* (block << 9) | f-number */ - uint16_t fnum; /* f-number (9 bits) */ - uint8_t blk; /* block (3 bits) */ - - /* envelope generator (eg) */ - uint8_t eg_state; /* current state */ - int32_t volume; /* current volume */ - uint8_t key_flag; /* key-on flag 1:on 0:off */ - uint8_t sus_flag; /* key-sus option 1:on 0:off */ - uint16_t tll; /* total level + key scale level*/ - uint8_t rks; /* key scale offset (rks) for eg speed */ - uint8_t eg_rate_h; /* eg speed rate high 4bits */ - uint8_t eg_rate_l; /* eg speed rate low 2bits */ - uint32_t eg_shift; /* shift for eg global counter, controls envelope speed */ - uint32_t eg_out; /* eg output */ - - uint32_t update_requests; /* flags to debounce update */ - -#if OPLL_DEBUG - uint8_t last_eg_state; -#endif -} OPLL_SLOT; - -/* mask */ -#define OPLL_MASK_CH(x) (1 << (x)) -#define OPLL_MASK_HH (1 << (9)) -#define OPLL_MASK_CYM (1 << (10)) -#define OPLL_MASK_TOM (1 << (11)) -#define OPLL_MASK_SD (1 << (12)) -#define OPLL_MASK_BD (1 << (13)) -#define OPLL_MASK_RHYTHM (OPLL_MASK_HH | OPLL_MASK_CYM | OPLL_MASK_TOM | OPLL_MASK_SD | OPLL_MASK_BD) - -/* rate conveter */ -typedef struct __OPLL_RateConv { - int ch; - double timer; - double f_ratio; - int16_t *sinc_table; - int16_t **buf; -} OPLL_RateConv; - -OPLL_RateConv *OPLL_RateConv_new(double f_inp, double f_out, int ch); -void OPLL_RateConv_reset(OPLL_RateConv *conv); -void OPLL_RateConv_putData(OPLL_RateConv *conv, int ch, int16_t data); -int16_t OPLL_RateConv_getData(OPLL_RateConv *conv, int ch); -void OPLL_RateConv_delete(OPLL_RateConv *conv); - -typedef struct __OPLL { - uint32_t clk; - uint32_t rate; - - uint8_t chip_type; - - uint32_t adr; - - uint32_t inp_step; - uint32_t out_step; - uint32_t out_time; - - uint8_t reg[0x40]; - uint8_t test_flag; - uint32_t slot_key_status; - uint8_t rhythm_mode; - - uint32_t eg_counter; - - uint32_t pm_phase; - int32_t am_phase; - - uint8_t lfo_am; - - uint32_t noise; - uint8_t short_noise; - - int32_t patch_number[9]; - OPLL_SLOT slot[18]; - OPLL_PATCH patch[19 * 2]; - - uint8_t pan[16]; - float pan_fine[16][2]; - - uint32_t mask; - - /* channel output */ - /* 0..8:tone 9:bd 10:hh 11:sd 12:tom 13:cym */ - int16_t ch_out[14]; - - int16_t mix_out[2]; - - OPLL_RateConv *conv; -} OPLL; - -OPLL *OPLL_new(uint32_t clk, uint32_t rate); -void OPLL_delete(OPLL *); - -void OPLL_reset(OPLL *); -void OPLL_resetPatch(OPLL *, uint8_t); - -/** - * Set output wave sampling rate. - * @param rate sampling rate. If clock / 72 (typically 49716 or 49715 at 3.58MHz) is set, the internal rate converter is - * disabled. - */ -void OPLL_setRate(OPLL *opll, uint32_t rate); - -/** - * Set internal calcuration quality. Currently no effects, just for compatibility. - * >= v1.0.0 always synthesizes internal output at clock/72 Hz. - */ -void OPLL_setQuality(OPLL *opll, uint8_t q); - -/** - * Set pan pot (extra function - not YM2413 chip feature) - * @param ch 0..8:tone 9:bd 10:hh 11:sd 12:tom 13:cym 14,15:reserved - * @param pan 0:mute 1:right 2:left 3:center - * ``` - * pan: 76543210 - * |+- bit 1: enable Left output - * +-- bit 0: enable Right output - * ``` - */ -void OPLL_setPan(OPLL *opll, uint32_t ch, uint8_t pan); - -/** - * Set fine-grained panning - * @param ch 0..8:tone 9:bd 10:hh 11:sd 12:tom 13:cym 14,15:reserved - * @param pan output strength of left/right channel. - * pan[0]: left, pan[1]: right. pan[0]=pan[1]=1.0f for center. - */ -void OPLL_setPanFine(OPLL *opll, uint32_t ch, float pan[2]); - -/** - * Set chip type. If vrc7 is selected, r#14 is ignored. - * This method not change the current ROM patch set. - * To change ROM patch set, use OPLL_resetPatch. - * @param type 0:YM2413 1:VRC7 - */ -void OPLL_setChipType(OPLL *opll, uint8_t type); - -void OPLL_writeIO(OPLL *opll, uint32_t reg, uint8_t val); -void OPLL_writeReg(OPLL *opll, uint32_t reg, uint8_t val); - -/** - * Calculate one sample - */ -int16_t OPLL_calc(OPLL *opll); - -/** - * Calulate stereo sample - */ -void OPLL_calcStereo(OPLL *opll, int32_t out[2]); - -void OPLL_setPatch(OPLL *, const uint8_t *dump); -void OPLL_copyPatch(OPLL *, int32_t, OPLL_PATCH *); - -/** - * Force to refresh. - * External program should call this function after updating patch parameters. - */ -void OPLL_forceRefresh(OPLL *); - -void OPLL_dumpToPatch(const uint8_t *dump, OPLL_PATCH *patch); -void OPLL_patchToDump(const OPLL_PATCH *patch, uint8_t *dump); -void OPLL_getDefaultPatch(int32_t type, int32_t num, OPLL_PATCH *); - -/** - * Set channel mask - * @param mask mask flag: OPLL_MASK_* can be used. - * - bit 0..8: mask for ch 1 to 9 (OPLL_MASK_CH(i)) - * - bit 9: mask for Hi-Hat (OPLL_MASK_HH) - * - bit 10: mask for Top-Cym (OPLL_MASK_CYM) - * - bit 11: mask for Tom (OPLL_MASK_TOM) - * - bit 12: mask for Snare Drum (OPLL_MASK_SD) - * - bit 13: mask for Bass Drum (OPLL_MASK_BD) - */ -uint32_t OPLL_setMask(OPLL *, uint32_t mask); - -/** - * Toggler channel mask flag - */ -uint32_t OPLL_toggleMask(OPLL *, uint32_t mask); - -/* for compatibility */ -#define OPLL_set_rate OPLL_setRate -#define OPLL_set_quality OPLL_setQuality -#define OPLL_set_pan OPLL_setPan -#define OPLL_set_pan_fine OPLL_setPanFine -#define OPLL_calc_stereo OPLL_calcStereo -#define OPLL_reset_patch OPLL_resetPatch -#define OPLL_dump2patch OPLL_dumpToPatch -#define OPLL_patch2dump OPLL_patchToDump -#define OPLL_setChipMode OPLL_setChipType - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/extern/NSFplay/legacy/emutypes.h b/extern/NSFplay/legacy/emutypes.h deleted file mode 100644 index bf5d7e1bf..000000000 --- a/extern/NSFplay/legacy/emutypes.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _EMUTYPES_H_ -#define _EMUTYPES_H_ - -#if defined(_MSC_VER) -#define INLINE __forceinline -#elif defined(__GNUC__) -#define INLINE __inline__ -#elif defined(_MWERKS_) -#define INLINE inline -#else -#define INLINE -#endif - -#if defined(EMU_DLL_IMPORTS) -#define EMU2149_DLL_IMPORTS -#define EMU2212_DLL_IMPORTS -#define EMU2413_DLL_IMPORTS -#define EMU8950_DLL_IMPORTS -#define EMU76489_DLL_IMPORTS -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef unsigned int e_uint; -typedef signed int e_int; - -typedef unsigned char e_uint8 ; -typedef signed char e_int8 ; - -typedef unsigned short e_uint16 ; -typedef signed short e_int16 ; - -typedef unsigned int e_uint32 ; -typedef signed int e_int32 ; - -#ifdef __cplusplus -} -#endif -#endif diff --git a/extern/NSFplay/legacy/vrc7tone_ft35.h b/extern/NSFplay/legacy/vrc7tone_ft35.h deleted file mode 100644 index 7af08bcf7..000000000 --- a/extern/NSFplay/legacy/vrc7tone_ft35.h +++ /dev/null @@ -1,20 +0,0 @@ -// patch set by Mitsutaka Okazaki used in FamiTracker 0.3.5 and prior (6/24/2001) -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x33, 0x01, 0x09, 0x0e, 0x94, 0x90, 0x40, 0x01, -0x13, 0x41, 0x0f, 0x0d, 0xce, 0xd3, 0x43, 0x13, -0x01, 0x12, 0x1b, 0x06, 0xff, 0xd2, 0x00, 0x32, -0x61, 0x61, 0x1b, 0x07, 0xaf, 0x63, 0x20, 0x28, -0x22, 0x21, 0x1e, 0x06, 0xf0, 0x76, 0x08, 0x28, -0x66, 0x21, 0x15, 0x00, 0x93, 0x94, 0x20, 0xf8, -0x21, 0x61, 0x1c, 0x07, 0x82, 0x81, 0x10, 0x17, -0x23, 0x21, 0x20, 0x1f, 0xc0, 0x71, 0x07, 0x47, -0x25, 0x31, 0x26, 0x05, 0x64, 0x41, 0x18, 0xf8, -0x17, 0x21, 0x28, 0x07, 0xff, 0x83, 0x02, 0xf8, -0x97, 0x81, 0x25, 0x07, 0xcf, 0xc8, 0x02, 0x14, -0x21, 0x21, 0x54, 0x0f, 0x80, 0x7f, 0x07, 0x07, -0x01, 0x01, 0x56, 0x03, 0xd3, 0xb2, 0x43, 0x58, -0x31, 0x21, 0x0c, 0x03, 0x82, 0xc0, 0x40, 0x07, -0x21, 0x01, 0x0c, 0x03, 0xd4, 0xd3, 0x40, 0x84, -0x04, 0x21, 0x28, 0x00, 0xdf, 0xf8, 0xff, 0xf8, -0x23, 0x22, 0x00, 0x00, 0xa8, 0xf8, 0xf8, 0xf8, -0x25, 0x18, 0x00, 0x00, 0xf8, 0xa9, 0xf8, 0x55, diff --git a/extern/NSFplay/legacy/vrc7tone_ft36.h b/extern/NSFplay/legacy/vrc7tone_ft36.h deleted file mode 100644 index f693955e6..000000000 --- a/extern/NSFplay/legacy/vrc7tone_ft36.h +++ /dev/null @@ -1,21 +0,0 @@ -// patch set by quietust (1/18/2004), used in FamiTracker 0.3.6 -// Source: http://nesdev.com/cgi-bin/wwwthreads/showpost.pl?Board=NESemdev&Number=1440 -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x03, 0x21, 0x04, 0x06, 0x8D, 0xF2, 0x42, 0x17, -0x13, 0x41, 0x05, 0x0E, 0x99, 0x96, 0x63, 0x12, -0x31, 0x11, 0x10, 0x0A, 0xF0, 0x9C, 0x32, 0x02, -0x21, 0x61, 0x1D, 0x07, 0x9F, 0x64, 0x20, 0x27, -0x22, 0x21, 0x1E, 0x06, 0xF0, 0x76, 0x08, 0x28, -0x02, 0x01, 0x06, 0x00, 0xF0, 0xF2, 0x03, 0x95, -0x21, 0x61, 0x1C, 0x07, 0x82, 0x81, 0x16, 0x07, -0x23, 0x21, 0x1A, 0x17, 0xEF, 0x82, 0x25, 0x15, -0x25, 0x11, 0x1F, 0x00, 0x86, 0x41, 0x20, 0x11, -0x85, 0x01, 0x1F, 0x0F, 0xE4, 0xA2, 0x11, 0x12, -0x07, 0xC1, 0x2B, 0x45, 0xB4, 0xF1, 0x24, 0xF4, -0x61, 0x23, 0x11, 0x06, 0x96, 0x96, 0x13, 0x16, -0x01, 0x02, 0xD3, 0x05, 0x82, 0xA2, 0x31, 0x51, -0x61, 0x22, 0x0D, 0x02, 0xC3, 0x7F, 0x24, 0x05, -0x21, 0x62, 0x0E, 0x00, 0xA1, 0xA0, 0x44, 0x17, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/extern/NSFplay/legacy/vrc7tone_kt1.h b/extern/NSFplay/legacy/vrc7tone_kt1.h deleted file mode 100644 index 59cff8a3a..000000000 --- a/extern/NSFplay/legacy/vrc7tone_kt1.h +++ /dev/null @@ -1,21 +0,0 @@ -// patch set 1 by kevtris (11/14/1999) -// http://kevtris.org/nes/vrcvii.txt -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x05, 0x03, 0x10, 0x06, 0x74, 0xA1, 0x13, 0xF4, -0x05, 0x01, 0x16, 0x00, 0xF9, 0xA2, 0x15, 0xF5, -0x01, 0x41, 0x11, 0x00, 0xA0, 0xA0, 0x83, 0x95, -0x01, 0x41, 0x17, 0x00, 0x60, 0xF0, 0x83, 0x95, -0x24, 0x41, 0x1F, 0x00, 0x50, 0xB0, 0x94, 0x94, -0x05, 0x01, 0x0B, 0x04, 0x65, 0xA0, 0x54, 0x95, -0x11, 0x41, 0x0E, 0x04, 0x70, 0xC7, 0x13, 0x10, -0x02, 0x44, 0x16, 0x06, 0xE0, 0xE0, 0x31, 0x35, -0x48, 0x22, 0x22, 0x07, 0x50, 0xA1, 0xA5, 0xF4, -0x05, 0xA1, 0x18, 0x00, 0xA2, 0xA2, 0xF5, 0xF5, -0x07, 0x81, 0x2B, 0x05, 0xA5, 0xA5, 0x03, 0x03, -0x01, 0x41, 0x08, 0x08, 0xA0, 0xA0, 0x83, 0x95, -0x21, 0x61, 0x12, 0x00, 0x93, 0x92, 0x74, 0x75, -0x21, 0x62, 0x21, 0x00, 0x84, 0x85, 0x34, 0x15, -0x21, 0x62, 0x0E, 0x00, 0xA1, 0xA0, 0x34, 0x15, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/extern/NSFplay/legacy/vrc7tone_kt2.h b/extern/NSFplay/legacy/vrc7tone_kt2.h deleted file mode 100644 index 92caa42bf..000000000 --- a/extern/NSFplay/legacy/vrc7tone_kt2.h +++ /dev/null @@ -1,21 +0,0 @@ -// patch set 2 by kevtris (11/15/1999) -// http://kevtris.org/nes/vrcvii.txt -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x31, 0x22, 0x23, 0x07, 0xF0, 0xF0, 0xE8, 0xF7, -0x03, 0x31, 0x68, 0x05, 0xF2, 0x74, 0x79, 0x9C, -0x01, 0x51, 0x72, 0x04, 0xF1, 0xD3, 0x9D, 0x8B, -0x22, 0x61, 0x1B, 0x05, 0xC0, 0xA1, 0xF8, 0xE8, -0x22, 0x61, 0x2C, 0x03, 0xD2, 0xA1, 0xA7, 0xE8, -0x31, 0x22, 0xFA, 0x01, 0xF1, 0xF1, 0xF4, 0xEE, -0x21, 0x61, 0x28, 0x06, 0xF1, 0xF1, 0xCE, 0x9B, -0x27, 0x61, 0x60, 0x00, 0xF0, 0xF0, 0xFF, 0xFD, -0x60, 0x21, 0x2B, 0x06, 0x85, 0xF1, 0x79, 0x9D, -0x31, 0xA1, 0xFF, 0x0A, 0x53, 0x62, 0x5E, 0xAF, -0x03, 0xA1, 0x70, 0x0F, 0xD4, 0xA3, 0x94, 0xBE, -0x2B, 0x61, 0xE4, 0x07, 0xF6, 0x93, 0xBD, 0xAC, -0x21, 0x63, 0xED, 0x07, 0x77, 0xF1, 0xC7, 0xE8, -0x21, 0x61, 0x2A, 0x03, 0xF3, 0xE2, 0xB6, 0xD9, -0x21, 0x63, 0x37, 0x03, 0xF3, 0xE2, 0xB6, 0xD9, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/extern/NSFplay/legacy/vrc7tone_mo.h b/extern/NSFplay/legacy/vrc7tone_mo.h deleted file mode 100644 index 3b216f874..000000000 --- a/extern/NSFplay/legacy/vrc7tone_mo.h +++ /dev/null @@ -1,20 +0,0 @@ -/* VRC7 TONES by okazaki@angel.ne.jp (4/10/2004) */ -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x33,0x01,0x09,0x0e,0x94,0x90,0x40,0x01, -0x13,0x41,0x0f,0x0d,0xce,0xd3,0x43,0x13, -0x01,0x12,0x1b,0x06,0xff,0xd2,0x00,0x32, -0x61,0x61,0x1b,0x07,0xaf,0x63,0x20,0x28, -0x22,0x21,0x1e,0x06,0xf0,0x76,0x08,0x28, -0x66,0x21,0x15,0x00,0x93,0x94,0x20,0xf8, -0x21,0x61,0x1c,0x07,0x82,0x81,0x10,0x17, -0x23,0x21,0x20,0x1f,0xc0,0x71,0x07,0x47, -0x25,0x31,0x26,0x05,0x64,0x41,0x18,0xf8, -0x17,0x21,0x28,0x07,0xff,0x83,0x02,0xf8, -0x97,0x81,0x25,0x07,0xcf,0xc8,0x02,0x14, -0x21,0x21,0x54,0x0f,0x80,0x7f,0x07,0x07, -0x01,0x01,0x56,0x03,0xd3,0xb2,0x43,0x58, -0x31,0x21,0x0c,0x03,0x82,0xc0,0x40,0x07, -0x21,0x01,0x0c,0x03,0xd4,0xd3,0x40,0x84, -0x07,0x21,0x14,0x00,0xee,0xf8,0xff,0xf8, -0x01,0x31,0x00,0x00,0xf8,0xf7,0xf8,0xf7, -0x25,0x11,0x00,0x00,0xf8,0xfa,0xf8,0x55, diff --git a/extern/NSFplay/legacy/vrc7tone_nuke.h b/extern/NSFplay/legacy/vrc7tone_nuke.h deleted file mode 100644 index 0afcc4ce0..000000000 --- a/extern/NSFplay/legacy/vrc7tone_nuke.h +++ /dev/null @@ -1,21 +0,0 @@ -// patch set by Nuke.YKT (3/15/2019) -// https://siliconpr0n.org/archive/doku.php?id=vendor:yamaha:opl2#ym2413_instruments -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x03, 0x21, 0x05, 0x06, 0xE8, 0x81, 0x42, 0x27, -0x13, 0x41, 0x14, 0x0D, 0xD8, 0xF6, 0x23, 0x12, -0x11, 0x11, 0x08, 0x08, 0xFA, 0xB2, 0x20, 0x12, -0x31, 0x61, 0x0C, 0x07, 0xA8, 0x64, 0x61, 0x27, -0x32, 0x21, 0x1E, 0x06, 0xE1, 0x76, 0x01, 0x28, -0x02, 0x01, 0x06, 0x00, 0xA3, 0xE2, 0xF4, 0xF4, -0x21, 0x61, 0x1D, 0x07, 0x82, 0x81, 0x11, 0x07, -0x23, 0x21, 0x22, 0x17, 0xA2, 0x72, 0x01, 0x17, -0x35, 0x11, 0x25, 0x00, 0x40, 0x73, 0x72, 0x01, -0xB5, 0x01, 0x0F, 0x0F, 0xA8, 0xA5, 0x51, 0x02, -0x17, 0xC1, 0x24, 0x07, 0xF8, 0xF8, 0x22, 0x12, -0x71, 0x23, 0x11, 0x06, 0x65, 0x74, 0x18, 0x16, -0x01, 0x02, 0xD3, 0x05, 0xC9, 0x95, 0x03, 0x02, -0x61, 0x63, 0x0C, 0x00, 0x94, 0xC0, 0x33, 0xF6, -0x21, 0x72, 0x0D, 0x00, 0xC1, 0xD5, 0x56, 0x06, -0x01, 0x01, 0x18, 0x0F, 0xDF, 0xF8, 0x6A, 0x6D, -0x01, 0x01, 0x00, 0x00, 0xC8, 0xD8, 0xA7, 0x68, -0x05, 0x01, 0x00, 0x00, 0xF8, 0xAA, 0x59, 0x55, diff --git a/extern/NSFplay/legacy/vrc7tone_rw.h b/extern/NSFplay/legacy/vrc7tone_rw.h deleted file mode 100644 index bf2261208..000000000 --- a/extern/NSFplay/legacy/vrc7tone_rw.h +++ /dev/null @@ -1,21 +0,0 @@ -// patch set by rainwarrior (8/01/2012) -// http://forums.nesdev.com/viewtopic.php?f=6&t=9141 -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x03, 0x21, 0x05, 0x06, 0xB8, 0x82, 0x42, 0x27, -0x13, 0x41, 0x13, 0x0D, 0xD8, 0xD6, 0x23, 0x12, -0x31, 0x11, 0x08, 0x08, 0xFA, 0x9A, 0x22, 0x02, -0x31, 0x61, 0x18, 0x07, 0x78, 0x64, 0x30, 0x27, -0x22, 0x21, 0x1E, 0x06, 0xF0, 0x76, 0x08, 0x28, -0x02, 0x01, 0x06, 0x00, 0xF0, 0xF2, 0x03, 0xF5, -0x21, 0x61, 0x1D, 0x07, 0x82, 0x81, 0x16, 0x07, -0x23, 0x21, 0x1A, 0x17, 0xCF, 0x72, 0x25, 0x17, -0x15, 0x11, 0x25, 0x00, 0x4F, 0x71, 0x00, 0x11, -0x85, 0x01, 0x12, 0x0F, 0x99, 0xA2, 0x40, 0x02, -0x07, 0xC1, 0x69, 0x07, 0xF3, 0xF5, 0xA7, 0x12, -0x71, 0x23, 0x0D, 0x06, 0x66, 0x75, 0x23, 0x16, -0x01, 0x02, 0xD3, 0x05, 0xA3, 0x92, 0xF7, 0x52, -0x61, 0x63, 0x0C, 0x00, 0x94, 0xAF, 0x34, 0x06, -0x21, 0x62, 0x0D, 0x00, 0xB1, 0xA0, 0x54, 0x17, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/extern/NSFplay/nes_apu.cpp b/extern/NSFplay/nes_apu.cpp index 9d50dfc78..b2ebb677a 100644 --- a/extern/NSFplay/nes_apu.cpp +++ b/extern/NSFplay/nes_apu.cpp @@ -1,400 +1,400 @@ -// -// NES 2A03 -// -#include -#include "nes_apu.h" - -namespace xgm -{ - void NES_APU::sweep_sqr (int i) - { - int shifted = freq[i] >> sweep_amount[i]; - if (i == 0 && sweep_mode[i]) shifted += 1; - sfreq[i] = freq[i] + (sweep_mode[i] ? -shifted : shifted); - //DEBUG_OUT("shifted[%d] = %d (%d >> %d)\n",i,shifted,freq[i],sweep_amount[i]); - } - - void NES_APU::FrameSequence(int s) - { - //DEBUG_OUT("FrameSequence(%d)\n",s); - - if (s > 3) return; // no operation in step 4 - - // 240hz clock - for (int i=0; i < 2; ++i) - { - bool divider = false; - if (envelope_write[i]) - { - envelope_write[i] = false; - envelope_counter[i] = 15; - envelope_div[i] = 0; - } - else - { - ++envelope_div[i]; - if (envelope_div[i] > envelope_div_period[i]) - { - divider = true; - envelope_div[i] = 0; - } - } - if (divider) - { - if (envelope_loop[i] && envelope_counter[i] == 0) - envelope_counter[i] = 15; - else if (envelope_counter[i] > 0) - --envelope_counter[i]; - } - } - - // 120hz clock - if ((s&1) == 0) - for (int i=0; i < 2; ++i) - { - if (!envelope_loop[i] && (length_counter[i] > 0)) - --length_counter[i]; - - if (sweep_enable[i]) - { - //DEBUG_OUT("Clock sweep: %d\n", i); - - --sweep_div[i]; - if (sweep_div[i] <= 0) - { - sweep_sqr(i); // calculate new sweep target - - //DEBUG_OUT("sweep_div[%d] (0/%d)\n",i,sweep_div_period[i]); - //DEBUG_OUT("freq[%d]=%d > sfreq[%d]=%d\n",i,freq[i],i,sfreq[i]); - - if (freq[i] >= 8 && sfreq[i] < 0x800 && sweep_amount[i] > 0) // update frequency if appropriate - { - freq[i] = sfreq[i] < 0 ? 0 : sfreq[i]; - } - sweep_div[i] = sweep_div_period[i] + 1; - - //DEBUG_OUT("freq[%d]=%d\n",i,freq[i]); - } - - if (sweep_write[i]) - { - sweep_div[i] = sweep_div_period[i] + 1; - sweep_write[i] = false; - } - } - } - - } - - INT32 NES_APU::calc_sqr (int i, UINT32 clocks) - { - static const INT16 sqrtbl[4][16] = { - {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, - {1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} - }; - - scounter[i] -= clocks; - while (scounter[i] < 0) - { - sphase[i] = (sphase[i] + 1) & 15; - scounter[i] += freq[i] + 1; - } - - INT32 ret = 0; - if (length_counter[i] > 0 && - freq[i] >= 8 && - sfreq[i] < 0x800 - ) - { - int v = envelope_disable[i] ? volume[i] : envelope_counter[i]; - ret = sqrtbl[duty[i]][sphase[i]] ? v : 0; - } - - return ret; - } - - bool NES_APU::Read (UINT32 adr, UINT32 & val, UINT32 id) - { - if (0x4000 <= adr && adr < 0x4008) - { - val |= reg[adr&0x7]; - return true; - } - else if(adr==0x4015) - { - val |= (length_counter[1]?2:0)|(length_counter[0]?1:0); - return true; - } - else - return false; - } - - void NES_APU::Tick (UINT32 clocks) - { - out[0] = calc_sqr(0, clocks); - out[1] = calc_sqr(1, clocks); - } - - // ¶¬‚³‚ê‚é”gŒ`‚ÌU•‚Í0-8191 - UINT32 NES_APU::Render (INT32 b[2]) - { - out[0] = (mask & 1) ? 0 : out[0]; - out[1] = (mask & 2) ? 0 : out[1]; - - INT32 m[2]; - - if(option[OPT_NONLINEAR_MIXER]) - { - INT32 voltage = square_table[out[0] + out[1]]; - m[0] = out[0] << 6; - m[1] = out[1] << 6; - INT32 ref = m[0] + m[1]; - if (ref > 0) - { - m[0] = (m[0] * voltage) / ref; - m[1] = (m[1] * voltage) / ref; - } - else - { - m[0] = voltage; - m[1] = voltage; - } - } - else - { - m[0] = (out[0] * square_linear) / 15; - m[1] = (out[1] * square_linear) / 15; - } - - b[0] = m[0] * sm[0][0]; - b[0] += m[1] * sm[0][1]; - b[0] >>= 7; - - b[1] = m[0] * sm[1][0]; - b[1] += m[1] * sm[1][1]; - b[1] >>= 7; - - return 2; - } - - NES_APU::NES_APU () - { - SetClock (DEFAULT_CLOCK); - SetRate (DEFAULT_RATE); - option[OPT_UNMUTE_ON_RESET] = true; - option[OPT_PHASE_REFRESH] = true; - option[OPT_NONLINEAR_MIXER] = true; - option[OPT_DUTY_SWAP] = false; - option[OPT_NEGATE_SWEEP_INIT] = false; - - square_table[0] = 0; - for(int i=1;i<32;i++) - square_table[i]=(INT32)((8192.0*95.88)/(8128.0/i+100)); - - square_linear = square_table[15]; // match linear scale to one full volume square of nonlinear - - for(int c=0;c<2;++c) - for(int t=0;t<2;++t) - sm[c][t] = 128; - } - - NES_APU::~NES_APU () - { - } - - void NES_APU::Reset () - { - int i; - gclock = 0; - mask = 0; - - for (int i=0; i<2; ++i) - { - scounter[i] = 0; - sphase[i] = 0; - duty[i] = 0; - volume[i] = 0; - freq[i] = 0; - sfreq[i] = 0; - sweep_enable[i] = 0; - sweep_mode[i] = 0; - sweep_write[i] = 0; - sweep_div_period[i] = 0; - sweep_div[i] = 1; - sweep_amount[i] = 0; - envelope_disable[i] = 0; - envelope_loop[i] = 0; - envelope_write[i] = 0; - envelope_div_period[i] = 0; - envelope_div[0] = 0; - envelope_counter[i] = 0; - length_counter[i] = 0; - enable[i] = 0; - } - - for (i = 0x4000; i < 0x4008; i++) - Write (i, 0); - - Write (0x4015, 0); - if (option[OPT_UNMUTE_ON_RESET]) - Write (0x4015, 0x0f); - if (option[OPT_NEGATE_SWEEP_INIT]) - { - Write (0x4001, 0x08); - Write (0x4005, 0x08); - } - - for (i = 0; i < 2; i++) - out[i] = 0; - - SetRate(rate); - } - - void NES_APU::SetOption (int id, int val) - { - if(id 1) return; - sm[0][trk] = mixl; - sm[1][trk] = mixr; - } - - ITrackInfo *NES_APU::GetTrackInfo(int trk) - { - trkinfo[trk]._freq = freq[trk]; - if(freq[trk]) - trkinfo[trk].freq = clock/16/(freq[trk] + 1); - else - trkinfo[trk].freq = 0; - - trkinfo[trk].output = out[trk]; - trkinfo[trk].volume = volume[trk]+(envelope_disable[trk]?0:0x10)+(envelope_loop[trk]?0x20:0); - trkinfo[trk].key = - enable[trk] && - length_counter[trk] > 0 && - freq[trk] >= 8 && - sfreq[trk] < 0x800 && - (envelope_disable[trk] ? volume[trk] : (envelope_counter[trk] > 0)); - trkinfo[trk].tone = duty[trk]; - trkinfo[trk].max_volume = 15; - return &trkinfo[trk]; - } - - bool NES_APU::Write (UINT32 adr, UINT32 val, UINT32 id) - { - int ch; - - static const UINT8 length_table[32] = { - 0x0A, 0xFE, - 0x14, 0x02, - 0x28, 0x04, - 0x50, 0x06, - 0xA0, 0x08, - 0x3C, 0x0A, - 0x0E, 0x0C, - 0x1A, 0x0E, - 0x0C, 0x10, - 0x18, 0x12, - 0x30, 0x14, - 0x60, 0x16, - 0xC0, 0x18, - 0x48, 0x1A, - 0x10, 0x1C, - 0x20, 0x1E - }; - - if (0x4000 <= adr && adr < 0x4008) - { - //DEBUG_OUT("$%04X = %02X\n",adr,val); - - adr &= 0xf; - ch = adr >> 2; - switch (adr) - { - case 0x0: - case 0x4: - volume[ch] = val & 15; - envelope_disable[ch] = (val >> 4) & 1; - envelope_loop[ch] = (val >> 5) & 1; - envelope_div_period[ch] = (val & 15); - duty[ch] = (val >> 6) & 3; - if (option[OPT_DUTY_SWAP]) - { - if (duty[ch] == 1) duty[ch] = 2; - else if (duty[ch] == 2) duty[ch] = 1; - } - break; - - case 0x1: - case 0x5: - sweep_enable[ch] = (val >> 7) & 1; - sweep_div_period[ch] = (((val >> 4) & 7)); - sweep_mode[ch] = (val >> 3) & 1; - sweep_amount[ch] = val & 7; - sweep_write[ch] = true; - sweep_sqr(ch); - break; - - case 0x2: - case 0x6: - freq[ch] = val | (freq[ch] & 0x700) ; - sweep_sqr(ch); - break; - - case 0x3: - case 0x7: - freq[ch] = (freq[ch] & 0xFF) | ((val & 0x7) << 8) ; - if (option[OPT_PHASE_REFRESH]) - sphase[ch] = 0; - envelope_write[ch] = true; - if (enable[ch]) - { - length_counter[ch] = length_table[(val >> 3) & 0x1f]; - } - sweep_sqr(ch); - break; - - default: - return false; - } - reg[adr] = val; - return true; - } - else if (adr == 0x4015) - { - enable[0] = (val & 1) ? true : false; - enable[1] = (val & 2) ? true : false; - - if (!enable[0]) - length_counter[0] = 0; - if (!enable[1]) - length_counter[1] = 0; - - reg[adr-0x4000] = val; - return true; - } - - // 4017 is handled in nes_dmc.cpp - //else if (adr == 0x4017) - //{ - //} - - return false; - } -} // namespace xgm; +// +// NES 2A03 +// +#include +#include "nes_apu.h" + +namespace xgm +{ + void NES_APU::sweep_sqr (int i) + { + int shifted = freq[i] >> sweep_amount[i]; + if (i == 0 && sweep_mode[i]) shifted += 1; + sfreq[i] = freq[i] + (sweep_mode[i] ? -shifted : shifted); + //DEBUG_OUT("shifted[%d] = %d (%d >> %d)Â¥n",i,shifted,freq[i],sweep_amount[i]); + } + + void NES_APU::FrameSequence(int s) + { + //DEBUG_OUT("FrameSequence(%d)Â¥n",s); + + if (s > 3) return; // no operation in step 4 + + // 240hz clock + for (int i=0; i < 2; ++i) + { + bool divider = false; + if (envelope_write[i]) + { + envelope_write[i] = false; + envelope_counter[i] = 15; + envelope_div[i] = 0; + } + else + { + ++envelope_div[i]; + if (envelope_div[i] > envelope_div_period[i]) + { + divider = true; + envelope_div[i] = 0; + } + } + if (divider) + { + if (envelope_loop[i] && envelope_counter[i] == 0) + envelope_counter[i] = 15; + else if (envelope_counter[i] > 0) + --envelope_counter[i]; + } + } + + // 120hz clock + if ((s&1) == 0) + for (int i=0; i < 2; ++i) + { + if (!envelope_loop[i] && (length_counter[i] > 0)) + --length_counter[i]; + + if (sweep_enable[i]) + { + //DEBUG_OUT("Clock sweep: %dÂ¥n", i); + + --sweep_div[i]; + if (sweep_div[i] <= 0) + { + sweep_sqr(i); // calculate new sweep target + + //DEBUG_OUT("sweep_div[%d] (0/%d)Â¥n",i,sweep_div_period[i]); + //DEBUG_OUT("freq[%d]=%d > sfreq[%d]=%dÂ¥n",i,freq[i],i,sfreq[i]); + + if (freq[i] >= 8 && sfreq[i] < 0x800 && sweep_amount[i] > 0) // update frequency if appropriate + { + freq[i] = sfreq[i] < 0 ? 0 : sfreq[i]; + } + sweep_div[i] = sweep_div_period[i] + 1; + + //DEBUG_OUT("freq[%d]=%dÂ¥n",i,freq[i]); + } + + if (sweep_write[i]) + { + sweep_div[i] = sweep_div_period[i] + 1; + sweep_write[i] = false; + } + } + } + + } + + INT32 NES_APU::calc_sqr (int i, UINT32 clocks) + { + static const INT16 sqrtbl[4][16] = { + {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} + }; + + scounter[i] -= clocks; + while (scounter[i] < 0) + { + sphase[i] = (sphase[i] + 1) & 15; + scounter[i] += freq[i] + 1; + } + + INT32 ret = 0; + if (length_counter[i] > 0 && + freq[i] >= 8 && + sfreq[i] < 0x800 + ) + { + int v = envelope_disable[i] ? volume[i] : envelope_counter[i]; + ret = sqrtbl[duty[i]][sphase[i]] ? v : 0; + } + + return ret; + } + + bool NES_APU::Read (UINT32 adr, UINT32 & val, UINT32 id) + { + if (0x4000 <= adr && adr < 0x4008) + { + val |= reg[adr&0x7]; + return true; + } + else if(adr==0x4015) + { + val |= (length_counter[1]?2:0)|(length_counter[0]?1:0); + return true; + } + else + return false; + } + + void NES_APU::Tick (UINT32 clocks) + { + out[0] = calc_sqr(0, clocks); + out[1] = calc_sqr(1, clocks); + } + + // ツé’カツé’ャツã¤ï½³ï¾‚ã¥ï½ªï¾‚ã¥ï½©ï¾‚波ツ形ツã¥å€‹æŒ¯ï¾‚閉敖ã¥0-8191 + UINT32 NES_APU::Render (INT32 b[2]) + { + out[0] = (mask & 1) ? 0 : out[0]; + out[1] = (mask & 2) ? 0 : out[1]; + + INT32 m[2]; + + if(option[OPT_NONLINEAR_MIXER]) + { + INT32 voltage = square_table[out[0] + out[1]]; + m[0] = out[0] << 6; + m[1] = out[1] << 6; + INT32 ref = m[0] + m[1]; + if (ref > 0) + { + m[0] = (m[0] * voltage) / ref; + m[1] = (m[1] * voltage) / ref; + } + else + { + m[0] = voltage; + m[1] = voltage; + } + } + else + { + m[0] = (out[0] * square_linear) / 15; + m[1] = (out[1] * square_linear) / 15; + } + + b[0] = m[0] * sm[0][0]; + b[0] += m[1] * sm[0][1]; + b[0] >>= 7; + + b[1] = m[0] * sm[1][0]; + b[1] += m[1] * sm[1][1]; + b[1] >>= 7; + + return 2; + } + + NES_APU::NES_APU () + { + SetClock (DEFAULT_CLOCK); + SetRate (DEFAULT_RATE); + option[OPT_UNMUTE_ON_RESET] = true; + option[OPT_PHASE_REFRESH] = true; + option[OPT_NONLINEAR_MIXER] = true; + option[OPT_DUTY_SWAP] = false; + option[OPT_NEGATE_SWEEP_INIT] = false; + + square_table[0] = 0; + for(int i=1;i<32;i++) + square_table[i]=(INT32)((8192.0*95.88)/(8128.0/i+100)); + + square_linear = square_table[15]; // match linear scale to one full volume square of nonlinear + + for(int c=0;c<2;++c) + for(int t=0;t<2;++t) + sm[c][t] = 128; + } + + NES_APU::‾NES_APU () + { + } + + void NES_APU::Reset () + { + int i; + gclock = 0; + mask = 0; + + for (int i=0; i<2; ++i) + { + scounter[i] = 0; + sphase[i] = 0; + duty[i] = 0; + volume[i] = 0; + freq[i] = 0; + sfreq[i] = 0; + sweep_enable[i] = 0; + sweep_mode[i] = 0; + sweep_write[i] = 0; + sweep_div_period[i] = 0; + sweep_div[i] = 1; + sweep_amount[i] = 0; + envelope_disable[i] = 0; + envelope_loop[i] = 0; + envelope_write[i] = 0; + envelope_div_period[i] = 0; + envelope_div[0] = 0; + envelope_counter[i] = 0; + length_counter[i] = 0; + enable[i] = 0; + } + + for (i = 0x4000; i < 0x4008; i++) + Write (i, 0); + + Write (0x4015, 0); + if (option[OPT_UNMUTE_ON_RESET]) + Write (0x4015, 0x0f); + if (option[OPT_NEGATE_SWEEP_INIT]) + { + Write (0x4001, 0x08); + Write (0x4005, 0x08); + } + + for (i = 0; i < 2; i++) + out[i] = 0; + + SetRate(rate); + } + + void NES_APU::SetOption (int id, int val) + { + if(id 1) return; + sm[0][trk] = mixl; + sm[1][trk] = mixr; + } + + ITrackInfo *NES_APU::GetTrackInfo(int trk) + { + trkinfo[trk]._freq = freq[trk]; + if(freq[trk]) + trkinfo[trk].freq = clock/16/(freq[trk] + 1); + else + trkinfo[trk].freq = 0; + + trkinfo[trk].output = out[trk]; + trkinfo[trk].volume = volume[trk]+(envelope_disable[trk]?0:0x10)+(envelope_loop[trk]?0x20:0); + trkinfo[trk].key = + enable[trk] && + length_counter[trk] > 0 && + freq[trk] >= 8 && + sfreq[trk] < 0x800 && + (envelope_disable[trk] ? volume[trk] : (envelope_counter[trk] > 0)); + trkinfo[trk].tone = duty[trk]; + trkinfo[trk].max_volume = 15; + return &trkinfo[trk]; + } + + bool NES_APU::Write (UINT32 adr, UINT32 val, UINT32 id) + { + int ch; + + static const UINT8 length_table[32] = { + 0x0A, 0xFE, + 0x14, 0x02, + 0x28, 0x04, + 0x50, 0x06, + 0xA0, 0x08, + 0x3C, 0x0A, + 0x0E, 0x0C, + 0x1A, 0x0E, + 0x0C, 0x10, + 0x18, 0x12, + 0x30, 0x14, + 0x60, 0x16, + 0xC0, 0x18, + 0x48, 0x1A, + 0x10, 0x1C, + 0x20, 0x1E + }; + + if (0x4000 <= adr && adr < 0x4008) + { + //DEBUG_OUT("$%04X = %02XÂ¥n",adr,val); + + adr &= 0xf; + ch = adr >> 2; + switch (adr) + { + case 0x0: + case 0x4: + volume[ch] = val & 15; + envelope_disable[ch] = (val >> 4) & 1; + envelope_loop[ch] = (val >> 5) & 1; + envelope_div_period[ch] = (val & 15); + duty[ch] = (val >> 6) & 3; + if (option[OPT_DUTY_SWAP]) + { + if (duty[ch] == 1) duty[ch] = 2; + else if (duty[ch] == 2) duty[ch] = 1; + } + break; + + case 0x1: + case 0x5: + sweep_enable[ch] = (val >> 7) & 1; + sweep_div_period[ch] = (((val >> 4) & 7)); + sweep_mode[ch] = (val >> 3) & 1; + sweep_amount[ch] = val & 7; + sweep_write[ch] = true; + sweep_sqr(ch); + break; + + case 0x2: + case 0x6: + freq[ch] = val | (freq[ch] & 0x700) ; + sweep_sqr(ch); + break; + + case 0x3: + case 0x7: + freq[ch] = (freq[ch] & 0xFF) | ((val & 0x7) << 8) ; + if (option[OPT_PHASE_REFRESH]) + sphase[ch] = 0; + envelope_write[ch] = true; + if (enable[ch]) + { + length_counter[ch] = length_table[(val >> 3) & 0x1f]; + } + sweep_sqr(ch); + break; + + default: + return false; + } + reg[adr] = val; + return true; + } + else if (adr == 0x4015) + { + enable[0] = (val & 1) ? true : false; + enable[1] = (val & 2) ? true : false; + + if (!enable[0]) + length_counter[0] = 0; + if (!enable[1]) + length_counter[1] = 0; + + reg[adr-0x4000] = val; + return true; + } + + // 4017 is handled in nes_dmc.cpp + //else if (adr == 0x4017) + //{ + //} + + return false; + } +} // namespace xgm; diff --git a/extern/NSFplay/nes_apu.h b/extern/NSFplay/nes_apu.h index 2a8e75412..a6caa282b 100644 --- a/extern/NSFplay/nes_apu.h +++ b/extern/NSFplay/nes_apu.h @@ -22,7 +22,7 @@ namespace xgm { SQR0_MASK = 1, SQR1_MASK = 2, }; protected: - int option[OPT_END]; // ŠeŽíƒIƒvƒVƒ‡ƒ“ + int option[OPT_END]; // å„種オプション int mask; INT32 sm[2][2]; @@ -66,7 +66,7 @@ namespace xgm public: NES_APU (); - ~NES_APU (); + ‾NES_APU (); void FrameSequence(int s); diff --git a/extern/NSFplay/nes_dmc.cpp b/extern/NSFplay/nes_dmc.cpp index 8073a22ca..49a58eb5e 100644 --- a/extern/NSFplay/nes_dmc.cpp +++ b/extern/NSFplay/nes_dmc.cpp @@ -67,7 +67,7 @@ namespace xgm } - NES_DMC::~NES_DMC () + NES_DMC::‾NES_DMC () { } @@ -122,7 +122,7 @@ namespace xgm void NES_DMC::FrameSequence(int s) { - //DEBUG_OUT("FrameSequence: %d\n",s); + //DEBUG_OUT("FrameSequence: %dÂ¥n",s); if (s > 3) return; // no operation in step 4 @@ -193,7 +193,7 @@ namespace xgm } - // ŽOŠp”gƒ`ƒƒƒ“ƒlƒ‹‚ÌŒvŽZ –ß‚è’l‚Í0-15 + // 三角波ãƒãƒ£ãƒ³ãƒãƒ«ã®è¨ˆç®— 戻り値ã¯0-15 UINT32 NES_DMC::calc_tri (UINT32 clocks) { static UINT32 tritbl[32] = @@ -219,10 +219,10 @@ namespace xgm return ret; } - // ƒmƒCƒYƒ`ƒƒƒ“ƒlƒ‹‚ÌŒvŽZ –ß‚è’l‚Í0-127 - // ’áƒTƒ“ƒvƒŠƒ“ƒOƒŒ[ƒg‚Ҭ‚·‚é‚ƃGƒCƒŠƒAƒXƒmƒCƒY‚ªŒƒ‚µ‚¢‚Ì‚Å - // ƒmƒCƒY‚¾‚¯‚Í‚±‚ÌŠÖ”“à‚Å‚ƒNƒƒbƒN‡¬‚µAŠÈˆÕ‚ȃTƒ“ƒvƒŠƒ“ƒOƒŒ[ƒg - // •ÏŠ·‚ðs‚Á‚Ä‚¢‚éB + // ノイズãƒãƒ£ãƒ³ãƒãƒ«ã®è¨ˆç®— 戻り値ã¯0-127 + // 低サンプリングレートã§åˆæˆã™ã‚‹ã¨ã‚¨ã‚¤ãƒªã‚¢ã‚¹ãƒŽã‚¤ã‚ºãŒæ¿€ã—ã„ã®ã§ + // ノイズã ã‘ã¯ã“ã®é–¢æ•°å†…ã§é«˜ã‚¯ãƒ­ãƒƒã‚¯åˆæˆã—ã€ç°¡æ˜“ãªã‚µãƒ³ãƒ—リングレート + // 変æ›ã‚’è¡Œã£ã¦ã„る。 UINT32 NES_DMC::calc_noise(UINT32 clocks) { UINT32 env = envelope_disable ? noise_volume : envelope_counter; @@ -620,7 +620,7 @@ namespace xgm if (adr == 0x4017) { - //DEBUG_OUT("4017 = %02X\n", val); + //DEBUG_OUT("4017 = %02XÂ¥n", val); frame_irq_enable = ((val & 0x40) != 0x40); if (frame_irq_enable) frame_irq = false; cpu->UpdateIRQ(NES_CPU::IRQD_FRAME, false); @@ -645,7 +645,7 @@ namespace xgm reg[adr-0x4008] = val&0xff; - //DEBUG_OUT("$%04X %02X\n", adr, val); + //DEBUG_OUT("$%04X %02XÂ¥n", adr, val); switch (adr) { @@ -724,12 +724,12 @@ namespace xgm case 0x4012: adr_reg = val&0xff; - // ‚±‚±‚Ådaddress‚ÍXV‚³‚ê‚È‚¢ + // ã“ã“ã§daddressã¯æ›´æ–°ã•ã‚Œãªã„ break; case 0x4013: len_reg = val&0xff; - // ‚±‚±‚Ålength‚ÍXV‚³‚ê‚È‚¢ + // ã“ã“ã§lengthã¯æ›´æ–°ã•ã‚Œãªã„ break; default: diff --git a/extern/NSFplay/nes_dmc.h b/extern/NSFplay/nes_dmc.h index 9152584aa..6cc8058a2 100644 --- a/extern/NSFplay/nes_dmc.h +++ b/extern/NSFplay/nes_dmc.h @@ -1,129 +1,129 @@ -#ifndef _NES_DMC_H_ -#define _NES_DMC_H_ - -#include "../device.h" -#include "../Audio/MedianFilter.h" -#include "../CPU/nes_cpu.h" - -namespace xgm -{ - class NES_APU; // forward declaration - - /** Bottom Half of APU **/ - class NES_DMC:public ISoundChip - { - public: - enum - { - OPT_ENABLE_4011=0, - OPT_ENABLE_PNOISE, - OPT_UNMUTE_ON_RESET, - OPT_DPCM_ANTI_CLICK, - OPT_NONLINEAR_MIXER, - OPT_RANDOMIZE_NOISE, - OPT_TRI_MUTE, - OPT_RANDOMIZE_TRI, - OPT_DPCM_REVERSE, - OPT_END - }; - protected: - const int GETA_BITS; - static const UINT32 freq_table[2][16]; - static const UINT32 wavlen_table[2][16]; - UINT32 tnd_table[2][16][16][128]; - - int option[OPT_END]; - int mask; - INT32 sm[2][3]; - UINT8 reg[0x10]; - UINT32 len_reg; - UINT32 adr_reg; - IDevice *memory; - UINT32 out[3]; - UINT32 daddress; - UINT32 dlength; - UINT32 data; - bool empty; - INT16 damp; - int dac_lsb; - bool dmc_pop; - INT32 dmc_pop_offset; - INT32 dmc_pop_follow; - double clock; - UINT32 rate; - int pal; - int mode; - bool irq; - - INT32 counter[3]; // frequency dividers - int tphase; // triangle phase - UINT32 nfreq; // noise frequency - UINT32 dfreq; // DPCM frequency - - UINT32 tri_freq; - int linear_counter; - int linear_counter_reload; - bool linear_counter_halt; - bool linear_counter_control; - - int noise_volume; - UINT32 noise, noise_tap; - - // noise envelope - bool envelope_loop; - bool envelope_disable; - bool envelope_write; - int envelope_div_period; - int envelope_div; - int envelope_counter; - - bool enable[2]; // tri/noise enable - int length_counter[2]; // 0=tri, 1=noise - - TrackInfoBasic trkinfo[3]; - - // frame sequencer - NES_APU* apu; // apu is clocked by DMC's frame sequencer - int frame_sequence_count; // current cycle count - int frame_sequence_length; // CPU cycles per FrameSequence - int frame_sequence_step; // current step of frame sequence - int frame_sequence_steps; // 4/5 steps per frame - bool frame_irq; - bool frame_irq_enable; - - NES_CPU* cpu; // IRQ needs CPU access - - inline UINT32 calc_tri (UINT32 clocks); - inline UINT32 calc_dmc (UINT32 clocks); - inline UINT32 calc_noise (UINT32 clocks); - - public: - NES_DMC (); - ~NES_DMC (); - - void InitializeTNDTable(double wt, double wn, double wd); - void SetPal (bool is_pal); - void SetAPU (NES_APU* apu_); - void SetMemory (IDevice * r); - void FrameSequence(int s); - int GetDamp(){ return (damp<<1)|dac_lsb ; } - void TickFrameSequence (UINT32 clocks); - - virtual void Reset (); - virtual void Tick (UINT32 clocks); - virtual UINT32 Render (INT32 b[2]); - virtual bool Write (UINT32 adr, UINT32 val, UINT32 id=0); - virtual bool Read (UINT32 adr, UINT32 & val, UINT32 id=0); - virtual void SetRate (double rate); - virtual void SetClock (double rate); - virtual void SetOption (int, int); - virtual void SetMask(int m){ mask = m; } - virtual void SetStereoMix (int trk, xgm::INT16 mixl, xgm::INT16 mixr); - virtual ITrackInfo *GetTrackInfo(int trk); - - void SetCPU(NES_CPU* cpu_); - }; - -} - -#endif +#ifndef _NES_DMC_H_ +#define _NES_DMC_H_ + +#include "../device.h" +#include "../Audio/MedianFilter.h" +#include "../CPU/nes_cpu.h" + +namespace xgm +{ + class NES_APU; // forward declaration + + /** Bottom Half of APU **/ + class NES_DMC:public ISoundChip + { + public: + enum + { + OPT_ENABLE_4011=0, + OPT_ENABLE_PNOISE, + OPT_UNMUTE_ON_RESET, + OPT_DPCM_ANTI_CLICK, + OPT_NONLINEAR_MIXER, + OPT_RANDOMIZE_NOISE, + OPT_TRI_MUTE, + OPT_RANDOMIZE_TRI, + OPT_DPCM_REVERSE, + OPT_END + }; + protected: + const int GETA_BITS; + static const UINT32 freq_table[2][16]; + static const UINT32 wavlen_table[2][16]; + UINT32 tnd_table[2][16][16][128]; + + int option[OPT_END]; + int mask; + INT32 sm[2][3]; + UINT8 reg[0x10]; + UINT32 len_reg; + UINT32 adr_reg; + IDevice *memory; + UINT32 out[3]; + UINT32 daddress; + UINT32 dlength; + UINT32 data; + bool empty; + INT16 damp; + int dac_lsb; + bool dmc_pop; + INT32 dmc_pop_offset; + INT32 dmc_pop_follow; + double clock; + UINT32 rate; + int pal; + int mode; + bool irq; + + INT32 counter[3]; // frequency dividers + int tphase; // triangle phase + UINT32 nfreq; // noise frequency + UINT32 dfreq; // DPCM frequency + + UINT32 tri_freq; + int linear_counter; + int linear_counter_reload; + bool linear_counter_halt; + bool linear_counter_control; + + int noise_volume; + UINT32 noise, noise_tap; + + // noise envelope + bool envelope_loop; + bool envelope_disable; + bool envelope_write; + int envelope_div_period; + int envelope_div; + int envelope_counter; + + bool enable[2]; // tri/noise enable + int length_counter[2]; // 0=tri, 1=noise + + TrackInfoBasic trkinfo[3]; + + // frame sequencer + NES_APU* apu; // apu is clocked by DMC's frame sequencer + int frame_sequence_count; // current cycle count + int frame_sequence_length; // CPU cycles per FrameSequence + int frame_sequence_step; // current step of frame sequence + int frame_sequence_steps; // 4/5 steps per frame + bool frame_irq; + bool frame_irq_enable; + + NES_CPU* cpu; // IRQ needs CPU access + + inline UINT32 calc_tri (UINT32 clocks); + inline UINT32 calc_dmc (UINT32 clocks); + inline UINT32 calc_noise (UINT32 clocks); + + public: + NES_DMC (); + ‾NES_DMC (); + + void InitializeTNDTable(double wt, double wn, double wd); + void SetPal (bool is_pal); + void SetAPU (NES_APU* apu_); + void SetMemory (IDevice * r); + void FrameSequence(int s); + int GetDamp(){ return (damp<<1)|dac_lsb ; } + void TickFrameSequence (UINT32 clocks); + + virtual void Reset (); + virtual void Tick (UINT32 clocks); + virtual UINT32 Render (INT32 b[2]); + virtual bool Write (UINT32 adr, UINT32 val, UINT32 id=0); + virtual bool Read (UINT32 adr, UINT32 & val, UINT32 id=0); + virtual void SetRate (double rate); + virtual void SetClock (double rate); + virtual void SetOption (int, int); + virtual void SetMask(int m){ mask = m; } + virtual void SetStereoMix (int trk, xgm::INT16 mixl, xgm::INT16 mixr); + virtual ITrackInfo *GetTrackInfo(int trk); + + void SetCPU(NES_CPU* cpu_); + }; + +} + +#endif diff --git a/extern/NSFplay/nes_fds.cpp b/extern/NSFplay/nes_fds.cpp index 9d74c62f0..1e08100c0 100644 --- a/extern/NSFplay/nes_fds.cpp +++ b/extern/NSFplay/nes_fds.cpp @@ -22,7 +22,7 @@ NES_FDS::NES_FDS () Reset(); } -NES_FDS::~NES_FDS () +NES_FDS::‾NES_FDS () { } diff --git a/extern/NSFplay/nes_fds.h b/extern/NSFplay/nes_fds.h index 212e472b4..67c60fd1c 100644 --- a/extern/NSFplay/nes_fds.h +++ b/extern/NSFplay/nes_fds.h @@ -63,7 +63,7 @@ protected: public: NES_FDS (); - virtual ~ NES_FDS (); + virtual ‾ NES_FDS (); virtual void Reset (); virtual void Tick (UINT32 clocks); diff --git a/extern/NSFplay/nes_fme7.cpp b/extern/NSFplay/nes_fme7.cpp deleted file mode 100644 index 9d48de794..000000000 --- a/extern/NSFplay/nes_fme7.cpp +++ /dev/null @@ -1,186 +0,0 @@ -#include "nes_fme7.h" - -using namespace xgm; - -const int DIVIDER = 8; // TODO this is not optimal, rewrite PSG output - -NES_FME7::NES_FME7 () -{ - psg = PSG_new ((e_uint32)DEFAULT_CLOCK, DEFAULT_RATE); - divider = 0; - - for(int c=0;c<2;++c) - for(int t=0;t<3;++t) - sm[c][t] = 128; -} - -NES_FME7::~NES_FME7 () -{ - if (psg) - PSG_delete (psg); -} - -void NES_FME7::SetClock (double c) -{ - this->clock = c * 2.0; -} - -void NES_FME7::SetRate (double r) -{ - //rate = r ? r : DEFAULT_RATE; - rate = DEFAULT_CLOCK / double(DIVIDER); // TODO rewrite PSG to integrate with clock - if (psg) - PSG_set_rate (psg, (e_uint32)rate); -} - -void NES_FME7::SetOption (int id, int val) -{ - if(id= DIVIDER) - { - divider -= DIVIDER; - if (psg) PSG_calc(psg); - } -} - -xgm::UINT32 NES_FME7::Render (xgm::INT32 b[2]) -{ - b[0] = b[1] = 0; - - for (int i=0; i < 3; ++i) - { - // note negative polarity - b[0] -= psg->cout[i] * sm[0][i]; - b[1] -= psg->cout[i] * sm[1][i]; - } - b[0] >>= (7-4); - b[1] >>= (7-4); - - // master volume adjustment - const INT32 MASTER = INT32(0.64 * 256.0); - b[0] = (b[0] * MASTER) >> 8; - b[1] = (b[1] * MASTER) >> 8; - - return 2; -} - -void NES_FME7::SetStereoMix(int trk, xgm::INT16 mixl, xgm::INT16 mixr) -{ - if (trk < 0) return; - if (trk > 2) return; - sm[0][trk] = mixl; - sm[1][trk] = mixr; -} - -ITrackInfo *NES_FME7::GetTrackInfo(int trk) -{ - assert(trk<5); - - if(psg) - { - if (trk<3) - { - trkinfo[trk]._freq = psg->freq[trk]; - if(psg->freq[trk]) - trkinfo[trk].freq = psg->clk/32.0/psg->freq[trk]; - else - trkinfo[trk].freq = 0; - - trkinfo[trk].output = psg->cout[trk]; - trkinfo[trk].max_volume = 15; - trkinfo[trk].volume = psg->volume[trk] >> 1; - //trkinfo[trk].key = (psg->cout[trk]>0)?true:false; - trkinfo[trk].key = !(psg->tmask[trk]); - trkinfo[trk].tone = (psg->tmask[trk]?2:0)+(psg->nmask[trk]?1:0); - } - else if (trk == 3) // envelope - { - trkinfo[trk]._freq = psg->env_freq; - if(psg->env_freq) - trkinfo[trk].freq = psg->clk/512.0/psg->env_freq; - else - trkinfo[trk].freq = 0; - - if (psg->env_continue && psg->env_alternate && !psg->env_hold) // triangle wave - { - trkinfo[trk].freq *= 0.5f; // sounds an octave down - } - - trkinfo[trk].output = psg->voltbl[psg->env_ptr]; - trkinfo[trk].max_volume = 0; - trkinfo[trk].volume = 0; - trkinfo[trk].key = (((psg->volume[0]|psg->volume[1]|psg->volume[2])&32) != 0); - trkinfo[trk].tone = - (psg->env_continue ?8:0) | - (psg->env_attack ?4:0) | - (psg->env_alternate?2:0) | - (psg->env_hold ?1:0) ; - } - else if (trk == 4) // noise - { - trkinfo[trk]._freq = psg->noise_freq >> 1; - if(trkinfo[trk]._freq > 0) - trkinfo[trk].freq = psg->clk/16.0/psg->noise_freq; - else - trkinfo[trk].freq = 0; - - trkinfo[trk].output = psg->noise_seed & 1; - trkinfo[trk].max_volume = 0; - trkinfo[trk].volume = 0; - //trkinfo[trk].key = ((psg->nmask[0]&psg->nmask[1]&psg->nmask[2]) == 0); - trkinfo[trk].key = false; - trkinfo[trk].tone = 0; - } - } - return &trkinfo[trk]; -} diff --git a/extern/NSFplay/nes_fme7.h b/extern/NSFplay/nes_fme7.h deleted file mode 100644 index d351b0859..000000000 --- a/extern/NSFplay/nes_fme7.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _NES_FME7_H_ -#define _NES_FME7_H_ -#include "../device.h" -#include "legacy/emu2149.h" - -namespace xgm -{ - - class NES_FME7:public ISoundChip - { - public: - enum - { - OPT_END - }; - protected: - //int option[OPT_END]; - INT32 sm[2][3]; // stereo mix - INT16 buf[2]; - PSG *psg; - int divider; // clock divider - double clock, rate; - TrackInfoBasic trkinfo[5]; - public: - NES_FME7 (); - ~NES_FME7 (); - virtual void Reset (); - virtual void Tick (UINT32 clocks); - virtual UINT32 Render (INT32 b[2]); - virtual bool Read (UINT32 adr, UINT32 & val, UINT32 id=0); - virtual bool Write (UINT32 adr, UINT32 val, UINT32 id=0); - virtual void SetClock (double); - virtual void SetRate (double); - virtual void SetOption (int, int); - virtual void SetMask (int m){ if(psg) PSG_setMask(psg,m); } - virtual void SetStereoMix (int trk, xgm::INT16 mixl, xgm::INT16 mixr); - virtual ITrackInfo *GetTrackInfo(int trk); - }; - -} // namespace - -#endif diff --git a/extern/NSFplay/nes_mmc5.cpp b/extern/NSFplay/nes_mmc5.cpp index 2b2f8fcb7..9243f6595 100644 --- a/extern/NSFplay/nes_mmc5.cpp +++ b/extern/NSFplay/nes_mmc5.cpp @@ -35,7 +35,7 @@ namespace xgm sm[c][t] = 128; } - NES_MMC5::~NES_MMC5 () + NES_MMC5::‾NES_MMC5 () { } diff --git a/extern/NSFplay/nes_mmc5.h b/extern/NSFplay/nes_mmc5.h index b05fbb506..5747ab0d6 100644 --- a/extern/NSFplay/nes_mmc5.h +++ b/extern/NSFplay/nes_mmc5.h @@ -31,8 +31,8 @@ namespace xgm INT32 out[3]; bool enable[2]; - bool envelope_disable[2]; // ƒGƒ“ƒxƒ[ƒv—LŒøƒtƒ‰ƒO - bool envelope_loop[2]; // ƒGƒ“ƒxƒ[ƒvƒ‹[ƒv + bool envelope_disable[2]; // エンベロープ有効フラグ + bool envelope_loop[2]; // エンベロープループ bool envelope_write[2]; int envelope_div_period[2]; int envelope_div[2]; @@ -49,7 +49,7 @@ namespace xgm TrackInfoBasic trkinfo[3]; public: NES_MMC5 (); - ~NES_MMC5 (); + ‾NES_MMC5 (); void FrameSequence (); void TickFrameSequence (UINT32 clocks); diff --git a/extern/NSFplay/nes_n106.cpp b/extern/NSFplay/nes_n106.cpp index f53d4ae7c..ae793dc08 100644 --- a/extern/NSFplay/nes_n106.cpp +++ b/extern/NSFplay/nes_n106.cpp @@ -18,7 +18,7 @@ NES_N106::NES_N106 () Reset(); } -NES_N106::~NES_N106 () +NES_N106::‾NES_N106 () { } diff --git a/extern/NSFplay/nes_n106.h b/extern/NSFplay/nes_n106.h index 82d7eaa6a..aebb6cb46 100644 --- a/extern/NSFplay/nes_n106.h +++ b/extern/NSFplay/nes_n106.h @@ -54,7 +54,7 @@ protected: public: NES_N106 (); - ~NES_N106 (); + ‾NES_N106 (); virtual void Reset (); virtual void Tick (UINT32 clocks); diff --git a/extern/NSFplay/nes_vrc6.cpp b/extern/NSFplay/nes_vrc6.cpp index 6a19b5ea5..c46109403 100644 --- a/extern/NSFplay/nes_vrc6.cpp +++ b/extern/NSFplay/nes_vrc6.cpp @@ -16,7 +16,7 @@ namespace xgm sm[c][t] = 128; } - NES_VRC6::~NES_VRC6 () + NES_VRC6::‾NES_VRC6 () { } diff --git a/extern/NSFplay/nes_vrc6.h b/extern/NSFplay/nes_vrc6.h index 2e277e6ee..2bb64eb8a 100644 --- a/extern/NSFplay/nes_vrc6.h +++ b/extern/NSFplay/nes_vrc6.h @@ -36,7 +36,7 @@ namespace xgm public: NES_VRC6 (); - ~NES_VRC6 (); + ‾NES_VRC6 (); virtual void Reset (); virtual void Tick (UINT32 clocks); diff --git a/extern/NSFplay/nes_vrc7.cpp b/extern/NSFplay/nes_vrc7.cpp deleted file mode 100644 index 4123fb36b..000000000 --- a/extern/NSFplay/nes_vrc7.cpp +++ /dev/null @@ -1,189 +0,0 @@ -#include -#include "nes_vrc7.h" - -namespace xgm -{ - NES_VRC7::NES_VRC7 () - { - use_all_channels = false; - patch_set = OPLL_VRC7_TONE; - patch_custom = NULL; - divider = 0; - - opll = OPLL_new ( 3579545, DEFAULT_RATE); - OPLL_reset_patch (opll, patch_set); - SetClock(DEFAULT_CLOCK); - - for(int c=0;c<2;++c) - //for(int t=0;t<6;++t) - for(int t=0;t<9;++t) // HACK for YM2413 support - sm[c][t] = 128; - } - - NES_VRC7::~NES_VRC7 () - { - OPLL_delete (opll); - } - - void NES_VRC7::UseAllChannels(bool b) - { - use_all_channels = b; - } - - void NES_VRC7::SetPatchSet(int p) - { - patch_set = p; - } - - void NES_VRC7::SetPatchSetCustom (const UINT8* pset) - { - patch_custom = pset; - } - - void NES_VRC7::SetClock (double c) - { - clock = c / 36; - } - - void NES_VRC7::SetRate (double r) - { - //rate = r ? r : DEFAULT_RATE; - (void)r; // rate is ignored - rate = 49716; - OPLL_set_quality(opll, 1); // quality always on (not really a CPU hog) - OPLL_set_rate(opll,(uint32_t)rate); - } - - void NES_VRC7::SetOption (int id, int val) - { - if(id 5) return; - if (trk > 8) return; // HACK YM2413 - sm[0][trk] = mixl; - sm[1][trk] = mixr; - } - - ITrackInfo *NES_VRC7::GetTrackInfo(int trk) - { - //if(opll&&trk<6) - if(opll&&trk<9) // HACK YM2413 (percussion mode isn't very diagnostic this way though) - { - trkinfo[trk].max_volume = 15; - trkinfo[trk].volume = 15 - ((opll->reg[0x30+trk])&15); - trkinfo[trk]._freq = opll->reg[0x10+trk]+((opll->reg[0x20+trk]&1)<<8); - int blk = (opll->reg[0x20+trk]>>1)&7; - trkinfo[trk].freq = clock*trkinfo[trk]._freq/(double)(0x80000>>blk); - trkinfo[trk].tone = (opll->reg[0x30+trk]>>4)&15; - //trkinfo[trk].key = (opll->reg[0x20+trk]&0x10)?true:false; - trkinfo[trk].key = opll->slot_key_status & (3 << trk)?true:false; - return &trkinfo[trk]; - } - else - return NULL; - } - - bool NES_VRC7::Write (UINT32 adr, UINT32 val, UINT32 id) - { - if (adr == 0x9010) - { - OPLL_writeIO (opll, 0, val); - return true; - } - if (adr == 0x9030) - { - OPLL_writeIO (opll, 1, val); - return true; - } - else - return false; - } - - bool NES_VRC7::Read (UINT32 adr, UINT32 & val, UINT32 id) - { - return false; - } - - void NES_VRC7::Tick (UINT32 clocks) - { - divider += clocks; - while (divider >= 36) - { - divider -= 36; - OPLL_calc(opll); - } - } - - UINT32 NES_VRC7::Render (INT32 b[2]) - { - b[0] = b[1] = 0; - for (int i=0; i < 6; ++i) - { - INT32 val = (mask & (1<ch_out[i] >> 4; - b[0] += val * sm[0][i]; - b[1] += val * sm[1][i]; - } - - // HACK for YM2413 support - if (use_all_channels) - { - for (int i=6; i < 9; ++i) - { - if (mask & (1<patch_number[i] > 15) // rhytm mode - { - if (i == 6) val = opll->ch_out[9]; // BD - else if (i == 7) val = opll->ch_out[10] + opll->ch_out[11]; // HH&SD - else val = opll->ch_out[12] + opll->ch_out[13]; // TOM&CYM - /* (i == 8) is implied */ - } - else - { - val = opll->ch_out[i]; - } - val >>= 4; - b[0] += val * sm[0][i]; - b[1] += val * sm[1][i]; - } - } - - b[0] >>= (7 - 4); - b[1] >>= (7 - 4); - - // master volume adjustment - const INT32 MASTER = INT32(1.15 * 256.0); - b[0] = (b[0] * MASTER) >> 8; - b[1] = (b[1] * MASTER) >> 8; - - return 2; - } -} diff --git a/extern/NSFplay/nes_vrc7.h b/extern/NSFplay/nes_vrc7.h deleted file mode 100644 index e8a91d61d..000000000 --- a/extern/NSFplay/nes_vrc7.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef _NES_VRC7_H_ -#define _NES_VRC7_H_ -#include "../device.h" -#include "legacy/emu2413.h" - -namespace xgm -{ - - class NES_VRC7 : public ISoundChip - { - public: - enum - { - OPT_OPLL=0, - OPT_END - }; - protected: - int option[OPT_END]; - int mask; - int patch_set; - const UINT8* patch_custom; - //INT32 sm[2][6]; // stereo mix - INT32 sm[2][9]; // stereo mix temporary HACK to support YM2413 - INT16 buf[2]; - OPLL *opll; - UINT32 divider; // clock divider - double clock, rate; - //TrackInfoBasic trkinfo[6]; - TrackInfoBasic trkinfo[9]; // HACK to support YM2413 - bool use_all_channels; - public: - NES_VRC7 (); - ~NES_VRC7 (); - - virtual void Reset (); - virtual void Tick (UINT32 clocks); - virtual UINT32 Render (INT32 b[2]); - virtual bool Read (UINT32 adr, UINT32 & val, UINT32 id=0); - virtual bool Write (UINT32 adr, UINT32 val, UINT32 id=0); - virtual void UseAllChannels (bool b); - virtual void SetPatchSet (int p); - virtual void SetPatchSetCustom (const UINT8* pset); - virtual void SetClock (double); - virtual void SetRate (double); - virtual void SetOption (int, int); - virtual void SetMask (int m){ mask = m; if(opll) OPLL_setMask(opll, m); } - virtual void SetStereoMix (int trk, xgm::INT16 mixl, xgm::INT16 mixr); - virtual ITrackInfo *GetTrackInfo(int trk); - }; - -} // namespace - -#endif