Skip to content

Commit

Permalink
Support PSG pitch bend
Browse files Browse the repository at this point in the history
  • Loading branch information
rhargreaves committed Dec 16, 2018
1 parent 8b8e765 commit c6def8d
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/midi.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct VTable {
};

static const VTable PSG_VTable = { midi_psg_noteOn, midi_psg_noteOff,
midi_psg_channelVolume, midi_nop_pitchBend };
midi_psg_channelVolume, midi_psg_pitchBend };

static const VTable FM_VTable = { midi_fm_noteOn, midi_fm_noteOff,
midi_fm_channelVolume, midi_fm_pitchBend };
Expand Down
18 changes: 17 additions & 1 deletion src/midi_psg.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,18 @@ static const u8 ATTENUATIONS[] = { 15, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12,
2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

static u8 pitches[MAX_PSG_CHANS];

static u8 psgChannel(u8 midiChannel)
{
return midiChannel - MIN_PSG_CHAN;
}

void midi_psg_noteOn(u8 chan, u8 pitch, u8 velocity)
{
psg_noteOn(psgChannel(chan), FREQUENCIES[pitch]);
u8 psgChan = psgChannel(chan);
pitches[psgChan] = pitch;
psg_noteOn(psgChan, FREQUENCIES[pitch]);
}

void midi_psg_noteOff(u8 chan)
Expand All @@ -43,3 +47,15 @@ void midi_psg_channelVolume(u8 chan, u8 volume)
{
psg_attenuation(psgChannel(chan), ATTENUATIONS[volume]);
}

void midi_psg_pitchBend(u8 chan, u16 bend)
{
u8 psgChan = psgChannel(chan);
u8 origPitch = pitches[psgChan];
u16 freq = FREQUENCIES[origPitch];

s16 bendRelative = bend - 0x2000;
freq = freq + (bendRelative / 100);

psg_noteOn(psgChan, freq);
}
1 change: 1 addition & 0 deletions src/midi_psg.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
void midi_psg_noteOn(u8 chan, u8 pitch, u8 velocity);
void midi_psg_noteOff(u8 chan);
void midi_psg_channelVolume(u8 chan, u8 volume);
void midi_psg_pitchBend(u8 chan, u16 bend);
1 change: 1 addition & 0 deletions tests/unit/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ int main(void)
cmocka_unit_test(test_midi_channel_volume_sets_psg_attenuation_2),
cmocka_unit_test(test_midi_ignores_channels_above_10),
cmocka_unit_test(test_midi_sets_synth_pitch_bend),
cmocka_unit_test(test_midi_sets_psg_pitch_bend),

cmocka_unit_test(test_synth_init_sets_initial_registers),
cmocka_unit_test(test_synth_sets_note_on_fm_reg_chan_0_to_2),
Expand Down
15 changes: 15 additions & 0 deletions tests/unit/test_midi.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,18 @@ static void test_midi_sets_synth_pitch_bend(void** state)
__real_midi_pitchBend(chan, 1000);
}
}

static void test_midi_sets_psg_pitch_bend(void** state)
{
for (int chan = MIN_PSG_CHAN; chan <= MAX_PSG_CHAN; chan++) {
expect_value(__wrap_psg_noteOn, channel, chan - MIN_PSG_CHAN);
expect_value(__wrap_psg_noteOn, freq, 262);

__real_midi_noteOn(chan, 60, 127);

expect_value(__wrap_psg_noteOn, channel, chan - MIN_PSG_CHAN);
expect_value(__wrap_psg_noteOn, freq, 191);

__real_midi_pitchBend(chan, 1000);
}
}

0 comments on commit c6def8d

Please sign in to comment.