From 5a8af1f670709d6cd28ad5edda223d9ecbc03bc3 Mon Sep 17 00:00:00 2001 From: Takamichi Horikawa Date: Sun, 13 Aug 2017 23:08:54 +0900 Subject: added levelmeter --- fmdriver/fmdriver_fmp.c | 59 +++++++++++++++++++++++++++++++++++++------------ fmdriver/fmdriver_fmp.h | 1 + fmdriver/ppz8.c | 11 +++++++-- fmdriver/ppz8.h | 3 +++ 4 files changed, 58 insertions(+), 16 deletions(-) (limited to 'fmdriver') 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 #include +#include +#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 { -- cgit v1.2.3