diff options
Diffstat (limited to 'fmdriver/fmdriver_pmd.h')
-rw-r--r-- | fmdriver/fmdriver_pmd.h | 462 |
1 files changed, 462 insertions, 0 deletions
diff --git a/fmdriver/fmdriver_pmd.h b/fmdriver/fmdriver_pmd.h new file mode 100644 index 0000000..356099e --- /dev/null +++ b/fmdriver/fmdriver_pmd.h @@ -0,0 +1,462 @@ +#ifndef MYON_FMDRIVER_PMD_H_INCLUDED +#define MYON_FMDRIVER_PMD_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include "fmdriver.h" +enum { + PMD_FILENAMELEN = 8+1+3 +}; + +enum { + PMD_PART_FM_1, + PMD_PART_FM_2, + PMD_PART_FM_3, + PMD_PART_FM_4, + PMD_PART_FM_5, + PMD_PART_FM_6, + PMD_PART_SSG_1, + PMD_PART_SSG_2, + PMD_PART_SSG_3, + PMD_PART_ADPCM, + PMD_PART_RHYTHM, + PMD_PART_FM_3B, + PMD_PART_FM_3C, + PMD_PART_FM_3D, + PMD_PART_PPZ_1, + PMD_PART_PPZ_2, + PMD_PART_PPZ_3, + PMD_PART_PPZ_4, + PMD_PART_PPZ_5, + PMD_PART_PPZ_6, + PMD_PART_PPZ_7, + PMD_PART_PPZ_8, + PMD_PART_FM_EFF, + PMD_PART_NUM, +}; + +struct pmd_lfo { + uint8_t delay; + uint8_t speed; + uint8_t step; + uint8_t times; +}; + +struct pmd_part { + // 0000 + uint16_t ptr; + // 0002 + uint16_t loop_ptr; + // 0004 + uint8_t len_cnt; + // 0005 + uint8_t gate; + // 0006 + uint16_t actual_freq; + // 0008 + int16_t detune; + // 000a + int16_t lfo_diff; + // 000c + int16_t portamento_diff; + // 000e + int16_t portamento_add; + // 0010 + int16_t portamento_rem; + // 0012 + uint8_t vol; + // 0013 + uint8_t transpose; + // 0014 + struct pmd_lfo lfo; + // 0018 + struct pmd_lfo lfo_set; + // 001c + struct pmd_part_lfo_flags { + // bit 0 + bool freq; + // bit 1 + bool vol; + // bit 2 + bool sync; + // bit 3 + bool portamento; + } lfof, lfof_b; + // 001d + uint8_t volume_save; + // 001e + uint8_t md_depth; + // 001f + uint8_t md_speed; + // 0020 + uint8_t md_speed_set; + // 0021 + uint8_t ssg_env_state_old; + // 0022 + uint8_t ssg_env_state_new; + // 0023 + uint8_t ssg_env_param_set[4]; + // 0027 + uint8_t ssg_env_param_sl; + // 0028 + uint8_t ssg_env_param_al; + // 0029 + uint8_t ssg_env_param[4]; + // 002d + int8_t ssg_env_vol; + // 002e + struct pmd_part_flagext { + // bit 0 + bool detune; + // bit 1 + bool lfo; + // bit 2 + bool env; + } flagext, flagext_b; + // 002f + uint8_t fm_pan_ams_pms; + // 0030 + uint8_t ssg_mix; + // 0031 + uint8_t tonenum; + // 0032 + struct { + // bit 0 + bool looped; + // bit 1 + bool ended; + // bit 2 + bool env; + } loop; + // 0033 + // bit 7-4: slot 4,3,2,1 + uint8_t fm_slotout; + // 0034 + // 1,3,2,4 + uint8_t fm_tone_tl[4]; + // 0038 + // 4,3,2,1,0,0,0,0 + // when 1, enabled + uint8_t fm_slotmask; + // 0039 + // 1,3,2,4,1,3,2,4 + uint8_t fm_tone_slotmask; + // 003a + uint8_t lfo_waveform; + // 003b + struct { + // bit 0 + bool ext; + // bit 1 + bool effect; + // bit 2 + bool disabled; + // bit 5 + // true when all slots masked (part->fm_slotmask == 0) + bool slot; + // bit 6 + bool mml; + // bit 7 + bool ff; + } mask; + // 003c + struct { + // bit 0, 2-7 + bool off; + // bit 1 + bool off_mask; + } keystatus; + // 003d + // default: same as part->fm_slotout + // bit 7-4: mask slot 4,3,2,1 + // bit 3-0: if 1, overridden by user + uint8_t vol_lfo_slotmask; + // 003e + // q + uint8_t gate_abs; + // 003f + // Q + uint8_t gate_rel; + // 0040 + uint8_t hlfo_delay_set; + // 0041 + uint8_t hlfo_delay; + // 0042 + int16_t lfo_diff_b; + // 0044 + struct pmd_lfo lfo_b; + // 0048 + struct pmd_lfo lfo_set_b; + // 004c + uint8_t md_depth_b; + // 004d + uint8_t md_speed_b; + // 004e + uint8_t md_speed_set_b; + // 004f + uint8_t lfo_waveform_b; + // 0050 + uint8_t vol_lfo_slotmask_b; + // 0051 + uint8_t md_cnt; + // 0052 + uint8_t md_cnt_set; + // 0053 + uint8_t md_cnt_b; + // 0054 + uint8_t md_cnt_set_b; + // 0055 + uint8_t actual_note; + // 0056 + uint8_t slot_delay; + // 0057 + uint8_t slot_delay_cnt; + // 0058 + uint8_t slot_delay_mask; + // 0059 + uint8_t fb_alg; + // 005a + // increment when new note/rest processed + uint8_t note_proc; + // 005b + uint8_t gate_min; + // 005e + uint8_t curr_note; + // 005f + uint8_t transpose_master; + // 0060 + uint8_t gate_rand_range; + + // original + // used from pmd_part_proc_ssg, pmd_cmdc0, pmd_cmdcf_slotmask + bool proc_masked; + // for display + uint8_t len; + uint16_t output_freq; +}; + +struct pmd_ssgeff_data { + // ticks to wait, or 0xff to end + uint8_t wait; + uint16_t tone_freq; + uint8_t noise_freq; + bool tone_mix; + bool noise_mix; + uint8_t env_level; + uint16_t env_freq; + uint8_t env_waveform; + int8_t tonefreq_add; + int8_t noisefreq_add; + uint8_t noisefreq_wait; +}; + +#include "pmd_ssgeff.h" + +struct driver_pmd { + // pmd->data = data+1; + // pmd->datalen = datalen-1; + // data[-1] is valid (OPM flag) + uint8_t *data; + uint16_t datalen; + // 0ee1 + const struct pmd_ssgeff_data *ssgeff_ptr; + // 0ee3 + uint16_t ssgeff_tonefreq; + // 0ee5 + int16_t ssgeff_tonefreq_add; + // 0ee7 + uint8_t ssgeff_wait; + // 0ee8 + uint8_t ssgeff_noisefreq; + // 0ee9 + int8_t ssgeff_noisefreq_add; + uint8_t ssgeff_noisefreq_cnt_set; + // 0eea + uint8_t ssgeff_noisefreq_cnt; + // 0eeb + uint8_t ssgeff_priority; + // 0eec + uint8_t ssgeff_num; + // 0eed + bool ssgeff_internal; + // 0eee + // 2fc2 + uint16_t rand; + // 42ae + uint8_t proc_ch; + // 42af + // set with 0xfb + // when next command is 0xfb, disable gate (q/Q) + // used to implement tie + bool no_keyoff; + // 42b0 + // set when volume saved for soft echo (W) + bool volume_saved; + // 42b2 + bool opna_a1; + // 42b3 + // same format as opna 0x28 + // 0b4321____ + uint8_t fm_slotkey[6]; + // 42b9 + // compare with part->loop + struct { + // bit 0 + bool looped; + // bit 1 + bool ended; + // bit 2 + bool env; + } loop; + // 42ba + bool ppsdrv_enabled; + // 42c1 + // 42c3 + // timera_cnt sampled at timerb + uint8_t timera_cnt_b; + // 42c5 + // needed when fm3ex_det valid + bool fm3ex_force; + // 42c6 + // 1: ch3 + // 2: ch3a + // 4: ch3b + // 8: ch3c + // when 0, not needed to extend fm3 + uint8_t fm3ex_needed; + // 42d2 + uint8_t fm3ex_fb_alg; + // 42d3 + bool tonemask_fb_alg; + // 42d5 + struct pmd_part_lfo_flags lfoprocf, lfoprocf_b; + // 42d6 + // 430e + uint16_t tone_ptr; + // 4310 + uint16_t r_offset; + // 4312 + uint16_t r_ptr; + // 4314 + uint8_t opnarhythm_mask; + // 4317 + uint8_t fm_voldown; + // 4318 + uint8_t ssg_voldown; + // 4319 + uint8_t adpcm_voldown; + // 431a + uint8_t opnarhythm_voldown; + // 431b + bool tone_included; + // 431c + bool opm_flag; + // 431d + uint8_t status1; + // 431e + uint8_t status2; + // 431f + uint8_t timerb; + // 4320 + uint8_t fadeout_speed; + // 4321 + uint8_t fadeout_vol; + // 4322 + uint8_t timerb_bak; + // 4323 + uint8_t meas_len; + // 4324 + uint8_t tick_cnt; + // 4325 + uint8_t timera_cnt; + // 4326 + bool ssgeff_disabled; + // 4327 + uint8_t ssg_noise_freq; + // 4328 + uint8_t ssg_noise_freq_wrote; + // 432a + bool fmeff_playing; + // 432c + bool adpcmeff_playing; + // 432d + uint16_t adpcm_start; + // 432f + uint16_t adpcm_stop; + // 433a + uint8_t opnarhythm; + // 433b + uint8_t opnarhythm_ilpan[6]; + // 4341 + uint8_t opnarhythm_tl; + // 4342 + uint16_t ssgrhythm; + // 4348 + bool playing; + // 4349 + bool paused; + // 434a + //bool fadeout_mstop; + // 434b + bool ssgrhythm_opna; + // 4350 + bool adpcm_disabled; + // 4354 + int16_t fm3ex_det[4]; + // 4362 + uint8_t timerb_wrote; + // 4363 + bool faded_out; + // 4366 + bool pcm86_vol_spb; + // 4367 + uint16_t meas_cnt; + // 436a + uint8_t opna_last22; + // 436b + uint8_t tempo; + // 436c + uint8_t tempo_bak; + // 4370 + uint8_t fm_voldown_orig; + // 4371 + uint8_t ssg_voldown_orig; + // 4372 + uint8_t adpcm_voldown_orig; + // 4373 + uint8_t opnarhythm_voldown_orig; + // 4374 + bool pcm86_vol_spb_orig; + // 4386 + uint8_t opnarhythm_shot_inc[6]; + // 438c + uint8_t opnarhythm_dump_inc[6]; + // 4392 + // 0b0e111111 + // output to 0x27 + uint8_t fm3ex_mode; + // 4394 + uint8_t ppz8_voldown; + // 4395 + uint8_t ppz8_voldown_orig; + // 43ce + struct pmd_part parts[PMD_PART_NUM]; + + bool ssgeff_tone_mix; + bool ssgeff_noise_mix; + bool ssgeff_on; + char ppzfile[PMD_FILENAMELEN+1]; + char ppsfile[PMD_FILENAMELEN+1]; + char ppcfile[PMD_FILENAMELEN+1]; +}; + +bool pmd_load(struct driver_pmd *pmd, uint8_t *data, uint16_t datalen); +void pmd_init(struct fmdriver_work *work, struct driver_pmd *pmd); + +#ifdef __cplusplus +} +#endif + +#endif // MYON_FMDRIVER_PMD_H_INCLUDED |