diff options
Diffstat (limited to 'fmdriver')
| -rw-r--r-- | fmdriver/fmdriver_fmp.c | 59 | ||||
| -rw-r--r-- | fmdriver/fmdriver_fmp.h | 1 | ||||
| -rw-r--r-- | fmdriver/ppz8.c | 11 | ||||
| -rw-r--r-- | fmdriver/ppz8.h | 3 | 
4 files changed, 58 insertions, 16 deletions
| diff --git a/fmdriver/fmdriver_fmp.c b/fmdriver/fmdriver_fmp.c index 5e01089..74c119c 100644 --- a/fmdriver/fmdriver_fmp.c +++ b/fmdriver/fmdriver_fmp.c @@ -2698,6 +2698,7 @@ static void fmp_part_cmd_rhythm(struct fmdriver_work *work,              uint8_t voice = fmp->pdzf.rhythm[p&1].voice[((rhythm->volumes[p] & 0x10) >> 4)];
              uint8_t pan = fmp->pdzf.rhythm[p&1].pan + 5;
              uint32_t freq = fmp_ppz8_note_freq(fmp->pdzf.rhythm[p&1].note);
 +            fmp->pdzf.rhythm_current_note = fmp->pdzf.rhythm[p&1].note;
              uint8_t channel = 6;
              work->ppz8_functbl->channel_play(
                work->ppz8,
 @@ -2777,15 +2778,40 @@ static void fmp_work_status_init(struct fmdriver_work *work,  static void fmp_work_status_update(struct fmdriver_work *work,
                                     const struct driver_fmp *fmp) {
    work->ssg_noise_freq = fmp->ssg_noise_freq;
 -  for (int t = 0; t < FMDRIVER_TRACK_NUM; t++) {
 +  for (int t = 0; t < FMDRIVER_TRACK_PPZ8_1; t++) {
      struct fmdriver_track_status *track = &work->track_status[t];
      const struct fmp_part *part = &fmp->parts[fmp_track_map[t]];
      track->playing = !part->status.off;
      track->info = FMDRIVER_TRACK_INFO_NORMAL;
 +    track->ticks = part->status.off ? 0 : part->tonelen-1;
 +    track->ticks_left = part->tonelen_cnt;
 +    track->key = part->status.rest ? 0xff : fmp_note2key(part->prev_note);
 +    track->tonenum = part->tone;
 +    track->detune = part->detune - ((part->detune & 0x8000) ? 0x10000 : 0);
 +    track->status[0] = part->lfo_f.p ? 'P' : '-';
 +    track->status[1] = part->lfo_f.q ? 'Q' : '-';
 +    track->status[2] = part->lfo_f.r ? 'R' : '-';
 +    track->status[3] = part->lfo_f.a ? 'A' : '-';
 +    track->status[4] = '-';
 +    track->status[5] = part->lfo_f.e ? 'e' : '-';
 +    track->status[6] = (part->type.fm && part->u.fm.hlfo_apms) ? 'H' : '-';
 +    track->status[7] = part->status.pitchbend ? 'P' : '-';
      if (part->type.adpcm) {
        track->actual_key = 0xff;
        track->volume = part->actual_vol;
      } else if (part->type.ssg) {
 +      struct fmdriver_track_status *ppztrack =
 +          &work->track_status[FMDRIVER_TRACK_PPZ8_1-1+track->ppz8_ch];
 +      ppztrack->actual_key = 0xff;
 +      if (part->pdzf.mode || part->u.ssg.env_f.ppz) {
 +        ppztrack->playing = !part->status.off;
 +        ppztrack->key = track->key;
 +        ppztrack->tonenum = track->tonenum;
 +        ppztrack->info = FMDRIVER_TRACK_INFO_NORMAL;
 +      } else {
 +        ppztrack->playing = false;
 +        ppztrack->key = 0xff;
 +      }
        if (part->pdzf.mode) {
          track->info = FMDRIVER_TRACK_INFO_PDZF;
          track->actual_key = 0xff;
 @@ -2801,8 +2827,15 @@ static void fmp_work_status_update(struct fmdriver_work *work,        track->volume = part->current_vol - 1;
      } else {
        if (part->pdzf.mode) {
 +        struct fmdriver_track_status *ppztrack =
 +            &work->track_status[FMDRIVER_TRACK_PPZ8_1-1+track->ppz8_ch];
          track->info = FMDRIVER_TRACK_INFO_PDZF;
          track->actual_key = 0xff;
 +        ppztrack->actual_key = 0xff;
 +        ppztrack->playing = !part->status.off;
 +        ppztrack->key = track->key;
 +        ppztrack->tonenum = work->ppz8 ? work->ppz8->channel[track->ppz8_ch-1].voice : 0;
 +        ppztrack->info = FMDRIVER_TRACK_INFO_NORMAL;
        } else {
          if (part->u.fm.slot_mask & 0xf0) {
            track->info = FMDRIVER_TRACK_INFO_FM3EX;
 @@ -2814,20 +2847,13 @@ static void fmp_work_status_update(struct fmdriver_work *work,        }
        track->volume = 0x7f - part->actual_vol;
      }
 -    track->ticks = part->status.off ? 0 : part->tonelen-1;
 -    track->ticks_left = part->tonelen_cnt;
 -    track->key = part->status.rest ? 0xff : fmp_note2key(part->prev_note);
 -    track->tonenum = part->tone;
 -    track->detune = part->detune - ((part->detune & 0x8000) ? 0x10000 : 0);
 -    track->status[0] = part->lfo_f.p ? 'P' : '-';
 -    track->status[1] = part->lfo_f.q ? 'Q' : '-';
 -    track->status[2] = part->lfo_f.r ? 'R' : '-';
 -    track->status[3] = part->lfo_f.a ? 'A' : '-';
 -    track->status[4] = '-';
 -    track->status[5] = part->lfo_f.e ? 'e' : '-';
 -    track->status[6] = (part->type.fm && part->u.fm.hlfo_apms) ? 'H' : '-';
 -    track->status[7] = part->status.pitchbend ? 'P' : '-';
    }
 +  work->track_status[FMDRIVER_TRACK_PPZ8_7].playing = fmp->pdzf.rhythm[0].enabled || fmp->pdzf.rhythm[1].enabled;
 +  work->track_status[FMDRIVER_TRACK_PPZ8_7].tonenum = work->ppz8 ? work->ppz8->channel[6].voice : 0;
 +  uint8_t key = 0xff;
 +  if (work->ppz8 && work->ppz8->channel[6].playing) key = fmp->pdzf.rhythm_current_note;
 +  work->track_status[FMDRIVER_TRACK_PPZ8_7].key = key;
 +  work->track_status[FMDRIVER_TRACK_PPZ8_7].actual_key = key;
  }
  static void fmp_part_pdzf_freq_update(
 @@ -3147,6 +3173,11 @@ static void fmp_struct_init(struct fmdriver_work *work,    fmp->parts[FMP_PART_FM_EX3].pdzf.ppz8_channel = 5;
    fmp->parts[FMP_PART_FM_EX3].pdzf.loopstart32 = -1;
    fmp->parts[FMP_PART_FM_EX3].pdzf.loopend32 = -1;
 +  
 +  // ppz8 unused parts
 +  for (int i = 0; i < 8; i++) {
 +    fmp->parts[FMP_PART_PPZ8_1+i].status.off = true;
 +  }
  }
  // 1774
 diff --git a/fmdriver/fmdriver_fmp.h b/fmdriver/fmdriver_fmp.h index 4fd107a..ead8074 100644 --- a/fmdriver/fmdriver_fmp.h +++ b/fmdriver/fmdriver_fmp.h @@ -534,6 +534,7 @@ struct driver_fmp {        uint8_t note;        bool enabled;      } rhythm[2]; +    uint8_t rhythm_current_note;    } pdzf;  }; diff --git a/fmdriver/ppz8.c b/fmdriver/ppz8.c index 4dea524..d1afd72 100644 --- a/fmdriver/ppz8.c +++ b/fmdriver/ppz8.c @@ -37,6 +37,7 @@ void ppz8_init(struct ppz8 *ppz8, uint16_t srate, uint16_t mix_volume) {      channel->vol = 8;      channel->pan = 5;      channel->voice = 0; +    leveldata_init(&channel->leveldata);    }    ppz8->srate = srate;    ppz8->totalvol = 12; @@ -128,6 +129,7 @@ static int32_t ppz8_channel_calc(struct ppz8 *ppz8, struct ppz8_channel *channel  }  void ppz8_mix(struct ppz8 *ppz8, int16_t *buf, unsigned samples) { +  unsigned level[8] = {0};    static const uint8_t pan_vol[10][2] = {      {0, 0},      {4, 0}, @@ -144,11 +146,13 @@ void ppz8_mix(struct ppz8 *ppz8, int16_t *buf, unsigned samples) {      int32_t lo = buf[i*2+0];      int32_t ro = buf[i*2+1];      for (int p = 0; p < 8; p++) { -      //if (p < 3) continue; -      //if (p >= 6) continue;        struct ppz8_channel *channel = &ppz8->channel[p];        if (!channel->playing) continue;        int32_t out = ppz8_channel_calc(ppz8, channel); +      { +        unsigned uout = out > 0 ? out : -out; +        if (uout > level[p]) level[p] = uout; +      }        if ((1u << p) & (ppz8->mask)) continue;        out *= ppz8->mix_volume;        out >>= 15; @@ -162,6 +166,9 @@ void ppz8_mix(struct ppz8 *ppz8, int16_t *buf, unsigned samples) {      buf[i*2+0] = lo;      buf[i*2+1] = ro;    } +  for (int p = 0; p < 8; p++) { +    leveldata_update(&ppz8->channel[p].leveldata, level[p]); +  }  }  static int16_t calc_acc(int16_t acc, uint16_t adpcmd, uint8_t data) { diff --git a/fmdriver/ppz8.h b/fmdriver/ppz8.h index f4ef4cb..35c67dc 100644 --- a/fmdriver/ppz8.h +++ b/fmdriver/ppz8.h @@ -3,6 +3,8 @@  #include <stdint.h>  #include <stdbool.h> +#include <stdatomic.h> +#include "leveldata/leveldata.h"  #ifdef __cplusplus  extern "C" { @@ -35,6 +37,7 @@ struct ppz8_channel {    uint8_t pan;    uint8_t voice;    bool playing; +  struct leveldata leveldata;  };  struct ppz8 { | 
