Skip to content

Commit

Permalink
mdx2midi: preliminary pitch bend support
Browse files Browse the repository at this point in the history
  • Loading branch information
vampirefrog committed Nov 21, 2024
1 parent 007bdd8 commit 1aed75e
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 12 deletions.
4 changes: 2 additions & 2 deletions fm_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ void fm_driver_set_noise_freq(struct fm_driver *driver, int channel, int freq) {
driver->set_noise_freq(driver, channel, freq);
}

void fm_driver_load_voice(struct fm_driver *driver, int channel, uint8_t *v, int opm_volume, int pan) {
void fm_driver_load_voice(struct fm_driver *driver, int channel, uint8_t *v, int voice_num, int opm_volume, int pan) {
if(driver->load_voice)
driver->load_voice(driver, channel, v, opm_volume, pan);
driver->load_voice(driver, channel, v, voice_num, opm_volume, pan);
}

void fm_driver_load_lfo(struct fm_driver *driver, int channel, uint8_t wave, uint8_t freq, uint8_t pmd, uint8_t amd) {
Expand Down
4 changes: 2 additions & 2 deletions fm_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct fm_driver {
void (*write_opm_reg)(struct fm_driver *driver, uint8_t reg, uint8_t data);
void (*set_pan)(struct fm_driver *driver, int channel, uint8_t pan, uint8_t *v);
void (*set_noise_freq)(struct fm_driver *driver, int channel, int freq);
void (*load_voice)(struct fm_driver *driver, int channel, uint8_t *v, int opm_volume, int pan);
void (*load_voice)(struct fm_driver *driver, int channel, uint8_t *v, int voice_num, int opm_volume, int pan);
void (*load_lfo)(struct fm_driver *driver, int channel, uint8_t wave, uint8_t freq, uint8_t pmd, uint8_t amd);
};
void fm_driver_init(struct fm_driver *driver);
Expand All @@ -29,7 +29,7 @@ void fm_driver_note_off(struct fm_driver *driver, int channel);
void fm_driver_write_opm_reg(struct fm_driver *driver, uint8_t reg, uint8_t val);
void fm_driver_set_pan(struct fm_driver *driver, int channel, uint8_t pan, uint8_t *v);
void fm_driver_set_noise_freq(struct fm_driver *driver, int channel, int freq);
void fm_driver_load_voice(struct fm_driver *driver, int channel, uint8_t *v, int opm_volume, int pan);
void fm_driver_load_voice(struct fm_driver *driver, int channel, uint8_t *v, int voice_num, int opm_volume, int pan);
void fm_driver_load_lfo(struct fm_driver *driver, int channel, uint8_t wave, uint8_t freq, uint8_t pmd, uint8_t amd);

#endif /* FM_DRIVER_H_ */
26 changes: 21 additions & 5 deletions fm_midi_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,14 @@ void fm_midi_driver_set_pitch(struct fm_driver *driver, int channel, int pitch)
if(mididrv->channels[channel].on && pitch != mididrv->channels[channel].pitch) {
pitch >>= 8;
pitch -= 5;
int detune = pitch & 0x3f;
int note = pitch >> 6;
mididrv->channels[channel].ticks = 0;
int root_pitch = mididrv->channels[channel].note << 6;
int detune = (pitch - root_pitch);

if(detune != mididrv->channels[channel].detune) {
midi_track_write_pitch_bend(&mididrv->midi_file->tracks[channel + 1], mididrv->channels[channel].ticks, channel, detune);
mididrv->channels[channel].detune = detune;
mididrv->channels[channel].ticks = 0;
}
}
mididrv->channels[channel].pitch = pitch;
}
Expand All @@ -33,6 +38,11 @@ void fm_midi_driver_note_on(struct fm_driver *driver, int channel, uint8_t op_ma
int pitch = (mididrv->channels[channel].pitch >> 8) - 5;
int detune = pitch & 0x3f;
int note = pitch >> 6;
mididrv->channels[channel].note = note;
if(detune != mididrv->channels[channel].detune) {
midi_track_write_pitch_bend(&mididrv->midi_file->tracks[channel + 1], mididrv->channels[channel].ticks, channel, detune);
mididrv->channels[channel].ticks = 0;
}
midi_track_write_note_on(&mididrv->midi_file->tracks[channel + 1], mididrv->channels[channel].ticks, channel, note, 127);
mididrv->channels[channel].ticks = 0;
}
Expand All @@ -44,6 +54,8 @@ void fm_midi_driver_note_off(struct fm_driver *driver, int channel) {
int pitch = (mididrv->channels[channel].pitch >> 8) - 5;
int detune = pitch & 0x3f;
int note = pitch >> 6;

mididrv->channels[channel].detune = detune;
midi_track_write_note_off(&mididrv->midi_file->tracks[channel + 1], mididrv->channels[channel].ticks, channel, note, 127);
mididrv->channels[channel].ticks = 0;
}
Expand All @@ -63,9 +75,10 @@ void fm_midi_driver_set_noise_freq(struct fm_driver *driver, int channel, int fr
(void)mididrv;
}

void fm_midi_driver_load_voice(struct fm_driver *driver, int channel, uint8_t *v, int volume, int pan) {
void fm_midi_driver_load_voice(struct fm_driver *driver, int channel, uint8_t *v, int voice_num, int volume, int pan) {
struct fm_midi_driver *mididrv = (struct fm_midi_driver *)driver;
(void)mididrv;
midi_track_write_program_change(&mididrv->midi_file->tracks[channel + 1], mididrv->channels[channel].ticks, channel, voice_num);
mididrv->channels[channel].ticks = 0;
}

void fm_midi_driver_load_lfo(struct fm_driver *driver, int channel, uint8_t wave, uint8_t freq, uint8_t pmd, uint8_t amd) {
Expand All @@ -91,6 +104,9 @@ void fm_midi_driver_init(struct fm_midi_driver *driver, struct midi_file *midi_f
for(int i = 0; i < 8; i++) {
driver->channels[i].on = 0;
driver->channels[i].pitch = 0;
driver->channels[i].note = 0;
driver->channels[i].detune = 0;
driver->channels[i].tl = 0;
driver->channels[i].ticks = 0;
}
}
Expand Down
2 changes: 1 addition & 1 deletion fm_midi_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "midilib/midi_file.h"

struct fm_midi_driver_channel {
int on, pitch, tl, ticks;
int on, pitch, note, detune, tl, ticks;
};

/* MIDI driver */
Expand Down
2 changes: 1 addition & 1 deletion fm_opm_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ static void fm_opm_driver_set_noise_freq(struct fm_driver *driver, int channel,
fm_opm_driver_write(fmdrv, 0x0F, freq & 0x1f);
}

static void fm_opm_driver_load_voice(struct fm_driver *driver, int channel, uint8_t *v, int opm_volume, int pan) {
static void fm_opm_driver_load_voice(struct fm_driver *driver, int channel, uint8_t *v, int voice_num, int opm_volume, int pan) {
struct fm_opm_driver *fmdrv = (struct fm_opm_driver *)driver;

for(int i = 0; i < 4; i++)
Expand Down
2 changes: 1 addition & 1 deletion mdx_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ static int mdx_driver_track_advance(struct mdx_driver *driver, int track_num) {
case 0xfd: // Set voice
if(track_num < 8) {
track->voice_num = track->data[track->pos + 1];
fm_driver_load_voice(driver->fm_driver, track_num, driver->mdx_file->voices[track->voice_num], track->opm_volume, track->pan);
fm_driver_load_voice(driver->fm_driver, track_num, driver->mdx_file->voices[track->voice_num], track->voice_num, track->opm_volume, track->pan);
}
track->pos += 2;
break;
Expand Down
1 change: 1 addition & 0 deletions midi_timer_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ int midi_timer_driver_init(struct midi_timer_driver *driver) {
timer_driver_init(&driver->timer_driver);
driver->ticks_per_quarter_note = 48;
driver->timer_driver.set_opm_tempo = midi_timer_driver_set_opm_tempo;
return 0;
}

void midi_timer_driver_deinit(struct midi_timer_driver *driver) {
Expand Down

0 comments on commit 1aed75e

Please sign in to comment.