Skip to content

Commit

Permalink
Introduce new YM2612 helper methods
Browse files Browse the repository at this point in the history
  • Loading branch information
rhargreaves committed Feb 19, 2025
1 parent db3399a commit e61c582
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 50 deletions.
30 changes: 30 additions & 0 deletions tests/mocks/mock_ym2612.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#include "cmocka_inc.h"
#include "mocks/mock_ym2612.h"
#include "ym2612_regs.h"

static bool disableChecks = false;

#define REG_PART(chan) (chan < 3 ? 0 : 1)
#define REG_OFFSET(chan) (chan % 3)
#define KEY_ON_OFF_CH_INDEX(chan) (chan < 3 ? chan : chan + 1)

void mock_ym2612_disable_checks(void)
{
Expand Down Expand Up @@ -115,3 +117,31 @@ void _expect_ym2612_write_channel_any_data(
{
_expect_ym2612_write_reg_any_data(REG_PART(chan), baseReg + REG_OFFSET(chan), file, line);
}

void _expect_ym2612_write_all_operators(
u8 chan, u8 baseReg, u8 data, const char* const file, const int line)
{
for (u8 op = 0; op < 4; op++) {
_expect_ym2612_write_operator(chan, op, baseReg, data, file, line);
}
}

void _expect_ym2612_write_all_operators_any_data(
u8 chan, u8 baseReg, const char* const file, const int line)
{
for (u8 op = 0; op < 4; op++) {
expect_ym2612_write_operator_any_data(chan, op, baseReg);
}
}

void _expect_ym2612_note_on(u8 chan, const char* const file, const int line)
{
u8 data = 0xF0 + KEY_ON_OFF_CH_INDEX(chan);
_expect_ym2612_write_reg(0, YM_KEY_ON_OFF, data, file, line);
}

void _expect_ym2612_note_off(u8 chan, const char* const file, const int line)
{
u8 data = KEY_ON_OFF_CH_INDEX(chan);
_expect_ym2612_write_reg(0, YM_KEY_ON_OFF, data, file, line);
}
12 changes: 12 additions & 0 deletions tests/mocks/mock_ym2612.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ void _expect_ym2612_write_channel_any_data(
void _expect_ym2612_write_operator(
u8 chan, u8 op, u8 baseReg, u8 data, const char* const file, const int line);
void expect_ym2612_write_operator_any_data(u8 chan, u8 op, u8 baseReg);
void _expect_ym2612_write_all_operators(
u8 chan, u8 baseReg, u8 data, const char* const file, const int line);
void _expect_ym2612_write_all_operators_any_data(
u8 chan, u8 baseReg, const char* const file, const int line);
void _expect_ym2612_note_on(u8 chan, const char* const file, const int line);
void _expect_ym2612_note_off(u8 chan, const char* const file, const int line);

#define expect_ym2612_write_reg(part, reg, data) \
_expect_ym2612_write_reg(part, reg, data, __FILE__, __LINE__)
Expand All @@ -29,3 +35,9 @@ void expect_ym2612_write_operator_any_data(u8 chan, u8 op, u8 baseReg);
_expect_ym2612_write_channel_any_data(chan, baseReg, __FILE__, __LINE__)
#define expect_ym2612_write_operator(chan, op, baseReg, data) \
_expect_ym2612_write_operator(chan, op, baseReg, data, __FILE__, __LINE__)
#define expect_ym2612_write_all_operators(chan, baseReg, data) \
_expect_ym2612_write_all_operators(chan, baseReg, data, __FILE__, __LINE__)
#define expect_ym2612_write_all_operators_any_data(chan, baseReg) \
_expect_ym2612_write_all_operators_any_data(chan, baseReg, __FILE__, __LINE__)
#define expect_ym2612_note_on(chan) _expect_ym2612_note_on(chan, __FILE__, __LINE__)
#define expect_ym2612_note_off(chan) _expect_ym2612_note_off(chan, __FILE__, __LINE__)
49 changes: 24 additions & 25 deletions tests/system/test_e2e.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ void test_midi_note_on_event_sent_to_ym2612(void** state)
stub_usb_receive_note_on(TEST_MIDI_CHANNEL_1, 48, 127);
expect_ym2612_write_channel(0, 0xA4, 0x1A);
expect_ym2612_write_channel(0, 0xA0, 0x84);
expect_ym2612_write_reg(0, 0x28, 0xF0);
expect_ym2612_note_on(0);
midi_receiver_read();
}

Expand All @@ -70,14 +70,13 @@ void test_polyphonic_midi_sent_to_separate_ym2612_channels(void** state)
stub_usb_receive_note_on(TEST_MIDI_CHANNEL_1, 48, TEST_VELOCITY_MAX);
expect_ym2612_write_channel(0, 0xA4, 0x1A);
expect_ym2612_write_channel(0, 0xA0, 0x84);
expect_ym2612_write_reg(0, 0x28, 0xF0);
expect_ym2612_note_on(0);
midi_receiver_read();

stub_usb_receive_note_on(TEST_MIDI_CHANNEL_1, 49, TEST_VELOCITY_MAX);
expect_ym2612_write_channel(1, 0xA4, 0x1A);
expect_ym2612_write_channel(1, 0xA0, 0xA9);
expect_ym2612_write_reg(0, 0x28, 0xF1);

expect_ym2612_note_on(1);
midi_receiver_read();
}

Expand Down Expand Up @@ -107,7 +106,7 @@ void test_general_midi_reset_sysex_stops_all_notes(void** state)
stub_usb_receive_note_on(TEST_MIDI_CHANNEL_1, noteOnKey, TEST_VELOCITY_MAX);
expect_ym2612_write_channel(0, 0xA4, 0x1A);
expect_ym2612_write_channel(0, 0xA0, 0x84);
expect_ym2612_write_reg(0, 0x28, 0xF0);
expect_ym2612_note_on(0);
midi_receiver_read();

// PSG note
Expand All @@ -121,12 +120,12 @@ void test_general_midi_reset_sysex_stops_all_notes(void** state)
for (u16 i = 0; i < sizeof(sysExGeneralMidiResetSequence); i++) {
stub_usb_receive_byte(sysExGeneralMidiResetSequence[i]);
}
expect_ym2612_write_reg(0, 0x28, 0x00);
expect_ym2612_write_reg(0, 0x28, 0x01);
expect_ym2612_write_reg(0, 0x28, 0x02);
expect_ym2612_write_reg(0, 0x28, 0x04);
expect_ym2612_write_reg(0, 0x28, 0x05);
expect_ym2612_write_reg(0, 0x28, 0x06);
expect_ym2612_note_off(0);
expect_ym2612_note_off(1);
expect_ym2612_note_off(2);
expect_ym2612_note_off(3);
expect_ym2612_note_off(4);
expect_ym2612_note_off(5);
expect_psg_attenuation(0, 0xF);
midi_receiver_read();
}
Expand Down Expand Up @@ -302,45 +301,45 @@ void test_midi_last_note_played_priority_respected_on_fm(void** state)
stub_usb_receive_note_on(TEST_MIDI_CHANNEL_1, 48, 127);
expect_ym2612_write_channel(0, 0xA4, 0x1A);
expect_ym2612_write_channel(0, 0xA0, 0x84);
expect_ym2612_write_reg(0, 0x28, 0xF0);
expect_ym2612_note_on(0);
midi_receiver_read();

