aboutsummaryrefslogtreecommitdiff
path: root/fmdriver
diff options
context:
space:
mode:
Diffstat (limited to 'fmdriver')
-rw-r--r--fmdriver/fmdriver_fmp.c59
-rw-r--r--fmdriver/fmdriver_fmp.h1
-rw-r--r--fmdriver/ppz8.c11
-rw-r--r--fmdriver/ppz8.h3
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 {