diff --git a/src/midi.c b/src/midi.c index e29589c..ee54d7d 100644 --- a/src/midi.c +++ b/src/midi.c @@ -818,6 +818,11 @@ static void setFmChanParameter(DeviceChannel* devChan, u8 controller, u8 value) break; synth_stereo(devChan->number, RANGE(value, 4)); break; + case CC_GENMDM_ENABLE_DAC: + if (isIgnoringNonGeneralMidiCCs()) + break; + synth_enableDac(RANGE(value, 2)); + break; case CC_EXPRESSION: case CC_SUSTAIN_PEDAL: case CC_DATA_ENTRY_LSB: diff --git a/src/midi.h b/src/midi.h index b70bc28..f26446e 100644 --- a/src/midi.h +++ b/src/midi.h @@ -82,6 +82,7 @@ #define CC_GENMDM_FMS 75 #define CC_GENMDM_AMS 76 #define CC_GENMDM_STEREO 77 +#define CC_GENMDM_ENABLE_DAC 78 #define CC_GENMDM_CH3_SPECIAL_MODE 80 #define CC_GENMDM_POLYPHONIC_MODE 84 #define CC_DEVICE_SELECT 86 diff --git a/src/synth.c b/src/synth.c index e1802ec..9be0467 100644 --- a/src/synth.c +++ b/src/synth.c @@ -459,4 +459,9 @@ void synth_specialModeVolume(u8 operator, u8 volume) void synth_directWriteYm2612(u8 part, u8 reg, u8 data) { YM2612_writeReg(part, reg, data); -} \ No newline at end of file +} + +void synth_enableDac(bool enable) +{ + YM2612_writeReg(0, 0x2B, enable ? 0x80 : 0); +} diff --git a/src/synth.h b/src/synth.h index 5b7fb7a..f6f2d8c 100644 --- a/src/synth.h +++ b/src/synth.h @@ -89,4 +89,5 @@ void synth_setParameterUpdateCallback(ParameterUpdatedCallback* cb); void synth_setSpecialMode(bool enable); void synth_specialModePitch(u8 op, u8 octave, u16 freqNumber); void synth_specialModeVolume(u8 op, u8 volume); -void synth_directWriteYm2612(u8 part, u8 reg, u8 data); \ No newline at end of file +void synth_directWriteYm2612(u8 part, u8 reg, u8 data); +void synth_enableDac(bool enable); diff --git a/tests/Makefile b/tests/Makefile index a5b368d..3714e93 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -68,10 +68,11 @@ MOCKS=midi_process \ synth_volume \ synth_channelParameters \ synth_globalParameters \ - synth_setSpecialMode \ + synth_setSpecialMode \ synth_specialModePitch \ synth_specialModeVolume \ synth_directWriteYm2612 \ + synth_enableDac \ fm_writeReg \ midi_note_off \ midi_note_on \ diff --git a/tests/unit/main.c b/tests/unit/main.c index 5ffbdfa..467f9d6 100644 --- a/tests/unit/main.c +++ b/tests/unit/main.c @@ -12,12 +12,14 @@ #include "test_midi_psg.c" #include "test_midi_receiver.c" #include "test_midi_sysex.c" +#include "test_midi_pcm.c" #include "test_scheduler.c" #include "test_synth.c" #include "test_vstring.c" #include "test_buffer.c" #define midi_test(test) cmocka_unit_test_setup(test, test_midi_setup) +#define midi_pcm_test(test) cmocka_unit_test_setup(test, test_midi_setup) #define dynamic_midi_test(test) \ cmocka_unit_test_setup(test, test_dynamic_midi_setup) #define synth_test(test) cmocka_unit_test_setup(test, test_synth_setup) @@ -35,6 +37,7 @@ int main(void) { const struct CMUnitTest tests[] = { + // clang-format off midi_receiver_test( test_midi_receiver_read_passes_note_on_to_midi_processor), midi_receiver_test( @@ -178,6 +181,9 @@ int main(void) midi_test(test_midi_resets_fm_values_to_defaults), midi_test(test_midi_resets_psg_values_to_defaults), + midi_pcm_test(test_midi_enables_dac), + midi_pcm_test(test_midi_disables_dac), + synth_test(test_synth_init_sets_initial_registers), synth_test(test_synth_sets_note_on_fm_reg_chan_0_to_2), synth_test(test_synth_sets_note_on_fm_reg_chan_3_to_5), @@ -238,6 +244,8 @@ int main(void) test_synth_sets_ch3_special_mode_op_tl_only_if_output_operator_alg_6), synth_test( test_synth_sets_ch3_special_mode_op_tl_only_if_output_operator_alg_7), + synth_test(test_synth_enables_dac), + synth_test(test_synth_disables_dac), comm_test(test_comm_reads_from_serial_when_ready), comm_test(test_comm_reads_when_ready), @@ -351,6 +359,7 @@ int main(void) buffer_test(test_buffer_available_returns_correct_value_when_full), buffer_test(test_buffer_returns_cannot_write_if_full), buffer_test(test_buffer_returns_can_write_if_empty) + // clang-format on }; return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/tests/unit/test_midi_pcm.c b/tests/unit/test_midi_pcm.c new file mode 100644 index 0000000..7049434 --- /dev/null +++ b/tests/unit/test_midi_pcm.c @@ -0,0 +1,15 @@ +#include "test_midi.h" + +static void test_midi_enables_dac(UNUSED void** state) +{ + expect_value(__wrap_synth_enableDac, enable, true); + + __real_midi_cc(0, 78, 0x7F); +} + +static void test_midi_disables_dac(UNUSED void** state) +{ + expect_value(__wrap_synth_enableDac, enable, false); + + __real_midi_cc(0, 78, 0); +} diff --git a/tests/unit/test_midi_sysex.c b/tests/unit/test_midi_sysex.c index b5fcddf..4912c09 100644 --- a/tests/unit/test_midi_sysex.c +++ b/tests/unit/test_midi_sysex.c @@ -195,7 +195,7 @@ static void test_midi_sysex_disables_fm_parameter_CCs(UNUSED void** state) CC_GENMDM_RATE_SCALING_OP1, CC_GENMDM_RELEASE_RATE_OP4, CC_GENMDM_AMPLITUDE_MODULATION_OP1, CC_GENMDM_STEREO, CC_GENMDM_SSG_EG_OP1, CC_GENMDM_SSG_EG_OP4, - CC_GENMDM_GLOBAL_LFO_FREQUENCY }; + CC_GENMDM_GLOBAL_LFO_FREQUENCY, CC_GENMDM_ENABLE_DAC }; for (u16 i = 0; i < sizeof(nonGeneralMidiCCs) / sizeof(u8); i++) { u8 cc = nonGeneralMidiCCs[i]; @@ -297,4 +297,4 @@ static void test_midi_sysex_ignores_incorrect_length_ym2612_direct_writes( const u8 badSeq3[] = { SYSEX_MANU_EXTENDED, SYSEX_MANU_REGION, SYSEX_MANU_ID, SYSEX_COMMAND_WRITE_YM2612_REG_PART_0 }; __real_midi_sysex(badSeq3, sizeof(badSeq3)); -} \ No newline at end of file +} diff --git a/tests/unit/test_synth.c b/tests/unit/test_synth.c index dc0bcff..d5c9e74 100644 --- a/tests/unit/test_synth.c +++ b/tests/unit/test_synth.c @@ -38,6 +38,7 @@ extern const Global* __real_synth_globalParameters(); extern void __real_synth_setSpecialMode(bool enable); extern void __real_synth_specialModePitch(u8 op, u8 octave, u16 freqNumber); extern void __real_synth_specialModeVolume(u8 op, u8 volume); +extern void __real_synth_enableDac(bool enable); static bool updated = false; static u8 lastChan = -1; @@ -740,4 +741,18 @@ test_synth_sets_ch3_special_mode_op_tl_only_if_output_operator_alg_7( UNUSED void** state) { synth_sets_ch3_special_mode_op_tl_only_if_output_operator(7); -} \ No newline at end of file +} + +static void test_synth_enables_dac(UNUSED void** state) +{ + expect_ym2612_write_reg(0, 0x2B, 0x80); + + __real_synth_enableDac(true); +} + +static void test_synth_disables_dac(UNUSED void** state) +{ + expect_ym2612_write_reg(0, 0x2B, 0); + + __real_synth_enableDac(false); +} diff --git a/tests/wraps.c b/tests/wraps.c index 4d3a28e..e05c6ca 100644 --- a/tests/wraps.c +++ b/tests/wraps.c @@ -237,6 +237,11 @@ void __wrap_synth_directWriteYm2612(u8 part, u8 reg, u8 data) check_expected(data); } +void __wrap_synth_enableDac(bool enable) +{ + check_expected(enable); +} + void __wrap_comm_write(u8 data) { check_expected(data); diff --git a/tests/wraps.h b/tests/wraps.h index 9d6a597..8c9d4a9 100644 --- a/tests/wraps.h +++ b/tests/wraps.h @@ -65,6 +65,7 @@ void __wrap_synth_setSpecialMode(bool enable); void __wrap_synth_specialModePitch(u8 op, u8 octave, u16 freqNumber); void __wrap_synth_specialModeVolume(u8 op, u8 volume); void __wrap_synth_directWriteYm2612(u8 part, u8 reg, u8 data); +void __wrap_synth_enableDac(bool enable); bool __wrap_comm_read_ready(void); u8 __wrap_comm_read(void);