stub_usb_receive_note_on(TEST_MIDI_CHANNEL_1, 50, 127);
expect_ym2612_write_channel(0, 0xA4, 0x1A);
expect_ym2612_write_channel(0, 0xA0, 0xD2);
expect_ym2612_write_reg(0, 0x28, 0xF0);
expect_ym2612_note_on(0);
midi_receiver_read();

stub_usb_receive_note_off(TEST_MIDI_CHANNEL_1, 50);
expect_ym2612_write_channel(0, 0xA4, 0x1A);
expect_ym2612_write_channel(0, 0xA0, 0x84);
expect_ym2612_write_reg(0, 0x28, 0xF0);
expect_ym2612_note_on(0);
midi_receiver_read();
}

void test_midi_last_note_played_remembers_velocity_on_fm(void** state)
{
stub_everdrive_as_present();
stub_usb_receive_note_on(TEST_MIDI_CHANNEL_1, 48, 100);
expect_ym2612_write_channel(0, 0x40, 0x27);
expect_ym2612_write_channel(0, 0x48, 0x04);
expect_ym2612_write_channel(0, 0x44, 0x24);
expect_ym2612_write_channel(0, 0x4C, 0x04);
expect_ym2612_write_operator(0, 0, 0x40, 0x27);
expect_ym2612_write_operator(0, 1, 0x40, 0x04);
expect_ym2612_write_operator(0, 2, 0x40, 0x24);
expect_ym2612_write_operator(0, 3, 0x40, 0x04);
expect_ym2612_write_channel(0, 0xA4, 0x1A);
expect_ym2612_write_channel(0, 0xA0, 0x84);
expect_ym2612_write_reg(0, 0x28, 0xF0);
expect_ym2612_note_on(0);
midi_receiver_read();

stub_usb_receive_note_on(TEST_MIDI_CHANNEL_1, 50, 100);
expect_ym2612_write_channel(0, 0xA4, 0x1A);
expect_ym2612_write_channel(0, 0xA0, 0xD2);
expect_ym2612_write_reg(0, 0x28, 0xF0);
expect_ym2612_note_on(0);
midi_receiver_read();

stub_usb_receive_note_off(TEST_MIDI_CHANNEL_1, 50);
expect_ym2612_write_channel(0, 0xA4, 0x1A);
expect_ym2612_write_channel(0, 0xA0, 0x84);
expect_ym2612_write_reg(0, 0x28, 0xF0);
expect_ym2612_note_on(0);
midi_receiver_read();
}

