diff options
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 + | 
