diff options
author | Takamichi Horikawa <takamichiho@gmail.com> | 2017-02-19 17:25:56 +0900 |
---|---|---|
committer | Takamichi Horikawa <takamichiho@gmail.com> | 2017-02-19 17:25:56 +0900 |
commit | d78900cd1497441d7712805b08072e46ee361ff8 (patch) | |
tree | 5a696ac5ffa4e6d71992c9329ff5b13ad14cf977 /libopna | |
parent | be500d48fbc381273dfdc600898f68df725aa954 (diff) |
add opna status display
Diffstat (limited to 'libopna')
-rw-r--r-- | libopna/opna.c | 13 | ||||
-rw-r--r-- | libopna/opna.h | 24 | ||||
-rw-r--r-- | libopna/opnaadpcm.c | 22 | ||||
-rw-r--r-- | libopna/opnaadpcm.h | 1 | ||||
-rw-r--r-- | libopna/opnadrum.c | 7 | ||||
-rw-r--r-- | libopna/opnadrum.h | 1 | ||||
-rw-r--r-- | libopna/opnafm.c | 2 | ||||
-rw-r--r-- | libopna/opnafm.h | 4 | ||||
-rw-r--r-- | libopna/opnassg.c | 2 | ||||
-rw-r--r-- | libopna/opnassg.h | 1 |
10 files changed, 64 insertions, 13 deletions
diff --git a/libopna/opna.c b/libopna/opna.c index 4e198a0..fb9e24a 100644 --- a/libopna/opna.c +++ b/libopna/opna.c @@ -6,6 +6,7 @@ void opna_reset(struct opna *opna) { opna_ssg_resampler_reset(&opna->resampler); opna_drum_reset(&opna->drum); opna_adpcm_reset(&opna->adpcm); + opna->mask = 0; } void opna_writereg(struct opna *opna, unsigned reg, unsigned val) { @@ -22,3 +23,15 @@ void opna_mix(struct opna *opna, int16_t *buf, unsigned samples) { opna_drum_mix(&opna->drum, buf, samples); opna_adpcm_mix(&opna->adpcm, buf, samples); } + +unsigned opna_get_mask(const struct opna *opna) { + return opna->mask; +} + +void opna_set_mask(struct opna *opna, unsigned mask) { + opna->mask = mask & 0xffffu; + opna->fm.mask = mask & ((1<<(6+1))-1); + opna->ssg.mask = (mask >> 6) & ((1<<(3+1))-1); + opna->adpcm.masked = mask & LIBOPNA_CHAN_ADPCM; + opna->drum.mask = (mask >> 9) & ((1<<(6+1))-1); +} diff --git a/libopna/opna.h b/libopna/opna.h index a056156..b5e9d87 100644 --- a/libopna/opna.h +++ b/libopna/opna.h @@ -10,18 +10,40 @@ extern "C" { #endif +enum { + LIBOPNA_CHAN_FM_1 = 0x0001, + LIBOPNA_CHAN_FM_2 = 0x0002, + LIBOPNA_CHAN_FM_3 = 0x0004, + LIBOPNA_CHAN_FM_4 = 0x0008, + LIBOPNA_CHAN_FM_5 = 0x0010, + LIBOPNA_CHAN_FM_6 = 0x0020, + LIBOPNA_CHAN_SSG_1 = 0x0040, + LIBOPNA_CHAN_SSG_2 = 0x0080, + LIBOPNA_CHAN_SSG_3 = 0x0100, + LIBOPNA_CHAN_DRUM_BD = 0x0200, + LIBOPNA_CHAN_DRUM_SD = 0x0400, + LIBOPNA_CHAN_DRUM_TOP = 0x0800, + LIBOPNA_CHAN_DRUM_HH = 0x1000, + LIBOPNA_CHAN_DRUM_TOM = 0x2000, + LIBOPNA_CHAN_DRUM_RIM = 0x4000, + LIBOPNA_CHAN_DRUM_ALL = 0x7e00, + LIBOPNA_CHAN_ADPCM = 0x8000, +}; + struct opna { struct opna_fm fm; struct opna_ssg ssg; struct opna_drum drum; struct opna_adpcm adpcm; struct opna_ssg_resampler resampler; - + unsigned mask; }; void opna_reset(struct opna *opna); void opna_writereg(struct opna *opna, unsigned reg, unsigned val); void opna_mix(struct opna *opna, int16_t *buf, unsigned samples); +unsigned opna_get_mask(const struct opna *opna); +void opna_set_mask(struct opna *opna, unsigned mask); #ifdef __cplusplus } diff --git a/libopna/opnaadpcm.c b/libopna/opnaadpcm.c index 1157b56..68dbae5 100644 --- a/libopna/opnaadpcm.c +++ b/libopna/opnaadpcm.c @@ -185,16 +185,18 @@ void opna_adpcm_mix(struct opna_adpcm *adpcm, int16_t *buf, unsigned samples) { if (!(adpcm->control1 & C1_START)) return; for (unsigned i = 0; i < samples; i++) { adpcm_calc(adpcm); - int32_t lo = buf[i*2+0]; - int32_t ro = buf[i*2+1]; - if (adpcm->control2 & C2_L) lo += (adpcm->out>>1); - if (adpcm->control2 & C2_R) ro += (adpcm->out>>1); - if (lo < INT16_MIN) lo = INT16_MIN; - if (lo > INT16_MAX) lo = INT16_MAX; - if (ro < INT16_MIN) ro = INT16_MIN; - if (ro > INT16_MAX) ro = INT16_MAX; - buf[i*2+0] = lo; - buf[i*2+1] = ro; + if (!adpcm->masked) { + int32_t lo = buf[i*2+0]; + int32_t ro = buf[i*2+1]; + if (adpcm->control2 & C2_L) lo += (adpcm->out>>1); + if (adpcm->control2 & C2_R) ro += (adpcm->out>>1); + if (lo < INT16_MIN) lo = INT16_MIN; + if (lo > INT16_MAX) lo = INT16_MAX; + if (ro < INT16_MIN) ro = INT16_MIN; + if (ro > INT16_MAX) ro = INT16_MAX; + buf[i*2+0] = lo; + buf[i*2+1] = ro; + } if (!(adpcm->control1 & C1_START)) return; } } diff --git a/libopna/opnaadpcm.h b/libopna/opnaadpcm.h index 27a1349..42033ad 100644 --- a/libopna/opnaadpcm.h +++ b/libopna/opnaadpcm.h @@ -23,6 +23,7 @@ struct opna_adpcm { int16_t prev_acc; uint16_t adpcmd; int16_t out; + bool masked; }; void opna_adpcm_reset(struct opna_adpcm *adpcm); diff --git a/libopna/opnadrum.c b/libopna/opnadrum.c index 2527c1a..1a298af 100644 --- a/libopna/opnadrum.c +++ b/libopna/opnadrum.c @@ -25,6 +25,7 @@ void opna_drum_reset(struct opna_drum *drum) { drum->drums[d].right = false; } drum->total_level = 0; + drum->mask = 0; } void opna_drum_set_rom(struct opna_drum *drum, void *romptr) { @@ -90,8 +91,10 @@ void opna_drum_mix(struct opna_drum *drum, int16_t *buf, int samples) { unsigned level = (drum->drums[d].level^0x1f) + (drum->total_level^0x3f); co *= 15 - (level&7); co >>= 1+(level>>3); - if (drum->drums[d].left) lo += co; - if (drum->drums[d].right) ro += co; + if (!(drum->mask & (1u << d))) { + if (drum->drums[d].left) lo += co; + if (drum->drums[d].right) ro += co; + } drum->drums[d].index++; if (drum->drums[d].index == drum->drums[d].len) { drum->drums[d].index = 0; diff --git a/libopna/opnadrum.h b/libopna/opnadrum.h index 7c13098..79f95a2 100644 --- a/libopna/opnadrum.h +++ b/libopna/opnadrum.h @@ -40,6 +40,7 @@ struct opna_drum { int16_t rom_hh[OPNA_ROM_HH_SIZE]; int16_t rom_tom[OPNA_ROM_TOM_SIZE]; int16_t rom_rim[OPNA_ROM_RIM_SIZE]; + unsigned mask; }; void opna_drum_reset(struct opna_drum *drum); diff --git a/libopna/opnafm.c b/libopna/opnafm.c index c7512a8..437fcdc 100644 --- a/libopna/opnafm.c +++ b/libopna/opnafm.c @@ -58,6 +58,7 @@ void opna_fm_reset(struct opna_fm *fm) { fm->ch3.fnum[i] = 0; fm->ch3.blk[i] = 0; } + fm->mask = 0; } #define LIBOPNA_ENABLE_HIRES // maximum output: 2042<<2 = 8168 @@ -497,6 +498,7 @@ void opna_fm_mix(struct opna_fm *fm, int16_t *buf, unsigned samples) { opna_fm_chan_phase(&fm->channel[c]); } o >>= 1; + if (fm->mask & (1<<c)) continue; if (fm->lselect[c]) lo += o; if (fm->rselect[c]) ro += o; } diff --git a/libopna/opnafm.h b/libopna/opnafm.h index acd673f..cf4fff5 100644 --- a/libopna/opnafm.h +++ b/libopna/opnafm.h @@ -78,6 +78,10 @@ struct opna_fm { // pan bool lselect[6]; bool rselect[6]; + + // mask + // when (1<<channel), the channel is masked + unsigned mask; }; void opna_fm_reset(struct opna_fm *fm); diff --git a/libopna/opnassg.c b/libopna/opnassg.c index cc797b0..1345502 100644 --- a/libopna/opnassg.c +++ b/libopna/opnassg.c @@ -73,6 +73,7 @@ void opna_ssg_reset(struct opna_ssg *ssg) { ssg->env_alt = false; ssg->env_hld = false; ssg->env_holding = false; + ssg->mask = 0; } void opna_ssg_resampler_reset(struct opna_ssg_resampler *resampler) { @@ -171,6 +172,7 @@ void opna_ssg_generate_raw(struct opna_ssg *ssg, int16_t *buf, int samples) { ssg->ch[ch].tone_counter = 0; ssg->ch[ch].out = !ssg->ch[ch].out; } + if (ssg->mask & (1<<ch)) continue; #if 0 if (opna_ssg_tone_out(ssg, ch)) { int level = opna_ssg_chan_env(ssg, ch) diff --git a/libopna/opnassg.h b/libopna/opnassg.h index 5928c49..adcd231 100644 --- a/libopna/opnassg.h +++ b/libopna/opnassg.h @@ -24,6 +24,7 @@ struct opna_ssg { bool env_alt; bool env_hld; bool env_holding; + unsigned mask; }; struct opna_ssg_resampler { |