Expand All @@ -350,20 +349,20 @@ void test_midi_last_note_played_cleared_when_released_on_fm(void** state)
stub_usb_receive_note_on(TEST_MIDI_CHANNEL_1, 48, 127);
expect_ym2612_write_channel(0, 0xA4, 0x1A);
expect_ym2612_write_channel(0, 0xA0, 0x84);
expect_ym2612_write_reg(0, 0x28, 0xF0);
expect_ym2612_note_on(0);
midi_receiver_read();

stub_usb_receive_note_on(TEST_MIDI_CHANNEL_1, 50, 127);
expect_ym2612_write_channel(0, 0xA4, 0x1A);
expect_ym2612_write_channel(0, 0xA0, 0xD2);
expect_ym2612_write_reg(0, 0x28, 0xF0);
expect_ym2612_note_on(0);
midi_receiver_read();

stub_usb_receive_note_off(TEST_MIDI_CHANNEL_1, 48);
midi_receiver_read();

stub_usb_receive_note_off(TEST_MIDI_CHANNEL_1, 50);
expect_ym2612_write_reg(0, 0x28, 0x0);
expect_ym2612_note_off(0);
midi_receiver_read();
}

Expand Down Expand Up @@ -470,7 +469,7 @@ void test_midi_portamento_glides_note(void** state)
stub_usb_receive_note_on(TEST_MIDI_CHANNEL_1, 48, 127);
expect_ym2612_write_channel(0, 0xA4, 0x1A);
expect_ym2612_write_channel(0, 0xA0, 0x84);
expect_ym2612_write_reg(0, 0x28, 0xF0);
expect_ym2612_note_on(0);
midi_receiver_read();

stub_usb_receive_note_on(TEST_MIDI_CHANNEL_1, 58, 127);
Expand Down
36 changes: 11 additions & 25 deletions tests/unit/test_synth.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,31 +58,31 @@ void test_synth_init_sets_initial_registers(UNUSED void** state)
void test_synth_sets_note_on_fm_reg_chan_0_to_2(UNUSED void** state)
{
for (u8 chan = 0; chan < 3; chan++) {
expect_ym2612_write_reg(0, YM_KEY_ON_OFF, 0xF0 + chan);
expect_ym2612_note_on(chan);
__real_synth_noteOn(chan);
}
}

void test_synth_sets_note_on_fm_reg_chan_3_to_5(UNUSED void** state)
{
for (u8 chan = 3; chan < MAX_FM_CHANS; chan++) {
expect_ym2612_write_reg(0, YM_KEY_ON_OFF, 0xF1 + chan);
expect_ym2612_note_on(chan);
__real_synth_noteOn(chan);
}
}

void test_synth_sets_note_off_fm_reg_chan_0_to_2(UNUSED void** state)
{
for (u8 chan = 0; chan < 3; chan++) {
expect_ym2612_write_reg(0, YM_KEY_ON_OFF, chan);
expect_ym2612_note_off(chan);
__real_synth_noteOff(chan);
}
}

