diff options
author | Takamichi Horikawa <takamichiho@gmail.com> | 2017-03-01 00:22:33 +0900 |
---|---|---|
committer | Takamichi Horikawa <takamichiho@gmail.com> | 2017-03-01 00:22:33 +0900 |
commit | 23dc19065c182e61bce9c997f31e23b001a85f2c (patch) | |
tree | ec4dc1d49362b1fc95c2608bb40651cc6f8f2917 /tonedata | |
parent | 2432f71b1e1b1e474a2ff5b833107246a3e3762a (diff) |
gtk: add tone viewer
Diffstat (limited to 'tonedata')
-rw-r--r-- | tonedata/tonedata.c | 107 | ||||
-rw-r--r-- | tonedata/tonedata.h | 48 |
2 files changed, 155 insertions, 0 deletions
diff --git a/tonedata/tonedata.c b/tonedata/tonedata.c new file mode 100644 index 0000000..0d5daa6 --- /dev/null +++ b/tonedata/tonedata.c @@ -0,0 +1,107 @@ +#include "tonedata.h" +#include "libopna/opna.h" +#include <stdio.h> +void tonedata_from_opna( + struct fmplayer_tonedata *tonedata, + const struct opna *opna +) { + const struct opna_fm *fm = &opna->fm; + for (int c = 0; c < 6; c++) { + const struct opna_fm_channel *op_ch = &fm->channel[c]; + struct fmplayer_tonedata_channel *td_ch = &tonedata->ch[c]; + for (int s = 0; s < 4; s++) { + const struct opna_fm_slot *op_sl = &op_ch->slot[s]; + struct fmplayer_tonedata_slot *td_sl = &td_ch->slot[s]; + td_sl->ar = op_sl->ar; + td_sl->dr = op_sl->dr; + td_sl->sr = op_sl->sr; + td_sl->rr = op_sl->rr; + td_sl->sl = op_sl->sl; + td_sl->tl = op_sl->tl; + td_sl->ks = op_sl->ks; + td_sl->ml = op_sl->mul; + td_sl->dt = op_sl->det; + // TODO: hardware LFO not implemented + td_sl->ams = 0; + } + td_ch->alg = op_ch->alg; + td_ch->fb = op_ch->fb; + } +} + +void tonedata_ch_normalize_tl( + struct fmplayer_tonedata_channel *ch +) { + static const uint8_t alg_out[8] = { + 0x8, 0x8, 0x8, 0x8, 0xa, 0xe, 0xe, 0xf + }; + uint8_t outbit = alg_out[ch->alg & 7]; + uint8_t max_tl = 127; + for (int s = 0; s < 4; s++) { + if (!(outbit & (1<<s))) continue; + if (max_tl > ch->slot[s].tl) max_tl = ch->slot[s].tl; + } + for (int s = 0; s < 4; s++) { + if (!(outbit & (1<<s))) continue; + ch->slot[s].tl -= max_tl; + } +} + +void tonedata_ch_string( + enum fmplayer_tonedata_format format, + char *buf, + const struct fmplayer_tonedata_channel *ch, + uint8_t tonenum +) { + switch (format) { + case FMPLAYER_TONEDATA_FMT_PMD: + snprintf(buf, FMPLAYER_TONEDATA_STR_SIZE, + "@%3d %1d %1d\n" + " %2d %2d %2d %2d %2d %3d %1d %2d %1d %1d\n" + " %2d %2d %2d %2d %2d %3d %1d %2d %1d %1d\n" + " %2d %2d %2d %2d %2d %3d %1d %2d %1d %1d\n" + " %2d %2d %2d %2d %2d %3d %1d %2d %1d %1d\n", + tonenum, ch->alg, ch->fb, + ch->slot[0].ar, ch->slot[0].dr, ch->slot[0].sr, ch->slot[0].rr, + ch->slot[0].sl, ch->slot[0].tl, ch->slot[0].ks, ch->slot[0].ml, + ch->slot[0].dt, ch->slot[0].ams, + ch->slot[1].ar, ch->slot[1].dr, ch->slot[1].sr, ch->slot[1].rr, + ch->slot[1].sl, ch->slot[1].tl, ch->slot[1].ks, ch->slot[1].ml, + ch->slot[1].dt, ch->slot[1].ams, + ch->slot[2].ar, ch->slot[2].dr, ch->slot[2].sr, ch->slot[2].rr, + ch->slot[2].sl, ch->slot[2].tl, ch->slot[2].ks, ch->slot[2].ml, + ch->slot[2].dt, ch->slot[2].ams, + ch->slot[3].ar, ch->slot[3].dr, ch->slot[3].sr, ch->slot[3].rr, + ch->slot[3].sl, ch->slot[3].tl, ch->slot[3].ks, ch->slot[3].ml, + ch->slot[3].dt, ch->slot[3].ams + ); + break; + case FMPLAYER_TONEDATA_FMT_FMP: + snprintf(buf, FMPLAYER_TONEDATA_STR_SIZE, + "'@%3d\n" + "'@ %2d, %2d, %2d, %2d, %2d, %3d, %1d, %2d, %1d\n" + "'@ %2d, %2d, %2d, %2d, %2d, %3d, %1d, %2d, %1d\n" + "'@ %2d, %2d, %2d, %2d, %2d, %3d, %1d, %2d, %1d\n" + "'@ %2d, %2d, %2d, %2d, %2d, %3d, %1d, %2d, %1d\n" + "'@ %1d, %1d", + tonenum, + ch->slot[0].ar, ch->slot[0].dr, ch->slot[0].sr, ch->slot[0].rr, + ch->slot[0].sl, ch->slot[0].tl, ch->slot[0].ks, ch->slot[0].ml, + ch->slot[0].dt, + ch->slot[1].ar, ch->slot[1].dr, ch->slot[1].sr, ch->slot[1].rr, + ch->slot[1].sl, ch->slot[1].tl, ch->slot[1].ks, ch->slot[1].ml, + ch->slot[1].dt, + ch->slot[2].ar, ch->slot[2].dr, ch->slot[2].sr, ch->slot[2].rr, + ch->slot[2].sl, ch->slot[2].tl, ch->slot[2].ks, ch->slot[2].ml, + ch->slot[2].dt, + ch->slot[3].ar, ch->slot[3].dr, ch->slot[3].sr, ch->slot[3].rr, + ch->slot[3].sl, ch->slot[3].tl, ch->slot[3].ks, ch->slot[3].ml, + ch->slot[3].dt, + ch->alg, ch->fb + ); + break; + default: + buf[0] = 0; + break; + } +} diff --git a/tonedata/tonedata.h b/tonedata/tonedata.h new file mode 100644 index 0000000..c8dd03c --- /dev/null +++ b/tonedata/tonedata.h @@ -0,0 +1,48 @@ +#ifndef MYON_FMPLAYER_TONEDATA_H_INCLUDED +#define MYON_FMPLAYER_TONEDATA_H_INCLUDED + +#include <stdint.h> + +struct fmplayer_tonedata { + struct fmplayer_tonedata_channel { + struct fmplayer_tonedata_slot { + uint8_t ar; + uint8_t dr; + uint8_t sr; + uint8_t rr; + uint8_t sl; + uint8_t tl; + uint8_t ks; + uint8_t ml; + uint8_t dt; + uint8_t ams; + } slot[4]; + uint8_t fb; + uint8_t alg; + } ch[6]; +}; + +struct opna; +void tonedata_from_opna( + struct fmplayer_tonedata *tonedata, + const struct opna *opna +); + +enum fmplayer_tonedata_format { + FMPLAYER_TONEDATA_FMT_PMD, + FMPLAYER_TONEDATA_FMT_FMP +}; + +enum { + FMPLAYER_TONEDATA_STR_SIZE = 0x100 +}; +void tonedata_ch_normalize_tl(struct fmplayer_tonedata_channel *ch); +void tonedata_ch_string( + enum fmplayer_tonedata_format format, + char *buf, + const struct fmplayer_tonedata_channel *ch, + uint8_t tonenum +); + +#endif // MYON_FMPLAYER_TONEDATA_H_INCLUDED + |