void test_synth_sets_note_off_fm_reg_chan_3_to_5(UNUSED void** state)
{
for (u8 chan = 3; chan < MAX_FM_CHANS; chan++) {
expect_ym2612_write_reg(0, YM_KEY_ON_OFF, 1 + chan);
expect_ym2612_note_off(chan);
__real_synth_noteOff(chan);
}
}
Expand Down Expand Up @@ -370,22 +370,16 @@ void test_synth_applies_volume_modifier_to_output_operators_algorithm_7(UNUSED v
expect_ym2612_write_channel_any_data(chan, YM_BASE_ALGORITHM_FEEDBACK);
__real_synth_algorithm(chan, algorithm);

for (u8 op = 0; op < MAX_FM_OPERATORS; op++) {
expect_ym2612_write_operator(chan, op, YM_BASE_TOTAL_LEVEL, YM_TOTAL_LEVEL_LOUDEST);
}
expect_ym2612_write_all_operators(chan, YM_BASE_TOTAL_LEVEL, YM_TOTAL_LEVEL_LOUDEST);
for (u8 op = 0; op < MAX_FM_OPERATORS; op++) {
__real_synth_operatorTotalLevel(chan, op, YM_TOTAL_LEVEL_LOUDEST);
}

const u8 expectedTotalLevel = 0xb;
for (u8 op = 0; op < MAX_FM_OPERATORS; op++) {
expect_ym2612_write_operator(chan, op, YM_BASE_TOTAL_LEVEL, expectedTotalLevel);
}
expect_ym2612_write_all_operators(chan, YM_BASE_TOTAL_LEVEL, expectedTotalLevel);
__real_synth_volume(chan, SYNTH_VOLUME_MAX / 2);

for (u8 op = 0; op < MAX_FM_OPERATORS; op++) {
expect_ym2612_write_operator(chan, op, YM_BASE_TOTAL_LEVEL, YM_TOTAL_LEVEL_LOUDEST);
}
expect_ym2612_write_all_operators(chan, YM_BASE_TOTAL_LEVEL, YM_TOTAL_LEVEL_LOUDEST);
__real_synth_volume(chan, SYNTH_VOLUME_MAX);
}
}
Expand All @@ -397,17 +391,13 @@ void test_synth_does_not_apply_volume_if_equal(UNUSED void** state)
expect_ym2612_write_channel_any_data(chan, YM_BASE_ALGORITHM_FEEDBACK);
__real_synth_algorithm(chan, algorithm);

for (u8 op = 0; op < MAX_FM_OPERATORS; op++) {
expect_ym2612_write_operator(chan, op, YM_BASE_TOTAL_LEVEL, YM_TOTAL_LEVEL_LOUDEST);
}
expect_ym2612_write_all_operators(chan, YM_BASE_TOTAL_LEVEL, YM_TOTAL_LEVEL_LOUDEST);
for (u8 op = 0; op < MAX_FM_OPERATORS; op++) {
__real_synth_operatorTotalLevel(chan, op, YM_TOTAL_LEVEL_LOUDEST);
}

const u8 expectedTotalLevel = 0xb;
for (u8 op = 0; op < MAX_FM_OPERATORS; op++) {
expect_ym2612_write_operator(chan, op, YM_BASE_TOTAL_LEVEL, expectedTotalLevel);
}
expect_ym2612_write_all_operators(chan, YM_BASE_TOTAL_LEVEL, expectedTotalLevel);
__real_synth_volume(chan, SYNTH_VOLUME_MAX / 2);

__real_synth_volume(chan, SYNTH_VOLUME_MAX / 2);
Expand All @@ -420,17 +410,13 @@ void test_synth_applies_volume_modifier_to_output_operators_algorithm_7_quieter(
expect_ym2612_write_channel_any_data(chan, YM_BASE_ALGORITHM_FEEDBACK);
__real_synth_algorithm(chan, algorithm);

for (u8 op = 0; op < MAX_FM_OPERATORS; op++) {
expect_ym2612_write_operator(chan, op, YM_BASE_TOTAL_LEVEL, 0);
}
expect_ym2612_write_all_operators(chan, YM_BASE_TOTAL_LEVEL, 0);
for (u8 op = 0; op < MAX_FM_OPERATORS; op++) {
__real_synth_operatorTotalLevel(chan, op, YM_TOTAL_LEVEL_LOUDEST);
}

const u8 expectedTotalLevel = 0x26;
for (u8 op = 0; op < MAX_FM_OPERATORS; op++) {
expect_ym2612_write_operator(chan, op, YM_BASE_TOTAL_LEVEL, expectedTotalLevel);
}
expect_ym2612_write_all_operators(chan, YM_BASE_TOTAL_LEVEL, expectedTotalLevel);
__real_synth_volume(chan, SYNTH_VOLUME_MAX / 4);
}
}
Expand Down

0 comments on commit e61c582

Please sign in to comment.