From dc64b02b030c119f8b259185381e0a210671b219 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 11 Feb 2024 12:28:24 +0900 Subject: [PATCH 001/106] Add PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING option --- .../Digital-Synth-PRA32-U.ino | 41 +++++++++++++++++++ Digital-Synth-PRA32-U/pra32-u-synth.h | 16 +++++--- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 31998dc..070ff8a 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -39,6 +39,8 @@ #define PRA32_U_USE_EMULATED_EEPROM +#define PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING + //////////////////////////////////////////////////////////////// #include "pra32-u-common.h" @@ -71,6 +73,7 @@ void handleNoteOff(byte channel, byte pitch, byte velocity); void handleControlChange(byte channel, byte number, byte value); void handleHandleProgramChange(byte channel, byte number); void handleHandlePitchBend(byte channel, int bend); +void writeProgramsToFlashAndEndSketch(); void __not_in_flash_func(setup1)() { } @@ -175,6 +178,23 @@ void __not_in_flash_func(loop)() { uint32_t debug_measurement_start0_us = micros(); #endif // defined(PRA32_U_USE_DEBUG_PRINT) +#if defined(PRA32_U_USE_EMULATED_EEPROM) +#if (defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) && !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S)) \ + || (defined(PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING) \ + && (defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W))) +#else + static uint32_t s_bootsel_count = 0; + if (BOOTSEL) { + ++s_bootsel_count; + if (s_bootsel_count >= (3 * SAMPLING_RATE) / PRA32_U_I2S_BUFFER_WORDS) { + writeUserProgramsToFlashAndStopProcessing(); + } + } else { + s_bootsel_count = 0; + } +#endif +#endif // defined(PRA32_U_USE_EMULATED_EEPROM) + for (uint32_t i = 0; i < (PRA32_U_I2S_BUFFER_WORDS + 15) / 16; i++) { #if defined(PRA32_U_USE_USB_MIDI) USB_MIDI.read(); @@ -281,3 +301,24 @@ void __not_in_flash_func(handleHandlePitchBend)(byte channel, int bend) g_synth.pitch_bend((bend + 8192) & 0x7F, (bend + 8192) >> 7); } } + +void writeUserProgramsToFlashAndStopProcessing() +{ +#if defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) + g_pwm_l.end(); + g_pwm_r.end(); +#else // defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) + g_i2s_output.end(); +#endif // defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) + + EEPROM.commit(); + + while (true) { +#if defined(ARDUINO_RASPBERRY_PI_PICO) + digitalWrite(LED_BUILTIN, LOW); + delay(500); + digitalWrite(LED_BUILTIN, HIGH); +#endif // defined(ARDUINO_RASPBERRY_PI_PICO) + delay(500); + } +} diff --git a/Digital-Synth-PRA32-U/pra32-u-synth.h b/Digital-Synth-PRA32-U/pra32-u-synth.h index 683e46a..bfd2897 100644 --- a/Digital-Synth-PRA32-U/pra32-u-synth.h +++ b/Digital-Synth-PRA32-U/pra32-u-synth.h @@ -268,9 +268,11 @@ class PRA32_U_Synth { #if defined(ARDUINO_ARCH_RP2040) #if defined(PRA32_U_USE_EMULATED_EEPROM) -#if defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) && !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) EEPROM.begin(2048); +#if (defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) && !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S)) \ + || (defined(PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING) \ + && (defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W))) for (uint32_t program_number = (PRESET_PROGRAM_NUMBER_MAX + 1); program_number <= PROGRAM_NUMBER_MAX; ++program_number) { if ((EEPROM.read(program_number * 128) == 'U') && (EEPROM.read(program_number * 128 + 1) == program_number)) { for (uint32_t i = 0; i < sizeof(s_program_table_parameters) / sizeof(s_program_table_parameters[0]); ++i) { @@ -279,7 +281,7 @@ class PRA32_U_Synth { } } } -#endif // defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) && !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) +#endif #endif // defined(PRA32_U_USE_EMULATED_EEPROM) #endif // defined(ARDUINO_ARCH_RP2040) @@ -857,9 +859,6 @@ class PRA32_U_Synth { #if defined(ARDUINO_ARCH_RP2040) #if defined(PRA32_U_USE_EMULATED_EEPROM) -#if defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) && !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) - // To avoid noise, the data will not be written to the flash - // if PRA32_U_I2S_DAC_MUTE_OFF_PIN is not defined or PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S is defined for (uint32_t i = 0; i < sizeof(s_program_table_parameters) / sizeof(s_program_table_parameters[0]); ++i) { uint32_t control_number = s_program_table_parameters[i]; EEPROM.write(m_program_number_to_write * 128 + control_number, m_current_controller_value_table[control_number]); @@ -868,12 +867,17 @@ class PRA32_U_Synth { EEPROM.write(m_program_number_to_write * 128, 'U'); EEPROM.write(m_program_number_to_write * 128 + 1, m_program_number_to_write); +#if (defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) && !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S)) \ + || (defined(PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING) \ + && (defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W))) + // To avoid noise, the data will not be written to the flash + // if PRA32_U_I2S_DAC_MUTE_OFF_PIN is not defined or PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S is defined digitalWrite(PRA32_U_I2S_DAC_MUTE_OFF_PIN, LOW); EEPROM.commit(); digitalWrite(PRA32_U_I2S_DAC_MUTE_OFF_PIN, HIGH); -#endif // defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) && !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) +#endif #endif // defined(PRA32_U_USE_EMULATED_EEPROM) #endif // defined(ARDUINO_ARCH_RP2040) } From b87847a6fa66b2f040cfca20c2ed01b7cd9f6849 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 11 Feb 2024 12:39:45 +0900 Subject: [PATCH 002/106] Add PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING option (2) --- Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino | 9 ++++----- Digital-Synth-PRA32-U/pra32-u-synth.h | 4 +--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 070ff8a..cc1caf4 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -39,7 +39,7 @@ #define PRA32_U_USE_EMULATED_EEPROM -#define PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING +//#define PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING //////////////////////////////////////////////////////////////// @@ -179,10 +179,9 @@ void __not_in_flash_func(loop)() { #endif // defined(PRA32_U_USE_DEBUG_PRINT) #if defined(PRA32_U_USE_EMULATED_EEPROM) -#if (defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) && !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S)) \ - || (defined(PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING) \ - && (defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W))) -#else +#if (defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) && !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S)) +#elif (defined(PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING) \ + && (defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W))) static uint32_t s_bootsel_count = 0; if (BOOTSEL) { ++s_bootsel_count; diff --git a/Digital-Synth-PRA32-U/pra32-u-synth.h b/Digital-Synth-PRA32-U/pra32-u-synth.h index bfd2897..f18cec9 100644 --- a/Digital-Synth-PRA32-U/pra32-u-synth.h +++ b/Digital-Synth-PRA32-U/pra32-u-synth.h @@ -867,9 +867,7 @@ class PRA32_U_Synth { EEPROM.write(m_program_number_to_write * 128, 'U'); EEPROM.write(m_program_number_to_write * 128 + 1, m_program_number_to_write); -#if (defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) && !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S)) \ - || (defined(PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING) \ - && (defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W))) +#if (defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) && !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S)) // To avoid noise, the data will not be written to the flash // if PRA32_U_I2S_DAC_MUTE_OFF_PIN is not defined or PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S is defined digitalWrite(PRA32_U_I2S_DAC_MUTE_OFF_PIN, LOW); From d3ace7c89a50fa8a29d4cee742855ab4dc8c8460 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 11 Feb 2024 13:03:06 +0900 Subject: [PATCH 003/106] Add PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING option (3) --- Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index cc1caf4..798d380 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -184,7 +184,7 @@ void __not_in_flash_func(loop)() { && (defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W))) static uint32_t s_bootsel_count = 0; if (BOOTSEL) { - ++s_bootsel_count; + s_bootsel_count++; if (s_bootsel_count >= (3 * SAMPLING_RATE) / PRA32_U_I2S_BUFFER_WORDS) { writeUserProgramsToFlashAndStopProcessing(); } @@ -304,6 +304,19 @@ void __not_in_flash_func(handleHandlePitchBend)(byte channel, int bend) void writeUserProgramsToFlashAndStopProcessing() { #if defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) + for (int16_t i = 0; i > -32768; i--) { +#if ((PRA32_U_PWM_AUDIO_L_PIN + 1) == PRA32_U_PWM_AUDIO_R_PIN) && ((PRA32_U_PWM_AUDIO_L_PIN % 2) == 0) + g_pwm_l.write(i); + g_pwm_l.write(i); +#elif ((PRA32_U_PWM_AUDIO_R_PIN + 1) == PRA32_U_PWM_AUDIO_L_PIN) && ((PRA32_U_PWM_AUDIO_R_PIN % 2) == 0) + g_pwm_r.write(i); + g_pwm_r.write(i); +#else + g_pwm_l.write(i); + g_pwm_r.write(i); +#endif + } + g_pwm_l.end(); g_pwm_r.end(); #else // defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) From b025e83dd4fb7b502ab5477b61a957730c881ee8 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 11 Feb 2024 13:44:11 +0900 Subject: [PATCH 004/106] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index d682f4e..62ac116 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,10 @@ - Write: Write the current parameters to PRA32-U (Program #8-15 and the flash) - Program Change: Send Program Change to PRA32-U directry (NOTE: The current parameters of PRA32-U will not be updated) + - Optional: Write Program #8-15 to the flash when using I2S DAC without a mute off pin or PWM audio (for Raspberry Pi Pico/H/W/WH) + - Uncomment out `//#define PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING` + - Write the current parameters to Program #8-15 + - Press BOOTSEL button for 3 seconds to write the user program to flash and stop audio processing (Pico needs to be rebooted!) ## Examples of Option Combinations From 344f828b27f2274f14d68073bfa33ffc7a895a38 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 11 Feb 2024 13:44:14 +0900 Subject: [PATCH 005/106] Update PRA32-U-Change-History.md --- PRA32-U-Change-History.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PRA32-U-Change-History.md b/PRA32-U-Change-History.md index a36a2d4..8162451 100644 --- a/PRA32-U-Change-History.md +++ b/PRA32-U-Change-History.md @@ -1,5 +1,7 @@ ## Digital Synth PRA32-U Change History +- v2.3.0 (2024-**-**): + - Add option to write user programs to the flash when using I2S DAC without a mute off pin or PWM audio (for Raspberry Pi Pico/H/W/WH) - v2.2.2 (2024-02-10): - Fix a bug that the parameters are not written to the flash when using I2S DAC, even if PRA32_U_I2S_DAC_MUTE_OFF_PIN is defined - Tested with Arduino-Pico version 3.7.0 From d5d6997d3786e4392f05e0bd35f92742bf19e10f Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 11 Feb 2024 14:02:40 +0900 Subject: [PATCH 006/106] Allow user programs to be written to the flash when using I2S DAC without mute-off pin --- Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino | 2 +- Digital-Synth-PRA32-U/pra32-u-synth.h | 15 +++++++++++++-- PRA32-U-Change-History.md | 3 ++- README.md | 3 +-- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 798d380..751e0ca 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -179,7 +179,7 @@ void __not_in_flash_func(loop)() { #endif // defined(PRA32_U_USE_DEBUG_PRINT) #if defined(PRA32_U_USE_EMULATED_EEPROM) -#if (defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) && !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S)) +#if !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) #elif (defined(PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING) \ && (defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W))) static uint32_t s_bootsel_count = 0; diff --git a/Digital-Synth-PRA32-U/pra32-u-synth.h b/Digital-Synth-PRA32-U/pra32-u-synth.h index f18cec9..b20f114 100644 --- a/Digital-Synth-PRA32-U/pra32-u-synth.h +++ b/Digital-Synth-PRA32-U/pra32-u-synth.h @@ -13,6 +13,8 @@ #if defined(ARDUINO_ARCH_RP2040) #include +#include +extern I2S g_i2s_output; #endif // defined(ARDUINO_ARCH_RP2040) #include @@ -270,7 +272,7 @@ class PRA32_U_Synth { #if defined(PRA32_U_USE_EMULATED_EEPROM) EEPROM.begin(2048); -#if (defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) && !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S)) \ +#if !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) \ || (defined(PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING) \ && (defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W))) for (uint32_t program_number = (PRESET_PROGRAM_NUMBER_MAX + 1); program_number <= PROGRAM_NUMBER_MAX; ++program_number) { @@ -867,14 +869,23 @@ class PRA32_U_Synth { EEPROM.write(m_program_number_to_write * 128, 'U'); EEPROM.write(m_program_number_to_write * 128 + 1, m_program_number_to_write); -#if (defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) && !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S)) +#if !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) // To avoid noise, the data will not be written to the flash // if PRA32_U_I2S_DAC_MUTE_OFF_PIN is not defined or PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S is defined + +#if defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) digitalWrite(PRA32_U_I2S_DAC_MUTE_OFF_PIN, LOW); +#else // defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) + g_i2s_output.end(); +#endif // defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) EEPROM.commit(); +#if defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) digitalWrite(PRA32_U_I2S_DAC_MUTE_OFF_PIN, HIGH); +#else // defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) + g_i2s_output.begin(); +#endif // defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) #endif #endif // defined(PRA32_U_USE_EMULATED_EEPROM) #endif // defined(ARDUINO_ARCH_RP2040) diff --git a/PRA32-U-Change-History.md b/PRA32-U-Change-History.md index 8162451..947c0d0 100644 --- a/PRA32-U-Change-History.md +++ b/PRA32-U-Change-History.md @@ -1,7 +1,8 @@ ## Digital Synth PRA32-U Change History - v2.3.0 (2024-**-**): - - Add option to write user programs to the flash when using I2S DAC without a mute off pin or PWM audio (for Raspberry Pi Pico/H/W/WH) + - Allow user programs to be written to the flash when using I2S DAC without mute-off pin + - Add option to write user programs to the flash when using PWM audio (for Raspberry Pi Pico/H/W/WH) - v2.2.2 (2024-02-10): - Fix a bug that the parameters are not written to the flash when using I2S DAC, even if PRA32_U_I2S_DAC_MUTE_OFF_PIN is defined - Tested with Arduino-Pico version 3.7.0 diff --git a/README.md b/README.md index 62ac116..85afdd2 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,6 @@ - Modify `PRA32_U_I2S_DAC_MUTE_OFF_PIN`, `PRA32_U_I2S_DATA_PIN`, `PRA32_U_I2S_MCLK_PIN`, `PRA32_U_I2S_MCLK_MULT`, `PRA32_U_I2S_BCLK_PIN`, and `PRA32_U_I2S_SWAP_BCLK_AND_LRCLK_PINS` in "Digital-Synth-PRA32-U.ino" to match the hardware configuration - - NOTE: To avoid noise, the parameters will not be written to the flash if `PRA32_U_I2S_DAC_MUTE_OFF_PIN` is not defined - The default setting is for Pimoroni [Pico Audio Pack](https://shop.pimoroni.com/products/pico-audio-pack) (PIM544) ``` #define PRA32_U_I2S_DAC_MUTE_OFF_PIN (22) @@ -155,7 +154,7 @@ - Write: Write the current parameters to PRA32-U (Program #8-15 and the flash) - Program Change: Send Program Change to PRA32-U directry (NOTE: The current parameters of PRA32-U will not be updated) - - Optional: Write Program #8-15 to the flash when using I2S DAC without a mute off pin or PWM audio (for Raspberry Pi Pico/H/W/WH) + - Optional: Write Program #8-15 to the flash when using PWM audio (for Raspberry Pi Pico/H/W/WH) - Uncomment out `//#define PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING` - Write the current parameters to Program #8-15 - Press BOOTSEL button for 3 seconds to write the user program to flash and stop audio processing (Pico needs to be rebooted!) From f964aa02543c3b51b740e55e59e6d9872c7581a2 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 11 Feb 2024 14:30:32 +0900 Subject: [PATCH 007/106] Add the option PRA32_U_I2S_SWAP_LEFT_AND_RIGHT --- Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino | 7 ++++++- PRA32-U-Change-History.md | 3 ++- README.md | 15 ++++----------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 751e0ca..f9bcb1d 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -23,6 +23,7 @@ //#define PRA32_U_I2S_MCLK_MULT (0) #define PRA32_U_I2S_BCLK_PIN (10) // LRCLK Pin is PRA32_U_I2S_BCLK_PIN + 1 #define PRA32_U_I2S_SWAP_BCLK_AND_LRCLK_PINS (false) +#define PRA32_U_I2S_SWAP_LEFT_AND_RIGHT (false) #define PRA32_U_I2S_BUFFERS (4) #define PRA32_U_I2S_BUFFER_WORDS (64) @@ -233,7 +234,11 @@ void __not_in_flash_func(loop)() { } #else // defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) for (uint32_t i = 0; i < PRA32_U_I2S_BUFFER_WORDS; i++) { - g_i2s_output.write16(left_buffer[i], right_buffer[i]); + if (PRA32_U_I2S_SWAP_LEFT_AND_RIGHT) { + g_i2s_output.write16(right_buffer[i], left_buffer[i]); + } else { + g_i2s_output.write16(left_buffer[i], right_buffer[i]); + } } #endif // defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) diff --git a/PRA32-U-Change-History.md b/PRA32-U-Change-History.md index 947c0d0..38e2211 100644 --- a/PRA32-U-Change-History.md +++ b/PRA32-U-Change-History.md @@ -2,7 +2,8 @@ - v2.3.0 (2024-**-**): - Allow user programs to be written to the flash when using I2S DAC without mute-off pin - - Add option to write user programs to the flash when using PWM audio (for Raspberry Pi Pico/H/W/WH) + - Add the option to write user programs to the flash when using PWM audio (for Raspberry Pi Pico/H/W/WH) + - Add the option PRA32_U_I2S_SWAP_LEFT_AND_RIGHT - v2.2.2 (2024-02-10): - Fix a bug that the parameters are not written to the flash when using I2S DAC, even if PRA32_U_I2S_DAC_MUTE_OFF_PIN is defined - Tested with Arduino-Pico version 3.7.0 diff --git a/README.md b/README.md index 85afdd2..53792fd 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ - Use an I2S DAC (e.g. Texas Instruments PCM5100A and Cirrus Logic CS4344), Sampling Rate: 48 kHz, Bit Depth: 16 bit - NOTE: The RP2040 system clock (sysclk) changes to overclocked 147.6 MHz by I2S Audio Library setSysClk() - Modify `PRA32_U_I2S_DAC_MUTE_OFF_PIN`, `PRA32_U_I2S_DATA_PIN`, `PRA32_U_I2S_MCLK_PIN`, `PRA32_U_I2S_MCLK_MULT`, - `PRA32_U_I2S_BCLK_PIN`, and `PRA32_U_I2S_SWAP_BCLK_AND_LRCLK_PINS` + `PRA32_U_I2S_BCLK_PIN`, `PRA32_U_I2S_SWAP_BCLK_AND_LRCLK_PINS`, and `PRA32_U_I2S_SWAP_LEFT_AND_RIGHT` in "Digital-Synth-PRA32-U.ino" to match the hardware configuration - The default setting is for Pimoroni [Pico Audio Pack](https://shop.pimoroni.com/products/pico-audio-pack) (PIM544) ``` @@ -75,18 +75,9 @@ //#define PRA32_U_I2S_MCLK_MULT (0) #define PRA32_U_I2S_BCLK_PIN (10) // LRCLK Pin is PRA32_U_I2S_BCLK_PIN + 1 #define PRA32_U_I2S_SWAP_BCLK_AND_LRCLK_PINS (false) +#define PRA32_U_I2S_SWAP_LEFT_AND_RIGHT (false) ``` - The following is setting is for [Pimoroni Pico VGA Demo Base](https://shop.pimoroni.com/products/pimoroni-pico-vga-demo-base) (PIM553) - and [Pimoroni Pico DV Demo Base](https://shop.pimoroni.com/products/pimoroni-pico-dv-demo-base) (PIM588) -``` -//#define PRA32_U_I2S_DAC_MUTE_OFF_PIN (0) -#define PRA32_U_I2S_DATA_PIN (26) -//#define PRA32_U_I2S_MCLK_PIN (0) -//#define PRA32_U_I2S_MCLK_MULT (0) -#define PRA32_U_I2S_BCLK_PIN (27) // LRCLK Pin is is PRA32_U_I2S_BCLK_PIN + 1 -#define PRA32_U_I2S_SWAP_BCLK_AND_LRCLK_PINS (false) -``` -- The following is setting is for Waveshare Pico-Audio Initial Version (WAVESHARE-20167) ``` //#define PRA32_U_I2S_DAC_MUTE_OFF_PIN (0) #define PRA32_U_I2S_DATA_PIN (26) @@ -94,6 +85,7 @@ //#define PRA32_U_I2S_MCLK_MULT (0) #define PRA32_U_I2S_BCLK_PIN (27) // LRCLK Pin is is PRA32_U_I2S_BCLK_PIN + 1 #define PRA32_U_I2S_SWAP_BCLK_AND_LRCLK_PINS (false) +#define PRA32_U_I2S_SWAP_LEFT_AND_RIGHT (false) ``` - The following is setting is for [Waveshare Pico-Audio](https://www.waveshare.com/wiki/Pico-Audio) Rev2.1 Version (WAVESHARE-20167) ``` @@ -103,6 +95,7 @@ #define PRA32_U_I2S_MCLK_MULT (256) #define PRA32_U_I2S_BCLK_PIN (27) // LRCLK Pin is is PRA32_U_I2S_BCLK_PIN + 1 #define PRA32_U_I2S_SWAP_BCLK_AND_LRCLK_PINS (true) +#define PRA32_U_I2S_SWAP_LEFT_AND_RIGHT (true) ``` From 89b9f3782a0e3ee3ea156a7d3aeeacabeb9ee4ab Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 11 Feb 2024 17:54:31 +0900 Subject: [PATCH 008/106] Update Digital-Synth-PRA32-U.ino --- Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index f9bcb1d..8506280 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -16,7 +16,7 @@ #define PRA32_U_MIDI_CH (0) // 0-based -// for Pimoroni Pico Audio Pack [PIM544] +// for Pimoroni Pico Audio Pack (PIM544) #define PRA32_U_I2S_DAC_MUTE_OFF_PIN (22) #define PRA32_U_I2S_DATA_PIN (9) //#define PRA32_U_I2S_MCLK_PIN (0) @@ -34,8 +34,6 @@ #define PRA32_U_PWM_AUDIO_L_PIN (28) #define PRA32_U_PWM_AUDIO_R_PIN (27) -//#define PRA32_U_USE_PWM_AUDIO_DITHERING_INSTEAD_OF_ERROR_DIFFUSION - #define PRA32_U_USE_2_CORES_FOR_SIGNAL_PROCESSING #define PRA32_U_USE_EMULATED_EEPROM From cab8fdee6a6f9ae9bef542e964ad5805460c0fc5 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 11 Feb 2024 18:00:04 +0900 Subject: [PATCH 009/106] Rename PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING --- Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino | 4 ++-- Digital-Synth-PRA32-U/pra32-u-synth.h | 2 +- README.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 8506280..cd65617 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -38,7 +38,7 @@ #define PRA32_U_USE_EMULATED_EEPROM -//#define PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING +//#define PRA32_U_USE_EMULATED_EEPROM_PRESS_BOOTSEL_TO_WRITE_USER_PROGRAMS //////////////////////////////////////////////////////////////// @@ -179,7 +179,7 @@ void __not_in_flash_func(loop)() { #if defined(PRA32_U_USE_EMULATED_EEPROM) #if !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) -#elif (defined(PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING) \ +#elif (defined(PRA32_U_USE_EMULATED_EEPROM_PRESS_BOOTSEL_TO_WRITE_USER_PROGRAMS) \ && (defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W))) static uint32_t s_bootsel_count = 0; if (BOOTSEL) { diff --git a/Digital-Synth-PRA32-U/pra32-u-synth.h b/Digital-Synth-PRA32-U/pra32-u-synth.h index b20f114..7b25aca 100644 --- a/Digital-Synth-PRA32-U/pra32-u-synth.h +++ b/Digital-Synth-PRA32-U/pra32-u-synth.h @@ -273,7 +273,7 @@ class PRA32_U_Synth { EEPROM.begin(2048); #if !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) \ - || (defined(PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING) \ + || (defined(PRA32_U_USE_EMULATED_EEPROM_PRESS_BOOTSEL_TO_WRITE_USER_PROGRAMS) \ && (defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W))) for (uint32_t program_number = (PRESET_PROGRAM_NUMBER_MAX + 1); program_number <= PROGRAM_NUMBER_MAX; ++program_number) { if ((EEPROM.read(program_number * 128) == 'U') && (EEPROM.read(program_number * 128 + 1) == program_number)) { diff --git a/README.md b/README.md index 53792fd..8ced841 100644 --- a/README.md +++ b/README.md @@ -148,7 +148,7 @@ - Program Change: Send Program Change to PRA32-U directry (NOTE: The current parameters of PRA32-U will not be updated) - Optional: Write Program #8-15 to the flash when using PWM audio (for Raspberry Pi Pico/H/W/WH) - - Uncomment out `//#define PRA32_U_USE_EMULATED_EEPROM_BOOTSEL_LONG_PRESS_TO_WRITE_USER_PROGRAMS_AND_STOP_PROCESSING` + - Uncomment out `//#define PRA32_U_USE_EMULATED_EEPROM_PRESS_BOOTSEL_TO_WRITE_USER_PROGRAMS` - Write the current parameters to Program #8-15 - Press BOOTSEL button for 3 seconds to write the user program to flash and stop audio processing (Pico needs to be rebooted!) From c2623300c8a6e1b449c2e01442185d12dd8e8e45 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 11 Feb 2024 18:09:32 +0900 Subject: [PATCH 010/106] Update Digital-Synth-PRA32-U.ino --- Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index cd65617..2d3c3fe 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -185,7 +185,7 @@ void __not_in_flash_func(loop)() { if (BOOTSEL) { s_bootsel_count++; if (s_bootsel_count >= (3 * SAMPLING_RATE) / PRA32_U_I2S_BUFFER_WORDS) { - writeUserProgramsToFlashAndStopProcessing(); + writeUserProgramsToFlashAndShutDown(); } } else { s_bootsel_count = 0; @@ -304,7 +304,7 @@ void __not_in_flash_func(handleHandlePitchBend)(byte channel, int bend) } } -void writeUserProgramsToFlashAndStopProcessing() +void writeUserProgramsToFlashAndShutDown() { #if defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) for (int16_t i = 0; i > -32768; i--) { From e1287fda89d7b53fcbd2bed29ac09182da93ce47 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 11 Feb 2024 18:11:26 +0900 Subject: [PATCH 011/106] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8ced841..b7e76d7 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,7 @@ - Optional: Write Program #8-15 to the flash when using PWM audio (for Raspberry Pi Pico/H/W/WH) - Uncomment out `//#define PRA32_U_USE_EMULATED_EEPROM_PRESS_BOOTSEL_TO_WRITE_USER_PROGRAMS` - Write the current parameters to Program #8-15 - - Press BOOTSEL button for 3 seconds to write the user program to flash and stop audio processing (Pico needs to be rebooted!) + - Press BOOTSEL button for 3 seconds to write user programs to the flash and shut down (Pico needs to be rebooted!) ## Examples of Option Combinations From c32a59581b90b7be1226abe47391ec4b4ebec202 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 11 Feb 2024 20:16:30 +0900 Subject: [PATCH 012/106] Use core 1 for Debug Print --- .../Digital-Synth-PRA32-U.ino | 74 +++++++++++-------- Digital-Synth-PRA32-U/pra32-u-synth.h | 20 ++++- PRA32-U-Change-History.md | 1 + 3 files changed, 63 insertions(+), 32 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 2d3c3fe..3755ecd 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -67,6 +67,11 @@ PWMAudio g_pwm_r(PRA32_U_PWM_AUDIO_R_PIN); #include I2S g_i2s_output(OUTPUT); +static volatile uint32_t s_debug_measurement_elapsed0_us = 0; +static volatile uint32_t s_debug_measurement_max0_us = 0; +static volatile uint32_t s_debug_measurement_elapsed1_us = 0; +static volatile uint32_t s_debug_measurement_max1_us = 0; + void handleNoteOn(byte channel, byte pitch, byte velocity); void handleNoteOff(byte channel, byte pitch, byte velocity); void handleControlChange(byte channel, byte number, byte value); @@ -75,10 +80,36 @@ void handleHandlePitchBend(byte channel, int bend); void writeProgramsToFlashAndEndSketch(); void __not_in_flash_func(setup1)() { +#if defined(PRA32_U_USE_DEBUG_PRINT) + Serial1.setTX(0); + Serial1.setRX(1); + Serial1.begin(115200); +#endif // defined(PRA32_U_USE_DEBUG_PRINT) } void __not_in_flash_func(loop1)() { - g_synth.secondary_core_process(); + boolean processed = g_synth.secondary_core_process(); + if (processed) { + static uint32_t s_ui_counter = 0; + s_ui_counter++; + if (s_ui_counter >= 64 * 750) { + s_ui_counter = 0; + } + +#if defined(PRA32_U_USE_DEBUG_PRINT) + static uint32_t s_debug_loop_counter = 0; + s_debug_loop_counter++; + if (s_debug_loop_counter >= 64 * 3000) { + s_debug_loop_counter = 0; + + Serial1.println(s_debug_measurement_elapsed1_us); + Serial1.println(s_debug_measurement_max1_us); + Serial1.println(s_debug_measurement_elapsed0_us); + Serial1.println(s_debug_measurement_max0_us); + Serial1.println(); + } +#endif // defined(PRA32_U_USE_DEBUG_PRINT) + } } void __not_in_flash_func(setup)() { @@ -144,12 +175,6 @@ void __not_in_flash_func(setup)() { Serial2.begin(PRA32_U_UART_MIDI_SPEED); #endif // defined(PRA32_U_USE_UART_MIDI) -#if defined(PRA32_U_USE_DEBUG_PRINT) - Serial1.setTX(0); - Serial1.setRX(1); - Serial1.begin(115200); -#endif // defined(PRA32_U_USE_DEBUG_PRINT) - #if defined(ARDUINO_RASPBERRY_PI_PICO) pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); @@ -181,14 +206,14 @@ void __not_in_flash_func(loop)() { #if !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) #elif (defined(PRA32_U_USE_EMULATED_EEPROM_PRESS_BOOTSEL_TO_WRITE_USER_PROGRAMS) \ && (defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W))) - static uint32_t s_bootsel_count = 0; + static uint32_t s_bootsel_counter = 0; if (BOOTSEL) { - s_bootsel_count++; - if (s_bootsel_count >= (3 * SAMPLING_RATE) / PRA32_U_I2S_BUFFER_WORDS) { + s_bootsel_counter++; + if (s_bootsel_counter >= (3 * SAMPLING_RATE) / PRA32_U_I2S_BUFFER_WORDS) { writeUserProgramsToFlashAndShutDown(); } } else { - s_bootsel_count = 0; + s_bootsel_counter = 0; } #endif #endif // defined(PRA32_U_USE_EMULATED_EEPROM) @@ -241,26 +266,13 @@ void __not_in_flash_func(loop)() { #endif // defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) #if defined(PRA32_U_USE_DEBUG_PRINT) - static uint32_t s_debug_measurement_max0_us = 0; - uint32_t debug_measurement_elapsed0_us = debug_measurement_end_us - debug_measurement_start0_us; - s_debug_measurement_max0_us += (debug_measurement_elapsed0_us > s_debug_measurement_max0_us) * - (debug_measurement_elapsed0_us - s_debug_measurement_max0_us); - - static uint32_t s_debug_measurement_max1_us = 0; - uint32_t debug_measurement_elapsed1_us = debug_measurement_end_us - debug_measurement_start1_us; - s_debug_measurement_max1_us += (debug_measurement_elapsed1_us > s_debug_measurement_max1_us) * - (debug_measurement_elapsed1_us - s_debug_measurement_max1_us); - - static uint32_t s_debug_loop_counter = 0; - if (++s_debug_loop_counter == 4000) { - s_debug_loop_counter = 0; - - Serial1.println(debug_measurement_elapsed1_us); - Serial1.println(s_debug_measurement_max1_us); - Serial1.println(debug_measurement_elapsed0_us); - Serial1.println(s_debug_measurement_max0_us); - Serial1.println(); - } + s_debug_measurement_elapsed0_us = debug_measurement_end_us - debug_measurement_start0_us; + s_debug_measurement_max0_us += (s_debug_measurement_elapsed0_us > s_debug_measurement_max0_us) * + (s_debug_measurement_elapsed0_us - s_debug_measurement_max0_us); + + s_debug_measurement_elapsed1_us = debug_measurement_end_us - debug_measurement_start1_us; + s_debug_measurement_max1_us += (s_debug_measurement_elapsed1_us > s_debug_measurement_max1_us) * + (s_debug_measurement_elapsed1_us - s_debug_measurement_max1_us); #endif // defined(PRA32_U_USE_DEBUG_PRINT) } diff --git a/Digital-Synth-PRA32-U/pra32-u-synth.h b/Digital-Synth-PRA32-U/pra32-u-synth.h index 7b25aca..e7125d0 100644 --- a/Digital-Synth-PRA32-U/pra32-u-synth.h +++ b/Digital-Synth-PRA32-U/pra32-u-synth.h @@ -1058,6 +1058,11 @@ class PRA32_U_Synth { voice_mixer_output = amp_output[0]; } else { +#if defined(PRA32_U_USE_2_CORES_FOR_SIGNAL_PROCESSING) + m_secondary_core_processing_argument = 0; + m_secondary_core_processing_request = 1; +#endif // defined(PRA32_U_USE_2_CORES_FOR_SIGNAL_PROCESSING) + osc_output[0] = m_osc.process<0>(noise_int15); int16_t osc_mixer_output = osc_output[0] << 1; @@ -1065,6 +1070,12 @@ class PRA32_U_Synth { amp_output [0] = m_amp [0].process(filter_output[0]); voice_mixer_output = amp_output[0]; + +#if defined(PRA32_U_USE_2_CORES_FOR_SIGNAL_PROCESSING) + while (m_secondary_core_processing_request) { + ; + } +#endif // defined(PRA32_U_USE_2_CORES_FOR_SIGNAL_PROCESSING) } int16_t chorus_fx_output_r; @@ -1106,7 +1117,9 @@ class PRA32_U_Synth { #endif // defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) } - INLINE void secondary_core_process() { + INLINE boolean secondary_core_process() { + boolean processed = false; + #if defined(PRA32_U_USE_2_CORES_FOR_SIGNAL_PROCESSING) if (m_secondary_core_processing_request == 1) { int16_t noise_int15 = static_cast(m_secondary_core_processing_argument); @@ -1130,11 +1143,16 @@ class PRA32_U_Synth { osc_output[3] = m_osc.process<3>(noise_int15); m_secondary_core_processing_result = osc_output[2] + osc_output[3]; + } else { + m_secondary_core_processing_result = 0; } m_secondary_core_processing_request = 0; + processed = true; } #endif // defined(PRA32_U_USE_2_CORES_FOR_SIGNAL_PROCESSING) + + return processed; } private: diff --git a/PRA32-U-Change-History.md b/PRA32-U-Change-History.md index 38e2211..c2e921c 100644 --- a/PRA32-U-Change-History.md +++ b/PRA32-U-Change-History.md @@ -4,6 +4,7 @@ - Allow user programs to be written to the flash when using I2S DAC without mute-off pin - Add the option to write user programs to the flash when using PWM audio (for Raspberry Pi Pico/H/W/WH) - Add the option PRA32_U_I2S_SWAP_LEFT_AND_RIGHT + - Use core 1 for Debug Print - v2.2.2 (2024-02-10): - Fix a bug that the parameters are not written to the flash when using I2S DAC, even if PRA32_U_I2S_DAC_MUTE_OFF_PIN is defined - Tested with Arduino-Pico version 3.7.0 From f1329a2d2b2d20433607a646c6c0ed29ad16e70a Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 3 Mar 2024 20:52:49 +0900 Subject: [PATCH 013/106] Use escape sequences for Debug Print --- .../Digital-Synth-PRA32-U.ino | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 3755ecd..a4de8b4 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -2,7 +2,7 @@ * Digital Synth PRA32-U */ -//#define PRA32_U_USE_DEBUG_PRINT // Serial1 +#define PRA32_U_USE_DEBUG_PRINT // Serial1 #define PRA32_U_USE_USB_MIDI // Select USB Stack: "Adafruit TinyUSB" in the Arduino IDE "Tools" menu @@ -99,14 +99,19 @@ void __not_in_flash_func(loop1)() { #if defined(PRA32_U_USE_DEBUG_PRINT) static uint32_t s_debug_loop_counter = 0; s_debug_loop_counter++; - if (s_debug_loop_counter >= 64 * 3000) { + if (s_debug_loop_counter == 16 * 3000) { + Serial1.print("\e[10;1H\e[K"); + Serial1.print(s_debug_measurement_elapsed1_us); + } else if (s_debug_loop_counter == 32 * 3000) { + Serial1.print("\e[11;1H\e[K"); + Serial1.print(s_debug_measurement_max1_us); + } else if (s_debug_loop_counter == 48 * 3000) { + Serial1.print("\e[13;1H\e[K"); + Serial1.print(s_debug_measurement_elapsed0_us); + } else if (s_debug_loop_counter == 64 * 3000) { + Serial1.print("\e[14;1H\e[K"); + Serial1.print(s_debug_measurement_max0_us); s_debug_loop_counter = 0; - - Serial1.println(s_debug_measurement_elapsed1_us); - Serial1.println(s_debug_measurement_max1_us); - Serial1.println(s_debug_measurement_elapsed0_us); - Serial1.println(s_debug_measurement_max0_us); - Serial1.println(); } #endif // defined(PRA32_U_USE_DEBUG_PRINT) } From ec675812a92db76468514aa7f99861fa8c45c454 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 3 Mar 2024 21:42:58 +0900 Subject: [PATCH 014/106] Add wait --- Digital-Synth-PRA32-U/pra32-u-synth.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Digital-Synth-PRA32-U/pra32-u-synth.h b/Digital-Synth-PRA32-U/pra32-u-synth.h index e7125d0..2ac37c1 100644 --- a/Digital-Synth-PRA32-U/pra32-u-synth.h +++ b/Digital-Synth-PRA32-U/pra32-u-synth.h @@ -1072,6 +1072,11 @@ class PRA32_U_Synth { voice_mixer_output = amp_output[0]; #if defined(PRA32_U_USE_2_CORES_FOR_SIGNAL_PROCESSING) + // Wait + for (volatile uint32_t i = 0; i < 30; ++i) { + ; + } + while (m_secondary_core_processing_request) { ; } From e09950a034d6425627149cec240304babb353435 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sat, 16 Mar 2024 18:42:14 +0900 Subject: [PATCH 015/106] Implement panel functions (1) --- .../Digital-Synth-PRA32-U.ino | 60 +++++++++++++++++-- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index a4de8b4..40970c7 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -40,8 +40,13 @@ //#define PRA32_U_USE_EMULATED_EEPROM_PRESS_BOOTSEL_TO_WRITE_USER_PROGRAMS +#define PRA32_U_USE_PANEL +#define PRA32_U_USE_PANEL_ANALOG_INPUT + //////////////////////////////////////////////////////////////// +#include "hardware/adc.h" + #include "pra32-u-common.h" #include "pra32-u-synth.h" @@ -80,6 +85,13 @@ void handleHandlePitchBend(byte channel, int bend); void writeProgramsToFlashAndEndSketch(); void __not_in_flash_func(setup1)() { +#if defined(PRA32_U_USE_PANEL) && defined(PRA32_U_USE_PANEL_ANALOG_INPUT) + adc_init(); + adc_gpio_init(26); + adc_gpio_init(27); + adc_gpio_init(28); +#endif + #if defined(PRA32_U_USE_DEBUG_PRINT) Serial1.setTX(0); Serial1.setRX(1); @@ -96,22 +108,62 @@ void __not_in_flash_func(loop1)() { s_ui_counter = 0; } + static uint32_t a0 = 0; + static uint32_t a1 = 0; + static uint32_t a2 = 0; + +#if defined(PRA32_U_USE_PANEL) && defined(PRA32_U_USE_PANEL_ANALOG_INPUT) + if ((s_ui_counter & 0x3F) == 0x10) { + adc_select_input(0); + a0 = (adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read()) >> 7; + } else if ((s_ui_counter & 0x3F) == 0x20) { + adc_select_input(1); + a1 = (adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read()) >> 7; + } else if ((s_ui_counter & 0x3F) == 0x30) { + adc_select_input(2); + a2 = (adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read()) >> 7; + } +#endif + #if defined(PRA32_U_USE_DEBUG_PRINT) static uint32_t s_debug_loop_counter = 0; s_debug_loop_counter++; - if (s_debug_loop_counter == 16 * 3000) { + if (s_debug_loop_counter == 4 * 3000) { Serial1.print("\e[10;1H\e[K"); Serial1.print(s_debug_measurement_elapsed1_us); - } else if (s_debug_loop_counter == 32 * 3000) { + } else if (s_debug_loop_counter == 8 * 3000) { Serial1.print("\e[11;1H\e[K"); Serial1.print(s_debug_measurement_max1_us); - } else if (s_debug_loop_counter == 48 * 3000) { + } else if (s_debug_loop_counter == 12 * 3000) { Serial1.print("\e[13;1H\e[K"); Serial1.print(s_debug_measurement_elapsed0_us); - } else if (s_debug_loop_counter == 64 * 3000) { + } else if (s_debug_loop_counter == 16 * 3000) { Serial1.print("\e[14;1H\e[K"); Serial1.print(s_debug_measurement_max0_us); s_debug_loop_counter = 0; +#if defined(PRA32_U_USE_PANEL) && defined(PRA32_U_USE_PANEL_ANALOG_INPUT) + } else if ((s_debug_loop_counter == 1 * 3000) || + (s_debug_loop_counter == 5 * 3000) || + (s_debug_loop_counter == 9 * 3000) || + (s_debug_loop_counter == 13 * 3000)) { + Serial1.print("\e[16;1H\e[K"); + Serial1.print(a0); + } else if ((s_debug_loop_counter == 2 * 3000) || + (s_debug_loop_counter == 6 * 3000) || + (s_debug_loop_counter == 10 * 3000) || + (s_debug_loop_counter == 14 * 3000)) { + Serial1.print("\e[17;1H\e[K"); + Serial1.print(a1); + } else if ((s_debug_loop_counter == 3 * 3000) || + (s_debug_loop_counter == 7 * 3000) || + (s_debug_loop_counter == 11 * 3000) || + (s_debug_loop_counter == 15 * 3000)) { + Serial1.print("\e[18;1H\e[K"); + Serial1.print(a2); +#endif } #endif // defined(PRA32_U_USE_DEBUG_PRINT) } From 6e569c9a2bef687e4cbc391c9bd30d3447f3dd74 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sat, 16 Mar 2024 18:59:10 +0900 Subject: [PATCH 016/106] Implement panel functions (2) --- Digital-Synth-PRA32-U/pra32-u-synth.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-synth.h b/Digital-Synth-PRA32-U/pra32-u-synth.h index 2ac37c1..129fdfa 100644 --- a/Digital-Synth-PRA32-U/pra32-u-synth.h +++ b/Digital-Synth-PRA32-U/pra32-u-synth.h @@ -290,7 +290,7 @@ class PRA32_U_Synth { program_change(PROGRAM_NUMBER_DEFAULT); } - INLINE void note_on(uint8_t note_number, uint8_t velocity) { + /* INLINE */ void note_on(uint8_t note_number, uint8_t velocity) { if (m_note_on_total_count == 255) { return; } @@ -450,7 +450,7 @@ class PRA32_U_Synth { } } - INLINE void note_off(uint8_t note_number) { + /* INLINE */ void note_off(uint8_t note_number) { if (m_note_on_total_count == 0) { return; } @@ -599,7 +599,7 @@ class PRA32_U_Synth { set_sustain_pedal(0); } - INLINE void control_change(uint8_t control_number, uint8_t controller_value) { + /* INLINE */ void control_change(uint8_t control_number, uint8_t controller_value) { m_current_controller_value_table[control_number] = controller_value; switch (control_number) { @@ -915,7 +915,7 @@ class PRA32_U_Synth { } } - INLINE void pitch_bend(uint8_t lsb, uint8_t msb) { + /* INLINE */ void pitch_bend(uint8_t lsb, uint8_t msb) { int16_t pitch_bend = ((static_cast(msb) << 8) >> 1) + lsb - 8192; m_osc.set_pitch_bend(pitch_bend); } From 099cca2c8e8fd715c2c402aa3e9e96c20435c686 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sat, 16 Mar 2024 19:04:53 +0900 Subject: [PATCH 017/106] Remove unnecessary conditional branching --- Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 40970c7..f818d3e 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -336,11 +336,7 @@ void __not_in_flash_func(loop)() { void __not_in_flash_func(handleNoteOn)(byte channel, byte pitch, byte velocity) { if ((channel - 1) == PRA32_U_MIDI_CH) { - if (velocity > 0) { - g_synth.note_on(pitch, velocity); - } else { - g_synth.note_off(pitch); - } + g_synth.note_on(pitch, velocity); } } From f78ee951f8e58e051374731bef7b76b6a5f87aec Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 17 Mar 2024 09:56:06 +0900 Subject: [PATCH 018/106] Implement panel functions (3) --- .../Digital-Synth-PRA32-U.ino | 70 ++++--------------- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 60 ++++++++++++++++ 2 files changed, 75 insertions(+), 55 deletions(-) create mode 100644 Digital-Synth-PRA32-U/pra32-u-control-panel.h diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index f818d3e..ce374db 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -40,8 +40,8 @@ //#define PRA32_U_USE_EMULATED_EEPROM_PRESS_BOOTSEL_TO_WRITE_USER_PROGRAMS -#define PRA32_U_USE_PANEL -#define PRA32_U_USE_PANEL_ANALOG_INPUT +#define PRA32_U_USE_CONTROL_PANEL +#define PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT // ADC0, ADC1, ADC2 //////////////////////////////////////////////////////////////// @@ -49,6 +49,7 @@ #include "pra32-u-common.h" #include "pra32-u-synth.h" +#include "pra32-u-control-panel.h" PRA32_U_Synth g_synth; @@ -85,12 +86,7 @@ void handleHandlePitchBend(byte channel, int bend); void writeProgramsToFlashAndEndSketch(); void __not_in_flash_func(setup1)() { -#if defined(PRA32_U_USE_PANEL) && defined(PRA32_U_USE_PANEL_ANALOG_INPUT) - adc_init(); - adc_gpio_init(26); - adc_gpio_init(27); - adc_gpio_init(28); -#endif + PRA32_U_ControlPanel_setup(); #if defined(PRA32_U_USE_DEBUG_PRINT) Serial1.setTX(0); @@ -102,68 +98,32 @@ void __not_in_flash_func(setup1)() { void __not_in_flash_func(loop1)() { boolean processed = g_synth.secondary_core_process(); if (processed) { - static uint32_t s_ui_counter = 0; - s_ui_counter++; - if (s_ui_counter >= 64 * 750) { - s_ui_counter = 0; + static uint32_t s_panel_loop_counter = 0; + s_panel_loop_counter++; + if (s_panel_loop_counter >= 64 * 750) { + s_panel_loop_counter = 0; } - static uint32_t a0 = 0; - static uint32_t a1 = 0; - static uint32_t a2 = 0; - -#if defined(PRA32_U_USE_PANEL) && defined(PRA32_U_USE_PANEL_ANALOG_INPUT) - if ((s_ui_counter & 0x3F) == 0x10) { - adc_select_input(0); - a0 = (adc_read() + adc_read() + adc_read() + adc_read() + - adc_read() + adc_read() + adc_read() + adc_read()) >> 7; - } else if ((s_ui_counter & 0x3F) == 0x20) { - adc_select_input(1); - a1 = (adc_read() + adc_read() + adc_read() + adc_read() + - adc_read() + adc_read() + adc_read() + adc_read()) >> 7; - } else if ((s_ui_counter & 0x3F) == 0x30) { - adc_select_input(2); - a2 = (adc_read() + adc_read() + adc_read() + adc_read() + - adc_read() + adc_read() + adc_read() + adc_read()) >> 7; - } -#endif + PRA32_U_ControlPanel_update(s_panel_loop_counter); #if defined(PRA32_U_USE_DEBUG_PRINT) static uint32_t s_debug_loop_counter = 0; s_debug_loop_counter++; if (s_debug_loop_counter == 4 * 3000) { - Serial1.print("\e[10;1H\e[K"); + Serial1.print("\e[1;1H\e[K"); Serial1.print(s_debug_measurement_elapsed1_us); } else if (s_debug_loop_counter == 8 * 3000) { - Serial1.print("\e[11;1H\e[K"); + Serial1.print("\e[2;1H\e[K"); Serial1.print(s_debug_measurement_max1_us); } else if (s_debug_loop_counter == 12 * 3000) { - Serial1.print("\e[13;1H\e[K"); + Serial1.print("\e[4;1H\e[K"); Serial1.print(s_debug_measurement_elapsed0_us); } else if (s_debug_loop_counter == 16 * 3000) { - Serial1.print("\e[14;1H\e[K"); + Serial1.print("\e[5;1H\e[K"); Serial1.print(s_debug_measurement_max0_us); s_debug_loop_counter = 0; -#if defined(PRA32_U_USE_PANEL) && defined(PRA32_U_USE_PANEL_ANALOG_INPUT) - } else if ((s_debug_loop_counter == 1 * 3000) || - (s_debug_loop_counter == 5 * 3000) || - (s_debug_loop_counter == 9 * 3000) || - (s_debug_loop_counter == 13 * 3000)) { - Serial1.print("\e[16;1H\e[K"); - Serial1.print(a0); - } else if ((s_debug_loop_counter == 2 * 3000) || - (s_debug_loop_counter == 6 * 3000) || - (s_debug_loop_counter == 10 * 3000) || - (s_debug_loop_counter == 14 * 3000)) { - Serial1.print("\e[17;1H\e[K"); - Serial1.print(a1); - } else if ((s_debug_loop_counter == 3 * 3000) || - (s_debug_loop_counter == 7 * 3000) || - (s_debug_loop_counter == 11 * 3000) || - (s_debug_loop_counter == 15 * 3000)) { - Serial1.print("\e[18;1H\e[K"); - Serial1.print(a2); -#endif + } else { + PRA32_U_ControlPanel_debug_print(s_debug_loop_counter); } #endif // defined(PRA32_U_USE_DEBUG_PRINT) } diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h new file mode 100644 index 0000000..5f9b670 --- /dev/null +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -0,0 +1,60 @@ +#pragma once + +#include "pra32-u-common.h" + +static uint32_t s_adc_average_value_0 = 0; +static uint32_t s_adc_average_value_1 = 0; +static uint32_t s_adc_average_value_2 = 0; + +INLINE void PRA32_U_ControlPanel_setup() { +#if defined(PRA32_U_USE_CONTROL_PANEL) && defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) + adc_init(); + adc_gpio_init(26); + adc_gpio_init(27); + adc_gpio_init(28); +#endif // defined(PRA32_U_USE_CONTROL_PANEL) && defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) +} + +INLINE void PRA32_U_ControlPanel_update(uint32_t panel_loop_counter) { +#if defined(PRA32_U_USE_CONTROL_PANEL) && defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) + if ((panel_loop_counter & 0x3F) == 0x10) { + adc_select_input(0); + s_adc_average_value_0 = (adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read()) >> 7; + } else if ((panel_loop_counter & 0x3F) == 0x20) { + adc_select_input(1); + s_adc_average_value_1 = (adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read()) >> 7; + } else if ((panel_loop_counter & 0x3F) == 0x30) { + adc_select_input(2); + s_adc_average_value_2 = (adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read()) >> 7; + } +#endif // defined(PRA32_U_USE_CONTROL_PANEL) && defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) +} + +INLINE void PRA32_U_ControlPanel_debug_print(uint32_t debug_loop_counter) { +#if defined(PRA32_U_USE_DEBUG_PRINT) +#if defined(PRA32_U_USE_CONTROL_PANEL) && defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) + if ((debug_loop_counter == 1 * 3000) || + (debug_loop_counter == 5 * 3000) || + (debug_loop_counter == 9 * 3000) || + (debug_loop_counter == 13 * 3000)) { + Serial1.print("\e[16;1H\e[K"); + Serial1.print(s_adc_average_value_0); + } else if ((debug_loop_counter == 2 * 3000) || + (debug_loop_counter == 6 * 3000) || + (debug_loop_counter == 10 * 3000) || + (debug_loop_counter == 14 * 3000)) { + Serial1.print("\e[17;1H\e[K"); + Serial1.print(s_adc_average_value_1); + } else if ((debug_loop_counter == 3 * 3000) || + (debug_loop_counter == 7 * 3000) || + (debug_loop_counter == 11 * 3000) || + (debug_loop_counter == 15 * 3000)) { + Serial1.print("\e[18;1H\e[K"); + Serial1.print(s_adc_average_value_2); + } +#endif // defined(PRA32_U_USE_CONTROL_PANEL) && defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) +#endif // defined(PRA32_U_USE_DEBUG_PRINT) +} From df5077516c740b003015274f52cbe8a83b1edf85 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 17 Mar 2024 19:09:01 +0900 Subject: [PATCH 019/106] Implement panel functions (4) --- .../Digital-Synth-PRA32-U.ino | 24 +++--- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 79 +++++++++++++------ 2 files changed, 67 insertions(+), 36 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index ce374db..0c7ea7a 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -42,6 +42,7 @@ #define PRA32_U_USE_CONTROL_PANEL #define PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT // ADC0, ADC1, ADC2 +#define PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY // I2C1 (SSD1306) //////////////////////////////////////////////////////////////// @@ -98,32 +99,29 @@ void __not_in_flash_func(setup1)() { void __not_in_flash_func(loop1)() { boolean processed = g_synth.secondary_core_process(); if (processed) { - static uint32_t s_panel_loop_counter = 0; - s_panel_loop_counter++; - if (s_panel_loop_counter >= 64 * 750) { - s_panel_loop_counter = 0; + static uint32_t s_loop_counter = 0; + s_loop_counter++; + if (s_loop_counter >= 16 * 750) { + s_loop_counter = 0; } - PRA32_U_ControlPanel_update(s_panel_loop_counter); + PRA32_U_ControlPanel_update(s_loop_counter); #if defined(PRA32_U_USE_DEBUG_PRINT) - static uint32_t s_debug_loop_counter = 0; - s_debug_loop_counter++; - if (s_debug_loop_counter == 4 * 3000) { + if (s_loop_counter == 1 * 750) { Serial1.print("\e[1;1H\e[K"); Serial1.print(s_debug_measurement_elapsed1_us); - } else if (s_debug_loop_counter == 8 * 3000) { + } else if (s_loop_counter == 2 * 750) { Serial1.print("\e[2;1H\e[K"); Serial1.print(s_debug_measurement_max1_us); - } else if (s_debug_loop_counter == 12 * 3000) { + } else if (s_loop_counter == 3 * 750) { Serial1.print("\e[4;1H\e[K"); Serial1.print(s_debug_measurement_elapsed0_us); - } else if (s_debug_loop_counter == 16 * 3000) { + } else if (s_loop_counter == 4 * 750) { Serial1.print("\e[5;1H\e[K"); Serial1.print(s_debug_measurement_max0_us); - s_debug_loop_counter = 0; } else { - PRA32_U_ControlPanel_debug_print(s_debug_loop_counter); + PRA32_U_ControlPanel_debug_print(s_loop_counter); } #endif // defined(PRA32_U_USE_DEBUG_PRINT) } diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 5f9b670..33dd863 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -6,55 +6,88 @@ static uint32_t s_adc_average_value_0 = 0; static uint32_t s_adc_average_value_1 = 0; static uint32_t s_adc_average_value_2 = 0; +static char s_display_buffer[8][21 + 1] = { + " ", + "Filter Filter ", + "Cutoff Resonance ", + "A 127[127] B 0[ 0]", + " ", + " Filter ", + " EG Amt ", + " C 64[ +0]", +}; + INLINE void PRA32_U_ControlPanel_setup() { -#if defined(PRA32_U_USE_CONTROL_PANEL) && defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) +#if defined(PRA32_U_USE_CONTROL_PANEL) +#if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) adc_init(); adc_gpio_init(26); adc_gpio_init(27); adc_gpio_init(28); -#endif // defined(PRA32_U_USE_CONTROL_PANEL) && defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) +#endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) +#endif // defined(PRA32_U_USE_CONTROL_PANEL) } -INLINE void PRA32_U_ControlPanel_update(uint32_t panel_loop_counter) { -#if defined(PRA32_U_USE_CONTROL_PANEL) && defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) - if ((panel_loop_counter & 0x3F) == 0x10) { +INLINE void PRA32_U_ControlPanel_update(uint32_t loop_counter) { +#if defined(PRA32_U_USE_CONTROL_PANEL) +#if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) + if ((loop_counter & 0x3F) == 0x10) { adc_select_input(0); s_adc_average_value_0 = (adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read()) >> 7; - } else if ((panel_loop_counter & 0x3F) == 0x20) { + } else if ((loop_counter & 0x3F) == 0x20) { adc_select_input(1); s_adc_average_value_1 = (adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read()) >> 7; - } else if ((panel_loop_counter & 0x3F) == 0x30) { + } else if ((loop_counter & 0x3F) == 0x30) { adc_select_input(2); s_adc_average_value_2 = (adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read()) >> 7; } -#endif // defined(PRA32_U_USE_CONTROL_PANEL) && defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) +#endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) +#endif // defined(PRA32_U_USE_CONTROL_PANEL) } -INLINE void PRA32_U_ControlPanel_debug_print(uint32_t debug_loop_counter) { +INLINE void PRA32_U_ControlPanel_debug_print(uint32_t loop_counter) { #if defined(PRA32_U_USE_DEBUG_PRINT) -#if defined(PRA32_U_USE_CONTROL_PANEL) && defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) - if ((debug_loop_counter == 1 * 3000) || - (debug_loop_counter == 5 * 3000) || - (debug_loop_counter == 9 * 3000) || - (debug_loop_counter == 13 * 3000)) { +#if defined(PRA32_U_USE_CONTROL_PANEL) + if (loop_counter == 5 * 750) { + Serial1.print("\e[7;1H\e[K"); + Serial1.print(static_cast(s_display_buffer[0])); + } else if (loop_counter == 6 * 750) { + Serial1.print("\e[8;1H\e[K"); + Serial1.print(static_cast(s_display_buffer[1])); + } else if (loop_counter == 7 * 750) { + Serial1.print("\e[9;1H\e[K"); + Serial1.print(static_cast(s_display_buffer[2])); + } else if (loop_counter == 8 * 750) { + Serial1.print("\e[10;1H\e[K"); + Serial1.print(static_cast(s_display_buffer[3])); + } else if (loop_counter == 9 * 750) { + Serial1.print("\e[11;1H\e[K"); + Serial1.print(static_cast(s_display_buffer[4])); + } else if (loop_counter == 10 * 750) { + Serial1.print("\e[12;1H\e[K"); + Serial1.print(static_cast(s_display_buffer[5])); + } else if (loop_counter == 11 * 750) { + Serial1.print("\e[13;1H\e[K"); + Serial1.print(static_cast(s_display_buffer[6])); + } else if (loop_counter == 12 * 750) { + Serial1.print("\e[14;1H\e[K"); + Serial1.print(static_cast(s_display_buffer[7])); + } +#if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) + if (loop_counter == 13 * 750) { Serial1.print("\e[16;1H\e[K"); Serial1.print(s_adc_average_value_0); - } else if ((debug_loop_counter == 2 * 3000) || - (debug_loop_counter == 6 * 3000) || - (debug_loop_counter == 10 * 3000) || - (debug_loop_counter == 14 * 3000)) { + } else if (loop_counter == 14 * 750) { Serial1.print("\e[17;1H\e[K"); Serial1.print(s_adc_average_value_1); - } else if ((debug_loop_counter == 3 * 3000) || - (debug_loop_counter == 7 * 3000) || - (debug_loop_counter == 11 * 3000) || - (debug_loop_counter == 15 * 3000)) { + } else if (loop_counter == 15 * 750) { Serial1.print("\e[18;1H\e[K"); Serial1.print(s_adc_average_value_2); } -#endif // defined(PRA32_U_USE_CONTROL_PANEL) && defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) +#endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) +#endif // defined(PRA32_U_USE_CONTROL_PANEL) #endif // defined(PRA32_U_USE_DEBUG_PRINT) } From 28005ebf597d94fd632246ca7003939e0f2b34fa Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 17 Mar 2024 20:01:08 +0900 Subject: [PATCH 020/106] Implement panel functions (5) --- .../Digital-Synth-PRA32-U.ino | 16 +++-- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 64 ++++++++++++------- 2 files changed, 52 insertions(+), 28 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 0c7ea7a..a6a392e 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -108,20 +108,26 @@ void __not_in_flash_func(loop1)() { PRA32_U_ControlPanel_update(s_loop_counter); #if defined(PRA32_U_USE_DEBUG_PRINT) - if (s_loop_counter == 1 * 750) { + switch (s_loop_counter) { + case 1 * 750: Serial1.print("\e[1;1H\e[K"); Serial1.print(s_debug_measurement_elapsed1_us); - } else if (s_loop_counter == 2 * 750) { + break; + case 2 * 750: Serial1.print("\e[2;1H\e[K"); Serial1.print(s_debug_measurement_max1_us); - } else if (s_loop_counter == 3 * 750) { + break; + case 3 * 750: Serial1.print("\e[4;1H\e[K"); Serial1.print(s_debug_measurement_elapsed0_us); - } else if (s_loop_counter == 4 * 750) { + break; + case 4 * 750: Serial1.print("\e[5;1H\e[K"); Serial1.print(s_debug_measurement_max0_us); - } else { + break; + default: PRA32_U_ControlPanel_debug_print(s_loop_counter); + break; } #endif // defined(PRA32_U_USE_DEBUG_PRINT) } diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 33dd863..f27836f 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -7,7 +7,7 @@ static uint32_t s_adc_average_value_1 = 0; static uint32_t s_adc_average_value_2 = 0; static char s_display_buffer[8][21 + 1] = { - " ", + " 1", "Filter Filter ", "Cutoff Resonance ", "A 127[127] B 0[ 0]", @@ -31,18 +31,25 @@ INLINE void PRA32_U_ControlPanel_setup() { INLINE void PRA32_U_ControlPanel_update(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL) #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) - if ((loop_counter & 0x3F) == 0x10) { + switch (loop_counter & 0x3F) { + case 0x10: adc_select_input(0); - s_adc_average_value_0 = (adc_read() + adc_read() + adc_read() + adc_read() + - adc_read() + adc_read() + adc_read() + adc_read()) >> 7; - } else if ((loop_counter & 0x3F) == 0x20) { + s_adc_average_value_0 = + (adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read()) >> 7; + break; + case 0x20: adc_select_input(1); - s_adc_average_value_1 = (adc_read() + adc_read() + adc_read() + adc_read() + - adc_read() + adc_read() + adc_read() + adc_read()) >> 7; - } else if ((loop_counter & 0x3F) == 0x30) { + s_adc_average_value_1 = + (adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read()) >> 7; + break; + case 0x30: adc_select_input(2); - s_adc_average_value_2 = (adc_read() + adc_read() + adc_read() + adc_read() + - adc_read() + adc_read() + adc_read() + adc_read()) >> 7; + s_adc_average_value_2 = + (adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read()) >> 7; + break; } #endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) #endif // defined(PRA32_U_USE_CONTROL_PANEL) @@ -51,43 +58,54 @@ INLINE void PRA32_U_ControlPanel_update(uint32_t loop_counter) { INLINE void PRA32_U_ControlPanel_debug_print(uint32_t loop_counter) { #if defined(PRA32_U_USE_DEBUG_PRINT) #if defined(PRA32_U_USE_CONTROL_PANEL) - if (loop_counter == 5 * 750) { + switch (loop_counter) { + case 5 * 750: Serial1.print("\e[7;1H\e[K"); Serial1.print(static_cast(s_display_buffer[0])); - } else if (loop_counter == 6 * 750) { + break; + case 6 * 750: Serial1.print("\e[8;1H\e[K"); Serial1.print(static_cast(s_display_buffer[1])); - } else if (loop_counter == 7 * 750) { + break; + case 7 * 750: Serial1.print("\e[9;1H\e[K"); Serial1.print(static_cast(s_display_buffer[2])); - } else if (loop_counter == 8 * 750) { + break; + case 8 * 750: Serial1.print("\e[10;1H\e[K"); Serial1.print(static_cast(s_display_buffer[3])); - } else if (loop_counter == 9 * 750) { + break; + case 9 * 750: Serial1.print("\e[11;1H\e[K"); Serial1.print(static_cast(s_display_buffer[4])); - } else if (loop_counter == 10 * 750) { + break; + case 10 * 750: Serial1.print("\e[12;1H\e[K"); Serial1.print(static_cast(s_display_buffer[5])); - } else if (loop_counter == 11 * 750) { + break; + case 11 * 750: Serial1.print("\e[13;1H\e[K"); Serial1.print(static_cast(s_display_buffer[6])); - } else if (loop_counter == 12 * 750) { + break; + case 12 * 750: Serial1.print("\e[14;1H\e[K"); Serial1.print(static_cast(s_display_buffer[7])); - } + break; #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) - if (loop_counter == 13 * 750) { + case 13 * 750: Serial1.print("\e[16;1H\e[K"); Serial1.print(s_adc_average_value_0); - } else if (loop_counter == 14 * 750) { + break; + case 14 * 750: Serial1.print("\e[17;1H\e[K"); Serial1.print(s_adc_average_value_1); - } else if (loop_counter == 15 * 750) { + break; + case 15 * 750: Serial1.print("\e[18;1H\e[K"); Serial1.print(s_adc_average_value_2); - } + break; #endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) + } #endif // defined(PRA32_U_USE_CONTROL_PANEL) #endif // defined(PRA32_U_USE_DEBUG_PRINT) } From d6fc0906fd4f33104d7c5757a9f3e695e1c5a328 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 07:12:05 +0900 Subject: [PATCH 021/106] Update README.md --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b7e76d7..cd64ceb 100644 --- a/README.md +++ b/README.md @@ -48,14 +48,18 @@ #### UART MIDI (Optional) - UART MIDI can also be used + - Noise caused by USB communication can be avoided - Uncomment out `//#define PRA32_U_USE_UART_MIDI` in "Digital-Synth-PRA32-U.ino" and modify `PRA32_U_UART_MIDI_SPEED`, `PRA32_U_UART_MIDI_TX_PIN`, and `PRA32_U_UART_MIDI_RX_PIN` -- Speed: 31250 bps (default, for DIN/TRS MIDI) or 38400 bps -- GP4 and GP5 pins are used by UART1 TX and UART1 RX by default + - Speed: 31250 bps (default, for DIN/TRS MIDI) or 38400 bps (for PC) + - GP4 and GP5 pins are used by UART1 TX and UART1 RX by default - DIN/TRS MIDI is available by using (and modifying) Adafruit MIDI FeatherWing Kit, for example - Adafruit [MIDI FeatherWing Kit](https://www.adafruit.com/product/4740) - 木下研究所 [MIDI-UARTインターフェースさん キット](https://www.switch-science.com/products/8117) (Shipping to Japan only) - necobit電子 [MIDI Unit for GROVE](https://necobit.com/denshi/grove-midi-unit/) (Shipping to Japan only) +- We recommend using [Hairless MIDI<->Serial Bridge](https://projectgus.github.io/hairless-midiserial/) on PC + - On Windows, We recommend using [loopMIDI](https://www.tobias-erichsen.de/software/loopmidi.html) (virtual loopback MIDI cable) + - On Mac, a virtual MIDI bus (port) can be created by using the IAC bus ### Audio (Output) From a29cd46801a7aafe8e9e62cd81216c51ec0794f5 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 07:47:17 +0900 Subject: [PATCH 022/106] Implement panel functions (6) --- .../Digital-Synth-PRA32-U.ino | 9 +- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 82 ++++++++++++++----- 2 files changed, 71 insertions(+), 20 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index a6a392e..ecc485c 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -40,8 +40,13 @@ //#define PRA32_U_USE_EMULATED_EEPROM_PRESS_BOOTSEL_TO_WRITE_USER_PROGRAMS +//////////////////////////////////////////////////////////////// + #define PRA32_U_USE_CONTROL_PANEL + #define PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT // ADC0, ADC1, ADC2 +#define PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT (true) + #define PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY // I2C1 (SSD1306) //////////////////////////////////////////////////////////////// @@ -105,7 +110,7 @@ void __not_in_flash_func(loop1)() { s_loop_counter = 0; } - PRA32_U_ControlPanel_update(s_loop_counter); + PRA32_U_ControlPanel_update_input(s_loop_counter); #if defined(PRA32_U_USE_DEBUG_PRINT) switch (s_loop_counter) { @@ -249,6 +254,8 @@ void __not_in_flash_func(loop)() { #endif } + PRA32_U_ControlPanel_update_control(); + #if defined(PRA32_U_USE_DEBUG_PRINT) uint32_t debug_measurement_start1_us = micros(); #endif // defined(PRA32_U_USE_DEBUG_PRINT) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index f27836f..2a5cf00 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -2,9 +2,13 @@ #include "pra32-u-common.h" -static uint32_t s_adc_average_value_0 = 0; -static uint32_t s_adc_average_value_1 = 0; -static uint32_t s_adc_average_value_2 = 0; +static volatile uint32_t s_adc_current_value_0 = 0; +static volatile uint32_t s_adc_current_value_1 = 0; +static volatile uint32_t s_adc_current_value_2 = 0; + +static volatile uint32_t s_adc_control_value_0 = 0; +static volatile uint32_t s_adc_control_value_1 = 0; +static volatile uint32_t s_adc_control_value_2 = 0; static char s_display_buffer[8][21 + 1] = { " 1", @@ -28,33 +32,73 @@ INLINE void PRA32_U_ControlPanel_setup() { #endif // defined(PRA32_U_USE_CONTROL_PANEL) } -INLINE void PRA32_U_ControlPanel_update(uint32_t loop_counter) { +INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL) #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) switch (loop_counter & 0x3F) { case 0x10: - adc_select_input(0); - s_adc_average_value_0 = - (adc_read() + adc_read() + adc_read() + adc_read() + - adc_read() + adc_read() + adc_read() + adc_read()) >> 7; + { + adc_select_input(0); + uint32_t adc_average_value = + (adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read()) >> 6; + + if (s_adc_current_value_0 > adc_average_value + 4) { + s_adc_current_value_0 = adc_average_value; + } else if (s_adc_current_value_0 + 4 < adc_average_value ) { + s_adc_current_value_0 = adc_average_value; + } + } break; case 0x20: - adc_select_input(1); - s_adc_average_value_1 = - (adc_read() + adc_read() + adc_read() + adc_read() + - adc_read() + adc_read() + adc_read() + adc_read()) >> 7; + { + adc_select_input(1); + uint32_t adc_average_value = + (adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read()) >> 6; + + if (s_adc_current_value_1 > adc_average_value + 4) { + s_adc_current_value_1 = adc_average_value; + } else if (s_adc_current_value_1 + 4 < adc_average_value ) { + s_adc_current_value_1 = adc_average_value; + } + } break; case 0x30: - adc_select_input(2); - s_adc_average_value_2 = - (adc_read() + adc_read() + adc_read() + adc_read() + - adc_read() + adc_read() + adc_read() + adc_read()) >> 7; + { + adc_select_input(2); + uint32_t adc_average_value = + (adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read()) >> 6; + + if (s_adc_current_value_2 > adc_average_value + 4) { + s_adc_current_value_2 = adc_average_value; + } else if (s_adc_current_value_2 + 4 < adc_average_value ) { + s_adc_current_value_2 = adc_average_value; + } + } break; } #endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) #endif // defined(PRA32_U_USE_CONTROL_PANEL) } +INLINE void PRA32_U_ControlPanel_update_control() { +#if defined(PRA32_U_USE_CONTROL_PANEL) +#if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) +#if defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) + s_adc_control_value_0 = 127 - (s_adc_current_value_0 >> 2); + s_adc_control_value_1 = 127 - (s_adc_current_value_1 >> 2); + s_adc_control_value_2 = 127 - (s_adc_current_value_2 >> 2); +#else // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) + s_adc_control_value_0 = s_adc_current_value_0 >> 2; + s_adc_control_value_1 = s_adc_current_value_1 >> 2; + s_adc_control_value_2 = s_adc_current_value_2 >> 2; +#endif // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) +#endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) +#endif // defined(PRA32_U_USE_CONTROL_PANEL) +} + INLINE void PRA32_U_ControlPanel_debug_print(uint32_t loop_counter) { #if defined(PRA32_U_USE_DEBUG_PRINT) #if defined(PRA32_U_USE_CONTROL_PANEL) @@ -94,15 +138,15 @@ INLINE void PRA32_U_ControlPanel_debug_print(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) case 13 * 750: Serial1.print("\e[16;1H\e[K"); - Serial1.print(s_adc_average_value_0); + Serial1.print(s_adc_control_value_0); break; case 14 * 750: Serial1.print("\e[17;1H\e[K"); - Serial1.print(s_adc_average_value_1); + Serial1.print(s_adc_control_value_1); break; case 15 * 750: Serial1.print("\e[18;1H\e[K"); - Serial1.print(s_adc_average_value_2); + Serial1.print(s_adc_control_value_2); break; #endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) } From 48450b7929d3cfd418fe47eded7c3f663aeb04f8 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 08:19:54 +0900 Subject: [PATCH 023/106] Implement panel functions (7) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 80 ++++++++++++------- 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 2a5cf00..94e27aa 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -2,23 +2,20 @@ #include "pra32-u-common.h" -static volatile uint32_t s_adc_current_value_0 = 0; -static volatile uint32_t s_adc_current_value_1 = 0; -static volatile uint32_t s_adc_current_value_2 = 0; +#include -static volatile uint32_t s_adc_control_value_0 = 0; -static volatile uint32_t s_adc_control_value_1 = 0; -static volatile uint32_t s_adc_control_value_2 = 0; +static volatile uint32_t s_adc_current_value[3]; +static volatile uint32_t s_adc_control_value[3]; static char s_display_buffer[8][21 + 1] = { - " 1", + " 5", "Filter Filter ", "Cutoff Resonance ", - "A 127[127] B 0[ 0]", + "A B ", " ", " Filter ", " EG Amt ", - " C 64[ +0]", + " C [ ]", }; INLINE void PRA32_U_ControlPanel_setup() { @@ -43,10 +40,10 @@ INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { (adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read()) >> 6; - if (s_adc_current_value_0 > adc_average_value + 4) { - s_adc_current_value_0 = adc_average_value; - } else if (s_adc_current_value_0 + 4 < adc_average_value ) { - s_adc_current_value_0 = adc_average_value; + if (s_adc_current_value[0] > adc_average_value + 4) { + s_adc_current_value[0] = adc_average_value; + } else if (s_adc_current_value[0] + 4 < adc_average_value ) { + s_adc_current_value[0] = adc_average_value; } } break; @@ -57,10 +54,10 @@ INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { (adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read()) >> 6; - if (s_adc_current_value_1 > adc_average_value + 4) { - s_adc_current_value_1 = adc_average_value; - } else if (s_adc_current_value_1 + 4 < adc_average_value ) { - s_adc_current_value_1 = adc_average_value; + if (s_adc_current_value[1] > adc_average_value + 4) { + s_adc_current_value[1] = adc_average_value; + } else if (s_adc_current_value[1] + 4 < adc_average_value ) { + s_adc_current_value[1] = adc_average_value; } } break; @@ -71,10 +68,10 @@ INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { (adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read()) >> 6; - if (s_adc_current_value_2 > adc_average_value + 4) { - s_adc_current_value_2 = adc_average_value; - } else if (s_adc_current_value_2 + 4 < adc_average_value ) { - s_adc_current_value_2 = adc_average_value; + if (s_adc_current_value[2] > adc_average_value + 4) { + s_adc_current_value[2] = adc_average_value; + } else if (s_adc_current_value[2] + 4 < adc_average_value ) { + s_adc_current_value[2] = adc_average_value; } } break; @@ -87,14 +84,37 @@ INLINE void PRA32_U_ControlPanel_update_control() { #if defined(PRA32_U_USE_CONTROL_PANEL) #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) #if defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) - s_adc_control_value_0 = 127 - (s_adc_current_value_0 >> 2); - s_adc_control_value_1 = 127 - (s_adc_current_value_1 >> 2); - s_adc_control_value_2 = 127 - (s_adc_current_value_2 >> 2); + s_adc_control_value[0] = 127 - (s_adc_current_value[0] >> 2); + s_adc_control_value[1] = 127 - (s_adc_current_value[1] >> 2); + s_adc_control_value[2] = 127 - (s_adc_current_value[2] >> 2); #else // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) - s_adc_control_value_0 = s_adc_current_value_0 >> 2; - s_adc_control_value_1 = s_adc_current_value_1 >> 2; - s_adc_control_value_2 = s_adc_current_value_2 >> 2; + s_adc_control_value[0] = s_adc_current_value[0] >> 2; + s_adc_control_value[1] = s_adc_current_value[1] >> 2; + s_adc_control_value[2] = s_adc_current_value[2] >> 2; #endif // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) + + char buff[4]; + + std::sprintf(buff, "%3u", s_adc_control_value[0]); + s_display_buffer[3][ 2] = buff[0]; + s_display_buffer[3][ 3] = buff[1]; + s_display_buffer[3][ 4] = buff[2]; + + std::sprintf(buff, "%3u", s_adc_control_value[1]); + s_display_buffer[3][13] = buff[0]; + s_display_buffer[3][14] = buff[1]; + s_display_buffer[3][15] = buff[2]; + + std::sprintf(buff, "%3u", s_adc_control_value[2]); + s_display_buffer[7][13] = buff[0]; + s_display_buffer[7][14] = buff[1]; + s_display_buffer[7][15] = buff[2]; + + std::sprintf(buff, "%+3d", static_cast(s_adc_control_value[2]) - 64); + s_display_buffer[7][17] = buff[0]; + s_display_buffer[7][18] = buff[1]; + s_display_buffer[7][19] = buff[2]; + #endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) #endif // defined(PRA32_U_USE_CONTROL_PANEL) } @@ -138,15 +158,15 @@ INLINE void PRA32_U_ControlPanel_debug_print(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) case 13 * 750: Serial1.print("\e[16;1H\e[K"); - Serial1.print(s_adc_control_value_0); + Serial1.print(s_adc_control_value[0]); break; case 14 * 750: Serial1.print("\e[17;1H\e[K"); - Serial1.print(s_adc_control_value_1); + Serial1.print(s_adc_control_value[1]); break; case 15 * 750: Serial1.print("\e[18;1H\e[K"); - Serial1.print(s_adc_control_value_2); + Serial1.print(s_adc_control_value[2]); break; #endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) } From 8e40729b59462e9edf9ec77ce8320981e461d373 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 08:41:39 +0900 Subject: [PATCH 024/106] Implement panel functions (8) --- .../Digital-Synth-PRA32-U.ino | 3 ++- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 27 ++++++++++++++----- Digital-Synth-PRA32-U/pra32-u-synth.h | 4 +++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index ecc485c..e0c762d 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -55,10 +55,11 @@ #include "pra32-u-common.h" #include "pra32-u-synth.h" -#include "pra32-u-control-panel.h" PRA32_U_Synth g_synth; +#include "pra32-u-control-panel.h" + #include #if defined(PRA32_U_USE_USB_MIDI) #include diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 94e27aa..a9ee51f 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -40,9 +40,9 @@ INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { (adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read()) >> 6; - if (s_adc_current_value[0] > adc_average_value + 4) { + if (s_adc_current_value[0] >= adc_average_value + 4) { s_adc_current_value[0] = adc_average_value; - } else if (s_adc_current_value[0] + 4 < adc_average_value ) { + } else if (s_adc_current_value[0] + 4 <= adc_average_value ) { s_adc_current_value[0] = adc_average_value; } } @@ -83,6 +83,8 @@ INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { INLINE void PRA32_U_ControlPanel_update_control() { #if defined(PRA32_U_USE_CONTROL_PANEL) #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) + static boolean s_s_adc_current_values_initialized = false; + if (s_s_adc_current_values_initialized == false) { #if defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) s_adc_control_value[0] = 127 - (s_adc_current_value[0] >> 2); s_adc_control_value[1] = 127 - (s_adc_current_value[1] >> 2); @@ -92,25 +94,38 @@ INLINE void PRA32_U_ControlPanel_update_control() { s_adc_control_value[1] = s_adc_current_value[1] >> 2; s_adc_control_value[2] = s_adc_current_value[2] >> 2; #endif // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) + s_s_adc_current_values_initialized = true; + } + +#if defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) + uint32_t adc_control_value_candidate = 127 - (s_adc_current_value[0] >> 2); +#else // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) + uint32_t adc_control_value_candidate = s_adc_current_value[0] >> 2; +#endif // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) + + if (s_adc_control_value[0] != adc_control_value_candidate) { + s_adc_control_value[0] = adc_control_value_candidate; + g_synth.control_change(FILTER_CUTOFF , s_adc_control_value[0]); + } char buff[4]; - std::sprintf(buff, "%3u", s_adc_control_value[0]); + std::sprintf(buff, "%3u", g_synth.m_current_controller_value_table[FILTER_CUTOFF ]); s_display_buffer[3][ 2] = buff[0]; s_display_buffer[3][ 3] = buff[1]; s_display_buffer[3][ 4] = buff[2]; - std::sprintf(buff, "%3u", s_adc_control_value[1]); + std::sprintf(buff, "%3u", g_synth.m_current_controller_value_table[FILTER_RESO ]); s_display_buffer[3][13] = buff[0]; s_display_buffer[3][14] = buff[1]; s_display_buffer[3][15] = buff[2]; - std::sprintf(buff, "%3u", s_adc_control_value[2]); + std::sprintf(buff, "%3u", g_synth.m_current_controller_value_table[FILTER_EG_AMT ]); s_display_buffer[7][13] = buff[0]; s_display_buffer[7][14] = buff[1]; s_display_buffer[7][15] = buff[2]; - std::sprintf(buff, "%+3d", static_cast(s_adc_control_value[2]) - 64); + std::sprintf(buff, "%+3d", static_cast(g_synth.m_current_controller_value_table[FILTER_EG_AMT ]) - 64); s_display_buffer[7][17] = buff[0]; s_display_buffer[7][18] = buff[1]; s_display_buffer[7][19] = buff[2]; diff --git a/Digital-Synth-PRA32-U/pra32-u-synth.h b/Digital-Synth-PRA32-U/pra32-u-synth.h index 129fdfa..e98bfc0 100644 --- a/Digital-Synth-PRA32-U/pra32-u-synth.h +++ b/Digital-Synth-PRA32-U/pra32-u-synth.h @@ -125,7 +125,11 @@ class PRA32_U_Synth { uint8_t m_program_number_to_write; uint8_t m_wr_prog_to_flash_cc_value; uint8_t m_sp_prog_chg_cc_values[8]; + +public: uint8_t m_current_controller_value_table[128]; + +private: uint8_t m_program_table[128][PROGRAM_NUMBER_MAX + 1]; volatile int32_t m_secondary_core_processing_argument; From 7560a377a44511fe9de0ced18f6e8754731cf888 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 09:09:24 +0900 Subject: [PATCH 025/106] Implement panel functions (9) --- .../Digital-Synth-PRA32-U.ino | 11 ++- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 96 ++++++++++--------- Digital-Synth-PRA32-U/pra32-u-synth.h | 8 +- 3 files changed, 61 insertions(+), 54 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index e0c762d..3863e00 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -107,27 +107,28 @@ void __not_in_flash_func(loop1)() { if (processed) { static uint32_t s_loop_counter = 0; s_loop_counter++; - if (s_loop_counter >= 16 * 750) { + if (s_loop_counter >= 16 * 375) { s_loop_counter = 0; } PRA32_U_ControlPanel_update_input(s_loop_counter); + PRA32_U_ControlPanel_update_display_buffer(s_loop_counter); #if defined(PRA32_U_USE_DEBUG_PRINT) switch (s_loop_counter) { - case 1 * 750: + case 1 * 375: Serial1.print("\e[1;1H\e[K"); Serial1.print(s_debug_measurement_elapsed1_us); break; - case 2 * 750: + case 2 * 375: Serial1.print("\e[2;1H\e[K"); Serial1.print(s_debug_measurement_max1_us); break; - case 3 * 750: + case 3 * 375: Serial1.print("\e[4;1H\e[K"); Serial1.print(s_debug_measurement_elapsed0_us); break; - case 4 * 750: + case 4 * 375: Serial1.print("\e[5;1H\e[K"); Serial1.print(s_debug_measurement_max0_us); break; diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index a9ee51f..bf61d3a 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -83,103 +83,109 @@ INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { INLINE void PRA32_U_ControlPanel_update_control() { #if defined(PRA32_U_USE_CONTROL_PANEL) #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) - static boolean s_s_adc_current_values_initialized = false; - if (s_s_adc_current_values_initialized == false) { + static uint32_t s_initialize_counter = 0; + if (s_initialize_counter < 16) { + ++s_initialize_counter; #if defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) - s_adc_control_value[0] = 127 - (s_adc_current_value[0] >> 2); - s_adc_control_value[1] = 127 - (s_adc_current_value[1] >> 2); - s_adc_control_value[2] = 127 - (s_adc_current_value[2] >> 2); + s_adc_control_value[0] = 127 - (s_adc_current_value[0] >> 2); + s_adc_control_value[1] = 127 - (s_adc_current_value[1] >> 2); + s_adc_control_value[2] = 127 - (s_adc_current_value[2] >> 2); #else // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) - s_adc_control_value[0] = s_adc_current_value[0] >> 2; - s_adc_control_value[1] = s_adc_current_value[1] >> 2; - s_adc_control_value[2] = s_adc_current_value[2] >> 2; + s_adc_control_value[0] = s_adc_current_value[0] >> 2; + s_adc_control_value[1] = s_adc_current_value[1] >> 2; + s_adc_control_value[2] = s_adc_current_value[2] >> 2; #endif // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) - s_s_adc_current_values_initialized = true; + return; } #if defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) - uint32_t adc_control_value_candidate = 127 - (s_adc_current_value[0] >> 2); + uint32_t adc_control_value_candidate = 127 - (s_adc_current_value[0] >> 2); #else // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) - uint32_t adc_control_value_candidate = s_adc_current_value[0] >> 2; + uint32_t adc_control_value_candidate = s_adc_current_value[0] >> 2; #endif // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) if (s_adc_control_value[0] != adc_control_value_candidate) { s_adc_control_value[0] = adc_control_value_candidate; g_synth.control_change(FILTER_CUTOFF , s_adc_control_value[0]); } - - char buff[4]; - - std::sprintf(buff, "%3u", g_synth.m_current_controller_value_table[FILTER_CUTOFF ]); - s_display_buffer[3][ 2] = buff[0]; - s_display_buffer[3][ 3] = buff[1]; - s_display_buffer[3][ 4] = buff[2]; - - std::sprintf(buff, "%3u", g_synth.m_current_controller_value_table[FILTER_RESO ]); - s_display_buffer[3][13] = buff[0]; - s_display_buffer[3][14] = buff[1]; - s_display_buffer[3][15] = buff[2]; - - std::sprintf(buff, "%3u", g_synth.m_current_controller_value_table[FILTER_EG_AMT ]); - s_display_buffer[7][13] = buff[0]; - s_display_buffer[7][14] = buff[1]; - s_display_buffer[7][15] = buff[2]; - - std::sprintf(buff, "%+3d", static_cast(g_synth.m_current_controller_value_table[FILTER_EG_AMT ]) - 64); - s_display_buffer[7][17] = buff[0]; - s_display_buffer[7][18] = buff[1]; - s_display_buffer[7][19] = buff[2]; - #endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) #endif // defined(PRA32_U_USE_CONTROL_PANEL) } +INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { +#if defined(PRA32_U_USE_CONTROL_PANEL) + if (loop_counter == 0) { + char buff[4]; + + std::sprintf(buff, "%3u", g_synth.current_controller_value(FILTER_CUTOFF )); + s_display_buffer[3][ 2] = buff[0]; + s_display_buffer[3][ 3] = buff[1]; + s_display_buffer[3][ 4] = buff[2]; + + std::sprintf(buff, "%3u", g_synth.current_controller_value(FILTER_RESO )); + s_display_buffer[3][13] = buff[0]; + s_display_buffer[3][14] = buff[1]; + s_display_buffer[3][15] = buff[2]; + + std::sprintf(buff, "%3u", g_synth.current_controller_value(FILTER_EG_AMT )); + s_display_buffer[7][13] = buff[0]; + s_display_buffer[7][14] = buff[1]; + s_display_buffer[7][15] = buff[2]; + + std::sprintf(buff, "%+3d", static_cast(g_synth.current_controller_value(FILTER_EG_AMT )) - 64); + s_display_buffer[7][17] = buff[0]; + s_display_buffer[7][18] = buff[1]; + s_display_buffer[7][19] = buff[2]; + } +#endif // defined(PRA32_U_USE_CONTROL_PANEL) +} + INLINE void PRA32_U_ControlPanel_debug_print(uint32_t loop_counter) { #if defined(PRA32_U_USE_DEBUG_PRINT) #if defined(PRA32_U_USE_CONTROL_PANEL) switch (loop_counter) { - case 5 * 750: + case 5 * 375: Serial1.print("\e[7;1H\e[K"); Serial1.print(static_cast(s_display_buffer[0])); break; - case 6 * 750: + case 6 * 375: Serial1.print("\e[8;1H\e[K"); Serial1.print(static_cast(s_display_buffer[1])); break; - case 7 * 750: + case 7 * 375: Serial1.print("\e[9;1H\e[K"); Serial1.print(static_cast(s_display_buffer[2])); break; - case 8 * 750: + case 8 * 375: Serial1.print("\e[10;1H\e[K"); Serial1.print(static_cast(s_display_buffer[3])); break; - case 9 * 750: + case 9 * 375: Serial1.print("\e[11;1H\e[K"); Serial1.print(static_cast(s_display_buffer[4])); break; - case 10 * 750: + case 10 * 375: Serial1.print("\e[12;1H\e[K"); Serial1.print(static_cast(s_display_buffer[5])); break; - case 11 * 750: + case 11 * 375: Serial1.print("\e[13;1H\e[K"); Serial1.print(static_cast(s_display_buffer[6])); break; - case 12 * 750: + case 12 * 375: Serial1.print("\e[14;1H\e[K"); Serial1.print(static_cast(s_display_buffer[7])); break; #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) - case 13 * 750: + case 13 * 375: Serial1.print("\e[16;1H\e[K"); Serial1.print(s_adc_control_value[0]); break; - case 14 * 750: + case 14 * 375: Serial1.print("\e[17;1H\e[K"); Serial1.print(s_adc_control_value[1]); break; - case 15 * 750: + case 15 * 375: Serial1.print("\e[18;1H\e[K"); Serial1.print(s_adc_control_value[2]); break; diff --git a/Digital-Synth-PRA32-U/pra32-u-synth.h b/Digital-Synth-PRA32-U/pra32-u-synth.h index e98bfc0..04f91fc 100644 --- a/Digital-Synth-PRA32-U/pra32-u-synth.h +++ b/Digital-Synth-PRA32-U/pra32-u-synth.h @@ -125,11 +125,7 @@ class PRA32_U_Synth { uint8_t m_program_number_to_write; uint8_t m_wr_prog_to_flash_cc_value; uint8_t m_sp_prog_chg_cc_values[8]; - -public: uint8_t m_current_controller_value_table[128]; - -private: uint8_t m_program_table[128][PROGRAM_NUMBER_MAX + 1]; volatile int32_t m_secondary_core_processing_argument; @@ -294,6 +290,10 @@ class PRA32_U_Synth { program_change(PROGRAM_NUMBER_DEFAULT); } + INLINE uint8_t current_controller_value(uint8_t control_number) { + return m_current_controller_value_table[control_number]; + } + /* INLINE */ void note_on(uint8_t note_number, uint8_t velocity) { if (m_note_on_total_count == 255) { return; From 81aa3532d9426a9466a3bdba4ff5aef5a54656c5 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 09:34:44 +0900 Subject: [PATCH 026/106] Implement panel functions (10) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 95 +++++++++++-------- 1 file changed, 54 insertions(+), 41 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index bf61d3a..2ba1cc6 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -6,6 +6,7 @@ static volatile uint32_t s_adc_current_value[3]; static volatile uint32_t s_adc_control_value[3]; +static volatile uint8_t s_adc_control_target[3] = {FILTER_CUTOFF , FILTER_RESO , FILTER_EG_AMT }; static char s_display_buffer[8][21 + 1] = { " 5", @@ -80,34 +81,37 @@ INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { #endif // defined(PRA32_U_USE_CONTROL_PANEL) } +static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(int adc_number) { +#if defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) + return (127 - (s_adc_current_value[adc_number] >> 2)); +#else // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) + return (s_adc_current_value[adc_number] >> 2); +#endif // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) +} + +static INLINE void PRA32_U_ControlPanel_update_adc_control(int adc_number) { + uint32_t adc_control_value_candidate = PRA32_U_ControlPanel_adc_control_value_candidate(adc_number); + if (s_adc_control_value[adc_number] != adc_control_value_candidate) { + s_adc_control_value[adc_number] = adc_control_value_candidate; + g_synth.control_change(s_adc_control_target[adc_number], s_adc_control_value[adc_number]); + } +} + INLINE void PRA32_U_ControlPanel_update_control() { #if defined(PRA32_U_USE_CONTROL_PANEL) #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) static uint32_t s_initialize_counter = 0; - if (s_initialize_counter < 16) { + if (s_initialize_counter < 2400) { ++s_initialize_counter; -#if defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) - s_adc_control_value[0] = 127 - (s_adc_current_value[0] >> 2); - s_adc_control_value[1] = 127 - (s_adc_current_value[1] >> 2); - s_adc_control_value[2] = 127 - (s_adc_current_value[2] >> 2); -#else // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) - s_adc_control_value[0] = s_adc_current_value[0] >> 2; - s_adc_control_value[1] = s_adc_current_value[1] >> 2; - s_adc_control_value[2] = s_adc_current_value[2] >> 2; -#endif // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) + s_adc_control_value[0] = PRA32_U_ControlPanel_adc_control_value_candidate(0); + s_adc_control_value[1] = PRA32_U_ControlPanel_adc_control_value_candidate(1); + s_adc_control_value[2] = PRA32_U_ControlPanel_adc_control_value_candidate(2); return; } -#if defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) - uint32_t adc_control_value_candidate = 127 - (s_adc_current_value[0] >> 2); -#else // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) - uint32_t adc_control_value_candidate = s_adc_current_value[0] >> 2; -#endif // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) - - if (s_adc_control_value[0] != adc_control_value_candidate) { - s_adc_control_value[0] = adc_control_value_candidate; - g_synth.control_change(FILTER_CUTOFF , s_adc_control_value[0]); - } + PRA32_U_ControlPanel_update_adc_control(0); + PRA32_U_ControlPanel_update_adc_control(1); + PRA32_U_ControlPanel_update_adc_control(2); #endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) #endif // defined(PRA32_U_USE_CONTROL_PANEL) } @@ -115,27 +119,36 @@ INLINE void PRA32_U_ControlPanel_update_control() { INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL) if (loop_counter == 0) { - char buff[4]; - - std::sprintf(buff, "%3u", g_synth.current_controller_value(FILTER_CUTOFF )); - s_display_buffer[3][ 2] = buff[0]; - s_display_buffer[3][ 3] = buff[1]; - s_display_buffer[3][ 4] = buff[2]; - - std::sprintf(buff, "%3u", g_synth.current_controller_value(FILTER_RESO )); - s_display_buffer[3][13] = buff[0]; - s_display_buffer[3][14] = buff[1]; - s_display_buffer[3][15] = buff[2]; - - std::sprintf(buff, "%3u", g_synth.current_controller_value(FILTER_EG_AMT )); - s_display_buffer[7][13] = buff[0]; - s_display_buffer[7][14] = buff[1]; - s_display_buffer[7][15] = buff[2]; - - std::sprintf(buff, "%+3d", static_cast(g_synth.current_controller_value(FILTER_EG_AMT )) - 64); - s_display_buffer[7][17] = buff[0]; - s_display_buffer[7][18] = buff[1]; - s_display_buffer[7][19] = buff[2]; + char buff[6]; + + uint8_t adc_control_target_0 = s_adc_control_target[0]; + if (adc_control_target_0 <= 127) { + std::sprintf(buff, "%3u", g_synth.current_controller_value(adc_control_target_0)); + s_display_buffer[3][ 2] = buff[0]; + s_display_buffer[3][ 3] = buff[1]; + s_display_buffer[3][ 4] = buff[2]; + } + + uint8_t adc_control_target_1 = s_adc_control_target[1]; + if (adc_control_target_1 <= 127) { + std::sprintf(buff, "%3u", g_synth.current_controller_value(adc_control_target_1)); + s_display_buffer[3][13] = buff[0]; + s_display_buffer[3][14] = buff[1]; + s_display_buffer[3][15] = buff[2]; + } + + uint8_t adc_control_target_2 = s_adc_control_target[2]; + if (adc_control_target_2 <= 127) { + std::sprintf(buff, "%3u", g_synth.current_controller_value(adc_control_target_2)); + s_display_buffer[7][13] = buff[0]; + s_display_buffer[7][14] = buff[1]; + s_display_buffer[7][15] = buff[2]; + + std::sprintf(buff, "%+3d", static_cast(g_synth.current_controller_value(adc_control_target_2)) - 64); + s_display_buffer[7][17] = buff[0]; + s_display_buffer[7][18] = buff[1]; + s_display_buffer[7][19] = buff[2]; + } } #endif // defined(PRA32_U_USE_CONTROL_PANEL) } From d09da06d30aea6f0dc891e74c44ccf2e0a8679fa Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 09:53:15 +0900 Subject: [PATCH 027/106] Implement panel functions (11) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 2ba1cc6..36abea9 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -81,7 +81,7 @@ INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { #endif // defined(PRA32_U_USE_CONTROL_PANEL) } -static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(int adc_number) { +static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t adc_number) { #if defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) return (127 - (s_adc_current_value[adc_number] >> 2)); #else // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) @@ -89,12 +89,15 @@ static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(int adc_n #endif // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) } -static INLINE void PRA32_U_ControlPanel_update_adc_control(int adc_number) { +static INLINE boolean PRA32_U_ControlPanel_update_adc_control(uint32_t adc_number) { uint32_t adc_control_value_candidate = PRA32_U_ControlPanel_adc_control_value_candidate(adc_number); if (s_adc_control_value[adc_number] != adc_control_value_candidate) { s_adc_control_value[adc_number] = adc_control_value_candidate; g_synth.control_change(s_adc_control_target[adc_number], s_adc_control_value[adc_number]); + return true; } + + return false; } INLINE void PRA32_U_ControlPanel_update_control() { @@ -109,9 +112,20 @@ INLINE void PRA32_U_ControlPanel_update_control() { return; } - PRA32_U_ControlPanel_update_adc_control(0); - PRA32_U_ControlPanel_update_adc_control(1); - PRA32_U_ControlPanel_update_adc_control(2); + static uint32_t s_adc_number_to_check = 0; + + boolean updated = PRA32_U_ControlPanel_update_adc_control(s_adc_number_to_check); + s_adc_number_to_check = (s_adc_number_to_check + 1) % 3; + + if (updated == false) { + updated = PRA32_U_ControlPanel_update_adc_control(s_adc_number_to_check); + s_adc_number_to_check = (s_adc_number_to_check + 1) % 3; + + if (updated == false) { + updated = PRA32_U_ControlPanel_update_adc_control(s_adc_number_to_check); + s_adc_number_to_check = (s_adc_number_to_check + 1) % 3; + } + } #endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) #endif // defined(PRA32_U_USE_CONTROL_PANEL) } From f277f40e46e643e2395aaca15a7ab96e17fec3d8 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 10:27:04 +0900 Subject: [PATCH 028/106] Implement panel functions (12) --- Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino | 2 +- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 3863e00..bd2d36f 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -42,7 +42,7 @@ //////////////////////////////////////////////////////////////// -#define PRA32_U_USE_CONTROL_PANEL +#define PRA32_U_USE_CONTROL_PANEL // Experimental #define PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT // ADC0, ADC1, ADC2 #define PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT (true) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 36abea9..cc2c61b 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -2,6 +2,8 @@ #include "pra32-u-common.h" +#include + #include static volatile uint32_t s_adc_current_value[3]; @@ -21,12 +23,27 @@ static char s_display_buffer[8][21 + 1] = { INLINE void PRA32_U_ControlPanel_setup() { #if defined(PRA32_U_USE_CONTROL_PANEL) + #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) adc_init(); adc_gpio_init(26); adc_gpio_init(27); adc_gpio_init(28); #endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) + +#if defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) + Wire1.setSDA(6); + Wire1.setSCL(7); + Wire1.begin(); + + Wire1.beginTransmission(0x3C); + Wire1.write(0x00); + Wire1.write(0x8D); + Wire1.write(0x14); + Wire1.write(0xAF); + Wire1.endTransmission(); +#endif // defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) + #endif // defined(PRA32_U_USE_CONTROL_PANEL) } From 7062a7c042b9937cf5715567cc75e925f6746b9c Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 12:51:33 +0900 Subject: [PATCH 029/106] Implement panel functions (13) --- .../pra32-u-control-panel-font-table.h | 772 ++++++++++++++++++ Digital-Synth-PRA32-U/pra32-u-control-panel.h | 1 + 2 files changed, 773 insertions(+) create mode 100644 Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h new file mode 100644 index 0000000..4d1373f --- /dev/null +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h @@ -0,0 +1,772 @@ +#pragma once + +uint8_t g_font_table[128][6] = { + 0b01111111, + 0b01111111, + 0b01111111, + 0b01111111, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01111111, + 0b01111111, + 0b01111111, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b00010100, + 0b01111111, + 0b00010100, + 0b01111111, + 0b00010100, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b00001000, + 0b00001000, + 0b00111110, + 0b00001000, + 0b00001000, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b00001000, + 0b00001000, + 0b00001000, + 0b00001000, + 0b00001000, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b00100000, + 0b00010000, + 0b00001000, + 0b00000100, + 0b00000010, + 0b00000000, + 0b00111110, + 0b01000001, + 0b01000001, + 0b01000001, + 0b00111110, + 0b00000000, + 0b00000000, + 0b01000010, + 0b01111111, + 0b01000000, + 0b00000000, + 0b00000000, + 0b01000010, + 0b01100001, + 0b01010001, + 0b01001001, + 0b01000110, + 0b00000000, + 0b00100010, + 0b01000001, + 0b01001001, + 0b01001001, + 0b00110110, + 0b00000000, + 0b00011000, + 0b00010100, + 0b00010010, + 0b01111111, + 0b00010000, + 0b00000000, + 0b00100111, + 0b01000101, + 0b01000101, + 0b01000101, + 0b00111001, + 0b00000000, + 0b00111100, + 0b01001010, + 0b01001001, + 0b01001001, + 0b00110000, + 0b00000000, + 0b00000011, + 0b00000001, + 0b01110001, + 0b00001101, + 0b00000011, + 0b00000000, + 0b00110110, + 0b01001001, + 0b01001001, + 0b01001001, + 0b00110110, + 0b00000000, + 0b00000110, + 0b01001001, + 0b01001001, + 0b00101001, + 0b00011110, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00110110, + 0b00110110, + 0b00000000, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b00000000, + 0b00001000, + 0b00010100, + 0b00100010, + 0b01000001, + 0b00000000, + 0b00010100, + 0b00010100, + 0b00010100, + 0b00010100, + 0b00010100, + 0b00000000, + 0b01000001, + 0b00100010, + 0b00010100, + 0b00001000, + 0b00000000, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01111111, + 0b01111111, + 0b01111111, + 0b01111111, + 0b00000000, + 0b01111110, + 0b00010001, + 0b00010001, + 0b00010001, + 0b01111110, + 0b00000000, + 0b01111111, + 0b01001001, + 0b01001001, + 0b01001001, + 0b00110110, + 0b00000000, + 0b00111110, + 0b01000001, + 0b01000001, + 0b01000001, + 0b00100010, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b00100010, + 0b00011100, + 0b00000000, + 0b01111111, + 0b01001001, + 0b01001001, + 0b01001001, + 0b01000001, + 0b00000000, + 0b01111111, + 0b00001001, + 0b00001001, + 0b00001001, + 0b00000001, + 0b00000000, + 0b00111110, + 0b01000001, + 0b01001001, + 0b01001001, + 0b00111010, + 0b00000000, + 0b01111111, + 0b00001000, + 0b00001000, + 0b00001000, + 0b01111111, + 0b00000000, + 0b00000000, + 0b01000001, + 0b01111111, + 0b01000001, + 0b00000000, + 0b00000000, + 0b00100000, + 0b01000000, + 0b01000001, + 0b00111111, + 0b00000001, + 0b00000000, + 0b01111111, + 0b00001000, + 0b00010100, + 0b00100010, + 0b01000001, + 0b00000000, + 0b01111111, + 0b01000000, + 0b01000000, + 0b01000000, + 0b01000000, + 0b00000000, + 0b01111111, + 0b00000010, + 0b00001100, + 0b00000010, + 0b01111111, + 0b00000000, + 0b01111111, + 0b00000100, + 0b00001000, + 0b00010000, + 0b01111111, + 0b00000000, + 0b00111110, + 0b01000001, + 0b01000001, + 0b01000001, + 0b00111110, + 0b00000000, + 0b01111111, + 0b00001001, + 0b00001001, + 0b00001001, + 0b00000110, + 0b00000000, + 0b00111110, + 0b01000001, + 0b01010001, + 0b00100001, + 0b01011110, + 0b00000000, + 0b01111111, + 0b00001001, + 0b00011001, + 0b00101001, + 0b01000110, + 0b00000000, + 0b00100110, + 0b01001001, + 0b01001001, + 0b01001001, + 0b00110010, + 0b00000000, + 0b00000001, + 0b00000001, + 0b01111111, + 0b00000001, + 0b00000001, + 0b00000000, + 0b00111111, + 0b01000000, + 0b01000000, + 0b01000000, + 0b00111111, + 0b00000000, + 0b00011111, + 0b00100000, + 0b01000000, + 0b00100000, + 0b00011111, + 0b00000000, + 0b00111111, + 0b01000000, + 0b00111100, + 0b01000000, + 0b00111111, + 0b00000000, + 0b01100011, + 0b00010100, + 0b00001000, + 0b00010100, + 0b01100011, + 0b00000000, + 0b00000011, + 0b00000100, + 0b01111000, + 0b00000100, + 0b00000011, + 0b00000000, + 0b01100001, + 0b01010001, + 0b01001001, + 0b01000101, + 0b01000011, + 0b00000000, + 0b00000000, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b00000000, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01111111, + 0b01111111, + 0b01111111, + 0b01111111, + 0b00000000, + 0b00100000, + 0b01010100, + 0b01010100, + 0b01010100, + 0b01111000, + 0b00000000, + 0b01111111, + 0b00101000, + 0b01000100, + 0b01000100, + 0b00111000, + 0b00000000, + 0b00111000, + 0b01000100, + 0b01000100, + 0b01000100, + 0b00101000, + 0b00000000, + 0b00111000, + 0b01000100, + 0b01000100, + 0b00101000, + 0b01111111, + 0b00000000, + 0b00111000, + 0b01010100, + 0b01010100, + 0b01010100, + 0b00011000, + 0b00000000, + 0b00001000, + 0b00001000, + 0b01111110, + 0b00001001, + 0b00001001, + 0b00000000, + 0b00001000, + 0b01010100, + 0b01010100, + 0b01010100, + 0b00111100, + 0b00000000, + 0b01111111, + 0b00001000, + 0b00000100, + 0b00000100, + 0b01111000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b01111101, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00100000, + 0b01000000, + 0b01000100, + 0b00111101, + 0b00000000, + 0b00000000, + 0b00000000, + 0b01111111, + 0b00010000, + 0b00101000, + 0b01000100, + 0b00000000, + 0b00000000, + 0b01000001, + 0b01111111, + 0b01000000, + 0b00000000, + 0b00000000, + 0b01111100, + 0b00000100, + 0b01111000, + 0b00000100, + 0b01111000, + 0b00000000, + 0b01111100, + 0b00001000, + 0b00000100, + 0b00000100, + 0b01111000, + 0b00000000, + 0b00111000, + 0b01000100, + 0b01000100, + 0b01000100, + 0b00111000, + 0b00000000, + 0b01111100, + 0b00010100, + 0b00010100, + 0b00010100, + 0b00001000, + 0b00000000, + 0b00001000, + 0b00010100, + 0b00010100, + 0b00010100, + 0b01111100, + 0b00000000, + 0b01111100, + 0b00001000, + 0b00000100, + 0b00000100, + 0b00001000, + 0b00000000, + 0b01001000, + 0b01010100, + 0b01010100, + 0b01010100, + 0b00100100, + 0b00000000, + 0b00000100, + 0b00000100, + 0b00111111, + 0b01000100, + 0b01000100, + 0b00000000, + 0b00111100, + 0b01000000, + 0b01000000, + 0b00100000, + 0b01111100, + 0b00000000, + 0b00011100, + 0b00100000, + 0b01000000, + 0b00100000, + 0b00011100, + 0b00000000, + 0b00111100, + 0b01000000, + 0b00111000, + 0b01000000, + 0b00111100, + 0b00000000, + 0b01000100, + 0b00101000, + 0b00010000, + 0b00101000, + 0b01000100, + 0b00000000, + 0b00001100, + 0b01010000, + 0b01010000, + 0b01010000, + 0b00111100, + 0b00000000, + 0b01000100, + 0b01100100, + 0b01010100, + 0b01001100, + 0b01000100, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, + 0b01111111, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111, + 0b00000000, +}; diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index cc2c61b..1ca9bdd 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -1,6 +1,7 @@ #pragma once #include "pra32-u-common.h" +#include "pra32-u-control-panel-font-table.h" #include From 105db235c282bf2fe2b2674958ade4b0bc4de3ec Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 13:27:04 +0900 Subject: [PATCH 030/106] Implement panel functions (14) --- .../Digital-Synth-PRA32-U.ino | 11 +++++--- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 27 +++++++++---------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index bd2d36f..1c3ad6a 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -42,12 +42,15 @@ //////////////////////////////////////////////////////////////// -#define PRA32_U_USE_CONTROL_PANEL // Experimental +#define PRA32_U_USE_CONTROL_PANEL // Experimental -#define PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT // ADC0, ADC1, ADC2 -#define PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT (true) +#define PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT // ADC0, ADC1, ADC2 +#define PRA32_U_CONTROL_PANEL_ANALOG_INPUT_REVERSED (true) -#define PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY // I2C1 (SSD1306) +#define PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY // I2C1 (SSD1306) +#define PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE (i2c1) +#define PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_SDA_PIN (6) +#define PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_SCL_PIN (7) //////////////////////////////////////////////////////////////// diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 1ca9bdd..010a22d 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -3,7 +3,7 @@ #include "pra32-u-common.h" #include "pra32-u-control-panel-font-table.h" -#include +#include "hardware/i2c.h" #include @@ -33,16 +33,15 @@ INLINE void PRA32_U_ControlPanel_setup() { #endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) #if defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) - Wire1.setSDA(6); - Wire1.setSCL(7); - Wire1.begin(); - - Wire1.beginTransmission(0x3C); - Wire1.write(0x00); - Wire1.write(0x8D); - Wire1.write(0x14); - Wire1.write(0xAF); - Wire1.endTransmission(); + i2c_init(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 400 * 1000); + i2c_set_slave_mode(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, false, 0); + gpio_set_function(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_SDA_PIN, GPIO_FUNC_I2C); + gpio_pull_up(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_SDA_PIN); + gpio_set_function(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_SCL_PIN, GPIO_FUNC_I2C); + gpio_pull_up(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_SCL_PIN); + + uint8_t send_data[] = {0x00, 0x8D, 0x14, 0xAF}; + i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, send_data, 4, false); #endif // defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) #endif // defined(PRA32_U_USE_CONTROL_PANEL) @@ -100,11 +99,11 @@ INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { } static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t adc_number) { -#if defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) +#if defined(PRA32_U_CONTROL_PANEL_ANALOG_INPUT_REVERSED) return (127 - (s_adc_current_value[adc_number] >> 2)); -#else // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) +#else // defined(PRA32_U_CONTROL_PANEL_ANALOG_INPUT_REVERSED) return (s_adc_current_value[adc_number] >> 2); -#endif // defined(PRA32_U_CONTROL_PANEL_REVERSE_ANALOG_INPUT) +#endif // defined(PRA32_U_CONTROL_PANEL_ANALOG_INPUT_REVERSED) } static INLINE boolean PRA32_U_ControlPanel_update_adc_control(uint32_t adc_number) { From 0b935077d3b3325c432475ea186d6d7bc4755274 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 17:26:57 +0900 Subject: [PATCH 031/106] Implement panel functions (15) --- .../Digital-Synth-PRA32-U.ino | 5 +-- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 36 +++++++++++++++++-- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 1c3ad6a..697940a 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -110,15 +110,16 @@ void __not_in_flash_func(loop1)() { if (processed) { static uint32_t s_loop_counter = 0; s_loop_counter++; - if (s_loop_counter >= 16 * 375) { + if (s_loop_counter >= 16 * 375 * 8) { s_loop_counter = 0; } PRA32_U_ControlPanel_update_input(s_loop_counter); PRA32_U_ControlPanel_update_display_buffer(s_loop_counter); + PRA32_U_ControlPanel_update_display(s_loop_counter); #if defined(PRA32_U_USE_DEBUG_PRINT) - switch (s_loop_counter) { + switch (s_loop_counter >> 3) { case 1 * 375: Serial1.print("\e[1;1H\e[K"); Serial1.print(s_debug_measurement_elapsed1_us); diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 010a22d..c7da67d 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -6,6 +6,7 @@ #include "hardware/i2c.h" #include +#include static volatile uint32_t s_adc_current_value[3]; static volatile uint32_t s_adc_control_value[3]; @@ -40,8 +41,8 @@ INLINE void PRA32_U_ControlPanel_setup() { gpio_set_function(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_SCL_PIN, GPIO_FUNC_I2C); gpio_pull_up(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_SCL_PIN); - uint8_t send_data[] = {0x00, 0x8D, 0x14, 0xAF}; - i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, send_data, 4, false); + uint8_t commands[] = {0x00, 0x81, 0xFF, 0xA1, 0xC8, 0x8D, 0x14, 0xAF}; + i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, commands, sizeof(commands), false); #endif // defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) #endif // defined(PRA32_U_USE_CONTROL_PANEL) @@ -184,10 +185,39 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { #endif // defined(PRA32_U_USE_CONTROL_PANEL) } +static INLINE void PRA32_U_ControlPanel_draw_character(uint8_t x, uint8_t y, uint8_t c) { + uint8_t commands[] = {0x00, static_cast(0xB0 + y), + static_cast(0x10 + ((x * 6) >> 4)), + static_cast(0x00 + ((x * 6) & 0x0F))}; + i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, commands, sizeof(commands), false); + + uint8_t data[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + std::memcpy(&data[1], g_font_table[c], 6); + i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, data, sizeof(data), false); +} + +INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { +#if defined(PRA32_U_USE_CONTROL_PANEL) +#if defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) + if ((loop_counter & 0x3F) == 0x00) { + static uint32_t s_display_draw_counter = 0; + if (s_display_draw_counter >= 8 * 21) { + s_display_draw_counter = 0; + } + s_display_draw_counter++; + + uint8_t x = s_display_draw_counter % 21; + uint8_t y = s_display_draw_counter / 21; + PRA32_U_ControlPanel_draw_character(x, y, s_display_buffer[y][x]); + } +#endif // defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) +#endif // defined(PRA32_U_USE_CONTROL_PANEL) +} + INLINE void PRA32_U_ControlPanel_debug_print(uint32_t loop_counter) { #if defined(PRA32_U_USE_DEBUG_PRINT) #if defined(PRA32_U_USE_CONTROL_PANEL) - switch (loop_counter) { + switch (loop_counter >> 3) { case 5 * 375: Serial1.print("\e[7;1H\e[K"); Serial1.print(static_cast(s_display_buffer[0])); From cf46865568b7b2997d66e7ab6a9d3984a419b891 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 18:38:36 +0900 Subject: [PATCH 032/106] Implement panel functions (16) --- Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino | 4 ++-- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 697940a..346952d 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -110,7 +110,7 @@ void __not_in_flash_func(loop1)() { if (processed) { static uint32_t s_loop_counter = 0; s_loop_counter++; - if (s_loop_counter >= 16 * 375 * 8) { + if (s_loop_counter >= 16 * 375) { s_loop_counter = 0; } @@ -119,7 +119,7 @@ void __not_in_flash_func(loop1)() { PRA32_U_ControlPanel_update_display(s_loop_counter); #if defined(PRA32_U_USE_DEBUG_PRINT) - switch (s_loop_counter >> 3) { + switch (s_loop_counter) { case 1 * 375: Serial1.print("\e[1;1H\e[K"); Serial1.print(s_debug_measurement_elapsed1_us); diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index c7da67d..808a3d3 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -23,6 +23,8 @@ static char s_display_buffer[8][21 + 1] = { " C [ ]", }; +static uint32_t s_display_draw_counter = 0; + INLINE void PRA32_U_ControlPanel_setup() { #if defined(PRA32_U_USE_CONTROL_PANEL) @@ -185,12 +187,14 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { #endif // defined(PRA32_U_USE_CONTROL_PANEL) } -static INLINE void PRA32_U_ControlPanel_draw_character(uint8_t x, uint8_t y, uint8_t c) { +static INLINE void PRA32_U_ControlPanel_set_draw_position(uint8_t x, uint8_t y) { uint8_t commands[] = {0x00, static_cast(0xB0 + y), static_cast(0x10 + ((x * 6) >> 4)), static_cast(0x00 + ((x * 6) & 0x0F))}; i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, commands, sizeof(commands), false); +} +static INLINE void PRA32_U_ControlPanel_draw_character(uint8_t c) { uint8_t data[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; std::memcpy(&data[1], g_font_table[c], 6); i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, data, sizeof(data), false); @@ -199,8 +203,7 @@ static INLINE void PRA32_U_ControlPanel_draw_character(uint8_t x, uint8_t y, uin INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL) #if defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) - if ((loop_counter & 0x3F) == 0x00) { - static uint32_t s_display_draw_counter = 0; + if ((loop_counter & 0x7F) == 0x00) { if (s_display_draw_counter >= 8 * 21) { s_display_draw_counter = 0; } @@ -208,7 +211,11 @@ INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { uint8_t x = s_display_draw_counter % 21; uint8_t y = s_display_draw_counter / 21; - PRA32_U_ControlPanel_draw_character(x, y, s_display_buffer[y][x]); + PRA32_U_ControlPanel_set_draw_position(x, y); + } else if ((loop_counter & 0x7F) == 0x40) { + uint8_t x = s_display_draw_counter % 21; + uint8_t y = s_display_draw_counter / 21; + PRA32_U_ControlPanel_draw_character(s_display_buffer[y][x]); } #endif // defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) #endif // defined(PRA32_U_USE_CONTROL_PANEL) @@ -217,7 +224,7 @@ INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { INLINE void PRA32_U_ControlPanel_debug_print(uint32_t loop_counter) { #if defined(PRA32_U_USE_DEBUG_PRINT) #if defined(PRA32_U_USE_CONTROL_PANEL) - switch (loop_counter >> 3) { + switch (loop_counter) { case 5 * 375: Serial1.print("\e[7;1H\e[K"); Serial1.print(static_cast(s_display_buffer[0])); From 4a72845eaaf76a7f9bb076ba62d7440a13ace679 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 18:57:57 +0900 Subject: [PATCH 033/106] Implement panel functions (17) --- .../Digital-Synth-PRA32-U.ino | 2 + Digital-Synth-PRA32-U/pra32-u-control-panel.h | 92 ++++++++++++------- 2 files changed, 59 insertions(+), 35 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 346952d..2e1abb0 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -226,6 +226,8 @@ void __not_in_flash_func(setup)() { #endif // defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) g_synth.initialize(); + + delay(100); } void __not_in_flash_func(loop)() { diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 808a3d3..deedf04 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -13,7 +13,7 @@ static volatile uint32_t s_adc_control_value[3]; static volatile uint8_t s_adc_control_target[3] = {FILTER_CUTOFF , FILTER_RESO , FILTER_EG_AMT }; static char s_display_buffer[8][21 + 1] = { - " 5", + " ", "Filter Filter ", "Cutoff Resonance ", "A B ", @@ -25,6 +25,38 @@ static char s_display_buffer[8][21 + 1] = { static uint32_t s_display_draw_counter = 0; +static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t adc_number) { +#if defined(PRA32_U_CONTROL_PANEL_ANALOG_INPUT_REVERSED) + return (127 - (s_adc_current_value[adc_number] >> 2)); +#else // defined(PRA32_U_CONTROL_PANEL_ANALOG_INPUT_REVERSED) + return (s_adc_current_value[adc_number] >> 2); +#endif // defined(PRA32_U_CONTROL_PANEL_ANALOG_INPUT_REVERSED) +} + +static INLINE boolean PRA32_U_ControlPanel_update_adc_control(uint32_t adc_number) { + uint32_t adc_control_value_candidate = PRA32_U_ControlPanel_adc_control_value_candidate(adc_number); + if (s_adc_control_value[adc_number] != adc_control_value_candidate) { + s_adc_control_value[adc_number] = adc_control_value_candidate; + g_synth.control_change(s_adc_control_target[adc_number], s_adc_control_value[adc_number]); + return true; + } + + return false; +} + +static INLINE void PRA32_U_ControlPanel_set_draw_position(uint8_t x, uint8_t y) { + uint8_t commands[] = {0x00, static_cast(0xB0 + y), + static_cast(0x10 + ((x * 6) >> 4)), + static_cast(0x00 + ((x * 6) & 0x0F))}; + i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, commands, sizeof(commands), false); +} + +static INLINE void PRA32_U_ControlPanel_draw_character(uint8_t c) { + uint8_t data[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + std::memcpy(&data[1], g_font_table[c], 6); + i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, data, sizeof(data), false); +} + INLINE void PRA32_U_ControlPanel_setup() { #if defined(PRA32_U_USE_CONTROL_PANEL) @@ -43,8 +75,24 @@ INLINE void PRA32_U_ControlPanel_setup() { gpio_set_function(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_SCL_PIN, GPIO_FUNC_I2C); gpio_pull_up(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_SCL_PIN); - uint8_t commands[] = {0x00, 0x81, 0xFF, 0xA1, 0xC8, 0x8D, 0x14, 0xAF}; - i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, commands, sizeof(commands), false); + uint8_t commands_init_0[] = {0x00, 0x81, 0xFF, 0xA1, 0xC8, 0x8D, 0x14}; + i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, commands_init_0, sizeof(commands_init_0), false); + + for (uint8_t y = 0; y <= 7; ++y) { + for (uint8_t x = 0; x <= 20; ++x) { + PRA32_U_ControlPanel_set_draw_position(x, y); + PRA32_U_ControlPanel_draw_character(s_display_buffer[y][x]); + } + + uint8_t commands[] = {0x00, static_cast(0xB0 + y), 0x17, 0x0E}; + i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, commands, sizeof(commands), false); + + uint8_t data[] = {0x40, 0x00, 0x00}; + i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, data, sizeof(data), false); + } + + uint8_t commands_init_1[] = {0x00, 0xAF}; + i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, commands_init_1, sizeof(commands_init_1), false); #endif // defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) #endif // defined(PRA32_U_USE_CONTROL_PANEL) @@ -52,6 +100,7 @@ INLINE void PRA32_U_ControlPanel_setup() { INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL) + #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) switch (loop_counter & 0x3F) { case 0x10: @@ -98,30 +147,13 @@ INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { break; } #endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) -#endif // defined(PRA32_U_USE_CONTROL_PANEL) -} - -static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t adc_number) { -#if defined(PRA32_U_CONTROL_PANEL_ANALOG_INPUT_REVERSED) - return (127 - (s_adc_current_value[adc_number] >> 2)); -#else // defined(PRA32_U_CONTROL_PANEL_ANALOG_INPUT_REVERSED) - return (s_adc_current_value[adc_number] >> 2); -#endif // defined(PRA32_U_CONTROL_PANEL_ANALOG_INPUT_REVERSED) -} - -static INLINE boolean PRA32_U_ControlPanel_update_adc_control(uint32_t adc_number) { - uint32_t adc_control_value_candidate = PRA32_U_ControlPanel_adc_control_value_candidate(adc_number); - if (s_adc_control_value[adc_number] != adc_control_value_candidate) { - s_adc_control_value[adc_number] = adc_control_value_candidate; - g_synth.control_change(s_adc_control_target[adc_number], s_adc_control_value[adc_number]); - return true; - } - return false; +#endif // defined(PRA32_U_USE_CONTROL_PANEL) } INLINE void PRA32_U_ControlPanel_update_control() { #if defined(PRA32_U_USE_CONTROL_PANEL) + #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) static uint32_t s_initialize_counter = 0; if (s_initialize_counter < 2400) { @@ -147,6 +179,7 @@ INLINE void PRA32_U_ControlPanel_update_control() { } } #endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) + #endif // defined(PRA32_U_USE_CONTROL_PANEL) } @@ -187,21 +220,9 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { #endif // defined(PRA32_U_USE_CONTROL_PANEL) } -static INLINE void PRA32_U_ControlPanel_set_draw_position(uint8_t x, uint8_t y) { - uint8_t commands[] = {0x00, static_cast(0xB0 + y), - static_cast(0x10 + ((x * 6) >> 4)), - static_cast(0x00 + ((x * 6) & 0x0F))}; - i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, commands, sizeof(commands), false); -} - -static INLINE void PRA32_U_ControlPanel_draw_character(uint8_t c) { - uint8_t data[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - std::memcpy(&data[1], g_font_table[c], 6); - i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, data, sizeof(data), false); -} - INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL) + #if defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) if ((loop_counter & 0x7F) == 0x00) { if (s_display_draw_counter >= 8 * 21) { @@ -218,6 +239,7 @@ INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { PRA32_U_ControlPanel_draw_character(s_display_buffer[y][x]); } #endif // defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) + #endif // defined(PRA32_U_USE_CONTROL_PANEL) } From 2c6d93f2baa287459ef5c3c436d96c38909523c0 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 19:08:30 +0900 Subject: [PATCH 034/106] Implement panel functions (18) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index deedf04..03f336f 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -225,10 +225,10 @@ INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) if ((loop_counter & 0x7F) == 0x00) { + ++s_display_draw_counter; if (s_display_draw_counter >= 8 * 21) { s_display_draw_counter = 0; } - s_display_draw_counter++; uint8_t x = s_display_draw_counter % 21; uint8_t y = s_display_draw_counter / 21; From 37df0be9c49dab6478498d452d84905721ed5cbe Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 19:26:57 +0900 Subject: [PATCH 035/106] Implement panel functions (19) --- .../Digital-Synth-PRA32-U.ino | 21 ++++++----- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 37 +++++++++++-------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 2e1abb0..ed72cfb 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -42,15 +42,18 @@ //////////////////////////////////////////////////////////////// -#define PRA32_U_USE_CONTROL_PANEL // Experimental - -#define PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT // ADC0, ADC1, ADC2 -#define PRA32_U_CONTROL_PANEL_ANALOG_INPUT_REVERSED (true) - -#define PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY // I2C1 (SSD1306) -#define PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE (i2c1) -#define PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_SDA_PIN (6) -#define PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_SCL_PIN (7) +#define PRA32_U_USE_CONTROL_PANEL // Experimental + +#define PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT // Use ADC0, ADC1, and ADC2 +#define PRA32_U_ANALOG_INPUT_REVERSED (true) + +#define PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY // Use SSD1306 monochrome 128x64 OLED +#define PRA32_U_OLED_DISPLAY_I2C (i2c1) +#define PRA32_U_OLED_DISPLAY_I2C_SDA_PIN (6) +#define PRA32_U_OLED_DISPLAY_I2C_SCL_PIN (7) +#define PRA32_U_OLED_DISPLAY_I2C_ADDRESS (0x3C) +#define PRA32_U_OLED_DISPLAY_CONTRAST (0xFF) +#define PRA32_U_OLED_DISPLAY_ROTATION (true) //////////////////////////////////////////////////////////////// diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 03f336f..3e8fa06 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -26,11 +26,11 @@ static char s_display_buffer[8][21 + 1] = { static uint32_t s_display_draw_counter = 0; static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t adc_number) { -#if defined(PRA32_U_CONTROL_PANEL_ANALOG_INPUT_REVERSED) +#if defined(PRA32_U_ANALOG_INPUT_REVERSED) return (127 - (s_adc_current_value[adc_number] >> 2)); -#else // defined(PRA32_U_CONTROL_PANEL_ANALOG_INPUT_REVERSED) +#else // defined(PRA32_U_ANALOG_INPUT_REVERSED) return (s_adc_current_value[adc_number] >> 2); -#endif // defined(PRA32_U_CONTROL_PANEL_ANALOG_INPUT_REVERSED) +#endif // defined(PRA32_U_ANALOG_INPUT_REVERSED) } static INLINE boolean PRA32_U_ControlPanel_update_adc_control(uint32_t adc_number) { @@ -48,13 +48,13 @@ static INLINE void PRA32_U_ControlPanel_set_draw_position(uint8_t x, uint8_t y) uint8_t commands[] = {0x00, static_cast(0xB0 + y), static_cast(0x10 + ((x * 6) >> 4)), static_cast(0x00 + ((x * 6) & 0x0F))}; - i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, commands, sizeof(commands), false); + i2c_write_blocking(PRA32_U_OLED_DISPLAY_I2C, PRA32_U_OLED_DISPLAY_I2C_ADDRESS, commands, sizeof(commands), false); } static INLINE void PRA32_U_ControlPanel_draw_character(uint8_t c) { uint8_t data[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; std::memcpy(&data[1], g_font_table[c], 6); - i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, data, sizeof(data), false); + i2c_write_blocking(PRA32_U_OLED_DISPLAY_I2C, PRA32_U_OLED_DISPLAY_I2C_ADDRESS, data, sizeof(data), false); } INLINE void PRA32_U_ControlPanel_setup() { @@ -68,15 +68,20 @@ INLINE void PRA32_U_ControlPanel_setup() { #endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) #if defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) - i2c_init(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 400 * 1000); - i2c_set_slave_mode(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, false, 0); - gpio_set_function(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_SDA_PIN, GPIO_FUNC_I2C); - gpio_pull_up(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_SDA_PIN); - gpio_set_function(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_SCL_PIN, GPIO_FUNC_I2C); - gpio_pull_up(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_SCL_PIN); + i2c_init(PRA32_U_OLED_DISPLAY_I2C, 400 * 1000); + i2c_set_slave_mode(PRA32_U_OLED_DISPLAY_I2C, false, 0); + gpio_set_function(PRA32_U_OLED_DISPLAY_I2C_SDA_PIN, GPIO_FUNC_I2C); + gpio_pull_up(PRA32_U_OLED_DISPLAY_I2C_SDA_PIN); + gpio_set_function(PRA32_U_OLED_DISPLAY_I2C_SCL_PIN, GPIO_FUNC_I2C); + gpio_pull_up(PRA32_U_OLED_DISPLAY_I2C_SCL_PIN); + + uint8_t commands_init_0[] = {0x00, 0x81, PRA32_U_OLED_DISPLAY_CONTRAST, 0xA0, 0xC0, 0x8D, 0x14}; + if (PRA32_U_OLED_DISPLAY_ROTATION) { + commands_init_0[3] = 0xA1; + commands_init_0[4] = 0xC8; + } - uint8_t commands_init_0[] = {0x00, 0x81, 0xFF, 0xA1, 0xC8, 0x8D, 0x14}; - i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, commands_init_0, sizeof(commands_init_0), false); + i2c_write_blocking(PRA32_U_OLED_DISPLAY_I2C, PRA32_U_OLED_DISPLAY_I2C_ADDRESS, commands_init_0, sizeof(commands_init_0), false); for (uint8_t y = 0; y <= 7; ++y) { for (uint8_t x = 0; x <= 20; ++x) { @@ -85,14 +90,14 @@ INLINE void PRA32_U_ControlPanel_setup() { } uint8_t commands[] = {0x00, static_cast(0xB0 + y), 0x17, 0x0E}; - i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, commands, sizeof(commands), false); + i2c_write_blocking(PRA32_U_OLED_DISPLAY_I2C, PRA32_U_OLED_DISPLAY_I2C_ADDRESS, commands, sizeof(commands), false); uint8_t data[] = {0x40, 0x00, 0x00}; - i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, data, sizeof(data), false); + i2c_write_blocking(PRA32_U_OLED_DISPLAY_I2C, PRA32_U_OLED_DISPLAY_I2C_ADDRESS, data, sizeof(data), false); } uint8_t commands_init_1[] = {0x00, 0xAF}; - i2c_write_blocking(PRA32_U_CONTROL_PANEL_OLED_DISPLAY_I2C_DEVICE, 0x3C, commands_init_1, sizeof(commands_init_1), false); + i2c_write_blocking(PRA32_U_OLED_DISPLAY_I2C, PRA32_U_OLED_DISPLAY_I2C_ADDRESS, commands_init_1, sizeof(commands_init_1), false); #endif // defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) #endif // defined(PRA32_U_USE_CONTROL_PANEL) From 750add2e2ceae2504966476d6c01398011e59a9b Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 21:22:27 +0900 Subject: [PATCH 036/106] Implement panel functions (20) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 3e8fa06..54ba655 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -231,16 +231,16 @@ INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) if ((loop_counter & 0x7F) == 0x00) { ++s_display_draw_counter; - if (s_display_draw_counter >= 8 * 21) { + if (s_display_draw_counter >= 2 * 21) { s_display_draw_counter = 0; } uint8_t x = s_display_draw_counter % 21; - uint8_t y = s_display_draw_counter / 21; + uint8_t y = ((s_display_draw_counter < 21) * 4) + 3; PRA32_U_ControlPanel_set_draw_position(x, y); } else if ((loop_counter & 0x7F) == 0x40) { uint8_t x = s_display_draw_counter % 21; - uint8_t y = s_display_draw_counter / 21; + uint8_t y = ((s_display_draw_counter < 21) * 4) + 3; PRA32_U_ControlPanel_draw_character(s_display_buffer[y][x]); } #endif // defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) From 8633b561198158843d41b04dc8e1c7683fc27b17 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 21:30:57 +0900 Subject: [PATCH 037/106] Implement panel functions (21) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 54ba655..b30ef4d 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -190,7 +190,7 @@ INLINE void PRA32_U_ControlPanel_update_control() { INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL) - if (loop_counter == 0) { + if ((loop_counter & 0x7F) == 0x00) { char buff[6]; uint8_t adc_control_target_0 = s_adc_control_target[0]; From 66fb14f8080a0da35666b7dc3fd38ddd4679c72e Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 21:41:11 +0900 Subject: [PATCH 038/106] Implement panel functions (22) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index b30ef4d..d30ef34 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -129,9 +129,9 @@ INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { (adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read()) >> 6; - if (s_adc_current_value[1] > adc_average_value + 4) { + if (s_adc_current_value[1] >= adc_average_value + 4) { s_adc_current_value[1] = adc_average_value; - } else if (s_adc_current_value[1] + 4 < adc_average_value ) { + } else if (s_adc_current_value[1] + 4 <= adc_average_value ) { s_adc_current_value[1] = adc_average_value; } } @@ -143,9 +143,9 @@ INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { (adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read()) >> 6; - if (s_adc_current_value[2] > adc_average_value + 4) { + if (s_adc_current_value[2] >= adc_average_value + 4) { s_adc_current_value[2] = adc_average_value; - } else if (s_adc_current_value[2] + 4 < adc_average_value ) { + } else if (s_adc_current_value[2] + 4 <= adc_average_value ) { s_adc_current_value[2] = adc_average_value; } } @@ -231,16 +231,16 @@ INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) if ((loop_counter & 0x7F) == 0x00) { ++s_display_draw_counter; - if (s_display_draw_counter >= 2 * 21) { + if (s_display_draw_counter >= 31) { s_display_draw_counter = 0; } - uint8_t x = s_display_draw_counter % 21; - uint8_t y = ((s_display_draw_counter < 21) * 4) + 3; + uint8_t x = (s_display_draw_counter % 21) + ((s_display_draw_counter >= 21) * 11); + uint8_t y = ((s_display_draw_counter >= 21) * 4) + 3; PRA32_U_ControlPanel_set_draw_position(x, y); } else if ((loop_counter & 0x7F) == 0x40) { - uint8_t x = s_display_draw_counter % 21; - uint8_t y = ((s_display_draw_counter < 21) * 4) + 3; + uint8_t x = (s_display_draw_counter % 21) + ((s_display_draw_counter >= 21) * 11); + uint8_t y = ((s_display_draw_counter >= 21) * 4) + 3; PRA32_U_ControlPanel_draw_character(s_display_buffer[y][x]); } #endif // defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) From c5fed042716f0132de4800dbf363ef09c8034e40 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 21:52:44 +0900 Subject: [PATCH 039/106] Implement panel functions (23) --- .../Digital-Synth-PRA32-U.ino | 10 ++++---- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 25 +++++++++---------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index ed72cfb..63e1d8e 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -113,7 +113,7 @@ void __not_in_flash_func(loop1)() { if (processed) { static uint32_t s_loop_counter = 0; s_loop_counter++; - if (s_loop_counter >= 16 * 375) { + if (s_loop_counter >= 16 * 400) { s_loop_counter = 0; } @@ -123,19 +123,19 @@ void __not_in_flash_func(loop1)() { #if defined(PRA32_U_USE_DEBUG_PRINT) switch (s_loop_counter) { - case 1 * 375: + case 1 * 400: Serial1.print("\e[1;1H\e[K"); Serial1.print(s_debug_measurement_elapsed1_us); break; - case 2 * 375: + case 2 * 400: Serial1.print("\e[2;1H\e[K"); Serial1.print(s_debug_measurement_max1_us); break; - case 3 * 375: + case 3 * 400: Serial1.print("\e[4;1H\e[K"); Serial1.print(s_debug_measurement_elapsed0_us); break; - case 4 * 375: + case 4 * 400: Serial1.print("\e[5;1H\e[K"); Serial1.print(s_debug_measurement_max0_us); break; diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index d30ef34..5e694b4 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -23,8 +23,6 @@ static char s_display_buffer[8][21 + 1] = { " C [ ]", }; -static uint32_t s_display_draw_counter = 0; - static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t adc_number) { #if defined(PRA32_U_ANALOG_INPUT_REVERSED) return (127 - (s_adc_current_value[adc_number] >> 2)); @@ -229,6 +227,7 @@ INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL) #if defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) + static uint32_t s_display_draw_counter = 0; if ((loop_counter & 0x7F) == 0x00) { ++s_display_draw_counter; if (s_display_draw_counter >= 31) { @@ -252,48 +251,48 @@ INLINE void PRA32_U_ControlPanel_debug_print(uint32_t loop_counter) { #if defined(PRA32_U_USE_DEBUG_PRINT) #if defined(PRA32_U_USE_CONTROL_PANEL) switch (loop_counter) { - case 5 * 375: + case 5 * 400: Serial1.print("\e[7;1H\e[K"); Serial1.print(static_cast(s_display_buffer[0])); break; - case 6 * 375: + case 6 * 400: Serial1.print("\e[8;1H\e[K"); Serial1.print(static_cast(s_display_buffer[1])); break; - case 7 * 375: + case 7 * 400: Serial1.print("\e[9;1H\e[K"); Serial1.print(static_cast(s_display_buffer[2])); break; - case 8 * 375: + case 8 * 400: Serial1.print("\e[10;1H\e[K"); Serial1.print(static_cast(s_display_buffer[3])); break; - case 9 * 375: + case 9 * 400: Serial1.print("\e[11;1H\e[K"); Serial1.print(static_cast(s_display_buffer[4])); break; - case 10 * 375: + case 10 * 400: Serial1.print("\e[12;1H\e[K"); Serial1.print(static_cast(s_display_buffer[5])); break; - case 11 * 375: + case 11 * 400: Serial1.print("\e[13;1H\e[K"); Serial1.print(static_cast(s_display_buffer[6])); break; - case 12 * 375: + case 12 * 400: Serial1.print("\e[14;1H\e[K"); Serial1.print(static_cast(s_display_buffer[7])); break; #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) - case 13 * 375: + case 13 * 400: Serial1.print("\e[16;1H\e[K"); Serial1.print(s_adc_control_value[0]); break; - case 14 * 375: + case 14 * 400: Serial1.print("\e[17;1H\e[K"); Serial1.print(s_adc_control_value[1]); break; - case 15 * 375: + case 15 * 400: Serial1.print("\e[18;1H\e[K"); Serial1.print(s_adc_control_value[2]); break; From 46a0d720949359a887814f6283d7d0e96960dc67 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 22:00:32 +0900 Subject: [PATCH 040/106] Implement panel functions (24) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 5e694b4..5338abd 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -20,7 +20,7 @@ static char s_display_buffer[8][21 + 1] = { " ", " Filter ", " EG Amt ", - " C [ ]", + " C ", }; static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t adc_number) { @@ -228,7 +228,7 @@ INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) static uint32_t s_display_draw_counter = 0; - if ((loop_counter & 0x7F) == 0x00) { + if ((loop_counter & 0x7F) == 0x40) { ++s_display_draw_counter; if (s_display_draw_counter >= 31) { s_display_draw_counter = 0; @@ -237,7 +237,7 @@ INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { uint8_t x = (s_display_draw_counter % 21) + ((s_display_draw_counter >= 21) * 11); uint8_t y = ((s_display_draw_counter >= 21) * 4) + 3; PRA32_U_ControlPanel_set_draw_position(x, y); - } else if ((loop_counter & 0x7F) == 0x40) { + } else if ((loop_counter & 0x7F) == 0x00) { uint8_t x = (s_display_draw_counter % 21) + ((s_display_draw_counter >= 21) * 11); uint8_t y = ((s_display_draw_counter >= 21) * 4) + 3; PRA32_U_ControlPanel_draw_character(s_display_buffer[y][x]); From bc60aab940b4052e4f5da63f50086077bb61b45e Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 20 Mar 2024 22:18:43 +0900 Subject: [PATCH 041/106] Implement panel functions (25) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 43 ++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 5338abd..9bc551f 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -20,7 +20,7 @@ static char s_display_buffer[8][21 + 1] = { " ", " Filter ", " EG Amt ", - " C ", + " C [ ]", }; static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t adc_number) { @@ -193,7 +193,18 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { uint8_t adc_control_target_0 = s_adc_control_target[0]; if (adc_control_target_0 <= 127) { - std::sprintf(buff, "%3u", g_synth.current_controller_value(adc_control_target_0)); + uint8_t adc_control_value = s_adc_control_value[0]; + uint8_t current_controller_value = g_synth.current_controller_value(adc_control_target_0); + + if (adc_control_value < current_controller_value) { + s_display_buffer[3][ 1] = '<'; + } else if (adc_control_value > current_controller_value) { + s_display_buffer[3][ 1] = '>'; + } else { + s_display_buffer[3][ 1] = '='; + } + + std::sprintf(buff, "%3u", current_controller_value); s_display_buffer[3][ 2] = buff[0]; s_display_buffer[3][ 3] = buff[1]; s_display_buffer[3][ 4] = buff[2]; @@ -201,7 +212,18 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { uint8_t adc_control_target_1 = s_adc_control_target[1]; if (adc_control_target_1 <= 127) { - std::sprintf(buff, "%3u", g_synth.current_controller_value(adc_control_target_1)); + uint8_t adc_control_value = s_adc_control_value[1]; + uint8_t current_controller_value = g_synth.current_controller_value(adc_control_target_1); + + if (adc_control_value < current_controller_value) { + s_display_buffer[3][12] = '<'; + } else if (adc_control_value > current_controller_value) { + s_display_buffer[3][12] = '>'; + } else { + s_display_buffer[3][12] = '='; + } + + std::sprintf(buff, "%3u", current_controller_value); s_display_buffer[3][13] = buff[0]; s_display_buffer[3][14] = buff[1]; s_display_buffer[3][15] = buff[2]; @@ -209,12 +231,23 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { uint8_t adc_control_target_2 = s_adc_control_target[2]; if (adc_control_target_2 <= 127) { - std::sprintf(buff, "%3u", g_synth.current_controller_value(adc_control_target_2)); + uint8_t adc_control_value = s_adc_control_value[2]; + uint8_t current_controller_value = g_synth.current_controller_value(adc_control_target_2); + + if (adc_control_value < current_controller_value) { + s_display_buffer[7][12] = '<'; + } else if (adc_control_value > current_controller_value) { + s_display_buffer[7][12] = '>'; + } else { + s_display_buffer[7][12] = '='; + } + + std::sprintf(buff, "%3u", current_controller_value); s_display_buffer[7][13] = buff[0]; s_display_buffer[7][14] = buff[1]; s_display_buffer[7][15] = buff[2]; - std::sprintf(buff, "%+3d", static_cast(g_synth.current_controller_value(adc_control_target_2)) - 64); + std::sprintf(buff, "%+3d", static_cast(current_controller_value) - 64); s_display_buffer[7][17] = buff[0]; s_display_buffer[7][18] = buff[1]; s_display_buffer[7][19] = buff[2]; From cbe8642ffda6be62be03eaf45911650ece4571b7 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Thu, 21 Mar 2024 19:50:45 +0900 Subject: [PATCH 042/106] Implement panel functions (26) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 9bc551f..e947eca 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -102,6 +102,8 @@ INLINE void PRA32_U_ControlPanel_setup() { } INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { + static_cast(loop_counter); + #if defined(PRA32_U_USE_CONTROL_PANEL) #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) @@ -187,6 +189,8 @@ INLINE void PRA32_U_ControlPanel_update_control() { } INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { + static_cast(loop_counter); + #if defined(PRA32_U_USE_CONTROL_PANEL) if ((loop_counter & 0x7F) == 0x00) { char buff[6]; @@ -257,6 +261,8 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { } INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { + static_cast(loop_counter); + #if defined(PRA32_U_USE_CONTROL_PANEL) #if defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) @@ -281,6 +287,8 @@ INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { } INLINE void PRA32_U_ControlPanel_debug_print(uint32_t loop_counter) { + static_cast(loop_counter); + #if defined(PRA32_U_USE_DEBUG_PRINT) #if defined(PRA32_U_USE_CONTROL_PANEL) switch (loop_counter) { From 31d8e22cafe61ae2af097ba0617c5204a79c49b4 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 25 Mar 2024 20:18:25 +0900 Subject: [PATCH 043/106] Implement panel functions (27) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index e947eca..58f0ee7 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -18,9 +18,9 @@ static char s_display_buffer[8][21 + 1] = { "Cutoff Resonance ", "A B ", " ", - " Filter ", + "Filter A Filter ", " EG Amt ", - " C [ ]", + "Page= 6 C [ ]", }; static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t adc_number) { @@ -161,7 +161,7 @@ INLINE void PRA32_U_ControlPanel_update_control() { #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) static uint32_t s_initialize_counter = 0; - if (s_initialize_counter < 2400) { + if (s_initialize_counter < 75) { ++s_initialize_counter; s_adc_control_value[0] = PRA32_U_ControlPanel_adc_control_value_candidate(0); s_adc_control_value[1] = PRA32_U_ControlPanel_adc_control_value_candidate(1); From 0a0513843aa3ad4899aaa0c2b5b1c4d971867622 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 25 Mar 2024 20:39:39 +0900 Subject: [PATCH 044/106] Implement panel functions (28) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 58f0ee7..d71017b 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -25,9 +25,9 @@ static char s_display_buffer[8][21 + 1] = { static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t adc_number) { #if defined(PRA32_U_ANALOG_INPUT_REVERSED) - return (127 - (s_adc_current_value[adc_number] >> 2)); + return (127 - (s_adc_current_value[adc_number] >> 9)); #else // defined(PRA32_U_ANALOG_INPUT_REVERSED) - return (s_adc_current_value[adc_number] >> 2); + return (s_adc_current_value[adc_number] >> 9); #endif // defined(PRA32_U_ANALOG_INPUT_REVERSED) } @@ -112,12 +112,14 @@ INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { { adc_select_input(0); uint32_t adc_average_value = - (adc_read() + adc_read() + adc_read() + adc_read() + - adc_read() + adc_read() + adc_read() + adc_read()) >> 6; + adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read(); - if (s_adc_current_value[0] >= adc_average_value + 4) { + if (s_adc_current_value[0] >= adc_average_value + 256) { s_adc_current_value[0] = adc_average_value; - } else if (s_adc_current_value[0] + 4 <= adc_average_value ) { + } else if (s_adc_current_value[0] + 256 <= adc_average_value ) { s_adc_current_value[0] = adc_average_value; } } @@ -126,12 +128,14 @@ INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { { adc_select_input(1); uint32_t adc_average_value = - (adc_read() + adc_read() + adc_read() + adc_read() + - adc_read() + adc_read() + adc_read() + adc_read()) >> 6; + adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read(); - if (s_adc_current_value[1] >= adc_average_value + 4) { + if (s_adc_current_value[1] >= adc_average_value + 256) { s_adc_current_value[1] = adc_average_value; - } else if (s_adc_current_value[1] + 4 <= adc_average_value ) { + } else if (s_adc_current_value[1] + 256 <= adc_average_value ) { s_adc_current_value[1] = adc_average_value; } } @@ -140,12 +144,14 @@ INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { { adc_select_input(2); uint32_t adc_average_value = - (adc_read() + adc_read() + adc_read() + adc_read() + - adc_read() + adc_read() + adc_read() + adc_read()) >> 6; + adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read(); - if (s_adc_current_value[2] >= adc_average_value + 4) { + if (s_adc_current_value[2] >= adc_average_value + 256) { s_adc_current_value[2] = adc_average_value; - } else if (s_adc_current_value[2] + 4 <= adc_average_value ) { + } else if (s_adc_current_value[2] + 256 <= adc_average_value ) { s_adc_current_value[2] = adc_average_value; } } From 34afa1d05a441af325a605dda3aad91138e19e36 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 25 Mar 2024 20:53:37 +0900 Subject: [PATCH 045/106] Implement panel functions (29) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 52 ++++++++++++------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index d71017b..8d68ce8 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -107,52 +107,68 @@ INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL) #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) + static uint32_t s_adc_average_value = 0; switch (loop_counter & 0x3F) { case 0x10: { adc_select_input(0); - uint32_t adc_average_value = - adc_read() + adc_read() + adc_read() + adc_read() + + s_adc_average_value = adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read(); + } + break; + case 0x18: + { + s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read(); - if (s_adc_current_value[0] >= adc_average_value + 256) { - s_adc_current_value[0] = adc_average_value; - } else if (s_adc_current_value[0] + 256 <= adc_average_value ) { - s_adc_current_value[0] = adc_average_value; + if (s_adc_current_value[0] >= s_adc_average_value + 256) { + s_adc_current_value[0] = s_adc_average_value; + } else if (s_adc_current_value[0] + 256 <= s_adc_average_value ) { + s_adc_current_value[0] = s_adc_average_value; } } break; case 0x20: { adc_select_input(1); - uint32_t adc_average_value = - adc_read() + adc_read() + adc_read() + adc_read() + + s_adc_average_value = adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read(); + } + break; + case 0x28: + { + s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read(); - if (s_adc_current_value[1] >= adc_average_value + 256) { - s_adc_current_value[1] = adc_average_value; - } else if (s_adc_current_value[1] + 256 <= adc_average_value ) { - s_adc_current_value[1] = adc_average_value; + if (s_adc_current_value[1] >= s_adc_average_value + 256) { + s_adc_current_value[1] = s_adc_average_value; + } else if (s_adc_current_value[1] + 256 <= s_adc_average_value ) { + s_adc_current_value[1] = s_adc_average_value; } } break; case 0x30: { adc_select_input(2); - uint32_t adc_average_value = - adc_read() + adc_read() + adc_read() + adc_read() + + s_adc_average_value = adc_read() + adc_read() + adc_read() + adc_read() + + adc_read() + adc_read() + adc_read() + adc_read(); + } + break; + case 0x38: + { + s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read() + adc_read(); - if (s_adc_current_value[2] >= adc_average_value + 256) { - s_adc_current_value[2] = adc_average_value; - } else if (s_adc_current_value[2] + 256 <= adc_average_value ) { - s_adc_current_value[2] = adc_average_value; + if (s_adc_current_value[2] >= s_adc_average_value + 256) { + s_adc_current_value[2] = s_adc_average_value; + } else if (s_adc_current_value[2] + 256 <= s_adc_average_value ) { + s_adc_current_value[2] = s_adc_average_value; } } break; From dd0207da06e49fa6953f5f21fb53570915adfdee Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 25 Mar 2024 21:01:43 +0900 Subject: [PATCH 046/106] Implement panel functions (30) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 87 +++++++++---------- 1 file changed, 39 insertions(+), 48 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 8d68ce8..09d1ce1 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -110,66 +110,57 @@ INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { static uint32_t s_adc_average_value = 0; switch (loop_counter & 0x3F) { case 0x10: - { - adc_select_input(0); - s_adc_average_value = - adc_read() + adc_read() + adc_read() + adc_read() + - adc_read() + adc_read() + adc_read() + adc_read(); - } + adc_select_input(0); + s_adc_average_value = adc_read() + adc_read() + adc_read() + adc_read(); + break; + case 0x14: + s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); break; case 0x18: - { - s_adc_average_value += - adc_read() + adc_read() + adc_read() + adc_read() + - adc_read() + adc_read() + adc_read() + adc_read(); - - if (s_adc_current_value[0] >= s_adc_average_value + 256) { - s_adc_current_value[0] = s_adc_average_value; - } else if (s_adc_current_value[0] + 256 <= s_adc_average_value ) { - s_adc_current_value[0] = s_adc_average_value; - } + s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); + break; + case 0x1C: + s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); + if (s_adc_current_value[0] >= s_adc_average_value + 256) { + s_adc_current_value[0] = s_adc_average_value; + } else if (s_adc_current_value[0] + 256 <= s_adc_average_value ) { + s_adc_current_value[0] = s_adc_average_value; } break; case 0x20: - { - adc_select_input(1); - s_adc_average_value = - adc_read() + adc_read() + adc_read() + adc_read() + - adc_read() + adc_read() + adc_read() + adc_read(); - } + adc_select_input(1); + s_adc_average_value = adc_read() + adc_read() + adc_read() + adc_read(); + break; + case 0x24: + s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); break; case 0x28: - { - s_adc_average_value += - adc_read() + adc_read() + adc_read() + adc_read() + - adc_read() + adc_read() + adc_read() + adc_read(); - - if (s_adc_current_value[1] >= s_adc_average_value + 256) { - s_adc_current_value[1] = s_adc_average_value; - } else if (s_adc_current_value[1] + 256 <= s_adc_average_value ) { - s_adc_current_value[1] = s_adc_average_value; - } + s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); + break; + case 0x2C: + s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); + if (s_adc_current_value[1] >= s_adc_average_value + 256) { + s_adc_current_value[1] = s_adc_average_value; + } else if (s_adc_current_value[1] + 256 <= s_adc_average_value ) { + s_adc_current_value[1] = s_adc_average_value; } break; case 0x30: - { - adc_select_input(2); - s_adc_average_value = - adc_read() + adc_read() + adc_read() + adc_read() + - adc_read() + adc_read() + adc_read() + adc_read(); - } + adc_select_input(2); + s_adc_average_value = adc_read() + adc_read() + adc_read() + adc_read(); + break; + case 0x34: + s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); break; case 0x38: - { - s_adc_average_value += - adc_read() + adc_read() + adc_read() + adc_read() + - adc_read() + adc_read() + adc_read() + adc_read(); - - if (s_adc_current_value[2] >= s_adc_average_value + 256) { - s_adc_current_value[2] = s_adc_average_value; - } else if (s_adc_current_value[2] + 256 <= s_adc_average_value ) { - s_adc_current_value[2] = s_adc_average_value; - } + s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); + break; + case 0x3C: + s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); + if (s_adc_current_value[2] >= s_adc_average_value + 256) { + s_adc_current_value[2] = s_adc_average_value; + } else if (s_adc_current_value[2] + 256 <= s_adc_average_value ) { + s_adc_current_value[2] = s_adc_average_value; } break; } From 5f917a0ca79fb9cfa4ff6e2b1af9cfe8c8915226 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Wed, 27 Mar 2024 07:32:23 +0900 Subject: [PATCH 047/106] Implement panel functions (31) --- .../pra32-u-control-panel-font-table.h | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h index 4d1373f..78de9aa 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h @@ -241,23 +241,23 @@ uint8_t g_font_table[128][6] = { 0b01000001, 0b01111111, 0b00000000, - 0b01111111, - 0b01000001, - 0b01000001, - 0b01000001, - 0b01111111, 0b00000000, - 0b01111111, - 0b01000001, - 0b01000001, + 0b00011100, + 0b00100010, 0b01000001, - 0b01111111, 0b00000000, - 0b01111111, - 0b01000001, - 0b01000001, + 0b00000000, + 0b00000000, 0b01000001, + 0b00100010, + 0b00011100, + 0b00000000, + 0b00000000, + 0b00100010, + 0b00010100, 0b01111111, + 0b00010100, + 0b00100010, 0b00000000, 0b00001000, 0b00001000, @@ -361,24 +361,24 @@ uint8_t g_font_table[128][6] = { 0b01000001, 0b01111111, 0b00000000, - 0b00000000, 0b00001000, 0b00010100, 0b00100010, 0b01000001, 0b00000000, + 0b00000000, 0b00010100, 0b00010100, 0b00010100, 0b00010100, 0b00010100, 0b00000000, + 0b00000000, 0b01000001, 0b00100010, 0b00010100, 0b00001000, 0b00000000, - 0b00000000, 0b01111111, 0b01000001, 0b01000001, From 67122a03b68110827a844ce7c42e697e2c595025 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 31 Mar 2024 09:23:12 +0900 Subject: [PATCH 048/106] Implement panel functions (32) --- .../Digital-Synth-PRA32-U.ino | 9 ++++- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 35 ++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 63e1d8e..d318482 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -44,6 +44,13 @@ #define PRA32_U_USE_CONTROL_PANEL // Experimental +#define PRA32_U_USE_CONTROL_PANEL_KEY_INPUT // Use tactile switches +#define PRA32_U_KEY_INPUT_ACTIVE_LEVEL (HIGH) +#define PRA32_U_KEY_INPUT_PREV_KEY_PIN (16) +#define PRA32_U_KEY_INPUT_NEXT_KEY_PIN (18) +#define PRA32_U_KEY_INPUT_PLAY_KEY_PIN (20) +#define PRA32_U_KEY_ANTI_CHATTERING_WAIT (15) + #define PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT // Use ADC0, ADC1, and ADC2 #define PRA32_U_ANALOG_INPUT_REVERSED (true) @@ -117,7 +124,7 @@ void __not_in_flash_func(loop1)() { s_loop_counter = 0; } - PRA32_U_ControlPanel_update_input(s_loop_counter); + PRA32_U_ControlPanel_update_analog_inputs(s_loop_counter); PRA32_U_ControlPanel_update_display_buffer(s_loop_counter); PRA32_U_ControlPanel_update_display(s_loop_counter); diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 09d1ce1..6142423 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -8,6 +8,16 @@ #include #include + + +static volatile uint32_t s_prev_key_current_value; +static volatile uint32_t s_next_key_current_value; +static volatile uint32_t s_play_key_current_value; + +static volatile uint32_t s_prev_key_value_changed_time; +static volatile uint32_t s_next_key_value_changed_time; +static volatile uint32_t s_play_key_value_changed_time; + static volatile uint32_t s_adc_current_value[3]; static volatile uint32_t s_adc_control_value[3]; static volatile uint8_t s_adc_control_target[3] = {FILTER_CUTOFF , FILTER_RESO , FILTER_EG_AMT }; @@ -23,6 +33,8 @@ static char s_display_buffer[8][21 + 1] = { "Page= 6 C [ ]", }; + + static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t adc_number) { #if defined(PRA32_U_ANALOG_INPUT_REVERSED) return (127 - (s_adc_current_value[adc_number] >> 9)); @@ -55,6 +67,8 @@ static INLINE void PRA32_U_ControlPanel_draw_character(uint8_t c) { i2c_write_blocking(PRA32_U_OLED_DISPLAY_I2C, PRA32_U_OLED_DISPLAY_I2C_ADDRESS, data, sizeof(data), false); } + + INLINE void PRA32_U_ControlPanel_setup() { #if defined(PRA32_U_USE_CONTROL_PANEL) @@ -101,7 +115,7 @@ INLINE void PRA32_U_ControlPanel_setup() { #endif // defined(PRA32_U_USE_CONTROL_PANEL) } -INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { +INLINE void PRA32_U_ControlPanel_update_analog_inputs(uint32_t loop_counter) { static_cast(loop_counter); #if defined(PRA32_U_USE_CONTROL_PANEL) @@ -172,6 +186,25 @@ INLINE void PRA32_U_ControlPanel_update_input(uint32_t loop_counter) { INLINE void PRA32_U_ControlPanel_update_control() { #if defined(PRA32_U_USE_CONTROL_PANEL) +#if defined(PRA32_U_USE_CONTROL_PANEL_KEY_INPUT) + static uint32_t s_key_inpuy_counter = 0; + s_key_inpuy_counter++; + if (s_key_inpuy_counter - s_prev_key_value_changed_time >= PRA32_U_KEY_ANTI_CHATTERING_WAIT) { + uint32_t value = digitalRead(PRA32_U_KEY_INPUT_PREV_KEY_PIN) == PRA32_U_KEY_INPUT_ACTIVE_LEVEL; + s_prev_key_current_value = value; + } + + if (s_key_inpuy_counter - s_prev_key_value_changed_time >= PRA32_U_KEY_ANTI_CHATTERING_WAIT) { + uint32_t value = digitalRead(PRA32_U_KEY_INPUT_NEXT_KEY_PIN) == PRA32_U_KEY_INPUT_ACTIVE_LEVEL; + s_next_key_current_value = value; + } + + if (s_key_inpuy_counter - s_prev_key_value_changed_time >= PRA32_U_KEY_ANTI_CHATTERING_WAIT) { + uint32_t value = digitalRead(PRA32_U_KEY_INPUT_PLAY_KEY_PIN) == PRA32_U_KEY_INPUT_ACTIVE_LEVEL; + s_play_key_current_value = value; + } +#endif // defined(PRA32_U_USE_CONTROL_PANEL_KEY_INPUT) + #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) static uint32_t s_initialize_counter = 0; if (s_initialize_counter < 75) { From eed7781dc877df4af29e7735ab37546e905ca08f Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 31 Mar 2024 09:34:02 +0900 Subject: [PATCH 049/106] Implement panel functions (33) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 6142423..408c9de 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -185,36 +185,49 @@ INLINE void PRA32_U_ControlPanel_update_analog_inputs(uint32_t loop_counter) { INLINE void PRA32_U_ControlPanel_update_control() { #if defined(PRA32_U_USE_CONTROL_PANEL) + static uint32_t s_initialize_counter = 0; + if (s_initialize_counter < 75) { + ++s_initialize_counter; +#if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) + s_adc_control_value[0] = PRA32_U_ControlPanel_adc_control_value_candidate(0); + s_adc_control_value[1] = PRA32_U_ControlPanel_adc_control_value_candidate(1); + s_adc_control_value[2] = PRA32_U_ControlPanel_adc_control_value_candidate(2); +#endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) + return; + } #if defined(PRA32_U_USE_CONTROL_PANEL_KEY_INPUT) static uint32_t s_key_inpuy_counter = 0; - s_key_inpuy_counter++; + ++s_key_inpuy_counter; if (s_key_inpuy_counter - s_prev_key_value_changed_time >= PRA32_U_KEY_ANTI_CHATTERING_WAIT) { uint32_t value = digitalRead(PRA32_U_KEY_INPUT_PREV_KEY_PIN) == PRA32_U_KEY_INPUT_ACTIVE_LEVEL; - s_prev_key_current_value = value; + if (s_prev_key_current_value != value) { + s_prev_key_current_value = value; + s_prev_key_value_changed_time = s_key_inpuy_counter; + return; + } } - if (s_key_inpuy_counter - s_prev_key_value_changed_time >= PRA32_U_KEY_ANTI_CHATTERING_WAIT) { + if (s_key_inpuy_counter - s_next_key_value_changed_time >= PRA32_U_KEY_ANTI_CHATTERING_WAIT) { uint32_t value = digitalRead(PRA32_U_KEY_INPUT_NEXT_KEY_PIN) == PRA32_U_KEY_INPUT_ACTIVE_LEVEL; - s_next_key_current_value = value; + if (s_next_key_current_value != value) { + s_next_key_current_value = value; + s_next_key_value_changed_time = s_key_inpuy_counter; + return; + } } - if (s_key_inpuy_counter - s_prev_key_value_changed_time >= PRA32_U_KEY_ANTI_CHATTERING_WAIT) { + if (s_key_inpuy_counter - s_play_key_value_changed_time >= PRA32_U_KEY_ANTI_CHATTERING_WAIT) { uint32_t value = digitalRead(PRA32_U_KEY_INPUT_PLAY_KEY_PIN) == PRA32_U_KEY_INPUT_ACTIVE_LEVEL; - s_play_key_current_value = value; + if (s_play_key_current_value != value) { + s_play_key_current_value = value; + s_play_key_value_changed_time = s_key_inpuy_counter; + return; + } } #endif // defined(PRA32_U_USE_CONTROL_PANEL_KEY_INPUT) #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) - static uint32_t s_initialize_counter = 0; - if (s_initialize_counter < 75) { - ++s_initialize_counter; - s_adc_control_value[0] = PRA32_U_ControlPanel_adc_control_value_candidate(0); - s_adc_control_value[1] = PRA32_U_ControlPanel_adc_control_value_candidate(1); - s_adc_control_value[2] = PRA32_U_ControlPanel_adc_control_value_candidate(2); - return; - } - static uint32_t s_adc_number_to_check = 0; boolean updated = PRA32_U_ControlPanel_update_adc_control(s_adc_number_to_check); From 91eab01a133a13176e56f58ab782d7e838e24e56 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 31 Mar 2024 10:19:29 +0900 Subject: [PATCH 050/106] Implement panel functions (34) --- .../pra32-u-control-panel-font-table.h | 2 +- .../pra32-u-control-panel-page-table.h | 33 +++++++++++++++++++ Digital-Synth-PRA32-U/pra32-u-control-panel.h | 22 ++++++++++++- 3 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h index 78de9aa..5f990c1 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h @@ -1,6 +1,6 @@ #pragma once -uint8_t g_font_table[128][6] = { +uint8_t g_control_panel_font_table[128][6] = { 0b01111111, 0b01111111, 0b01111111, diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h new file mode 100644 index 0000000..87471a3 --- /dev/null +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h @@ -0,0 +1,33 @@ +#pragma once + +struct { + char page_name_line_0 [10 + 1]; + char page_name_line_1 [10 + 1]; + char control_target_a_name_line_0[10 + 1]; + char control_target_a_name_line_1[10 + 1]; + uint8_t control_target_a; + char control_target_b_name_line_0[10 + 1]; + char control_target_b_name_line_1[10 + 1]; + uint8_t control_target_b; + char control_target_c_name_line_0[10 + 1]; + char control_target_c_name_line_1[10 + 1]; + uint8_t control_target_c; +} g_control_panel_page_table[] = { + { "Voice ", " ", "Voice ", "Mode ", VOICE_MODE , "Portamento", " ", PORTAMENTO , "Pitch ", "Bend Range", P_BEND_RANGE , }, + { "Osc 1 ", " ", "Osc 1 ", "Wave ", OSC_1_WAVE , "Osc 1 ", "Shape ", OSC_1_SHAPE , "Osc 1 ", "Morph ", OSC_1_MORPH , }, + { "Osc 2 ", " ", "Osc 2 ", "Wave ", OSC_2_WAVE , "Osc 2 ", "Coarse ", OSC_2_COARSE , "Osc 2 ", "Pitch ", OSC_2_PITCH , }, + { "Mixer ", " ", "Mixer ", "Osc Mix ", MIXER_OSC_MIX , "Mixer ", "Noise/Sub ", MIXER_SUB_OSC , " ", " ", 0xFF , }, + { "Filter a ", " ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Filter ", "EG Amt ", FILTER_EG_AMT , }, + { "Filter b ", " ", "Filter ", "Key Track ", FILTER_KEY_TRK , "Filter ", "Mode ", FILTER_MODE , " ", " ", 0xFF , }, + { "EG a ", " ", "EG ", "Attack ", EG_ATTACK , "EG ", "Decay ", EG_DECAY , "EG ", "Sustain ", EG_SUSTAIN , }, + { "EG b ", " ", "EG ", "Release ", EG_RELEASE , "EG ", "Amp Mod ", EG_AMP_MOD , "Release ", "= Decay ", REL_EQ_DECAY , }, + { "EG c ", " ", "EG ", "Osc Amt ", EG_OSC_AMT , "EG ", "Osc Dst ", EG_OSC_DST , "EG ", "Velo Sens ", EG_VEL_SENS , }, + { "Amp a ", " ", "Amp ", "Attack ", AMP_ATTACK , "Amp ", "Decay ", AMP_DECAY , "Amp ", "Sustain ", AMP_SUSTAIN , }, + { "Amp b ", " ", "Amp ", "Release ", AMP_RELEASE , "Amp ", "Gain ", AMP_GAIN , "Amp ", "Velo Sens ", AMP_VEL_SENS , }, + { "LFO a ", " ", "LFO ", "Wave ", LFO_WAVE , "LFO ", "Rate ", LFO_RATE , "LFO ", "Depth ", LFO_DEPTH , }, + { "LFO b ", " ", "LFO ", "Fade Time ", LFO_FADE_TIME , " ", " ", 0xFF , " ", " ", 0xFF , }, + { "LFO c ", " ", "LFO ", "Osc Amt ", LFO_OSC_AMT , "LFO ", "Osc Dst ", LFO_OSC_DST , "LFO ", "Filter Amt", LFO_FILTER_AMT , }, + { "Breath ", " ", "Breath ", "Filter Amt", BTH_FILTER_AMT , "Breath ", "Amp Mod ", BTH_AMP_MOD , " ", " ", 0xFF , }, + { "Chorus ", " ", "Chorus ", "Mix ", CHORUS_MIX , "Chorus ", "Rate ", CHORUS_RATE , "Chorus ", "Depth ", CHORUS_DEPTH , }, + { "Delay ", " ", "Delay ", "Feedback ", DELAY_FEEDBACK , "Delay ", "Time ", DELAY_TIME , "Delay ", "Mode ", DELAY_MODE , }, +}; diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 408c9de..fd99563 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -2,6 +2,7 @@ #include "pra32-u-common.h" #include "pra32-u-control-panel-font-table.h" +#include "pra32-u-control-panel-page-table.h" #include "hardware/i2c.h" @@ -63,7 +64,7 @@ static INLINE void PRA32_U_ControlPanel_set_draw_position(uint8_t x, uint8_t y) static INLINE void PRA32_U_ControlPanel_draw_character(uint8_t c) { uint8_t data[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - std::memcpy(&data[1], g_font_table[c], 6); + std::memcpy(&data[1], g_control_panel_font_table[c], 6); i2c_write_blocking(PRA32_U_OLED_DISPLAY_I2C, PRA32_U_OLED_DISPLAY_I2C_ADDRESS, data, sizeof(data), false); } @@ -326,6 +327,23 @@ INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) static uint32_t s_display_draw_counter = 0; + +#if 1 + if ((loop_counter & 0x7F) == 0x40) { + ++s_display_draw_counter; + if (s_display_draw_counter >= 8 * 21) { + s_display_draw_counter = 0; + } + + uint8_t x = s_display_draw_counter % 21; + uint8_t y = s_display_draw_counter / 21; + PRA32_U_ControlPanel_set_draw_position(x, y); + } else if ((loop_counter & 0x7F) == 0x00) { + uint8_t x = s_display_draw_counter % 21; + uint8_t y = s_display_draw_counter / 21; + PRA32_U_ControlPanel_draw_character(s_display_buffer[y][x]); + } +#else if ((loop_counter & 0x7F) == 0x40) { ++s_display_draw_counter; if (s_display_draw_counter >= 31) { @@ -340,6 +358,8 @@ INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { uint8_t y = ((s_display_draw_counter >= 21) * 4) + 3; PRA32_U_ControlPanel_draw_character(s_display_buffer[y][x]); } +#endif + #endif // defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) #endif // defined(PRA32_U_USE_CONTROL_PANEL) From 4cb68c93006c42ed32fac78f194e7fd2a373a4d3 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 31 Mar 2024 10:38:19 +0900 Subject: [PATCH 051/106] Implement panel functions (35) --- .../pra32-u-control-panel-page-table.h | 2 +- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 62 ++++++++++++++++--- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h index 87471a3..5206f67 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h @@ -1,6 +1,6 @@ #pragma once -struct { +struct PRA32_U_ControlPanelPage { char page_name_line_0 [10 + 1]; char page_name_line_1 [10 + 1]; char control_target_a_name_line_0[10 + 1]; diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index fd99563..1bb9402 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -11,31 +11,46 @@ -static volatile uint32_t s_prev_key_current_value; -static volatile uint32_t s_next_key_current_value; -static volatile uint32_t s_play_key_current_value; +#define NUMBER_OF_PAGES (sizeof(g_control_panel_page_table) / sizeof(g_control_panel_page_table[0])) -static volatile uint32_t s_prev_key_value_changed_time; -static volatile uint32_t s_next_key_value_changed_time; -static volatile uint32_t s_play_key_value_changed_time; +static volatile uint32_t s_current_page_index = 5; static volatile uint32_t s_adc_current_value[3]; static volatile uint32_t s_adc_control_value[3]; -static volatile uint8_t s_adc_control_target[3] = {FILTER_CUTOFF , FILTER_RESO , FILTER_EG_AMT }; +static volatile uint8_t s_adc_control_target[3] = { 0xFF, 0xFF, 0xFF }; static char s_display_buffer[8][21 + 1] = { " ", "Filter Filter ", "Cutoff Resonance ", - "A B ", + "A [ ] B [ ]", " ", - "Filter A Filter ", + " Filter ", " EG Amt ", - "Page= 6 C [ ]", + " C [ ]", }; +static INLINE void PRA32_U_ControlPanel_update_page() { + PRA32_U_ControlPanelPage& current_page = g_control_panel_page_table[s_current_page_index]; + + std::memcpy(&s_display_buffer[5][ 0], current_page.page_name_line_0 , 10); + std::memcpy(&s_display_buffer[6][ 0], current_page.page_name_line_1 , 10); + + std::memcpy(&s_display_buffer[1][ 0], current_page.control_target_a_name_line_0, 10); + std::memcpy(&s_display_buffer[2][ 0], current_page.control_target_a_name_line_1, 10); + s_adc_control_target[0] = current_page.control_target_a; + + std::memcpy(&s_display_buffer[1][11], current_page.control_target_b_name_line_0, 10); + std::memcpy(&s_display_buffer[2][11], current_page.control_target_b_name_line_1, 10); + s_adc_control_target[1] = current_page.control_target_b; + + std::memcpy(&s_display_buffer[5][11], current_page.control_target_c_name_line_0, 10); + std::memcpy(&s_display_buffer[6][11], current_page.control_target_c_name_line_1, 10); + s_adc_control_target[2] = current_page.control_target_c; +} + static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t adc_number) { #if defined(PRA32_U_ANALOG_INPUT_REVERSED) return (127 - (s_adc_current_value[adc_number] >> 9)); @@ -72,6 +87,7 @@ static INLINE void PRA32_U_ControlPanel_draw_character(uint8_t c) { INLINE void PRA32_U_ControlPanel_setup() { #if defined(PRA32_U_USE_CONTROL_PANEL) + PRA32_U_ControlPanel_update_page(); #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) adc_init(); @@ -198,6 +214,14 @@ INLINE void PRA32_U_ControlPanel_update_control() { } #if defined(PRA32_U_USE_CONTROL_PANEL_KEY_INPUT) + static uint32_t s_prev_key_current_value; + static uint32_t s_next_key_current_value; + static uint32_t s_play_key_current_value; + + static uint32_t s_prev_key_value_changed_time; + static uint32_t s_next_key_value_changed_time; + static uint32_t s_play_key_value_changed_time; + static uint32_t s_key_inpuy_counter = 0; ++s_key_inpuy_counter; if (s_key_inpuy_counter - s_prev_key_value_changed_time >= PRA32_U_KEY_ANTI_CHATTERING_WAIT) { @@ -205,6 +229,14 @@ INLINE void PRA32_U_ControlPanel_update_control() { if (s_prev_key_current_value != value) { s_prev_key_current_value = value; s_prev_key_value_changed_time = s_key_inpuy_counter; + + if (s_current_page_index == 0) { + s_current_page_index = NUMBER_OF_PAGES - 1; + } else { + --s_current_page_index; + } + + PRA32_U_ControlPanel_update_page(); return; } } @@ -214,6 +246,14 @@ INLINE void PRA32_U_ControlPanel_update_control() { if (s_next_key_current_value != value) { s_next_key_current_value = value; s_next_key_value_changed_time = s_key_inpuy_counter; + + if (s_current_page_index == NUMBER_OF_PAGES - 1) { + s_current_page_index = 0; + } else { + ++s_current_page_index; + } + + PRA32_U_ControlPanel_update_page(); return; } } @@ -311,10 +351,12 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { s_display_buffer[7][14] = buff[1]; s_display_buffer[7][15] = buff[2]; +#if 0 std::sprintf(buff, "%+3d", static_cast(current_controller_value) - 64); s_display_buffer[7][17] = buff[0]; s_display_buffer[7][18] = buff[1]; s_display_buffer[7][19] = buff[2]; +#endif } } #endif // defined(PRA32_U_USE_CONTROL_PANEL) From 282c3c4d66ba2ec8492b0a68b8c0ab7ef48c2854 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 31 Mar 2024 10:55:29 +0900 Subject: [PATCH 052/106] Implement panel functions (36) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 1bb9402..d5afbf3 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -13,7 +13,7 @@ #define NUMBER_OF_PAGES (sizeof(g_control_panel_page_table) / sizeof(g_control_panel_page_table[0])) -static volatile uint32_t s_current_page_index = 5; +static volatile uint32_t s_current_page_index = 4; static volatile uint32_t s_adc_current_value[3]; static volatile uint32_t s_adc_control_value[3]; @@ -21,13 +21,13 @@ static volatile uint8_t s_adc_control_target[3] = { 0xFF, 0xFF, 0xFF }; static char s_display_buffer[8][21 + 1] = { " ", - "Filter Filter ", - "Cutoff Resonance ", - "A [ ] B [ ]", " ", - " Filter ", - " EG Amt ", - " C [ ]", + " ", + " ", + " ", + " ", + " ", + " ", }; @@ -35,6 +35,9 @@ static char s_display_buffer[8][21 + 1] = { static INLINE void PRA32_U_ControlPanel_update_page() { PRA32_U_ControlPanelPage& current_page = g_control_panel_page_table[s_current_page_index]; + std::memset(&s_display_buffer[3], ' ', 21); + std::memset(&s_display_buffer[7], ' ', 21); + std::memcpy(&s_display_buffer[5][ 0], current_page.page_name_line_0 , 10); std::memcpy(&s_display_buffer[6][ 0], current_page.page_name_line_1 , 10); @@ -230,13 +233,15 @@ INLINE void PRA32_U_ControlPanel_update_control() { s_prev_key_current_value = value; s_prev_key_value_changed_time = s_key_inpuy_counter; - if (s_current_page_index == 0) { - s_current_page_index = NUMBER_OF_PAGES - 1; - } else { - --s_current_page_index; - } + if (s_prev_key_current_value == 1) { + if (s_current_page_index == 0) { + s_current_page_index = NUMBER_OF_PAGES - 1; + } else { + --s_current_page_index; + } - PRA32_U_ControlPanel_update_page(); + PRA32_U_ControlPanel_update_page(); + } return; } } @@ -247,13 +252,15 @@ INLINE void PRA32_U_ControlPanel_update_control() { s_next_key_current_value = value; s_next_key_value_changed_time = s_key_inpuy_counter; - if (s_current_page_index == NUMBER_OF_PAGES - 1) { - s_current_page_index = 0; - } else { - ++s_current_page_index; - } + if (s_next_key_current_value == 1) { + if (s_current_page_index == NUMBER_OF_PAGES - 1) { + s_current_page_index = 0; + } else { + ++s_current_page_index; + } - PRA32_U_ControlPanel_update_page(); + PRA32_U_ControlPanel_update_page(); + } return; } } @@ -300,6 +307,7 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { uint8_t adc_control_value = s_adc_control_value[0]; uint8_t current_controller_value = g_synth.current_controller_value(adc_control_target_0); + s_display_buffer[3][ 0] = 'A'; if (adc_control_value < current_controller_value) { s_display_buffer[3][ 1] = '<'; } else if (adc_control_value > current_controller_value) { @@ -319,6 +327,7 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { uint8_t adc_control_value = s_adc_control_value[1]; uint8_t current_controller_value = g_synth.current_controller_value(adc_control_target_1); + s_display_buffer[3][11] = 'B'; if (adc_control_value < current_controller_value) { s_display_buffer[3][12] = '<'; } else if (adc_control_value > current_controller_value) { @@ -338,6 +347,7 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { uint8_t adc_control_value = s_adc_control_value[2]; uint8_t current_controller_value = g_synth.current_controller_value(adc_control_target_2); + s_display_buffer[7][11] = 'C'; if (adc_control_value < current_controller_value) { s_display_buffer[7][12] = '<'; } else if (adc_control_value > current_controller_value) { From e4cfd4dbee5682730c3fc67f8d042f598ef5affa Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 31 Mar 2024 11:05:46 +0900 Subject: [PATCH 053/106] Implement panel functions (37) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index d5afbf3..707e27e 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -270,6 +270,12 @@ INLINE void PRA32_U_ControlPanel_update_control() { if (s_play_key_current_value != value) { s_play_key_current_value = value; s_play_key_value_changed_time = s_key_inpuy_counter; + + if (s_play_key_current_value == 1) { + g_synth.note_on(60, 100); + } else { + g_synth.note_off(60); + } return; } } From d6fab847647b5d673639519b8e58d12aa264c700 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 31 Mar 2024 18:02:54 +0900 Subject: [PATCH 054/106] Implement panel functions (38) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 72 ++++++++++--------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 707e27e..63c7bd2 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -38,19 +38,19 @@ static INLINE void PRA32_U_ControlPanel_update_page() { std::memset(&s_display_buffer[3], ' ', 21); std::memset(&s_display_buffer[7], ' ', 21); - std::memcpy(&s_display_buffer[5][ 0], current_page.page_name_line_0 , 10); - std::memcpy(&s_display_buffer[6][ 0], current_page.page_name_line_1 , 10); + std::memcpy(&s_display_buffer[1][ 0], current_page.page_name_line_0 , 10); + std::memcpy(&s_display_buffer[2][ 0], current_page.page_name_line_1 , 10); - std::memcpy(&s_display_buffer[1][ 0], current_page.control_target_a_name_line_0, 10); - std::memcpy(&s_display_buffer[2][ 0], current_page.control_target_a_name_line_1, 10); + std::memcpy(&s_display_buffer[5][ 0], current_page.control_target_a_name_line_0, 10); + std::memcpy(&s_display_buffer[6][ 0], current_page.control_target_a_name_line_1, 10); s_adc_control_target[0] = current_page.control_target_a; - std::memcpy(&s_display_buffer[1][11], current_page.control_target_b_name_line_0, 10); - std::memcpy(&s_display_buffer[2][11], current_page.control_target_b_name_line_1, 10); + std::memcpy(&s_display_buffer[5][11], current_page.control_target_b_name_line_0, 10); + std::memcpy(&s_display_buffer[6][11], current_page.control_target_b_name_line_1, 10); s_adc_control_target[1] = current_page.control_target_b; - std::memcpy(&s_display_buffer[5][11], current_page.control_target_c_name_line_0, 10); - std::memcpy(&s_display_buffer[6][11], current_page.control_target_c_name_line_1, 10); + std::memcpy(&s_display_buffer[1][11], current_page.control_target_c_name_line_0, 10); + std::memcpy(&s_display_buffer[2][11], current_page.control_target_c_name_line_1, 10); s_adc_control_target[2] = current_page.control_target_c; } @@ -233,7 +233,8 @@ INLINE void PRA32_U_ControlPanel_update_control() { s_prev_key_current_value = value; s_prev_key_value_changed_time = s_key_inpuy_counter; - if (s_prev_key_current_value == 1) { + if (s_prev_key_current_value == 0) { + // Prev key released if (s_current_page_index == 0) { s_current_page_index = NUMBER_OF_PAGES - 1; } else { @@ -252,7 +253,8 @@ INLINE void PRA32_U_ControlPanel_update_control() { s_next_key_current_value = value; s_next_key_value_changed_time = s_key_inpuy_counter; - if (s_next_key_current_value == 1) { + if (s_next_key_current_value == 0) { + // Next key released if (s_current_page_index == NUMBER_OF_PAGES - 1) { s_current_page_index = 0; } else { @@ -272,8 +274,10 @@ INLINE void PRA32_U_ControlPanel_update_control() { s_play_key_value_changed_time = s_key_inpuy_counter; if (s_play_key_current_value == 1) { + // Play key pressed g_synth.note_on(60, 100); } else { + // Play key released g_synth.note_off(60); } return; @@ -313,19 +317,19 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { uint8_t adc_control_value = s_adc_control_value[0]; uint8_t current_controller_value = g_synth.current_controller_value(adc_control_target_0); - s_display_buffer[3][ 0] = 'A'; + s_display_buffer[7][ 0] = 'A'; if (adc_control_value < current_controller_value) { - s_display_buffer[3][ 1] = '<'; + s_display_buffer[7][ 1] = '<'; } else if (adc_control_value > current_controller_value) { - s_display_buffer[3][ 1] = '>'; + s_display_buffer[7][ 1] = '>'; } else { - s_display_buffer[3][ 1] = '='; + s_display_buffer[7][ 1] = '='; } std::sprintf(buff, "%3u", current_controller_value); - s_display_buffer[3][ 2] = buff[0]; - s_display_buffer[3][ 3] = buff[1]; - s_display_buffer[3][ 4] = buff[2]; + s_display_buffer[7][ 2] = buff[0]; + s_display_buffer[7][ 3] = buff[1]; + s_display_buffer[7][ 4] = buff[2]; } uint8_t adc_control_target_1 = s_adc_control_target[1]; @@ -333,19 +337,19 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { uint8_t adc_control_value = s_adc_control_value[1]; uint8_t current_controller_value = g_synth.current_controller_value(adc_control_target_1); - s_display_buffer[3][11] = 'B'; + s_display_buffer[7][11] = 'B'; if (adc_control_value < current_controller_value) { - s_display_buffer[3][12] = '<'; + s_display_buffer[7][12] = '<'; } else if (adc_control_value > current_controller_value) { - s_display_buffer[3][12] = '>'; + s_display_buffer[7][12] = '>'; } else { - s_display_buffer[3][12] = '='; + s_display_buffer[7][12] = '='; } std::sprintf(buff, "%3u", current_controller_value); - s_display_buffer[3][13] = buff[0]; - s_display_buffer[3][14] = buff[1]; - s_display_buffer[3][15] = buff[2]; + s_display_buffer[7][13] = buff[0]; + s_display_buffer[7][14] = buff[1]; + s_display_buffer[7][15] = buff[2]; } uint8_t adc_control_target_2 = s_adc_control_target[2]; @@ -353,25 +357,25 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { uint8_t adc_control_value = s_adc_control_value[2]; uint8_t current_controller_value = g_synth.current_controller_value(adc_control_target_2); - s_display_buffer[7][11] = 'C'; + s_display_buffer[3][11] = 'C'; if (adc_control_value < current_controller_value) { - s_display_buffer[7][12] = '<'; + s_display_buffer[3][12] = '<'; } else if (adc_control_value > current_controller_value) { - s_display_buffer[7][12] = '>'; + s_display_buffer[3][12] = '>'; } else { - s_display_buffer[7][12] = '='; + s_display_buffer[3][12] = '='; } std::sprintf(buff, "%3u", current_controller_value); - s_display_buffer[7][13] = buff[0]; - s_display_buffer[7][14] = buff[1]; - s_display_buffer[7][15] = buff[2]; + s_display_buffer[3][13] = buff[0]; + s_display_buffer[3][14] = buff[1]; + s_display_buffer[3][15] = buff[2]; #if 0 std::sprintf(buff, "%+3d", static_cast(current_controller_value) - 64); - s_display_buffer[7][17] = buff[0]; - s_display_buffer[7][18] = buff[1]; - s_display_buffer[7][19] = buff[2]; + s_display_buffer[3][17] = buff[0]; + s_display_buffer[3][18] = buff[1]; + s_display_buffer[3][19] = buff[2]; #endif } } From e0231479c6cb6671a2add33574bfaaa2b16df989 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 31 Mar 2024 18:51:14 +0900 Subject: [PATCH 055/106] Implement panel functions (39) --- .../Digital-Synth-PRA32-U.ino | 1 + Digital-Synth-PRA32-U/pra32-u-control-panel.h | 49 ++++++++++++------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index d318482..6ce0356 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -53,6 +53,7 @@ #define PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT // Use ADC0, ADC1, and ADC2 #define PRA32_U_ANALOG_INPUT_REVERSED (true) +#define PRA32_U_ANALOG_INPUT_CORRECTION (-248) #define PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY // Use SSD1306 monochrome 128x64 OLED #define PRA32_U_OLED_DISPLAY_I2C (i2c1) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 63c7bd2..8c5ff04 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -15,8 +15,8 @@ static volatile uint32_t s_current_page_index = 4; -static volatile uint32_t s_adc_current_value[3]; -static volatile uint32_t s_adc_control_value[3]; +static volatile int32_t s_adc_current_value[3]; +static volatile uint8_t s_adc_control_value[3]; static volatile uint8_t s_adc_control_target[3] = { 0xFF, 0xFF, 0xFF }; static char s_display_buffer[8][21 + 1] = { @@ -55,11 +55,23 @@ static INLINE void PRA32_U_ControlPanel_update_page() { } static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t adc_number) { + volatile int32_t adc_control_value_candidate; + #if defined(PRA32_U_ANALOG_INPUT_REVERSED) - return (127 - (s_adc_current_value[adc_number] >> 9)); + adc_control_value_candidate = (127 - (s_adc_current_value[adc_number] >> 9)); #else // defined(PRA32_U_ANALOG_INPUT_REVERSED) - return (s_adc_current_value[adc_number] >> 9); + adc_control_value_candidate = (s_adc_current_value[adc_number] >> 9); #endif // defined(PRA32_U_ANALOG_INPUT_REVERSED) + + if (adc_control_value_candidate > 127) { + adc_control_value_candidate = 127; + } + + if (adc_control_value_candidate < 0) { + adc_control_value_candidate = 0; + } + + return adc_control_value_candidate; } static INLINE boolean PRA32_U_ControlPanel_update_adc_control(uint32_t adc_number) { @@ -141,11 +153,12 @@ INLINE void PRA32_U_ControlPanel_update_analog_inputs(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL) #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) - static uint32_t s_adc_average_value = 0; + static int32_t s_adc_average_value = 0; switch (loop_counter & 0x3F) { case 0x10: adc_select_input(0); - s_adc_average_value = adc_read() + adc_read() + adc_read() + adc_read(); + s_adc_average_value = PRA32_U_ANALOG_INPUT_CORRECTION; + s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); break; case 0x14: s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); @@ -155,15 +168,16 @@ INLINE void PRA32_U_ControlPanel_update_analog_inputs(uint32_t loop_counter) { break; case 0x1C: s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); - if (s_adc_current_value[0] >= s_adc_average_value + 256) { + if (s_adc_current_value[0] >= s_adc_average_value + 512) { s_adc_current_value[0] = s_adc_average_value; - } else if (s_adc_current_value[0] + 256 <= s_adc_average_value ) { + } else if (s_adc_current_value[0] + 512 <= s_adc_average_value ) { s_adc_current_value[0] = s_adc_average_value; } break; case 0x20: adc_select_input(1); - s_adc_average_value = adc_read() + adc_read() + adc_read() + adc_read(); + s_adc_average_value = PRA32_U_ANALOG_INPUT_CORRECTION; + s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); break; case 0x24: s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); @@ -173,15 +187,16 @@ INLINE void PRA32_U_ControlPanel_update_analog_inputs(uint32_t loop_counter) { break; case 0x2C: s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); - if (s_adc_current_value[1] >= s_adc_average_value + 256) { + if (s_adc_current_value[1] >= s_adc_average_value + 512) { s_adc_current_value[1] = s_adc_average_value; - } else if (s_adc_current_value[1] + 256 <= s_adc_average_value ) { + } else if (s_adc_current_value[1] + 512 <= s_adc_average_value ) { s_adc_current_value[1] = s_adc_average_value; } break; case 0x30: adc_select_input(2); - s_adc_average_value = adc_read() + adc_read() + adc_read() + adc_read(); + s_adc_average_value = PRA32_U_ANALOG_INPUT_CORRECTION; + s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); break; case 0x34: s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); @@ -191,9 +206,9 @@ INLINE void PRA32_U_ControlPanel_update_analog_inputs(uint32_t loop_counter) { break; case 0x3C: s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); - if (s_adc_current_value[2] >= s_adc_average_value + 256) { + if (s_adc_current_value[2] >= s_adc_average_value + 512) { s_adc_current_value[2] = s_adc_average_value; - } else if (s_adc_current_value[2] + 256 <= s_adc_average_value ) { + } else if (s_adc_current_value[2] + 512 <= s_adc_average_value ) { s_adc_current_value[2] = s_adc_average_value; } break; @@ -468,15 +483,15 @@ INLINE void PRA32_U_ControlPanel_debug_print(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) case 13 * 400: Serial1.print("\e[16;1H\e[K"); - Serial1.print(s_adc_control_value[0]); + Serial1.print(s_adc_current_value[0]); break; case 14 * 400: Serial1.print("\e[17;1H\e[K"); - Serial1.print(s_adc_control_value[1]); + Serial1.print(s_adc_current_value[1]); break; case 15 * 400: Serial1.print("\e[18;1H\e[K"); - Serial1.print(s_adc_control_value[2]); + Serial1.print(s_adc_current_value[2]); break; #endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) } From fc532f4a8e48e8b788aad6e5e12902679a3baf83 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 31 Mar 2024 19:56:32 +0900 Subject: [PATCH 056/106] Implement panel functions (40) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 60 +++++++++++-------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 8c5ff04..5444f4a 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -19,6 +19,8 @@ static volatile int32_t s_adc_current_value[3]; static volatile uint8_t s_adc_control_value[3]; static volatile uint8_t s_adc_control_target[3] = { 0xFF, 0xFF, 0xFF }; +static volatile uint32_t s_display_draw_counter = 0; + static char s_display_buffer[8][21 + 1] = { " ", " ", @@ -52,6 +54,8 @@ static INLINE void PRA32_U_ControlPanel_update_page() { std::memcpy(&s_display_buffer[1][11], current_page.control_target_c_name_line_0, 10); std::memcpy(&s_display_buffer[2][11], current_page.control_target_c_name_line_1, 10); s_adc_control_target[2] = current_page.control_target_c; + + s_display_draw_counter = 0; } static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t adc_number) { @@ -403,40 +407,44 @@ INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL) #if defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) - static uint32_t s_display_draw_counter = 0; + static uint32_t s_display_draw_position_x = 0; + static uint32_t s_display_draw_position_y = 0; -#if 1 if ((loop_counter & 0x7F) == 0x40) { - ++s_display_draw_counter; - if (s_display_draw_counter >= 8 * 21) { - s_display_draw_counter = 0; + uint32_t display_draw_counter = s_display_draw_counter; + + s_display_draw_counter++; + if (s_display_draw_counter == 6 * 21) { + s_display_draw_counter = 4 * 21; } - uint8_t x = s_display_draw_counter % 21; - uint8_t y = s_display_draw_counter / 21; - PRA32_U_ControlPanel_set_draw_position(x, y); - } else if ((loop_counter & 0x7F) == 0x00) { - uint8_t x = s_display_draw_counter % 21; - uint8_t y = s_display_draw_counter / 21; - PRA32_U_ControlPanel_draw_character(s_display_buffer[y][x]); - } -#else - if ((loop_counter & 0x7F) == 0x40) { - ++s_display_draw_counter; - if (s_display_draw_counter >= 31) { - s_display_draw_counter = 0; + switch (display_draw_counter / 21) { + case 0: + s_display_draw_position_y = 1; + break; + case 1: + s_display_draw_position_y = 2; + break; + case 2: + s_display_draw_position_y = 5; + break; + case 3: + s_display_draw_position_y = 6; + break; + case 4: + s_display_draw_position_y = 3; + break; + case 5: + s_display_draw_position_y = 7; + break; } - uint8_t x = (s_display_draw_counter % 21) + ((s_display_draw_counter >= 21) * 11); - uint8_t y = ((s_display_draw_counter >= 21) * 4) + 3; - PRA32_U_ControlPanel_set_draw_position(x, y); + s_display_draw_position_x = display_draw_counter % 21; + + PRA32_U_ControlPanel_set_draw_position(s_display_draw_position_x, s_display_draw_position_y); } else if ((loop_counter & 0x7F) == 0x00) { - uint8_t x = (s_display_draw_counter % 21) + ((s_display_draw_counter >= 21) * 11); - uint8_t y = ((s_display_draw_counter >= 21) * 4) + 3; - PRA32_U_ControlPanel_draw_character(s_display_buffer[y][x]); + PRA32_U_ControlPanel_draw_character(s_display_buffer[s_display_draw_position_y][s_display_draw_position_x]); } -#endif - #endif // defined(PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY) #endif // defined(PRA32_U_USE_CONTROL_PANEL) From e5383b9a84a9d653a0391e0617565adc5826e188 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 31 Mar 2024 20:05:56 +0900 Subject: [PATCH 057/106] Implement panel functions (41) --- .../pra32-u-control-panel-page-table.h | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h index 5206f67..b7cf5f9 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h @@ -13,21 +13,21 @@ struct PRA32_U_ControlPanelPage { char control_target_c_name_line_1[10 + 1]; uint8_t control_target_c; } g_control_panel_page_table[] = { - { "Voice ", " ", "Voice ", "Mode ", VOICE_MODE , "Portamento", " ", PORTAMENTO , "Pitch ", "Bend Range", P_BEND_RANGE , }, - { "Osc 1 ", " ", "Osc 1 ", "Wave ", OSC_1_WAVE , "Osc 1 ", "Shape ", OSC_1_SHAPE , "Osc 1 ", "Morph ", OSC_1_MORPH , }, - { "Osc 2 ", " ", "Osc 2 ", "Wave ", OSC_2_WAVE , "Osc 2 ", "Coarse ", OSC_2_COARSE , "Osc 2 ", "Pitch ", OSC_2_PITCH , }, - { "Mixer ", " ", "Mixer ", "Osc Mix ", MIXER_OSC_MIX , "Mixer ", "Noise/Sub ", MIXER_SUB_OSC , " ", " ", 0xFF , }, - { "Filter a ", " ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Filter ", "EG Amt ", FILTER_EG_AMT , }, - { "Filter b ", " ", "Filter ", "Key Track ", FILTER_KEY_TRK , "Filter ", "Mode ", FILTER_MODE , " ", " ", 0xFF , }, - { "EG a ", " ", "EG ", "Attack ", EG_ATTACK , "EG ", "Decay ", EG_DECAY , "EG ", "Sustain ", EG_SUSTAIN , }, - { "EG b ", " ", "EG ", "Release ", EG_RELEASE , "EG ", "Amp Mod ", EG_AMP_MOD , "Release ", "= Decay ", REL_EQ_DECAY , }, - { "EG c ", " ", "EG ", "Osc Amt ", EG_OSC_AMT , "EG ", "Osc Dst ", EG_OSC_DST , "EG ", "Velo Sens ", EG_VEL_SENS , }, - { "Amp a ", " ", "Amp ", "Attack ", AMP_ATTACK , "Amp ", "Decay ", AMP_DECAY , "Amp ", "Sustain ", AMP_SUSTAIN , }, - { "Amp b ", " ", "Amp ", "Release ", AMP_RELEASE , "Amp ", "Gain ", AMP_GAIN , "Amp ", "Velo Sens ", AMP_VEL_SENS , }, - { "LFO a ", " ", "LFO ", "Wave ", LFO_WAVE , "LFO ", "Rate ", LFO_RATE , "LFO ", "Depth ", LFO_DEPTH , }, - { "LFO b ", " ", "LFO ", "Fade Time ", LFO_FADE_TIME , " ", " ", 0xFF , " ", " ", 0xFF , }, - { "LFO c ", " ", "LFO ", "Osc Amt ", LFO_OSC_AMT , "LFO ", "Osc Dst ", LFO_OSC_DST , "LFO ", "Filter Amt", LFO_FILTER_AMT , }, - { "Breath ", " ", "Breath ", "Filter Amt", BTH_FILTER_AMT , "Breath ", "Amp Mod ", BTH_AMP_MOD , " ", " ", 0xFF , }, - { "Chorus ", " ", "Chorus ", "Mix ", CHORUS_MIX , "Chorus ", "Rate ", CHORUS_RATE , "Chorus ", "Depth ", CHORUS_DEPTH , }, - { "Delay ", " ", "Delay ", "Feedback ", DELAY_FEEDBACK , "Delay ", "Time ", DELAY_TIME , "Delay ", "Mode ", DELAY_MODE , }, + { "Page= 1 ", "Voice ", "Voice ", "Mode ", VOICE_MODE , "Portamento", " ", PORTAMENTO , "Pitch ", "Bend Range", P_BEND_RANGE , }, + { "Page= 2 ", "Osc 1 ", "Osc 1 ", "Wave ", OSC_1_WAVE , "Osc 1 ", "Shape ", OSC_1_SHAPE , "Osc 1 ", "Morph ", OSC_1_MORPH , }, + { "Page= 3 ", "Osc 2 ", "Osc 2 ", "Wave ", OSC_2_WAVE , "Osc 2 ", "Coarse ", OSC_2_COARSE , "Osc 2 ", "Pitch ", OSC_2_PITCH , }, + { "Page= 4 ", "Mixer ", "Mixer ", "Osc Mix ", MIXER_OSC_MIX , "Mixer ", "Noise/Sub ", MIXER_SUB_OSC , " ", " ", 0xFF , }, + { "Page= 5 ", "Filter a ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Filter ", "EG Amt ", FILTER_EG_AMT , }, + { "Page= 6 ", "Filter b ", "Filter ", "Key Track ", FILTER_KEY_TRK , "Filter ", "Mode ", FILTER_MODE , " ", " ", 0xFF , }, + { "Page= 7 ", "EG a ", "EG ", "Attack ", EG_ATTACK , "EG ", "Decay ", EG_DECAY , "EG ", "Sustain ", EG_SUSTAIN , }, + { "Page= 8 ", "EG b ", "EG ", "Release ", EG_RELEASE , "EG ", "Amp Mod ", EG_AMP_MOD , "Release ", "= Decay ", REL_EQ_DECAY , }, + { "Page= 9 ", "EG c ", "EG ", "Osc Amt ", EG_OSC_AMT , "EG ", "Osc Dst ", EG_OSC_DST , "EG ", "Velo Sens ", EG_VEL_SENS , }, + { "Page=10 ", "Amp a ", "Amp ", "Attack ", AMP_ATTACK , "Amp ", "Decay ", AMP_DECAY , "Amp ", "Sustain ", AMP_SUSTAIN , }, + { "Page=11 ", "Amp b ", "Amp ", "Release ", AMP_RELEASE , "Amp ", "Gain ", AMP_GAIN , "Amp ", "Velo Sens ", AMP_VEL_SENS , }, + { "Page=12 ", "LFO a ", "LFO ", "Wave ", LFO_WAVE , "LFO ", "Rate ", LFO_RATE , "LFO ", "Depth ", LFO_DEPTH , }, + { "Page=13 ", "LFO b ", "LFO ", "Fade Time ", LFO_FADE_TIME , " ", " ", 0xFF , " ", " ", 0xFF , }, + { "Page=14 ", "LFO c ", "LFO ", "Osc Amt ", LFO_OSC_AMT , "LFO ", "Osc Dst ", LFO_OSC_DST , "LFO ", "Filter Amt", LFO_FILTER_AMT , }, + { "Page=15 ", "Breath ", "Breath ", "Filter Amt", BTH_FILTER_AMT , "Breath ", "Amp Mod ", BTH_AMP_MOD , " ", " ", 0xFF , }, + { "Page=16 ", "Chorus ", "Chorus ", "Mix ", CHORUS_MIX , "Chorus ", "Rate ", CHORUS_RATE , "Chorus ", "Depth ", CHORUS_DEPTH , }, + { "Page=17 ", "Delay ", "Delay ", "Feedback ", DELAY_FEEDBACK , "Delay ", "Time ", DELAY_TIME , "Delay ", "Mode ", DELAY_MODE , }, }; From 19b8153d7443d94cf8950b57c9f3f51e7de9b21a Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 31 Mar 2024 20:27:09 +0900 Subject: [PATCH 058/106] Implement panel functions (42) --- .../Digital-Synth-PRA32-U.ino | 4 +- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 60 +++++++++---------- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 6ce0356..87d8e66 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -53,7 +53,9 @@ #define PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT // Use ADC0, ADC1, and ADC2 #define PRA32_U_ANALOG_INPUT_REVERSED (true) -#define PRA32_U_ANALOG_INPUT_CORRECTION (-248) +#define PRA32_U_ANALOG_INPUT_CORRECTION (-504) +#define PRA32_U_ANALOG_INPUT_THRESHOLD (504) +#define PRA32_U_ANALOG_INPUT_DENOMINATOR (504) #define PRA32_U_USE_CONTROL_PANEL_OLED_DISPLAY // Use SSD1306 monochrome 128x64 OLED #define PRA32_U_OLED_DISPLAY_I2C (i2c1) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 5444f4a..cbf5b3a 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -62,9 +62,9 @@ static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t volatile int32_t adc_control_value_candidate; #if defined(PRA32_U_ANALOG_INPUT_REVERSED) - adc_control_value_candidate = (127 - (s_adc_current_value[adc_number] >> 9)); + adc_control_value_candidate = (127 - (s_adc_current_value[adc_number] / PRA32_U_ANALOG_INPUT_DENOMINATOR)); #else // defined(PRA32_U_ANALOG_INPUT_REVERSED) - adc_control_value_candidate = (s_adc_current_value[adc_number] >> 9); + adc_control_value_candidate = (s_adc_current_value[adc_number] / PRA32_U_ANALOG_INPUT_DENOMINATOR); #endif // defined(PRA32_U_ANALOG_INPUT_REVERSED) if (adc_control_value_candidate > 127) { @@ -157,63 +157,63 @@ INLINE void PRA32_U_ControlPanel_update_analog_inputs(uint32_t loop_counter) { #if defined(PRA32_U_USE_CONTROL_PANEL) #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) - static int32_t s_adc_average_value = 0; + static int32_t s_adc_total_value = 0; switch (loop_counter & 0x3F) { case 0x10: adc_select_input(0); - s_adc_average_value = PRA32_U_ANALOG_INPUT_CORRECTION; - s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); + s_adc_total_value = PRA32_U_ANALOG_INPUT_CORRECTION; + s_adc_total_value += adc_read() + adc_read() + adc_read() + adc_read(); break; case 0x14: - s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); + s_adc_total_value += adc_read() + adc_read() + adc_read() + adc_read(); break; case 0x18: - s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); + s_adc_total_value += adc_read() + adc_read() + adc_read() + adc_read(); break; case 0x1C: - s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); - if (s_adc_current_value[0] >= s_adc_average_value + 512) { - s_adc_current_value[0] = s_adc_average_value; - } else if (s_adc_current_value[0] + 512 <= s_adc_average_value ) { - s_adc_current_value[0] = s_adc_average_value; + s_adc_total_value += adc_read() + adc_read() + adc_read() + adc_read(); + if (s_adc_current_value[0] >= s_adc_total_value + PRA32_U_ANALOG_INPUT_THRESHOLD) { + s_adc_current_value[0] = s_adc_total_value; + } else if (s_adc_current_value[0] + PRA32_U_ANALOG_INPUT_THRESHOLD <= s_adc_total_value ) { + s_adc_current_value[0] = s_adc_total_value; } break; case 0x20: adc_select_input(1); - s_adc_average_value = PRA32_U_ANALOG_INPUT_CORRECTION; - s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); + s_adc_total_value = PRA32_U_ANALOG_INPUT_CORRECTION; + s_adc_total_value += adc_read() + adc_read() + adc_read() + adc_read(); break; case 0x24: - s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); + s_adc_total_value += adc_read() + adc_read() + adc_read() + adc_read(); break; case 0x28: - s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); + s_adc_total_value += adc_read() + adc_read() + adc_read() + adc_read(); break; case 0x2C: - s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); - if (s_adc_current_value[1] >= s_adc_average_value + 512) { - s_adc_current_value[1] = s_adc_average_value; - } else if (s_adc_current_value[1] + 512 <= s_adc_average_value ) { - s_adc_current_value[1] = s_adc_average_value; + s_adc_total_value += adc_read() + adc_read() + adc_read() + adc_read(); + if (s_adc_current_value[1] >= s_adc_total_value + PRA32_U_ANALOG_INPUT_THRESHOLD) { + s_adc_current_value[1] = s_adc_total_value; + } else if (s_adc_current_value[1] + PRA32_U_ANALOG_INPUT_THRESHOLD <= s_adc_total_value ) { + s_adc_current_value[1] = s_adc_total_value; } break; case 0x30: adc_select_input(2); - s_adc_average_value = PRA32_U_ANALOG_INPUT_CORRECTION; - s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); + s_adc_total_value = PRA32_U_ANALOG_INPUT_CORRECTION; + s_adc_total_value += adc_read() + adc_read() + adc_read() + adc_read(); break; case 0x34: - s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); + s_adc_total_value += adc_read() + adc_read() + adc_read() + adc_read(); break; case 0x38: - s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); + s_adc_total_value += adc_read() + adc_read() + adc_read() + adc_read(); break; case 0x3C: - s_adc_average_value += adc_read() + adc_read() + adc_read() + adc_read(); - if (s_adc_current_value[2] >= s_adc_average_value + 512) { - s_adc_current_value[2] = s_adc_average_value; - } else if (s_adc_current_value[2] + 512 <= s_adc_average_value ) { - s_adc_current_value[2] = s_adc_average_value; + s_adc_total_value += adc_read() + adc_read() + adc_read() + adc_read(); + if (s_adc_current_value[2] >= s_adc_total_value + PRA32_U_ANALOG_INPUT_THRESHOLD) { + s_adc_current_value[2] = s_adc_total_value; + } else if (s_adc_current_value[2] + PRA32_U_ANALOG_INPUT_THRESHOLD <= s_adc_total_value ) { + s_adc_current_value[2] = s_adc_total_value; } break; } From b5b2479083076c653c5cd10533c96d51a1d65de2 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 11:32:18 +0900 Subject: [PATCH 059/106] Implement panel functions (43) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index cbf5b3a..409c3ea 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -414,8 +414,8 @@ INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { uint32_t display_draw_counter = s_display_draw_counter; s_display_draw_counter++; - if (s_display_draw_counter == 6 * 21) { - s_display_draw_counter = 4 * 21; + if (s_display_draw_counter == 8 * 21) { + s_display_draw_counter = (6 * 21) + 11; } switch (display_draw_counter / 21) { @@ -426,17 +426,23 @@ INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { s_display_draw_position_y = 2; break; case 2: - s_display_draw_position_y = 5; + s_display_draw_position_y = 3; break; case 3: - s_display_draw_position_y = 6; + s_display_draw_position_y = 5; break; case 4: - s_display_draw_position_y = 3; + s_display_draw_position_y = 6; break; case 5: s_display_draw_position_y = 7; break; + case 6: + s_display_draw_position_y = 3; + break; + case 7: + s_display_draw_position_y = 7; + break; } s_display_draw_position_x = display_draw_counter % 21; From 579c4a6a011debb7d2521227737f0fdf9e264660 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 11:32:37 +0900 Subject: [PATCH 060/106] Implement panel functions (44) --- .../pra32-u-control-panel-font-table.h | 6 +- .../pra32-u-control-panel-page-table.h | 70 ++++++++++++++----- 2 files changed, 56 insertions(+), 20 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h index 5f990c1..0f28af2 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h @@ -211,11 +211,11 @@ uint8_t g_control_panel_font_table[128][6] = { 0b01000001, 0b01111111, 0b00000000, + 0b00100010, 0b01111111, - 0b01000001, - 0b01000001, - 0b01000001, + 0b00100010, 0b01111111, + 0b00100010, 0b00000000, 0b01111111, 0b01000001, diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h index b7cf5f9..f4caab2 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h @@ -1,5 +1,32 @@ #pragma once +const uint8_t PC_BY_PANEL_0 = 128; +const uint8_t PC_BY_PANEL_1 = 129; +const uint8_t PC_BY_PANEL_2 = 130; +const uint8_t PC_BY_PANEL_3 = 131; +const uint8_t PC_BY_PANEL_4 = 132; +const uint8_t PC_BY_PANEL_5 = 133; +const uint8_t PC_BY_PANEL_6 = 134; +const uint8_t PC_BY_PANEL_7 = 135; + +const uint8_t PC_BY_PANEL_8 = 136; +const uint8_t PC_BY_PANEL_9 = 137; +const uint8_t PC_BY_PANEL_10 = 138; +const uint8_t PC_BY_PANEL_11 = 139; +const uint8_t PC_BY_PANEL_12 = 140; +const uint8_t PC_BY_PANEL_13 = 141; +const uint8_t PC_BY_PANEL_14 = 142; +const uint8_t PC_BY_PANEL_15 = 143; + +const uint8_t WR_BY_PANEL_8 = 152; +const uint8_t WR_BY_PANEL_9 = 153; +const uint8_t WR_BY_PANEL_10 = 154; +const uint8_t WR_BY_PANEL_11 = 155; +const uint8_t WR_BY_PANEL_12 = 156; +const uint8_t WR_BY_PANEL_13 = 157; +const uint8_t WR_BY_PANEL_14 = 158; +const uint8_t WR_BY_PANEL_15 = 159; + struct PRA32_U_ControlPanelPage { char page_name_line_0 [10 + 1]; char page_name_line_1 [10 + 1]; @@ -13,21 +40,30 @@ struct PRA32_U_ControlPanelPage { char control_target_c_name_line_1[10 + 1]; uint8_t control_target_c; } g_control_panel_page_table[] = { - { "Page= 1 ", "Voice ", "Voice ", "Mode ", VOICE_MODE , "Portamento", " ", PORTAMENTO , "Pitch ", "Bend Range", P_BEND_RANGE , }, - { "Page= 2 ", "Osc 1 ", "Osc 1 ", "Wave ", OSC_1_WAVE , "Osc 1 ", "Shape ", OSC_1_SHAPE , "Osc 1 ", "Morph ", OSC_1_MORPH , }, - { "Page= 3 ", "Osc 2 ", "Osc 2 ", "Wave ", OSC_2_WAVE , "Osc 2 ", "Coarse ", OSC_2_COARSE , "Osc 2 ", "Pitch ", OSC_2_PITCH , }, - { "Page= 4 ", "Mixer ", "Mixer ", "Osc Mix ", MIXER_OSC_MIX , "Mixer ", "Noise/Sub ", MIXER_SUB_OSC , " ", " ", 0xFF , }, - { "Page= 5 ", "Filter a ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Filter ", "EG Amt ", FILTER_EG_AMT , }, - { "Page= 6 ", "Filter b ", "Filter ", "Key Track ", FILTER_KEY_TRK , "Filter ", "Mode ", FILTER_MODE , " ", " ", 0xFF , }, - { "Page= 7 ", "EG a ", "EG ", "Attack ", EG_ATTACK , "EG ", "Decay ", EG_DECAY , "EG ", "Sustain ", EG_SUSTAIN , }, - { "Page= 8 ", "EG b ", "EG ", "Release ", EG_RELEASE , "EG ", "Amp Mod ", EG_AMP_MOD , "Release ", "= Decay ", REL_EQ_DECAY , }, - { "Page= 9 ", "EG c ", "EG ", "Osc Amt ", EG_OSC_AMT , "EG ", "Osc Dst ", EG_OSC_DST , "EG ", "Velo Sens ", EG_VEL_SENS , }, - { "Page=10 ", "Amp a ", "Amp ", "Attack ", AMP_ATTACK , "Amp ", "Decay ", AMP_DECAY , "Amp ", "Sustain ", AMP_SUSTAIN , }, - { "Page=11 ", "Amp b ", "Amp ", "Release ", AMP_RELEASE , "Amp ", "Gain ", AMP_GAIN , "Amp ", "Velo Sens ", AMP_VEL_SENS , }, - { "Page=12 ", "LFO a ", "LFO ", "Wave ", LFO_WAVE , "LFO ", "Rate ", LFO_RATE , "LFO ", "Depth ", LFO_DEPTH , }, - { "Page=13 ", "LFO b ", "LFO ", "Fade Time ", LFO_FADE_TIME , " ", " ", 0xFF , " ", " ", 0xFF , }, - { "Page=14 ", "LFO c ", "LFO ", "Osc Amt ", LFO_OSC_AMT , "LFO ", "Osc Dst ", LFO_OSC_DST , "LFO ", "Filter Amt", LFO_FILTER_AMT , }, - { "Page=15 ", "Breath ", "Breath ", "Filter Amt", BTH_FILTER_AMT , "Breath ", "Amp Mod ", BTH_AMP_MOD , " ", " ", 0xFF , }, - { "Page=16 ", "Chorus ", "Chorus ", "Mix ", CHORUS_MIX , "Chorus ", "Rate ", CHORUS_RATE , "Chorus ", "Depth ", CHORUS_DEPTH , }, - { "Page=17 ", "Delay ", "Delay ", "Feedback ", DELAY_FEEDBACK , "Delay ", "Time ", DELAY_TIME , "Delay ", "Mode ", DELAY_MODE , }, + { "Page= 1 ", "Voice ", "Voice ", "Mode ", VOICE_MODE , "Portamento", " ", PORTAMENTO , "Pitch ", "Bend Range", P_BEND_RANGE , }, + { "Page= 2 ", "Osc 1 ", "Osc 1 ", "Wave ", OSC_1_WAVE , "Osc 1 ", "Shape ", OSC_1_SHAPE , "Osc 1 ", "Morph ", OSC_1_MORPH , }, + { "Page= 3 ", "Osc 2 ", "Osc 2 ", "Wave ", OSC_2_WAVE , "Osc 2 ", "Coarse ", OSC_2_COARSE , "Osc 2 ", "Pitch ", OSC_2_PITCH , }, + { "Page= 4 ", "Mixer ", "Mixer ", "Osc Mix ", MIXER_OSC_MIX , "Mixer ", "Noise/Sub ", MIXER_SUB_OSC , " ", " ", 0xFF , }, + { "Page= 5 ", "Filter a ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Filter ", "EG Amt ", FILTER_EG_AMT , }, + { "Page= 6 ", "Filter b ", "Filter ", "Key Track ", FILTER_KEY_TRK , "Filter ", "Mode ", FILTER_MODE , " ", " ", 0xFF , }, + { "Page= 7 ", "EG a ", "EG ", "Attack ", EG_ATTACK , "EG ", "Decay ", EG_DECAY , "EG ", "Sustain ", EG_SUSTAIN , }, + { "Page= 8 ", "EG b ", "EG ", "Release ", EG_RELEASE , "EG ", "Amp Mod ", EG_AMP_MOD , "Release ", "= Decay ", REL_EQ_DECAY , }, + { "Page= 9 ", "EG c ", "EG ", "Osc Amt ", EG_OSC_AMT , "EG ", "Osc Dst ", EG_OSC_DST , "EG ", "Velo Sens ", EG_VEL_SENS , }, + { "Page=10 ", "Amp a ", "Amp ", "Attack ", AMP_ATTACK , "Amp ", "Decay ", AMP_DECAY , "Amp ", "Sustain ", AMP_SUSTAIN , }, + { "Page=11 ", "Amp b ", "Amp ", "Release ", AMP_RELEASE , "Amp ", "Gain ", AMP_GAIN , "Amp ", "Velo Sens ", AMP_VEL_SENS , }, + { "Page=12 ", "LFO a ", "LFO ", "Wave ", LFO_WAVE , "LFO ", "Rate ", LFO_RATE , "LFO ", "Depth ", LFO_DEPTH , }, + { "Page=13 ", "LFO b ", "LFO ", "Fade Time ", LFO_FADE_TIME , " ", " ", 0xFF , " ", " ", 0xFF , }, + { "Page=14 ", "LFO c ", "LFO ", "Osc Amt ", LFO_OSC_AMT , "LFO ", "Osc Dst ", LFO_OSC_DST , "LFO ", "Filter Amt", LFO_FILTER_AMT , }, + { "Page=15 ", "Breath ", "Breath ", "Filter Amt", BTH_FILTER_AMT , "Breath ", "Amp Mod ", BTH_AMP_MOD , " ", " ", 0xFF , }, + { "Page=16 ", "Chorus ", "Chorus ", "Mix ", CHORUS_MIX , "Chorus ", "Rate ", CHORUS_RATE , "Chorus ", "Depth ", CHORUS_DEPTH , }, + { "Page=17 ", "Delay ", "Delay ", "Feedback ", DELAY_FEEDBACK , "Delay ", "Time ", DELAY_TIME , "Delay ", "Mode ", DELAY_MODE , }, + { "Page=18 ", "Program a ", "Program ", "Change #0", PC_BY_PANEL_0 , "Program ", "Change #1", PC_BY_PANEL_1 , "Program ", "Change #2", PC_BY_PANEL_2 , }, + { "Page=19 ", "Program b ", "Program ", "Change #3", PC_BY_PANEL_3 , "Program ", "Change #4", PC_BY_PANEL_4 , "Program ", "Change #5", PC_BY_PANEL_5 , }, + { "Page=20 ", "Program c ", "Program ", "Change #6", PC_BY_PANEL_6 , "Program ", "Change #7", PC_BY_PANEL_7 , " ", " ", 0xFF , }, + { "Page=21 ", "Program d ", "Program ", "Change #8", PC_BY_PANEL_8 , "Program ", "Change #9", PC_BY_PANEL_9 , "Program ", "Change #10", PC_BY_PANEL_10 , }, + { "Page=22 ", "Program e ", "Program ", "Change #11", PC_BY_PANEL_11 , "Program ", "Change #12", PC_BY_PANEL_12 , "Program ", "Change #13", PC_BY_PANEL_13 , }, + { "Page=23 ", "Program f ", "Program ", "Change #14", PC_BY_PANEL_14 , "Program ", "Change #15", PC_BY_PANEL_15 , " ", " ", 0xFF , }, + { "Page=24 ", "Program g ", "Program ", "Write #8", WR_BY_PANEL_8 , "Program ", "Write #9", WR_BY_PANEL_9 , "Program ", "Write #10", WR_BY_PANEL_10 , }, + { "Page=25 ", "Program h ", "Program ", "Write #11", WR_BY_PANEL_11 , "Program ", "Write #12", WR_BY_PANEL_12 , "Program ", "Write #13", WR_BY_PANEL_13 , }, + { "Page=26 ", "Program i ", "Program ", "Write #14", WR_BY_PANEL_14 , "Program ", "Write #15", WR_BY_PANEL_15 , " ", " ", 0xFF , }, }; From 21fc4247396df4d3ab514f84f8763c3f777e76d4 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 11:44:59 +0900 Subject: [PATCH 061/106] Implement panel functions (45) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 409c3ea..4fc1f5b 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -332,9 +332,12 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { char buff[6]; uint8_t adc_control_target_0 = s_adc_control_target[0]; - if (adc_control_target_0 <= 127) { + if (adc_control_target_0 < 0xFF) { uint8_t adc_control_value = s_adc_control_value[0]; - uint8_t current_controller_value = g_synth.current_controller_value(adc_control_target_0); + uint8_t current_controller_value = adc_control_value; + if (adc_control_target_0 <= 0x7F) { + current_controller_value = g_synth.current_controller_value(adc_control_target_0); + } s_display_buffer[7][ 0] = 'A'; if (adc_control_value < current_controller_value) { @@ -352,9 +355,12 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { } uint8_t adc_control_target_1 = s_adc_control_target[1]; - if (adc_control_target_1 <= 127) { + if (adc_control_target_1 < 0xFF) { uint8_t adc_control_value = s_adc_control_value[1]; - uint8_t current_controller_value = g_synth.current_controller_value(adc_control_target_1); + uint8_t current_controller_value = adc_control_value; + if (adc_control_target_1 <= 0x7F) { + current_controller_value = g_synth.current_controller_value(adc_control_target_1); + } s_display_buffer[7][11] = 'B'; if (adc_control_value < current_controller_value) { @@ -372,9 +378,12 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { } uint8_t adc_control_target_2 = s_adc_control_target[2]; - if (adc_control_target_2 <= 127) { + if (adc_control_target_2 < 0xFF) { uint8_t adc_control_value = s_adc_control_value[2]; - uint8_t current_controller_value = g_synth.current_controller_value(adc_control_target_2); + uint8_t current_controller_value = adc_control_value; + if (adc_control_target_2 <= 0x7F) { + current_controller_value = g_synth.current_controller_value(adc_control_target_2); + } s_display_buffer[3][11] = 'C'; if (adc_control_value < current_controller_value) { From 8769a3e2f87cce52b6094d8b48f5527287ac66c6 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 12:48:51 +0900 Subject: [PATCH 062/106] Implement panel functions (46) --- .../pra32-u-control-panel-page-table.h | 30 +++++-- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 26 ++++-- Digital-Synth-PRA32-U/pra32-u-synth.h | 84 ++++++++++--------- 3 files changed, 86 insertions(+), 54 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h index f4caab2..a0f2091 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h @@ -18,6 +18,15 @@ const uint8_t PC_BY_PANEL_13 = 141; const uint8_t PC_BY_PANEL_14 = 142; const uint8_t PC_BY_PANEL_15 = 143; +const uint8_t WR_BY_PANEL_0 = 144; // Invalid +const uint8_t WR_BY_PANEL_1 = 145; // Invalid +const uint8_t WR_BY_PANEL_2 = 146; // Invalid +const uint8_t WR_BY_PANEL_3 = 147; // Invalid +const uint8_t WR_BY_PANEL_4 = 148; // Invalid +const uint8_t WR_BY_PANEL_5 = 149; // Invalid +const uint8_t WR_BY_PANEL_6 = 150; // Invalid +const uint8_t WR_BY_PANEL_7 = 151; // Invalid + const uint8_t WR_BY_PANEL_8 = 152; const uint8_t WR_BY_PANEL_9 = 153; const uint8_t WR_BY_PANEL_10 = 154; @@ -57,13 +66,16 @@ struct PRA32_U_ControlPanelPage { { "Page=15 ", "Breath ", "Breath ", "Filter Amt", BTH_FILTER_AMT , "Breath ", "Amp Mod ", BTH_AMP_MOD , " ", " ", 0xFF , }, { "Page=16 ", "Chorus ", "Chorus ", "Mix ", CHORUS_MIX , "Chorus ", "Rate ", CHORUS_RATE , "Chorus ", "Depth ", CHORUS_DEPTH , }, { "Page=17 ", "Delay ", "Delay ", "Feedback ", DELAY_FEEDBACK , "Delay ", "Time ", DELAY_TIME , "Delay ", "Mode ", DELAY_MODE , }, - { "Page=18 ", "Program a ", "Program ", "Change #0", PC_BY_PANEL_0 , "Program ", "Change #1", PC_BY_PANEL_1 , "Program ", "Change #2", PC_BY_PANEL_2 , }, - { "Page=19 ", "Program b ", "Program ", "Change #3", PC_BY_PANEL_3 , "Program ", "Change #4", PC_BY_PANEL_4 , "Program ", "Change #5", PC_BY_PANEL_5 , }, - { "Page=20 ", "Program c ", "Program ", "Change #6", PC_BY_PANEL_6 , "Program ", "Change #7", PC_BY_PANEL_7 , " ", " ", 0xFF , }, - { "Page=21 ", "Program d ", "Program ", "Change #8", PC_BY_PANEL_8 , "Program ", "Change #9", PC_BY_PANEL_9 , "Program ", "Change #10", PC_BY_PANEL_10 , }, - { "Page=22 ", "Program e ", "Program ", "Change #11", PC_BY_PANEL_11 , "Program ", "Change #12", PC_BY_PANEL_12 , "Program ", "Change #13", PC_BY_PANEL_13 , }, - { "Page=23 ", "Program f ", "Program ", "Change #14", PC_BY_PANEL_14 , "Program ", "Change #15", PC_BY_PANEL_15 , " ", " ", 0xFF , }, - { "Page=24 ", "Program g ", "Program ", "Write #8", WR_BY_PANEL_8 , "Program ", "Write #9", WR_BY_PANEL_9 , "Program ", "Write #10", WR_BY_PANEL_10 , }, - { "Page=25 ", "Program h ", "Program ", "Write #11", WR_BY_PANEL_11 , "Program ", "Write #12", WR_BY_PANEL_12 , "Program ", "Write #13", WR_BY_PANEL_13 , }, - { "Page=26 ", "Program i ", "Program ", "Write #14", WR_BY_PANEL_14 , "Program ", "Write #15", WR_BY_PANEL_15 , " ", " ", 0xFF , }, + { "Page=18 ", "Program a ", "Program ", "Change #0", PC_BY_PANEL_0 , "Program ", "Change #1", PC_BY_PANEL_1 , " ", " ", 0xFF , }, + { "Page=19 ", "Program b ", "Program ", "Change #2", PC_BY_PANEL_2 , "Program ", "Change #3", PC_BY_PANEL_3 , " ", " ", 0xFF , }, + { "Page=20 ", "Program c ", "Program ", "Change #4", PC_BY_PANEL_4 , "Program ", "Change #5", PC_BY_PANEL_5 , " ", " ", 0xFF , }, + { "Page=21 ", "Program d ", "Program ", "Change #6", PC_BY_PANEL_6 , "Program ", "Change #7", PC_BY_PANEL_7 , " ", " ", 0xFF , }, + { "Page=22 ", "Program e ", "Program ", "Change #8", PC_BY_PANEL_8 , "Program ", "Change #9", PC_BY_PANEL_9 , " ", " ", 0xFF , }, + { "Page=23 ", "Program f ", "Program ", "Change #10", PC_BY_PANEL_10 , "Program ", "Change #11", PC_BY_PANEL_11 , " ", " ", 0xFF , }, + { "Page=24 ", "Program g ", "Program ", "Change #12", PC_BY_PANEL_12 , "Program ", "Change #13", PC_BY_PANEL_13 , " ", " ", 0xFF , }, + { "Page=25 ", "Program h ", "Program ", "Change #14", PC_BY_PANEL_14 , "Program ", "Change #15", PC_BY_PANEL_15 , " ", " ", 0xFF , }, + { "Page=26 ", "Program i ", "Program ", "Write #8", WR_BY_PANEL_8 , "Program ", "Write #9", WR_BY_PANEL_9 , " ", " ", 0xFF , }, + { "Page=27 ", "Program j ", "Program ", "Write #10", WR_BY_PANEL_10 , "Program ", "Write #11", WR_BY_PANEL_11 , " ", " ", 0xFF , }, + { "Page=28 ", "Program k ", "Program ", "Write #12", WR_BY_PANEL_12 , "Program ", "Write #13", WR_BY_PANEL_13 , " ", " ", 0xFF , }, + { "Page=29 ", "Program l ", "Program ", "Write #14", WR_BY_PANEL_14 , "Program ", "Write #15", WR_BY_PANEL_15 , " ", " ", 0xFF , }, }; diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 4fc1f5b..cf672b2 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -78,11 +78,25 @@ static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t return adc_control_value_candidate; } -static INLINE boolean PRA32_U_ControlPanel_update_adc_control(uint32_t adc_number) { - uint32_t adc_control_value_candidate = PRA32_U_ControlPanel_adc_control_value_candidate(adc_number); +static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_number) { + uint8_t adc_control_value_candidate = PRA32_U_ControlPanel_adc_control_value_candidate(adc_number); + if (s_adc_control_value[adc_number] != adc_control_value_candidate) { + uint8_t s_adc_control_value_old = s_adc_control_value[adc_number]; s_adc_control_value[adc_number] = adc_control_value_candidate; - g_synth.control_change(s_adc_control_target[adc_number], s_adc_control_value[adc_number]); + + if (s_adc_control_target[adc_number] <= 0x7F) { + g_synth.control_change(s_adc_control_target[adc_number], s_adc_control_value[adc_number]); + } else if ((s_adc_control_target[adc_number] >= PC_BY_PANEL_0) && (s_adc_control_target[adc_number] <= PC_BY_PANEL_15)) { + if ((s_adc_control_value_old < 64) && (s_adc_control_value[adc_number] >= 64)) { + g_synth.program_change(s_adc_control_target[adc_number] - PC_BY_PANEL_0); + } + } else if ((s_adc_control_target[adc_number] >= WR_BY_PANEL_0) && (s_adc_control_target[adc_number] <= WR_BY_PANEL_15)) { + if ((s_adc_control_value_old < 64) && (s_adc_control_value[adc_number] >= 64)) { + g_synth.write_parameters_to_program(s_adc_control_target[adc_number] - WR_BY_PANEL_0); + } + } + return true; } @@ -307,15 +321,15 @@ INLINE void PRA32_U_ControlPanel_update_control() { #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) static uint32_t s_adc_number_to_check = 0; - boolean updated = PRA32_U_ControlPanel_update_adc_control(s_adc_number_to_check); + boolean updated = PRA32_U_ControlPanel_update_control_adc(s_adc_number_to_check); s_adc_number_to_check = (s_adc_number_to_check + 1) % 3; if (updated == false) { - updated = PRA32_U_ControlPanel_update_adc_control(s_adc_number_to_check); + updated = PRA32_U_ControlPanel_update_control_adc(s_adc_number_to_check); s_adc_number_to_check = (s_adc_number_to_check + 1) % 3; if (updated == false) { - updated = PRA32_U_ControlPanel_update_adc_control(s_adc_number_to_check); + updated = PRA32_U_ControlPanel_update_control_adc(s_adc_number_to_check); s_adc_number_to_check = (s_adc_number_to_check + 1) % 3; } } diff --git a/Digital-Synth-PRA32-U/pra32-u-synth.h b/Digital-Synth-PRA32-U/pra32-u-synth.h index 04f91fc..8574295 100644 --- a/Digital-Synth-PRA32-U/pra32-u-synth.h +++ b/Digital-Synth-PRA32-U/pra32-u-synth.h @@ -125,7 +125,7 @@ class PRA32_U_Synth { uint8_t m_program_number_to_write; uint8_t m_wr_prog_to_flash_cc_value; uint8_t m_sp_prog_chg_cc_values[8]; - uint8_t m_current_controller_value_table[128]; + uint8_t m_current_controller_value_table[128 + 128]; uint8_t m_program_table[128][PROGRAM_NUMBER_MAX + 1]; volatile int32_t m_secondary_core_processing_argument; @@ -856,44 +856,8 @@ class PRA32_U_Synth { uint8_t old_value = m_wr_prog_to_flash_cc_value; m_wr_prog_to_flash_cc_value = controller_value; - if (m_program_number_to_write >= (PRESET_PROGRAM_NUMBER_MAX + 1)) { - if ((old_value == 0) && (controller_value >= 1)) { - for (uint32_t i = 0; i < sizeof(s_program_table_parameters) / sizeof(s_program_table_parameters[0]); ++i) { - uint32_t control_number = s_program_table_parameters[i]; - m_program_table[control_number][m_program_number_to_write] = m_current_controller_value_table[control_number]; - } - -#if defined(ARDUINO_ARCH_RP2040) -#if defined(PRA32_U_USE_EMULATED_EEPROM) - for (uint32_t i = 0; i < sizeof(s_program_table_parameters) / sizeof(s_program_table_parameters[0]); ++i) { - uint32_t control_number = s_program_table_parameters[i]; - EEPROM.write(m_program_number_to_write * 128 + control_number, m_current_controller_value_table[control_number]); - } - - EEPROM.write(m_program_number_to_write * 128, 'U'); - EEPROM.write(m_program_number_to_write * 128 + 1, m_program_number_to_write); - -#if !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) - // To avoid noise, the data will not be written to the flash - // if PRA32_U_I2S_DAC_MUTE_OFF_PIN is not defined or PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S is defined - -#if defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) - digitalWrite(PRA32_U_I2S_DAC_MUTE_OFF_PIN, LOW); -#else // defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) - g_i2s_output.end(); -#endif // defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) - - EEPROM.commit(); - -#if defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) - digitalWrite(PRA32_U_I2S_DAC_MUTE_OFF_PIN, HIGH); -#else // defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) - g_i2s_output.begin(); -#endif // defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) -#endif -#endif // defined(PRA32_U_USE_EMULATED_EEPROM) -#endif // defined(ARDUINO_ARCH_RP2040) - } + if ((old_value == 0) && (m_wr_prog_to_flash_cc_value >= 1)) { + write_parameters_to_program(m_program_number_to_write); } } break; @@ -935,6 +899,48 @@ class PRA32_U_Synth { } } + /* INLINE */ void write_parameters_to_program(uint8_t program_number_to_write) { + if (m_program_number_to_write < (PRESET_PROGRAM_NUMBER_MAX + 1)) { + return; + } + + for (uint32_t i = 0; i < sizeof(s_program_table_parameters) / sizeof(s_program_table_parameters[0]); ++i) { + uint32_t control_number = s_program_table_parameters[i]; + m_program_table[control_number][program_number_to_write] = m_current_controller_value_table[control_number]; + } + +#if defined(ARDUINO_ARCH_RP2040) +#if defined(PRA32_U_USE_EMULATED_EEPROM) + for (uint32_t i = 0; i < sizeof(s_program_table_parameters) / sizeof(s_program_table_parameters[0]); ++i) { + uint32_t control_number = s_program_table_parameters[i]; + EEPROM.write(program_number_to_write * 128 + control_number, m_current_controller_value_table[control_number]); + } + + EEPROM.write(program_number_to_write * 128, 'U'); + EEPROM.write(program_number_to_write * 128 + 1, program_number_to_write); + +#if !defined(PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S) + // To avoid noise, the data will not be written to the flash + // if PRA32_U_I2S_DAC_MUTE_OFF_PIN is not defined or PRA32_U_USE_PWM_AUDIO_INSTEAD_OF_I2S is defined + +#if defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) + digitalWrite(PRA32_U_I2S_DAC_MUTE_OFF_PIN, LOW); +#else // defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) + g_i2s_output.end(); +#endif // defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) + + EEPROM.commit(); + +#if defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) + digitalWrite(PRA32_U_I2S_DAC_MUTE_OFF_PIN, HIGH); +#else // defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) + g_i2s_output.begin(); +#endif // defined(PRA32_U_I2S_DAC_MUTE_OFF_PIN) +#endif +#endif // defined(PRA32_U_USE_EMULATED_EEPROM) +#endif // defined(ARDUINO_ARCH_RP2040) + } + INLINE int16_t process(int16_t& right_level) { ++m_count; From 1caa6b2b0469aed60b08a647ce2ee0940629e184 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 13:36:31 +0900 Subject: [PATCH 063/106] Implement panel functions (47) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 11 +++++++++-- Digital-Synth-PRA32-U/pra32-u-synth.h | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index cf672b2..d0e4f84 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -92,8 +92,15 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe g_synth.program_change(s_adc_control_target[adc_number] - PC_BY_PANEL_0); } } else if ((s_adc_control_target[adc_number] >= WR_BY_PANEL_0) && (s_adc_control_target[adc_number] <= WR_BY_PANEL_15)) { - if ((s_adc_control_value_old < 64) && (s_adc_control_value[adc_number] >= 64)) { - g_synth.write_parameters_to_program(s_adc_control_target[adc_number] - WR_BY_PANEL_0); + static boolean s_ready_to_write[PROGRAM_NUMBER_MAX + 1] = {}; + + uint8_t program_number_to_write = s_adc_control_target[adc_number] - WR_BY_PANEL_0; + + if (s_adc_control_value[adc_number] == 0) { + s_ready_to_write[program_number_to_write] = true; + } else if (s_ready_to_write[program_number_to_write] && (s_adc_control_value[adc_number] == 127)) { + g_synth.write_parameters_to_program(program_number_to_write); + s_ready_to_write[program_number_to_write] = false; } } diff --git a/Digital-Synth-PRA32-U/pra32-u-synth.h b/Digital-Synth-PRA32-U/pra32-u-synth.h index 8574295..5d84542 100644 --- a/Digital-Synth-PRA32-U/pra32-u-synth.h +++ b/Digital-Synth-PRA32-U/pra32-u-synth.h @@ -900,7 +900,7 @@ class PRA32_U_Synth { } /* INLINE */ void write_parameters_to_program(uint8_t program_number_to_write) { - if (m_program_number_to_write < (PRESET_PROGRAM_NUMBER_MAX + 1)) { + if (program_number_to_write < (PRESET_PROGRAM_NUMBER_MAX + 1)) { return; } From 66989841c8f3e787011ff60f8db7354285bfb7cb Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 14:00:20 +0900 Subject: [PATCH 064/106] Implement panel functions (48) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 55 +++++++++++++++++-- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index d0e4f84..d96b02c 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -123,6 +123,26 @@ static INLINE void PRA32_U_ControlPanel_draw_character(uint8_t c) { i2c_write_blocking(PRA32_U_OLED_DISPLAY_I2C, PRA32_U_OLED_DISPLAY_I2C_ADDRESS, data, sizeof(data), false); } +static INLINE boolean PRA32_U_ControlPanel_calc_value_text(uint8_t control_target, uint8_t controller_value, char value_text[5]) +{ + boolean result = false; + + switch (control_target) { + case OSC_2_COARSE : + case OSC_2_PITCH : + case FILTER_EG_AMT : + case EG_OSC_AMT : + case LFO_OSC_AMT : + case LFO_FILTER_AMT : + case BTH_FILTER_AMT : + std::sprintf(value_text, "%+3d", static_cast(controller_value) - 64); + result = true; + break; + } + + return result; +} + INLINE void PRA32_U_ControlPanel_setup() { @@ -373,6 +393,16 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { s_display_buffer[7][ 2] = buff[0]; s_display_buffer[7][ 3] = buff[1]; s_display_buffer[7][ 4] = buff[2]; + + char value_text[5]; + boolean exists = PRA32_U_ControlPanel_calc_value_text(adc_control_target_0, current_controller_value, value_text); + if (exists) { + s_display_buffer[7][ 5] = '['; + s_display_buffer[7][ 6] = value_text[0]; + s_display_buffer[7][ 7] = value_text[1]; + s_display_buffer[7][ 8] = value_text[2]; + s_display_buffer[7][ 9] = ']'; + } } uint8_t adc_control_target_1 = s_adc_control_target[1]; @@ -396,6 +426,16 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { s_display_buffer[7][13] = buff[0]; s_display_buffer[7][14] = buff[1]; s_display_buffer[7][15] = buff[2]; + + char value_text[5]; + boolean exists = PRA32_U_ControlPanel_calc_value_text(adc_control_target_1, current_controller_value, value_text); + if (exists) { + s_display_buffer[7][16] = '['; + s_display_buffer[7][17] = value_text[0]; + s_display_buffer[7][18] = value_text[1]; + s_display_buffer[7][19] = value_text[2]; + s_display_buffer[7][20] = ']'; + } } uint8_t adc_control_target_2 = s_adc_control_target[2]; @@ -420,12 +460,15 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { s_display_buffer[3][14] = buff[1]; s_display_buffer[3][15] = buff[2]; -#if 0 - std::sprintf(buff, "%+3d", static_cast(current_controller_value) - 64); - s_display_buffer[3][17] = buff[0]; - s_display_buffer[3][18] = buff[1]; - s_display_buffer[3][19] = buff[2]; -#endif + char value_text[5]; + boolean exists = PRA32_U_ControlPanel_calc_value_text(adc_control_target_2, current_controller_value, value_text); + if (exists) { + s_display_buffer[3][16] = '['; + s_display_buffer[3][17] = value_text[0]; + s_display_buffer[3][18] = value_text[1]; + s_display_buffer[3][19] = value_text[2]; + s_display_buffer[3][20] = ']'; + } } } #endif // defined(PRA32_U_USE_CONTROL_PANEL) From de56ae7f8631e0959a8ee502d57f88cc7d49d84e Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 14:11:46 +0900 Subject: [PATCH 065/106] Implement panel functions (49) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 57 +++++++++++++------ 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index d96b02c..cafa1c9 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -123,11 +123,12 @@ static INLINE void PRA32_U_ControlPanel_draw_character(uint8_t c) { i2c_write_blocking(PRA32_U_OLED_DISPLAY_I2C, PRA32_U_OLED_DISPLAY_I2C_ADDRESS, data, sizeof(data), false); } -static INLINE boolean PRA32_U_ControlPanel_calc_value_text(uint8_t control_target, uint8_t controller_value, char value_text[5]) +static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_target, uint8_t controller_value, char value_display_text[5]) { boolean result = false; switch (control_target) { + case MIXER_SUB_OSC : // TODO case OSC_2_COARSE : case OSC_2_PITCH : case FILTER_EG_AMT : @@ -135,8 +136,28 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_text(uint8_t control_targe case LFO_OSC_AMT : case LFO_FILTER_AMT : case BTH_FILTER_AMT : - std::sprintf(value_text, "%+3d", static_cast(controller_value) - 64); - result = true; + { + std::sprintf(value_display_text, "%+3d", static_cast(controller_value) - 64); + result = true; + } + break; + case OSC_1_WAVE : + { + char ary[6][5] = {"Saw","Sin","---","Tri","---","Pls"}; + uint32_t index = ((controller_value * 10) + 127) / 254; + if (controller_value < 6) { index = controller_value; } + std::strcpy(value_display_text, ary[index]); + result = true; + } + break; + case OSC_2_WAVE : + { + char ary[6][5] = {"Saw","Sin","---","Tri","Nos","Sqr"}; + uint32_t index = ((controller_value * 10) + 127) / 254; + if (controller_value < 6) { index = controller_value; } + std::strcpy(value_display_text, ary[index]); + result = true; + } break; } @@ -394,13 +415,13 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { s_display_buffer[7][ 3] = buff[1]; s_display_buffer[7][ 4] = buff[2]; - char value_text[5]; - boolean exists = PRA32_U_ControlPanel_calc_value_text(adc_control_target_0, current_controller_value, value_text); + char value_display_text[5] = {}; + boolean exists = PRA32_U_ControlPanel_calc_value_display(adc_control_target_0, current_controller_value, value_display_text); if (exists) { s_display_buffer[7][ 5] = '['; - s_display_buffer[7][ 6] = value_text[0]; - s_display_buffer[7][ 7] = value_text[1]; - s_display_buffer[7][ 8] = value_text[2]; + s_display_buffer[7][ 6] = value_display_text[0]; + s_display_buffer[7][ 7] = value_display_text[1]; + s_display_buffer[7][ 8] = value_display_text[2]; s_display_buffer[7][ 9] = ']'; } } @@ -427,13 +448,13 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { s_display_buffer[7][14] = buff[1]; s_display_buffer[7][15] = buff[2]; - char value_text[5]; - boolean exists = PRA32_U_ControlPanel_calc_value_text(adc_control_target_1, current_controller_value, value_text); + char value_display_text[5] = {}; + boolean exists = PRA32_U_ControlPanel_calc_value_display(adc_control_target_1, current_controller_value, value_display_text); if (exists) { s_display_buffer[7][16] = '['; - s_display_buffer[7][17] = value_text[0]; - s_display_buffer[7][18] = value_text[1]; - s_display_buffer[7][19] = value_text[2]; + s_display_buffer[7][17] = value_display_text[0]; + s_display_buffer[7][18] = value_display_text[1]; + s_display_buffer[7][19] = value_display_text[2]; s_display_buffer[7][20] = ']'; } } @@ -460,13 +481,13 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { s_display_buffer[3][14] = buff[1]; s_display_buffer[3][15] = buff[2]; - char value_text[5]; - boolean exists = PRA32_U_ControlPanel_calc_value_text(adc_control_target_2, current_controller_value, value_text); + char value_display_text[5] = {}; + boolean exists = PRA32_U_ControlPanel_calc_value_display(adc_control_target_2, current_controller_value, value_display_text); if (exists) { s_display_buffer[3][16] = '['; - s_display_buffer[3][17] = value_text[0]; - s_display_buffer[3][18] = value_text[1]; - s_display_buffer[3][19] = value_text[2]; + s_display_buffer[3][17] = value_display_text[0]; + s_display_buffer[3][18] = value_display_text[1]; + s_display_buffer[3][19] = value_display_text[2]; s_display_buffer[3][20] = ']'; } } From f77b062133edc6c3c1e930407dc751ada4ab4cca Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 14:33:41 +0900 Subject: [PATCH 066/106] Implement panel functions (50) --- .../pra32-u-control-panel-font-table.h | 10 +-- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 73 +++++++++++++++++++ 2 files changed, 78 insertions(+), 5 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h index 0f28af2..fee7c14 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-font-table.h @@ -277,11 +277,11 @@ uint8_t g_control_panel_font_table[128][6] = { 0b00001000, 0b00001000, 0b00000000, - 0b01111111, - 0b01000001, - 0b01000001, - 0b01000001, - 0b01111111, + 0b00000000, + 0b00000000, + 0b00110000, + 0b00110000, + 0b00000000, 0b00000000, 0b00100000, 0b00010000, diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index cafa1c9..82674f1 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -159,6 +159,79 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta result = true; } break; + case FILTER_KEY_TRK : + { + char ary[3][5] = {"0.0","0.5","1.0"}; + uint32_t index = ((controller_value * 4) + 127) / 254; + std::strcpy(value_display_text, ary[index]); + result = true; + } + break; + case EG_OSC_DST : + case LFO_OSC_DST : + { + char ary[3][5] = {"P ","2P ","1S "}; + uint32_t index = ((controller_value * 4) + 127) / 254; + if (controller_value < 3) { index = controller_value; } + std::strcpy(value_display_text, ary[index]); + result = true; + } + break; + case VOICE_MODE : + { + char ary[6][5] = {"Pol","Par","---","Mon","LP ","Lgt"}; + uint32_t index = ((controller_value * 10) + 127) / 254; + if (controller_value < 6) { index = controller_value; } + std::strcpy(value_display_text, ary[index]); + result = true; + } + break; + case LFO_WAVE : + { + char ary[6][5] = {"Tri","Sin","---","Saw","SH ","Sqr"}; + uint32_t index = ((controller_value * 10) + 127) / 254; + if (controller_value < 6) { index = controller_value; } + std::strcpy(value_display_text, ary[index]); + result = true; + } + break; + case FILTER_MODE : + { + char ary[2][5] = {"LP ","HP "}; + uint32_t index = ((controller_value * 2) + 127) / 254; + if (controller_value < 2) { index = controller_value; } + std::strcpy(value_display_text, ary[index]); + result = true; + } + break; + case EG_AMP_MOD : + case REL_EQ_DECAY : + { + char ary[2][5] = {"Off","On "}; + uint32_t index = ((controller_value * 2) + 127) / 254; + if (controller_value < 2) { index = controller_value; } + std::strcpy(value_display_text, ary[index]); + result = true; + } + break; + case BTH_AMP_MOD : + { + char ary[3][5] = {"Off","Qad","Lin"}; + uint32_t index = ((controller_value * 4) + 127) / 254; + if (controller_value < 3) { index = controller_value; } + std::strcpy(value_display_text, ary[index]); + result = true; + } + break; + case DELAY_MODE : + { + char ary[2][5] = {"S ","P "}; + uint32_t index = ((controller_value * 2) + 127) / 254; + if (controller_value < 2) { index = controller_value; } + std::strcpy(value_display_text, ary[index]); + result = true; + } + break; } return result; From 791fdabdd7bf88618bc9730f8a2e5e8fec2138b8 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 14:34:52 +0900 Subject: [PATCH 067/106] Implement panel functions (51) --- pra32-u-ctrl.html | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/pra32-u-ctrl.html b/pra32-u-ctrl.html index f29343c..121cb45 100644 --- a/pra32-u-ctrl.html +++ b/pra32-u-ctrl.html @@ -699,6 +699,7 @@ dispValue = String(value); switch (number) { + case MIXER_SUB_OSC : case OSC_2_COARSE : case OSC_2_PITCH : case FILTER_EG_AMT : @@ -712,13 +713,6 @@ dispValue = String(value - 64); } break; - case MIXER_SUB_OSC : - if (value >= 64) { - dispValue = "S" + String(value - 64); - } else { - dispValue = "N" + String(64 - value); - } - break; case OSC_1_WAVE : { var ary = ["Saw","Sin","-","Tri","-","Pls"]; From b65b1f1b04c7d13362c46a9e421a65f8803408a6 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 14:41:39 +0900 Subject: [PATCH 068/106] Implement panel functions (52) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 82674f1..b6b325e 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -381,6 +381,8 @@ INLINE void PRA32_U_ControlPanel_update_control() { static uint32_t s_key_inpuy_counter = 0; ++s_key_inpuy_counter; + +#if defined(PRA32_U_KEY_INPUT_PREV_KEY_PIN) if (s_key_inpuy_counter - s_prev_key_value_changed_time >= PRA32_U_KEY_ANTI_CHATTERING_WAIT) { uint32_t value = digitalRead(PRA32_U_KEY_INPUT_PREV_KEY_PIN) == PRA32_U_KEY_INPUT_ACTIVE_LEVEL; if (s_prev_key_current_value != value) { @@ -400,7 +402,9 @@ INLINE void PRA32_U_ControlPanel_update_control() { return; } } +#endif // defined(PRA32_U_KEY_INPUT_PREV_KEY_PIN) +#if defined(PRA32_U_KEY_INPUT_NEXT_KEY_PIN) if (s_key_inpuy_counter - s_next_key_value_changed_time >= PRA32_U_KEY_ANTI_CHATTERING_WAIT) { uint32_t value = digitalRead(PRA32_U_KEY_INPUT_NEXT_KEY_PIN) == PRA32_U_KEY_INPUT_ACTIVE_LEVEL; if (s_next_key_current_value != value) { @@ -420,7 +424,9 @@ INLINE void PRA32_U_ControlPanel_update_control() { return; } } +#endif // defined(PRA32_U_KEY_INPUT_NEXT_KEY_PIN) +#if defined(PRA32_U_KEY_INPUT_PLAY_KEY_PIN) if (s_key_inpuy_counter - s_play_key_value_changed_time >= PRA32_U_KEY_ANTI_CHATTERING_WAIT) { uint32_t value = digitalRead(PRA32_U_KEY_INPUT_PLAY_KEY_PIN) == PRA32_U_KEY_INPUT_ACTIVE_LEVEL; if (s_play_key_current_value != value) { @@ -437,6 +443,8 @@ INLINE void PRA32_U_ControlPanel_update_control() { return; } } +#endif // defined(PRA32_U_KEY_INPUT_PLAY_KEY_PIN) + #endif // defined(PRA32_U_USE_CONTROL_PANEL_KEY_INPUT) #if defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) From 787171dc62ed6313ec6c3ad082a393fb9815417f Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 14:48:59 +0900 Subject: [PATCH 069/106] Implement panel functions (53) --- Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h index a0f2091..d0519e3 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h @@ -74,8 +74,8 @@ struct PRA32_U_ControlPanelPage { { "Page=23 ", "Program f ", "Program ", "Change #10", PC_BY_PANEL_10 , "Program ", "Change #11", PC_BY_PANEL_11 , " ", " ", 0xFF , }, { "Page=24 ", "Program g ", "Program ", "Change #12", PC_BY_PANEL_12 , "Program ", "Change #13", PC_BY_PANEL_13 , " ", " ", 0xFF , }, { "Page=25 ", "Program h ", "Program ", "Change #14", PC_BY_PANEL_14 , "Program ", "Change #15", PC_BY_PANEL_15 , " ", " ", 0xFF , }, - { "Page=26 ", "Program i ", "Program ", "Write #8", WR_BY_PANEL_8 , "Program ", "Write #9", WR_BY_PANEL_9 , " ", " ", 0xFF , }, - { "Page=27 ", "Program j ", "Program ", "Write #10", WR_BY_PANEL_10 , "Program ", "Write #11", WR_BY_PANEL_11 , " ", " ", 0xFF , }, - { "Page=28 ", "Program k ", "Program ", "Write #12", WR_BY_PANEL_12 , "Program ", "Write #13", WR_BY_PANEL_13 , " ", " ", 0xFF , }, - { "Page=29 ", "Program l ", "Program ", "Write #14", WR_BY_PANEL_14 , "Program ", "Write #15", WR_BY_PANEL_15 , " ", " ", 0xFF , }, + { "Page=26 ", "Write a ", "Write ", "to Pgm #8", WR_BY_PANEL_8 , "Write ", "to Pgm #9", WR_BY_PANEL_9 , " ", " ", 0xFF , }, + { "Page=27 ", "Write b ", "Write ", "to Pgm #10", WR_BY_PANEL_10 , "Write ", "to Pgm #11", WR_BY_PANEL_11 , " ", " ", 0xFF , }, + { "Page=28 ", "Write c ", "Write ", "to Pgm #12", WR_BY_PANEL_12 , "Write ", "to Pgm #13", WR_BY_PANEL_13 , " ", " ", 0xFF , }, + { "Page=29 ", "Write d ", "Write ", "to Pgm #14", WR_BY_PANEL_14 , "Write ", "to Pgm #15", WR_BY_PANEL_15 , " ", " ", 0xFF , }, }; From 1763feb333a233c956fa996cd5a39140041085b8 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 19:28:23 +0900 Subject: [PATCH 070/106] Implement panel functions (54) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 18 +++++++++++++++++- pra32-u-ctrl.html | 8 +++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index b6b325e..94a6f10 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -128,7 +128,6 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta boolean result = false; switch (control_target) { - case MIXER_SUB_OSC : // TODO case OSC_2_COARSE : case OSC_2_PITCH : case FILTER_EG_AMT : @@ -141,6 +140,23 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta result = true; } break; + case MIXER_SUB_OSC : + { + std::sprintf(value_display_text, "%+3d", static_cast(controller_value) - 64); + + if (controller_value < 55) { + value_display_text[0] = 'N'; + } else if (controller_value < 64) { + value_display_text[1] = 'N'; + } else if (controller_value < 74) { + value_display_text[1] = 'S'; + } else { + value_display_text[0] = 'S'; + } + + result = true; + } + break; case OSC_1_WAVE : { char ary[6][5] = {"Saw","Sin","---","Tri","---","Pls"}; diff --git a/pra32-u-ctrl.html b/pra32-u-ctrl.html index 121cb45..f29343c 100644 --- a/pra32-u-ctrl.html +++ b/pra32-u-ctrl.html @@ -699,7 +699,6 @@ dispValue = String(value); switch (number) { - case MIXER_SUB_OSC : case OSC_2_COARSE : case OSC_2_PITCH : case FILTER_EG_AMT : @@ -713,6 +712,13 @@ dispValue = String(value - 64); } break; + case MIXER_SUB_OSC : + if (value >= 64) { + dispValue = "S" + String(value - 64); + } else { + dispValue = "N" + String(64 - value); + } + break; case OSC_1_WAVE : { var ary = ["Saw","Sin","-","Tri","-","Pls"]; From 52f41e0e2426a54f06155f54b71393c6b680229b Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 19:41:23 +0900 Subject: [PATCH 071/106] Implement panel functions (55) --- .../pra32-u-control-panel-page-table.h | 24 +++---- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 64 +++++++++++++++++++ 2 files changed, 76 insertions(+), 12 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h index d0519e3..6583cab 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h @@ -66,16 +66,16 @@ struct PRA32_U_ControlPanelPage { { "Page=15 ", "Breath ", "Breath ", "Filter Amt", BTH_FILTER_AMT , "Breath ", "Amp Mod ", BTH_AMP_MOD , " ", " ", 0xFF , }, { "Page=16 ", "Chorus ", "Chorus ", "Mix ", CHORUS_MIX , "Chorus ", "Rate ", CHORUS_RATE , "Chorus ", "Depth ", CHORUS_DEPTH , }, { "Page=17 ", "Delay ", "Delay ", "Feedback ", DELAY_FEEDBACK , "Delay ", "Time ", DELAY_TIME , "Delay ", "Mode ", DELAY_MODE , }, - { "Page=18 ", "Program a ", "Program ", "Change #0", PC_BY_PANEL_0 , "Program ", "Change #1", PC_BY_PANEL_1 , " ", " ", 0xFF , }, - { "Page=19 ", "Program b ", "Program ", "Change #2", PC_BY_PANEL_2 , "Program ", "Change #3", PC_BY_PANEL_3 , " ", " ", 0xFF , }, - { "Page=20 ", "Program c ", "Program ", "Change #4", PC_BY_PANEL_4 , "Program ", "Change #5", PC_BY_PANEL_5 , " ", " ", 0xFF , }, - { "Page=21 ", "Program d ", "Program ", "Change #6", PC_BY_PANEL_6 , "Program ", "Change #7", PC_BY_PANEL_7 , " ", " ", 0xFF , }, - { "Page=22 ", "Program e ", "Program ", "Change #8", PC_BY_PANEL_8 , "Program ", "Change #9", PC_BY_PANEL_9 , " ", " ", 0xFF , }, - { "Page=23 ", "Program f ", "Program ", "Change #10", PC_BY_PANEL_10 , "Program ", "Change #11", PC_BY_PANEL_11 , " ", " ", 0xFF , }, - { "Page=24 ", "Program g ", "Program ", "Change #12", PC_BY_PANEL_12 , "Program ", "Change #13", PC_BY_PANEL_13 , " ", " ", 0xFF , }, - { "Page=25 ", "Program h ", "Program ", "Change #14", PC_BY_PANEL_14 , "Program ", "Change #15", PC_BY_PANEL_15 , " ", " ", 0xFF , }, - { "Page=26 ", "Write a ", "Write ", "to Pgm #8", WR_BY_PANEL_8 , "Write ", "to Pgm #9", WR_BY_PANEL_9 , " ", " ", 0xFF , }, - { "Page=27 ", "Write b ", "Write ", "to Pgm #10", WR_BY_PANEL_10 , "Write ", "to Pgm #11", WR_BY_PANEL_11 , " ", " ", 0xFF , }, - { "Page=28 ", "Write c ", "Write ", "to Pgm #12", WR_BY_PANEL_12 , "Write ", "to Pgm #13", WR_BY_PANEL_13 , " ", " ", 0xFF , }, - { "Page=29 ", "Write d ", "Write ", "to Pgm #14", WR_BY_PANEL_14 , "Write ", "to Pgm #15", WR_BY_PANEL_15 , " ", " ", 0xFF , }, + { "Page=18 ", "Write a ", "Write ", "to Pgm #8", WR_BY_PANEL_8 , "Write ", "to Pgm #9", WR_BY_PANEL_9 , " ", " ", 0xFF , }, + { "Page=19 ", "Write b ", "Write ", "to Pgm #10", WR_BY_PANEL_10 , "Write ", "to Pgm #11", WR_BY_PANEL_11 , " ", " ", 0xFF , }, + { "Page=20 ", "Write c ", "Write ", "to Pgm #12", WR_BY_PANEL_12 , "Write ", "to Pgm #13", WR_BY_PANEL_13 , " ", " ", 0xFF , }, + { "Page=21 ", "Write d ", "Write ", "to Pgm #14", WR_BY_PANEL_14 , "Write ", "to Pgm #15", WR_BY_PANEL_15 , " ", " ", 0xFF , }, + { "Page=22 ", "Program a ", "Program ", "Change #0", PC_BY_PANEL_0 , "Program ", "Change #1", PC_BY_PANEL_1 , " ", " ", 0xFF , }, + { "Page=23 ", "Program b ", "Program ", "Change #2", PC_BY_PANEL_2 , "Program ", "Change #3", PC_BY_PANEL_3 , " ", " ", 0xFF , }, + { "Page=24 ", "Program c ", "Program ", "Change #4", PC_BY_PANEL_4 , "Program ", "Change #5", PC_BY_PANEL_5 , " ", " ", 0xFF , }, + { "Page=25 ", "Program d ", "Program ", "Change #6", PC_BY_PANEL_6 , "Program ", "Change #7", PC_BY_PANEL_7 , " ", " ", 0xFF , }, + { "Page=26 ", "Program e ", "Program ", "Change #8", PC_BY_PANEL_8 , "Program ", "Change #9", PC_BY_PANEL_9 , " ", " ", 0xFF , }, + { "Page=27 ", "Program f ", "Program ", "Change #10", PC_BY_PANEL_10 , "Program ", "Change #11", PC_BY_PANEL_11 , " ", " ", 0xFF , }, + { "Page=28 ", "Program g ", "Program ", "Change #12", PC_BY_PANEL_12 , "Program ", "Change #13", PC_BY_PANEL_13 , " ", " ", 0xFF , }, + { "Page=29 ", "Program h ", "Program ", "Change #14", PC_BY_PANEL_14 , "Program ", "Change #15", PC_BY_PANEL_15 , " ", " ", 0xFF , }, }; diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 94a6f10..6478b92 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -248,6 +248,70 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta result = true; } break; + case PC_BY_PANEL_0 : + case PC_BY_PANEL_1 : + case PC_BY_PANEL_2 : + case PC_BY_PANEL_3 : + case PC_BY_PANEL_4 : + case PC_BY_PANEL_5 : + case PC_BY_PANEL_6 : + case PC_BY_PANEL_7 : + case PC_BY_PANEL_8 : + case PC_BY_PANEL_9 : + case PC_BY_PANEL_10 : + case PC_BY_PANEL_11 : + case PC_BY_PANEL_12 : + case PC_BY_PANEL_13 : + case PC_BY_PANEL_14 : + case PC_BY_PANEL_15 : + { + if (controller_value < 64) { + value_display_text[0] = 'R'; + value_display_text[1] = 'd'; + value_display_text[2] = 'y'; + } else { + value_display_text[0] = 'E'; + value_display_text[1] = 'x'; + value_display_text[2] = 'e'; + } + + result = true; + } + break; + case WR_BY_PANEL_0 : + case WR_BY_PANEL_1 : + case WR_BY_PANEL_2 : + case WR_BY_PANEL_3 : + case WR_BY_PANEL_4 : + case WR_BY_PANEL_5 : + case WR_BY_PANEL_6 : + case WR_BY_PANEL_7 : + case WR_BY_PANEL_8 : + case WR_BY_PANEL_9 : + case WR_BY_PANEL_10 : + case WR_BY_PANEL_11 : + case WR_BY_PANEL_12 : + case WR_BY_PANEL_13 : + case WR_BY_PANEL_14 : + case WR_BY_PANEL_15 : + { + if (controller_value == 0) { + value_display_text[0] = 'R'; + value_display_text[1] = 'd'; + value_display_text[2] = 'y'; + } else if (controller_value == 127) { + value_display_text[0] = 'E'; + value_display_text[1] = 'x'; + value_display_text[2] = 'e'; + } else { + value_display_text[0] = '-'; + value_display_text[1] = '-'; + value_display_text[2] = '-'; + } + + result = true; + } + break; } return result; From e7b9a6f8b6f1c6149673e7b8621703b510cde390 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 19:48:02 +0900 Subject: [PATCH 072/106] Implement panel functions (56) --- Digital-Synth-PRA32-U/pra32-u-program-table.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-program-table.h b/Digital-Synth-PRA32-U/pra32-u-program-table.h index 4f5f354..a7cdc24 100644 --- a/Digital-Synth-PRA32-U/pra32-u-program-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-program-table.h @@ -1,6 +1,6 @@ #pragma once -const uint8_t PROGRAM_NUMBER_DEFAULT = 0; +const uint8_t PROGRAM_NUMBER_DEFAULT = 8; // Preset #0 #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 #11 #12 #13 #14 #15 const uint8_t g_preset_table_OSC_1_WAVE [] = {127, 127, 127, 127, 127, 127, 127, 0 , 127, 127, 127, 127, 127, 127, 127, 0 }; From e35c951c3d1885594897f38bdc4343a2bb7a85ca Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 20:36:54 +0900 Subject: [PATCH 073/106] Implement panel functions (57) --- .../pra32-u-control-panel-page-table.h | 3 ++ Digital-Synth-PRA32-U/pra32-u-control-panel.h | 46 ++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h index 6583cab..45eb185 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h @@ -36,6 +36,8 @@ const uint8_t WR_BY_PANEL_13 = 157; const uint8_t WR_BY_PANEL_14 = 158; const uint8_t WR_BY_PANEL_15 = 159; +const uint8_t PANEL_PLAY_PIT = 160; + struct PRA32_U_ControlPanelPage { char page_name_line_0 [10 + 1]; char page_name_line_1 [10 + 1]; @@ -78,4 +80,5 @@ struct PRA32_U_ControlPanelPage { { "Page=27 ", "Program f ", "Program ", "Change #10", PC_BY_PANEL_10 , "Program ", "Change #11", PC_BY_PANEL_11 , " ", " ", 0xFF , }, { "Page=28 ", "Program g ", "Program ", "Change #12", PC_BY_PANEL_12 , "Program ", "Change #13", PC_BY_PANEL_13 , " ", " ", 0xFF , }, { "Page=29 ", "Program h ", "Program ", "Change #14", PC_BY_PANEL_14 , "Program ", "Change #15", PC_BY_PANEL_15 , " ", " ", 0xFF , }, + { "Page=30 ", "Panel ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Panel ", "Play Pitch", PANEL_PLAY_PIT , }, }; diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 6478b92..a7537f2 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -19,6 +19,11 @@ static volatile int32_t s_adc_current_value[3]; static volatile uint8_t s_adc_control_value[3]; static volatile uint8_t s_adc_control_target[3] = { 0xFF, 0xFF, 0xFF }; +static volatile uint8_t s_panel_play_pitch = 60; +static volatile uint8_t s_panel_playing_note_pitch = 0xFF; +static volatile uint8_t s_reserved_note_off = 0xFF; +static volatile uint8_t s_reserved_note_on = 0xFF; + static volatile uint32_t s_display_draw_counter = 0; static char s_display_buffer[8][21 + 1] = { @@ -102,6 +107,18 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe g_synth.write_parameters_to_program(program_number_to_write); s_ready_to_write[program_number_to_write] = false; } + } else if (s_adc_control_target[adc_number] == PANEL_PLAY_PIT) { + uint8_t ary[8] = { 60, 62, 64, 65, 67, 69, 71, 72 }; + uint32_t index = ((s_adc_control_value[adc_number] * 14) + 127) / 254; + uint8_t note_number = ary[index]; + + s_panel_play_pitch = note_number; + if (s_panel_playing_note_pitch <= 127) { + if (s_panel_playing_note_pitch != note_number) { + s_reserved_note_off = s_panel_playing_note_pitch; + s_reserved_note_on = s_panel_play_pitch; + } + } } return true; @@ -110,6 +127,24 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe return false; } +static INLINE boolean PRA32_U_ControlPanel_process_reserved_note_off_on() { + if (s_reserved_note_off <= 127) { + g_synth.note_off(s_reserved_note_off); + s_panel_playing_note_pitch = 0xFF; + s_reserved_note_off = 0xFF; + return true; + } + + if (s_reserved_note_on <= 127) { + g_synth.note_on(s_reserved_note_on, 100); + s_panel_playing_note_pitch = s_reserved_note_on; + s_reserved_note_on = 0xFF; + return true; + } + + return false; +} + static INLINE void PRA32_U_ControlPanel_set_draw_position(uint8_t x, uint8_t y) { uint8_t commands[] = {0x00, static_cast(0xB0 + y), static_cast(0x10 + ((x * 6) >> 4)), @@ -450,6 +485,11 @@ INLINE void PRA32_U_ControlPanel_update_control() { return; } + boolean processed = PRA32_U_ControlPanel_process_reserved_note_off_on(); + if (processed) { + return; + } + #if defined(PRA32_U_USE_CONTROL_PANEL_KEY_INPUT) static uint32_t s_prev_key_current_value; static uint32_t s_next_key_current_value; @@ -515,11 +555,13 @@ INLINE void PRA32_U_ControlPanel_update_control() { if (s_play_key_current_value == 1) { // Play key pressed - g_synth.note_on(60, 100); + s_reserved_note_on = s_panel_play_pitch; } else { // Play key released - g_synth.note_off(60); + s_reserved_note_off = s_panel_playing_note_pitch; } + + PRA32_U_ControlPanel_process_reserved_note_off_on(); return; } } From 81cff65ea39831c8328ff1c2216fc9eb7f131ddc Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 20:43:37 +0900 Subject: [PATCH 074/106] Implement panel functions (58) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index a7537f2..1ed6606 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -83,6 +83,24 @@ static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t return adc_control_value_candidate; } +static INLINE boolean PRA32_U_ControlPanel_process_reserved_note_off_on() { + if (s_reserved_note_off <= 127) { + g_synth.note_off(s_reserved_note_off); + s_panel_playing_note_pitch = 0xFF; + s_reserved_note_off = 0xFF; + return true; + } + + if (s_reserved_note_on <= 127) { + g_synth.note_on(s_reserved_note_on, 100); + s_panel_playing_note_pitch = s_reserved_note_on; + s_reserved_note_on = 0xFF; + return true; + } + + return false; +} + static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_number) { uint8_t adc_control_value_candidate = PRA32_U_ControlPanel_adc_control_value_candidate(adc_number); @@ -108,8 +126,8 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe s_ready_to_write[program_number_to_write] = false; } } else if (s_adc_control_target[adc_number] == PANEL_PLAY_PIT) { - uint8_t ary[8] = { 60, 62, 64, 65, 67, 69, 71, 72 }; - uint32_t index = ((s_adc_control_value[adc_number] * 14) + 127) / 254; + uint8_t ary[15] = { 48, 50, 52, 53, 55, 57, 59, 60, 62, 64, 65, 67, 69, 71, 72 }; + uint32_t index = ((s_adc_control_value[adc_number] * 28) + 127) / 254; uint8_t note_number = ary[index]; s_panel_play_pitch = note_number; @@ -117,6 +135,7 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe if (s_panel_playing_note_pitch != note_number) { s_reserved_note_off = s_panel_playing_note_pitch; s_reserved_note_on = s_panel_play_pitch; + PRA32_U_ControlPanel_process_reserved_note_off_on(); } } } @@ -127,24 +146,6 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe return false; } -static INLINE boolean PRA32_U_ControlPanel_process_reserved_note_off_on() { - if (s_reserved_note_off <= 127) { - g_synth.note_off(s_reserved_note_off); - s_panel_playing_note_pitch = 0xFF; - s_reserved_note_off = 0xFF; - return true; - } - - if (s_reserved_note_on <= 127) { - g_synth.note_on(s_reserved_note_on, 100); - s_panel_playing_note_pitch = s_reserved_note_on; - s_reserved_note_on = 0xFF; - return true; - } - - return false; -} - static INLINE void PRA32_U_ControlPanel_set_draw_position(uint8_t x, uint8_t y) { uint8_t commands[] = {0x00, static_cast(0xB0 + y), static_cast(0x10 + ((x * 6) >> 4)), From 813dbf10ffe483ca839ec632bcbf21c4d5fbfc3f Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 20:59:18 +0900 Subject: [PATCH 075/106] Implement panel functions (59) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 1ed6606..32f1a9e 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -19,10 +19,11 @@ static volatile int32_t s_adc_current_value[3]; static volatile uint8_t s_adc_control_value[3]; static volatile uint8_t s_adc_control_target[3] = { 0xFF, 0xFF, 0xFF }; -static volatile uint8_t s_panel_play_pitch = 60; -static volatile uint8_t s_panel_playing_note_pitch = 0xFF; -static volatile uint8_t s_reserved_note_off = 0xFF; -static volatile uint8_t s_reserved_note_on = 0xFF; +static volatile uint8_t s_panel_play_pitch_value = 64; +static volatile uint8_t s_panel_play_note_number = 60; +static volatile uint8_t s_panel_playing_note_number = 0xFF; +static volatile uint8_t s_reserved_note_off = 0xFF; +static volatile uint8_t s_reserved_note_on = 0xFF; static volatile uint32_t s_display_draw_counter = 0; @@ -86,14 +87,14 @@ static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t static INLINE boolean PRA32_U_ControlPanel_process_reserved_note_off_on() { if (s_reserved_note_off <= 127) { g_synth.note_off(s_reserved_note_off); - s_panel_playing_note_pitch = 0xFF; + s_panel_playing_note_number = 0xFF; s_reserved_note_off = 0xFF; return true; } if (s_reserved_note_on <= 127) { g_synth.note_on(s_reserved_note_on, 100); - s_panel_playing_note_pitch = s_reserved_note_on; + s_panel_playing_note_number = s_reserved_note_on; s_reserved_note_on = 0xFF; return true; } @@ -126,15 +127,17 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe s_ready_to_write[program_number_to_write] = false; } } else if (s_adc_control_target[adc_number] == PANEL_PLAY_PIT) { + s_panel_play_pitch_value = s_adc_control_value[adc_number]; + uint8_t ary[15] = { 48, 50, 52, 53, 55, 57, 59, 60, 62, 64, 65, 67, 69, 71, 72 }; - uint32_t index = ((s_adc_control_value[adc_number] * 28) + 127) / 254; + uint32_t index = ((s_panel_play_pitch_value * 28) + 127) / 254; uint8_t note_number = ary[index]; - s_panel_play_pitch = note_number; - if (s_panel_playing_note_pitch <= 127) { - if (s_panel_playing_note_pitch != note_number) { - s_reserved_note_off = s_panel_playing_note_pitch; - s_reserved_note_on = s_panel_play_pitch; + s_panel_play_note_number = note_number; + if (s_panel_playing_note_number <= 127) { + if (s_panel_playing_note_number != note_number) { + s_reserved_note_off = s_panel_playing_note_number; + s_reserved_note_on = s_panel_play_note_number; PRA32_U_ControlPanel_process_reserved_note_off_on(); } } @@ -556,10 +559,10 @@ INLINE void PRA32_U_ControlPanel_update_control() { if (s_play_key_current_value == 1) { // Play key pressed - s_reserved_note_on = s_panel_play_pitch; + s_reserved_note_on = s_panel_play_note_number; } else { // Play key released - s_reserved_note_off = s_panel_playing_note_pitch; + s_reserved_note_off = s_panel_playing_note_number; } PRA32_U_ControlPanel_process_reserved_note_off_on(); @@ -601,8 +604,10 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { if (adc_control_target_0 < 0xFF) { uint8_t adc_control_value = s_adc_control_value[0]; uint8_t current_controller_value = adc_control_value; - if (adc_control_target_0 <= 0x7F) { + if (adc_control_target_0 <= 0x7F) { current_controller_value = g_synth.current_controller_value(adc_control_target_0); + } else if (adc_control_target_0 == PANEL_PLAY_PIT) { + current_controller_value = s_panel_play_pitch_value; } s_display_buffer[7][ 0] = 'A'; @@ -634,8 +639,10 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { if (adc_control_target_1 < 0xFF) { uint8_t adc_control_value = s_adc_control_value[1]; uint8_t current_controller_value = adc_control_value; - if (adc_control_target_1 <= 0x7F) { + if (adc_control_target_1 <= 0x7F) { current_controller_value = g_synth.current_controller_value(adc_control_target_1); + } else if (adc_control_target_1 == PANEL_PLAY_PIT) { + current_controller_value = s_panel_play_pitch_value; } s_display_buffer[7][11] = 'B'; @@ -667,8 +674,10 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { if (adc_control_target_2 < 0xFF) { uint8_t adc_control_value = s_adc_control_value[2]; uint8_t current_controller_value = adc_control_value; - if (adc_control_target_2 <= 0x7F) { + if (adc_control_target_2 <= 0x7F) { current_controller_value = g_synth.current_controller_value(adc_control_target_2); + } else if (adc_control_target_2 == PANEL_PLAY_PIT) { + current_controller_value = s_panel_play_pitch_value; } s_display_buffer[3][11] = 'C'; From 2eca7e7dd59705f2b91b131547181096c1d588fd Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 21:23:14 +0900 Subject: [PATCH 076/106] Implement panel functions (60) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 32f1a9e..520dd52 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -129,9 +129,12 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe } else if (s_adc_control_target[adc_number] == PANEL_PLAY_PIT) { s_panel_play_pitch_value = s_adc_control_value[adc_number]; - uint8_t ary[15] = { 48, 50, 52, 53, 55, 57, 59, 60, 62, 64, 65, 67, 69, 71, 72 }; - uint32_t index = ((s_panel_play_pitch_value * 28) + 127) / 254; - uint8_t note_number = ary[index]; + uint8_t ary_major[48] = { 48, 48, 50, 50, 50, 50, 52, 52, 52, 53, 53, 53, + 55, 55, 55, 55, 57, 57, 57, 57, 59, 59, 59, 60, + 60, 60, 62, 62, 62, 62, 64, 64, 64, 65, 65, 65, + 67, 67, 67, 67, 69, 69, 69, 69, 71, 71, 71, 72, }; + uint32_t index = ((s_panel_play_pitch_value * 94) + 127) / 254; + uint8_t note_number = ary_major[index]; s_panel_play_note_number = note_number; if (s_panel_playing_note_number <= 127) { From 1c2f1b280106e2996d9f183a84c3d8d407073c08 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Mon, 8 Apr 2024 21:33:44 +0900 Subject: [PATCH 077/106] Implement panel functions (61) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 520dd52..305d839 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -201,7 +201,7 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta break; case OSC_1_WAVE : { - char ary[6][5] = {"Saw","Sin","---","Tri","---","Pls"}; + char ary[6][5] = {"Saw","Sin"," -","Tri"," -","Pls"}; uint32_t index = ((controller_value * 10) + 127) / 254; if (controller_value < 6) { index = controller_value; } std::strcpy(value_display_text, ary[index]); @@ -210,7 +210,7 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta break; case OSC_2_WAVE : { - char ary[6][5] = {"Saw","Sin","---","Tri","Nos","Sqr"}; + char ary[6][5] = {"Saw","Sin"," -","Tri","Nos","Sqr"}; uint32_t index = ((controller_value * 10) + 127) / 254; if (controller_value < 6) { index = controller_value; } std::strcpy(value_display_text, ary[index]); @@ -228,7 +228,7 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta case EG_OSC_DST : case LFO_OSC_DST : { - char ary[3][5] = {"P ","2P ","1S "}; + char ary[3][5] = {" P"," 2P"," 1S"}; uint32_t index = ((controller_value * 4) + 127) / 254; if (controller_value < 3) { index = controller_value; } std::strcpy(value_display_text, ary[index]); @@ -237,7 +237,7 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta break; case VOICE_MODE : { - char ary[6][5] = {"Pol","Par","---","Mon","LP ","Lgt"}; + char ary[6][5] = {"Pol","Par"," -","Mon"," LP","Lgt"}; uint32_t index = ((controller_value * 10) + 127) / 254; if (controller_value < 6) { index = controller_value; } std::strcpy(value_display_text, ary[index]); @@ -246,7 +246,7 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta break; case LFO_WAVE : { - char ary[6][5] = {"Tri","Sin","---","Saw","SH ","Sqr"}; + char ary[6][5] = {"Tri","Sin"," -","Saw"," SH","Sqr"}; uint32_t index = ((controller_value * 10) + 127) / 254; if (controller_value < 6) { index = controller_value; } std::strcpy(value_display_text, ary[index]); @@ -255,7 +255,7 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta break; case FILTER_MODE : { - char ary[2][5] = {"LP ","HP "}; + char ary[2][5] = {" LP"," HP"}; uint32_t index = ((controller_value * 2) + 127) / 254; if (controller_value < 2) { index = controller_value; } std::strcpy(value_display_text, ary[index]); @@ -265,7 +265,7 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta case EG_AMP_MOD : case REL_EQ_DECAY : { - char ary[2][5] = {"Off","On "}; + char ary[2][5] = {"Off"," On"}; uint32_t index = ((controller_value * 2) + 127) / 254; if (controller_value < 2) { index = controller_value; } std::strcpy(value_display_text, ary[index]); @@ -283,7 +283,7 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta break; case DELAY_MODE : { - char ary[2][5] = {"S ","P "}; + char ary[2][5] = {" S"," P"}; uint32_t index = ((controller_value * 2) + 127) / 254; if (controller_value < 2) { index = controller_value; } std::strcpy(value_display_text, ary[index]); From 064cf5c6b7a744a0280196e0a13bdc81a47acea7 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sat, 13 Apr 2024 15:51:33 +0900 Subject: [PATCH 078/106] Implement panel functions (62) --- .../pra32-u-control-panel-page-table.h | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h index 45eb185..91cc898 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h @@ -68,17 +68,17 @@ struct PRA32_U_ControlPanelPage { { "Page=15 ", "Breath ", "Breath ", "Filter Amt", BTH_FILTER_AMT , "Breath ", "Amp Mod ", BTH_AMP_MOD , " ", " ", 0xFF , }, { "Page=16 ", "Chorus ", "Chorus ", "Mix ", CHORUS_MIX , "Chorus ", "Rate ", CHORUS_RATE , "Chorus ", "Depth ", CHORUS_DEPTH , }, { "Page=17 ", "Delay ", "Delay ", "Feedback ", DELAY_FEEDBACK , "Delay ", "Time ", DELAY_TIME , "Delay ", "Mode ", DELAY_MODE , }, - { "Page=18 ", "Write a ", "Write ", "to Pgm #8", WR_BY_PANEL_8 , "Write ", "to Pgm #9", WR_BY_PANEL_9 , " ", " ", 0xFF , }, - { "Page=19 ", "Write b ", "Write ", "to Pgm #10", WR_BY_PANEL_10 , "Write ", "to Pgm #11", WR_BY_PANEL_11 , " ", " ", 0xFF , }, - { "Page=20 ", "Write c ", "Write ", "to Pgm #12", WR_BY_PANEL_12 , "Write ", "to Pgm #13", WR_BY_PANEL_13 , " ", " ", 0xFF , }, - { "Page=21 ", "Write d ", "Write ", "to Pgm #14", WR_BY_PANEL_14 , "Write ", "to Pgm #15", WR_BY_PANEL_15 , " ", " ", 0xFF , }, - { "Page=22 ", "Program a ", "Program ", "Change #0", PC_BY_PANEL_0 , "Program ", "Change #1", PC_BY_PANEL_1 , " ", " ", 0xFF , }, - { "Page=23 ", "Program b ", "Program ", "Change #2", PC_BY_PANEL_2 , "Program ", "Change #3", PC_BY_PANEL_3 , " ", " ", 0xFF , }, - { "Page=24 ", "Program c ", "Program ", "Change #4", PC_BY_PANEL_4 , "Program ", "Change #5", PC_BY_PANEL_5 , " ", " ", 0xFF , }, - { "Page=25 ", "Program d ", "Program ", "Change #6", PC_BY_PANEL_6 , "Program ", "Change #7", PC_BY_PANEL_7 , " ", " ", 0xFF , }, - { "Page=26 ", "Program e ", "Program ", "Change #8", PC_BY_PANEL_8 , "Program ", "Change #9", PC_BY_PANEL_9 , " ", " ", 0xFF , }, - { "Page=27 ", "Program f ", "Program ", "Change #10", PC_BY_PANEL_10 , "Program ", "Change #11", PC_BY_PANEL_11 , " ", " ", 0xFF , }, - { "Page=28 ", "Program g ", "Program ", "Change #12", PC_BY_PANEL_12 , "Program ", "Change #13", PC_BY_PANEL_13 , " ", " ", 0xFF , }, - { "Page=29 ", "Program h ", "Program ", "Change #14", PC_BY_PANEL_14 , "Program ", "Change #15", PC_BY_PANEL_15 , " ", " ", 0xFF , }, - { "Page=30 ", "Panel ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Panel ", "Play Pitch", PANEL_PLAY_PIT , }, + { "Page=18 ", "Write a ", "Write ", "Program 8", WR_BY_PANEL_8 , "Write ", "Program 9", WR_BY_PANEL_9 , " ", " ", 0xFF , }, + { "Page=19 ", "Write b ", "Write ", "Program 10", WR_BY_PANEL_10 , "Write ", "Program 11", WR_BY_PANEL_11 , " ", " ", 0xFF , }, + { "Page=20 ", "Write c ", "Write ", "Program 12", WR_BY_PANEL_12 , "Write ", "Program 13", WR_BY_PANEL_13 , " ", " ", 0xFF , }, + { "Page=21 ", "Write d ", "Write ", "Program 14", WR_BY_PANEL_14 , "Write ", "Program 15", WR_BY_PANEL_15 , " ", " ", 0xFF , }, + { "Page=22 ", "Read a ", "Read ", "Program 0", PC_BY_PANEL_0 , "Read ", "Program 1", PC_BY_PANEL_1 , " ", " ", 0xFF , }, + { "Page=23 ", "Read b ", "Read ", "Program 2", PC_BY_PANEL_2 , "Read ", "Program 3", PC_BY_PANEL_3 , " ", " ", 0xFF , }, + { "Page=24 ", "Read c ", "Read ", "Program 4", PC_BY_PANEL_4 , "Read ", "Program 5", PC_BY_PANEL_5 , " ", " ", 0xFF , }, + { "Page=25 ", "Read d ", "Read ", "Program 6", PC_BY_PANEL_6 , "Read ", "Program 7", PC_BY_PANEL_7 , " ", " ", 0xFF , }, + { "Page=26 ", "Read e ", "Read ", "Program 8", PC_BY_PANEL_8 , "Read ", "Program 9", PC_BY_PANEL_9 , " ", " ", 0xFF , }, + { "Page=27 ", "Read f ", "Read ", "Program 10", PC_BY_PANEL_10 , "Read ", "Program 11", PC_BY_PANEL_11 , " ", " ", 0xFF , }, + { "Page=28 ", "Read g ", "Read ", "Program 12", PC_BY_PANEL_12 , "Read ", "Program 13", PC_BY_PANEL_13 , " ", " ", 0xFF , }, + { "Page=29 ", "Read h ", "Read ", "Program 14", PC_BY_PANEL_14 , "Read ", "Program 15", PC_BY_PANEL_15 , " ", " ", 0xFF , }, + { "Page=30 ", "Panel ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Panel ", "Pitch ", PANEL_PLAY_PIT , }, }; From 327bcf59165370670d61b06b9b14d40cabd28941 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sat, 13 Apr 2024 19:19:27 +0900 Subject: [PATCH 079/106] Implement panel functions (63) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 305d839..872bddc 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -19,6 +19,10 @@ static volatile int32_t s_adc_current_value[3]; static volatile uint8_t s_adc_control_value[3]; static volatile uint8_t s_adc_control_target[3] = { 0xFF, 0xFF, 0xFF }; +static uint32_t s_prev_key_current_value; +static uint32_t s_next_key_current_value; +static uint32_t s_play_key_current_value; + static volatile uint8_t s_panel_play_pitch_value = 64; static volatile uint8_t s_panel_play_note_number = 60; static volatile uint8_t s_panel_playing_note_number = 0xFF; @@ -129,15 +133,17 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe } else if (s_adc_control_target[adc_number] == PANEL_PLAY_PIT) { s_panel_play_pitch_value = s_adc_control_value[adc_number]; - uint8_t ary_major[48] = { 48, 48, 50, 50, 50, 50, 52, 52, 52, 53, 53, 53, - 55, 55, 55, 55, 57, 57, 57, 57, 59, 59, 59, 60, - 60, 60, 62, 62, 62, 62, 64, 64, 64, 65, 65, 65, - 67, 67, 67, 67, 69, 69, 69, 69, 71, 71, 71, 72, }; - uint32_t index = ((s_panel_play_pitch_value * 94) + 127) / 254; + uint8_t ary_major[53] = + { 0xFF, 0xFF, 48, 48, 48, 50, 50, 50, 50, 52, 52, 52, 53, 53, 53, + 55, 55, 55, 55, 57, 57, 57, 57, 59, 59, 59, 60, + 60, 60, 62, 62, 62, 62, 64, 64, 64, 65, 65, 65, + 67, 67, 67, 67, 69, 69, 69, 69, 71, 71, 71, 72, 72, 72 }; + uint32_t index = (((s_panel_play_pitch_value + 3) * 2) + 1) / 5; uint8_t note_number = ary_major[index]; s_panel_play_note_number = note_number; - if (s_panel_playing_note_number <= 127) { + + if (s_play_key_current_value == 1) { if (s_panel_playing_note_number != note_number) { s_reserved_note_off = s_panel_playing_note_number; s_reserved_note_on = s_panel_play_note_number; @@ -498,10 +504,6 @@ INLINE void PRA32_U_ControlPanel_update_control() { } #if defined(PRA32_U_USE_CONTROL_PANEL_KEY_INPUT) - static uint32_t s_prev_key_current_value; - static uint32_t s_next_key_current_value; - static uint32_t s_play_key_current_value; - static uint32_t s_prev_key_value_changed_time; static uint32_t s_next_key_value_changed_time; static uint32_t s_play_key_value_changed_time; From 7ad53ab4b85cc879c38eaa190958e7bb29d155f6 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sat, 13 Apr 2024 19:38:42 +0900 Subject: [PATCH 080/106] Implement panel functions (64) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 872bddc..346e132 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -138,8 +138,23 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe 55, 55, 55, 55, 57, 57, 57, 57, 59, 59, 59, 60, 60, 60, 62, 62, 62, 62, 64, 64, 64, 65, 65, 65, 67, 67, 67, 67, 69, 69, 69, 69, 71, 71, 71, 72, 72, 72 }; + + uint8_t ary_pentatonic[53] = + { 0xFF, 0xFF, 48, 48, 48, 50, 50, 50, 50, 52, 52, 52, 52, 52, 55, + 55, 55, 55, 55, 57, 57, 57, 57, 57, 60, 60, 60, + 60, 60, 62, 62, 62, 62, 64, 64, 64, 64, 64, 67, + 67, 67, 67, 67, 69, 69, 69, 69, 69, 72, 72, 72, 72, 72 }; + + uint8_t ary_chromatic[53] = + { 0xFF, 0xFF, 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, + 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59, 60, + 60, 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, 66, + 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 72, 72 }; + uint32_t index = (((s_panel_play_pitch_value + 3) * 2) + 1) / 5; uint8_t note_number = ary_major[index]; + static_cast(ary_pentatonic); + static_cast(ary_chromatic); s_panel_play_note_number = note_number; From 7cdaefbeac54cb627e65d0e6a7d5fde426d94784 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 14 Apr 2024 11:22:39 +0900 Subject: [PATCH 081/106] Implement panel functions (65) --- Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h | 4 +++- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h index 91cc898..2177e81 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h @@ -80,5 +80,7 @@ struct PRA32_U_ControlPanelPage { { "Page=27 ", "Read f ", "Read ", "Program 10", PC_BY_PANEL_10 , "Read ", "Program 11", PC_BY_PANEL_11 , " ", " ", 0xFF , }, { "Page=28 ", "Read g ", "Read ", "Program 12", PC_BY_PANEL_12 , "Read ", "Program 13", PC_BY_PANEL_13 , " ", " ", 0xFF , }, { "Page=29 ", "Read h ", "Read ", "Program 14", PC_BY_PANEL_14 , "Read ", "Program 15", PC_BY_PANEL_15 , " ", " ", 0xFF , }, - { "Page=30 ", "Panel ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Panel ", "Pitch ", PANEL_PLAY_PIT , }, + { "Page=30 ", "Panel a ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Panel ", "Pitch ", PANEL_PLAY_PIT , }, + { "Page=31 ", "Panel b ", "Modulation", " ", MODULATION , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PLAY_PIT , }, + { "Page=31 ", "Panel c ", "Breath ", "Controller", BTH_CONTROLLER , "Sustain ", "Pedal ", SUSTAIN_PEDAL , "Panel ", "Pitch ", PANEL_PLAY_PIT , }, }; diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 346e132..510bd73 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -152,8 +152,8 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 72, 72 }; uint32_t index = (((s_panel_play_pitch_value + 3) * 2) + 1) / 5; - uint8_t note_number = ary_major[index]; - static_cast(ary_pentatonic); + uint8_t note_number = ary_pentatonic[index]; + static_cast(ary_major); static_cast(ary_chromatic); s_panel_play_note_number = note_number; @@ -285,6 +285,7 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta break; case EG_AMP_MOD : case REL_EQ_DECAY : + case SUSTAIN_PEDAL : { char ary[2][5] = {"Off"," On"}; uint32_t index = ((controller_value * 2) + 127) / 254; From e3581d5ec7b07aafcf5fb4f35e538748ac1ea5dd Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 14 Apr 2024 11:52:27 +0900 Subject: [PATCH 082/106] Implement panel functions (66) --- .../pra32-u-control-panel-page-table.h | 8 +++--- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 26 ++++++++++++++----- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h index 2177e81..d7edd0a 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h @@ -36,7 +36,7 @@ const uint8_t WR_BY_PANEL_13 = 157; const uint8_t WR_BY_PANEL_14 = 158; const uint8_t WR_BY_PANEL_15 = 159; -const uint8_t PANEL_PLAY_PIT = 160; +const uint8_t PANEL_PITCH = 160; struct PRA32_U_ControlPanelPage { char page_name_line_0 [10 + 1]; @@ -80,7 +80,7 @@ struct PRA32_U_ControlPanelPage { { "Page=27 ", "Read f ", "Read ", "Program 10", PC_BY_PANEL_10 , "Read ", "Program 11", PC_BY_PANEL_11 , " ", " ", 0xFF , }, { "Page=28 ", "Read g ", "Read ", "Program 12", PC_BY_PANEL_12 , "Read ", "Program 13", PC_BY_PANEL_13 , " ", " ", 0xFF , }, { "Page=29 ", "Read h ", "Read ", "Program 14", PC_BY_PANEL_14 , "Read ", "Program 15", PC_BY_PANEL_15 , " ", " ", 0xFF , }, - { "Page=30 ", "Panel a ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Panel ", "Pitch ", PANEL_PLAY_PIT , }, - { "Page=31 ", "Panel b ", "Modulation", " ", MODULATION , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PLAY_PIT , }, - { "Page=31 ", "Panel c ", "Breath ", "Controller", BTH_CONTROLLER , "Sustain ", "Pedal ", SUSTAIN_PEDAL , "Panel ", "Pitch ", PANEL_PLAY_PIT , }, + { "Page=30 ", "Panel a ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=31 ", "Panel b ", "Modulation", " ", MODULATION , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=31 ", "Panel c ", "Breath ", "Controller", BTH_CONTROLLER , "Sustain ", "Pedal ", SUSTAIN_PEDAL , "Panel ", "Pitch ", PANEL_PITCH , }, }; diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 510bd73..36a83c0 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -130,9 +130,10 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe g_synth.write_parameters_to_program(program_number_to_write); s_ready_to_write[program_number_to_write] = false; } - } else if (s_adc_control_target[adc_number] == PANEL_PLAY_PIT) { + } else if (s_adc_control_target[adc_number] == PANEL_PITCH) { s_panel_play_pitch_value = s_adc_control_value[adc_number]; +#if 0 uint8_t ary_major[53] = { 0xFF, 0xFF, 48, 48, 48, 50, 50, 50, 50, 52, 52, 52, 53, 53, 53, 55, 55, 55, 55, 57, 57, 57, 57, 59, 59, 59, 60, @@ -144,6 +145,7 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe 55, 55, 55, 55, 57, 57, 57, 57, 57, 60, 60, 60, 60, 60, 62, 62, 62, 62, 64, 64, 64, 64, 64, 67, 67, 67, 67, 67, 69, 69, 69, 69, 69, 72, 72, 72, 72, 72 }; +#endif uint8_t ary_chromatic[53] = { 0xFF, 0xFF, 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, @@ -152,9 +154,7 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 72, 72 }; uint32_t index = (((s_panel_play_pitch_value + 3) * 2) + 1) / 5; - uint8_t note_number = ary_pentatonic[index]; - static_cast(ary_major); - static_cast(ary_chromatic); + uint8_t note_number = ary_chromatic[index]; s_panel_play_note_number = note_number; @@ -376,6 +376,18 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta result = true; } break; + case PANEL_PITCH : + { + char ary[53][5] = + { "Off", "Off", " C3", " C3", "C#3", "C#3", " D3", " D3", "D#3", "D#3", " E3", " E3", " F3", " F3", "F#3", + "F#3", " G3", " G3", "G#3", "G#3", " A3", " A3", "A#3", "A#3", " B3", " B3", " C4", + " C4", "C#4", "C#4", " D4", " D4", "D#4", "D#4", " E4", " E4", " F4", " F4", "F#4", + "F#4", " G4", " G4", "G#4", "G#4", " A4", " A4", "A#4", "A#4", " B4", " B4", " C5", " C5", " C5" }; + uint32_t index = (((s_panel_play_pitch_value + 3) * 2) + 1) / 5; + std::strcpy(value_display_text, ary[index]); + result = true; + } + break; } return result; @@ -627,7 +639,7 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { uint8_t current_controller_value = adc_control_value; if (adc_control_target_0 <= 0x7F) { current_controller_value = g_synth.current_controller_value(adc_control_target_0); - } else if (adc_control_target_0 == PANEL_PLAY_PIT) { + } else if (adc_control_target_0 == PANEL_PITCH) { current_controller_value = s_panel_play_pitch_value; } @@ -662,7 +674,7 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { uint8_t current_controller_value = adc_control_value; if (adc_control_target_1 <= 0x7F) { current_controller_value = g_synth.current_controller_value(adc_control_target_1); - } else if (adc_control_target_1 == PANEL_PLAY_PIT) { + } else if (adc_control_target_1 == PANEL_PITCH) { current_controller_value = s_panel_play_pitch_value; } @@ -697,7 +709,7 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { uint8_t current_controller_value = adc_control_value; if (adc_control_target_2 <= 0x7F) { current_controller_value = g_synth.current_controller_value(adc_control_target_2); - } else if (adc_control_target_2 == PANEL_PLAY_PIT) { + } else if (adc_control_target_2 == PANEL_PITCH) { current_controller_value = s_panel_play_pitch_value; } From c6e7b8e9e7ed7329c73d5182a38f9a91c21ab530 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 14 Apr 2024 12:25:06 +0900 Subject: [PATCH 083/106] Implement panel functions (67) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 54 ++++++++----------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 36a83c0..1ec6e54 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -23,7 +23,7 @@ static uint32_t s_prev_key_current_value; static uint32_t s_next_key_current_value; static uint32_t s_play_key_current_value; -static volatile uint8_t s_panel_play_pitch_value = 64; +static volatile uint8_t s_panel_play_pitch_value = 60; static volatile uint8_t s_panel_play_note_number = 60; static volatile uint8_t s_panel_playing_note_number = 0xFF; static volatile uint8_t s_reserved_note_off = 0xFF; @@ -133,33 +133,16 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe } else if (s_adc_control_target[adc_number] == PANEL_PITCH) { s_panel_play_pitch_value = s_adc_control_value[adc_number]; -#if 0 - uint8_t ary_major[53] = - { 0xFF, 0xFF, 48, 48, 48, 50, 50, 50, 50, 52, 52, 52, 53, 53, 53, - 55, 55, 55, 55, 57, 57, 57, 57, 59, 59, 59, 60, - 60, 60, 62, 62, 62, 62, 64, 64, 64, 65, 65, 65, - 67, 67, 67, 67, 69, 69, 69, 69, 71, 71, 71, 72, 72, 72 }; + uint8_t new_note_number = s_panel_play_pitch_value; - uint8_t ary_pentatonic[53] = - { 0xFF, 0xFF, 48, 48, 48, 50, 50, 50, 50, 52, 52, 52, 52, 52, 55, - 55, 55, 55, 55, 57, 57, 57, 57, 57, 60, 60, 60, - 60, 60, 62, 62, 62, 62, 64, 64, 64, 64, 64, 67, - 67, 67, 67, 67, 69, 69, 69, 69, 69, 72, 72, 72, 72, 72 }; -#endif - - uint8_t ary_chromatic[53] = - { 0xFF, 0xFF, 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, - 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59, 60, - 60, 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, 66, - 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 72, 72 }; - - uint32_t index = (((s_panel_play_pitch_value + 3) * 2) + 1) / 5; - uint8_t note_number = ary_chromatic[index]; - - s_panel_play_note_number = note_number; + bool panel_play_note_number_changed = false; + if (s_panel_play_note_number != new_note_number) { + s_panel_play_note_number = new_note_number; + panel_play_note_number_changed = true; + } if (s_play_key_current_value == 1) { - if (s_panel_playing_note_number != note_number) { + if (panel_play_note_number_changed) { s_reserved_note_off = s_panel_playing_note_number; s_reserved_note_on = s_panel_play_note_number; PRA32_U_ControlPanel_process_reserved_note_off_on(); @@ -378,13 +361,20 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta break; case PANEL_PITCH : { - char ary[53][5] = - { "Off", "Off", " C3", " C3", "C#3", "C#3", " D3", " D3", "D#3", "D#3", " E3", " E3", " F3", " F3", "F#3", - "F#3", " G3", " G3", "G#3", "G#3", " A3", " A3", "A#3", "A#3", " B3", " B3", " C4", - " C4", "C#4", "C#4", " D4", " D4", "D#4", "D#4", " E4", " E4", " F4", " F4", "F#4", - "F#4", " G4", " G4", "G#4", "G#4", " A4", " A4", "A#4", "A#4", " B4", " B4", " C5", " C5", " C5" }; - uint32_t index = (((s_panel_play_pitch_value + 3) * 2) + 1) / 5; - std::strcpy(value_display_text, ary[index]); + char ary[12][5] = { " C", "C#", " D", "D#", " E", " F", "F#", " G", "G#", " A", "A#", " B" }; + + uint32_t quotient = controller_value / 12; + uint32_t remainder = controller_value % 12; + + value_display_text[0] = ary[remainder][0]; + value_display_text[1] = ary[remainder][1]; + + if (quotient == 0) { + value_display_text[2] = '-'; + } else { + value_display_text[2] = '0' + quotient - 1; + } + result = true; } break; From 07227dd38e83297fbc61b97c6569ca1b89686d2a Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 14 Apr 2024 13:09:20 +0900 Subject: [PATCH 084/106] Implement panel functions (68) --- .../Digital-Synth-PRA32-U.ino | 4 + Digital-Synth-PRA32-U/pra32-u-control-panel.h | 73 +++++++++++++++---- Digital-Synth-PRA32-U/pra32-u-synth.h | 4 + 3 files changed, 68 insertions(+), 13 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 87d8e66..42b4f3d 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -69,6 +69,10 @@ #include "hardware/adc.h" +#if defined(PRA32_U_USE_CONTROL_PANEL) +extern void PRA32_U_ControlPanel_on_control_change(uint8_t control_number); +#endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) + #include "pra32-u-common.h" #include "pra32-u-synth.h" diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 1ec6e54..75964bf 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -18,6 +18,7 @@ static volatile uint32_t s_current_page_index = 4; static volatile int32_t s_adc_current_value[3]; static volatile uint8_t s_adc_control_value[3]; static volatile uint8_t s_adc_control_target[3] = { 0xFF, 0xFF, 0xFF }; +static volatile boolean s_adc_control_catched[3]; static uint32_t s_prev_key_current_value; static uint32_t s_next_key_current_value; @@ -113,8 +114,27 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe uint8_t s_adc_control_value_old = s_adc_control_value[adc_number]; s_adc_control_value[adc_number] = adc_control_value_candidate; + uint8_t current_controller_value = s_adc_control_value[adc_number]; + if (s_adc_control_target[adc_number] <= 0x7F) { + current_controller_value = g_synth.current_controller_value(s_adc_control_target[adc_number]); + } else if (s_adc_control_target[adc_number] == PANEL_PITCH) { + current_controller_value = s_panel_play_pitch_value; + } + + if ((s_adc_control_value_old <= current_controller_value) && + (s_adc_control_value[adc_number] >= current_controller_value)) { + s_adc_control_catched[adc_number] = true; + } + + if ((s_adc_control_value_old >= current_controller_value) && + (s_adc_control_value[adc_number] <= current_controller_value)) { + s_adc_control_catched[adc_number] = true; + } + if (s_adc_control_target[adc_number] <= 0x7F) { - g_synth.control_change(s_adc_control_target[adc_number], s_adc_control_value[adc_number]); + if (s_adc_control_catched[adc_number]) { + g_synth.control_change(s_adc_control_target[adc_number], s_adc_control_value[adc_number]); + } } else if ((s_adc_control_target[adc_number] >= PC_BY_PANEL_0) && (s_adc_control_target[adc_number] <= PC_BY_PANEL_15)) { if ((s_adc_control_value_old < 64) && (s_adc_control_value[adc_number] >= 64)) { g_synth.program_change(s_adc_control_target[adc_number] - PC_BY_PANEL_0); @@ -131,21 +151,23 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe s_ready_to_write[program_number_to_write] = false; } } else if (s_adc_control_target[adc_number] == PANEL_PITCH) { - s_panel_play_pitch_value = s_adc_control_value[adc_number]; + if (s_adc_control_catched[adc_number]) { + s_panel_play_pitch_value = s_adc_control_value[adc_number]; - uint8_t new_note_number = s_panel_play_pitch_value; + uint8_t new_note_number = s_panel_play_pitch_value; - bool panel_play_note_number_changed = false; - if (s_panel_play_note_number != new_note_number) { - s_panel_play_note_number = new_note_number; - panel_play_note_number_changed = true; - } + bool panel_play_note_number_changed = false; + if (s_panel_play_note_number != new_note_number) { + s_panel_play_note_number = new_note_number; + panel_play_note_number_changed = true; + } - if (s_play_key_current_value == 1) { - if (panel_play_note_number_changed) { - s_reserved_note_off = s_panel_playing_note_number; - s_reserved_note_on = s_panel_play_note_number; - PRA32_U_ControlPanel_process_reserved_note_off_on(); + if (s_play_key_current_value == 1) { + if (panel_play_note_number_changed) { + s_reserved_note_off = s_panel_playing_note_number; + s_reserved_note_on = s_panel_play_note_number; + PRA32_U_ControlPanel_process_reserved_note_off_on(); + } } } } @@ -545,6 +567,10 @@ INLINE void PRA32_U_ControlPanel_update_control() { } PRA32_U_ControlPanel_update_page(); + + s_adc_control_catched[0] = false; + s_adc_control_catched[1] = false; + s_adc_control_catched[2] = false; } return; } @@ -567,6 +593,10 @@ INLINE void PRA32_U_ControlPanel_update_control() { } PRA32_U_ControlPanel_update_page(); + + s_adc_control_catched[0] = false; + s_adc_control_catched[1] = false; + s_adc_control_catched[2] = false; } return; } @@ -786,6 +816,23 @@ INLINE void PRA32_U_ControlPanel_update_display(uint32_t loop_counter) { #endif // defined(PRA32_U_USE_CONTROL_PANEL) } +void PRA32_U_ControlPanel_on_control_change(uint8_t control_number) +{ +#if defined(PRA32_U_USE_CONTROL_PANEL) + if (s_adc_control_target[0] == control_number) { + s_adc_control_catched[0] = false; + } + + if (s_adc_control_target[1] == control_number) { + s_adc_control_catched[1] = false; + } + + if (s_adc_control_target[2] == control_number) { + s_adc_control_catched[2] = false; + } +#endif // defined(PRA32_U_USE_CONTROL_PANEL_ANALOG_INPUT) +} + INLINE void PRA32_U_ControlPanel_debug_print(uint32_t loop_counter) { static_cast(loop_counter); diff --git a/Digital-Synth-PRA32-U/pra32-u-synth.h b/Digital-Synth-PRA32-U/pra32-u-synth.h index 5d84542..f61bd57 100644 --- a/Digital-Synth-PRA32-U/pra32-u-synth.h +++ b/Digital-Synth-PRA32-U/pra32-u-synth.h @@ -606,6 +606,10 @@ class PRA32_U_Synth { /* INLINE */ void control_change(uint8_t control_number, uint8_t controller_value) { m_current_controller_value_table[control_number] = controller_value; +#if defined(PRA32_U_USE_CONTROL_PANEL) + PRA32_U_ControlPanel_on_control_change(control_number); +#endif // defined(PRA32_U_USE_CONTROL_PANEL) + switch (control_number) { case MODULATION : m_lfo.set_lfo_depth<1>(controller_value); From 8ed3762168d4c3f84477cfa03941ca0fcef63cd4 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 14 Apr 2024 13:11:42 +0900 Subject: [PATCH 085/106] Update Digital-Synth-PRA32-U.ino --- Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 42b4f3d..2be4ac7 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -2,7 +2,7 @@ * Digital Synth PRA32-U */ -#define PRA32_U_USE_DEBUG_PRINT // Serial1 +//#define PRA32_U_USE_DEBUG_PRINT // Serial1 #define PRA32_U_USE_USB_MIDI // Select USB Stack: "Adafruit TinyUSB" in the Arduino IDE "Tools" menu @@ -42,7 +42,7 @@ //////////////////////////////////////////////////////////////// -#define PRA32_U_USE_CONTROL_PANEL // Experimental +//#define PRA32_U_USE_CONTROL_PANEL // Experimental #define PRA32_U_USE_CONTROL_PANEL_KEY_INPUT // Use tactile switches #define PRA32_U_KEY_INPUT_ACTIVE_LEVEL (HIGH) From e72d555b2595007dad33f2089df3ff1cd1b56d98 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 14 Apr 2024 13:27:26 +0900 Subject: [PATCH 086/106] Update README.md --- README.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cd64ceb..8d1ec78 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ - Info: - Please install Arduino-Pico = **Raspberry Pi Pico/RP2040** (by Earle F. Philhower, III) core - Additional Board Manager URL: - - This sketch is tested with version **3.7.0**: - - Arduino-Pico version 3.7.0 includes Adafruit TinyUSB Library version 2.3.0 + - This sketch is tested with version **3.7.2**: + - Arduino-Pico version 3.7.2 includes Adafruit TinyUSB Library version 2.3.0 - Info: - Please install Arduino **MIDI Library** (by Francois Best, lathoub) - This sketch is tested with version **5.0.2**: @@ -120,6 +120,13 @@ ``` +#### PRA32-U with Panel (Optional) (Experimental) + +- This option requires 3 tactile switches, 3 ADCs, and SSD1306 monochrome 128x64 OLED +- Tested with Seeed Studio's Grove Shield for Pi Pico, Buttons, Rotary Angle Sensors, and a OLED Display 0.96 inch +- Uncomment out `//#define PRA32_U_USE_CONTROL_PANEL` in "Digital-Synth-PRA32-U.ino" and modify options + + ## Files - "Digital-Synth-PRA32-U.ino" is a Arduino sketch for Raspberry Pi Pico/RP2040 core @@ -145,7 +152,7 @@ - When not using PRA32-U CTRL - PRA32-U can also be controlled by MIDI without using PRA32-U CTRL - Refer to "PRA32-U-MIDI-Implementation-Chart.txt" for the supported functions - - The default program is #0 + - The default program is #8 - Programs #0-15 can be modified by editing "pra32-u-program-table.h" - PRA32-U CTRL functions related to parameter writing - Write: Write the current parameters to PRA32-U (Program #8-15 and the flash) From b084581f8e6b7591f23b91ac2d0e3c796614e0ab Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 14 Apr 2024 13:28:39 +0900 Subject: [PATCH 087/106] Update PRA32-U-Change-History.md --- PRA32-U-Change-History.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/PRA32-U-Change-History.md b/PRA32-U-Change-History.md index c2e921c..e6bfbb4 100644 --- a/PRA32-U-Change-History.md +++ b/PRA32-U-Change-History.md @@ -1,10 +1,13 @@ ## Digital Synth PRA32-U Change History -- v2.3.0 (2024-**-**): +- v2.3.0 (2024-04-**): - Allow user programs to be written to the flash when using I2S DAC without mute-off pin - Add the option to write user programs to the flash when using PWM audio (for Raspberry Pi Pico/H/W/WH) - Add the option PRA32_U_I2S_SWAP_LEFT_AND_RIGHT + - Add the option **PRA32-U with Panel** (experimental) + - Change the default program #0 to #8 - Use core 1 for Debug Print + - Tested with Arduino-Pico version 3.7.2 - v2.2.2 (2024-02-10): - Fix a bug that the parameters are not written to the flash when using I2S DAC, even if PRA32_U_I2S_DAC_MUTE_OFF_PIN is defined - Tested with Arduino-Pico version 3.7.0 From ca107960759d5332da7460c579e573e240a1019d Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 14 Apr 2024 22:08:13 +0900 Subject: [PATCH 088/106] Implement panel functions (69) --- .../pra32-u-control-panel-page-table.h | 71 +++++------ Digital-Synth-PRA32-U/pra32-u-control-panel.h | 114 ++++++++++++++---- 2 files changed, 125 insertions(+), 60 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h index d7edd0a..bcaaae0 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h @@ -1,42 +1,43 @@ #pragma once -const uint8_t PC_BY_PANEL_0 = 128; -const uint8_t PC_BY_PANEL_1 = 129; -const uint8_t PC_BY_PANEL_2 = 130; -const uint8_t PC_BY_PANEL_3 = 131; -const uint8_t PC_BY_PANEL_4 = 132; -const uint8_t PC_BY_PANEL_5 = 133; -const uint8_t PC_BY_PANEL_6 = 134; -const uint8_t PC_BY_PANEL_7 = 135; +const uint8_t PANEL_PITCH = 128 + 0; +const uint8_t PANEL_SCALE = 128 + 1; -const uint8_t PC_BY_PANEL_8 = 136; -const uint8_t PC_BY_PANEL_9 = 137; -const uint8_t PC_BY_PANEL_10 = 138; -const uint8_t PC_BY_PANEL_11 = 139; -const uint8_t PC_BY_PANEL_12 = 140; -const uint8_t PC_BY_PANEL_13 = 141; -const uint8_t PC_BY_PANEL_14 = 142; -const uint8_t PC_BY_PANEL_15 = 143; +const uint8_t PC_BY_PANEL_0 = 128 + 64; +const uint8_t PC_BY_PANEL_1 = 128 + 65; +const uint8_t PC_BY_PANEL_2 = 128 + 66; +const uint8_t PC_BY_PANEL_3 = 128 + 67; +const uint8_t PC_BY_PANEL_4 = 128 + 68; +const uint8_t PC_BY_PANEL_5 = 128 + 69; +const uint8_t PC_BY_PANEL_6 = 128 + 70; +const uint8_t PC_BY_PANEL_7 = 128 + 71; -const uint8_t WR_BY_PANEL_0 = 144; // Invalid -const uint8_t WR_BY_PANEL_1 = 145; // Invalid -const uint8_t WR_BY_PANEL_2 = 146; // Invalid -const uint8_t WR_BY_PANEL_3 = 147; // Invalid -const uint8_t WR_BY_PANEL_4 = 148; // Invalid -const uint8_t WR_BY_PANEL_5 = 149; // Invalid -const uint8_t WR_BY_PANEL_6 = 150; // Invalid -const uint8_t WR_BY_PANEL_7 = 151; // Invalid +const uint8_t PC_BY_PANEL_8 = 128 + 72; +const uint8_t PC_BY_PANEL_9 = 128 + 73; +const uint8_t PC_BY_PANEL_10 = 128 + 74; +const uint8_t PC_BY_PANEL_11 = 128 + 75; +const uint8_t PC_BY_PANEL_12 = 128 + 76; +const uint8_t PC_BY_PANEL_13 = 128 + 77; +const uint8_t PC_BY_PANEL_14 = 128 + 78; +const uint8_t PC_BY_PANEL_15 = 128 + 79; -const uint8_t WR_BY_PANEL_8 = 152; -const uint8_t WR_BY_PANEL_9 = 153; -const uint8_t WR_BY_PANEL_10 = 154; -const uint8_t WR_BY_PANEL_11 = 155; -const uint8_t WR_BY_PANEL_12 = 156; -const uint8_t WR_BY_PANEL_13 = 157; -const uint8_t WR_BY_PANEL_14 = 158; -const uint8_t WR_BY_PANEL_15 = 159; +const uint8_t WR_BY_PANEL_0 = 128 + 80; // Invalid +const uint8_t WR_BY_PANEL_1 = 128 + 81; // Invalid +const uint8_t WR_BY_PANEL_2 = 128 + 82; // Invalid +const uint8_t WR_BY_PANEL_3 = 128 + 83; // Invalid +const uint8_t WR_BY_PANEL_4 = 128 + 84; // Invalid +const uint8_t WR_BY_PANEL_5 = 128 + 85; // Invalid +const uint8_t WR_BY_PANEL_6 = 128 + 86; // Invalid +const uint8_t WR_BY_PANEL_7 = 128 + 87; // Invalid -const uint8_t PANEL_PITCH = 160; +const uint8_t WR_BY_PANEL_8 = 128 + 88; +const uint8_t WR_BY_PANEL_9 = 128 + 89; +const uint8_t WR_BY_PANEL_10 = 128 + 90; +const uint8_t WR_BY_PANEL_11 = 128 + 91; +const uint8_t WR_BY_PANEL_12 = 128 + 92; +const uint8_t WR_BY_PANEL_13 = 128 + 93; +const uint8_t WR_BY_PANEL_14 = 128 + 94; +const uint8_t WR_BY_PANEL_15 = 128 + 95; struct PRA32_U_ControlPanelPage { char page_name_line_0 [10 + 1]; @@ -81,6 +82,6 @@ struct PRA32_U_ControlPanelPage { { "Page=28 ", "Read g ", "Read ", "Program 12", PC_BY_PANEL_12 , "Read ", "Program 13", PC_BY_PANEL_13 , " ", " ", 0xFF , }, { "Page=29 ", "Read h ", "Read ", "Program 14", PC_BY_PANEL_14 , "Read ", "Program 15", PC_BY_PANEL_15 , " ", " ", 0xFF , }, { "Page=30 ", "Panel a ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=31 ", "Panel b ", "Modulation", " ", MODULATION , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=31 ", "Panel c ", "Breath ", "Controller", BTH_CONTROLLER , "Sustain ", "Pedal ", SUSTAIN_PEDAL , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=31 ", "Panel b ", "Modulation", " ", MODULATION , "Breath ", "Controller", BTH_CONTROLLER , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=31 ", "Panel c ", "Sustain ", "Pedal ", SUSTAIN_PEDAL , "Panel ", "Scale ", PANEL_SCALE , "Panel ", "Pitch ", PANEL_PITCH , }, }; diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 75964bf..567adc9 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -25,6 +25,7 @@ static uint32_t s_next_key_current_value; static uint32_t s_play_key_current_value; static volatile uint8_t s_panel_play_pitch_value = 60; +static volatile uint8_t s_panel_play_scale_value = 0; static volatile uint8_t s_panel_play_note_number = 60; static volatile uint8_t s_panel_playing_note_number = 0xFF; static volatile uint8_t s_reserved_note_off = 0xFF; @@ -107,6 +108,44 @@ static INLINE boolean PRA32_U_ControlPanel_process_reserved_note_off_on() { return false; } +static INLINE void PRA32_U_ControlPanel_update_pitch() { + uint32_t new_note_number = s_panel_play_pitch_value; + + uint32_t index_scale = ((s_panel_play_scale_value * 4) + 127) / 254; + if (index_scale == 1) { + const uint8_t ary_major[53] = + { 48, 48, 48, 48, 48, 50, 50, 50, 50, 52, 52, 52, 53, 53, 53, + 55, 55, 55, 55, 57, 57, 57, 57, 59, 59, 59, 60, + 60, 60, 62, 62, 62, 62, 64, 64, 64, 65, 65, 65, + 67, 67, 67, 67, 69, 69, 69, 69, 71, 71, 71, 72, 72, 72 }; + uint32_t index_pitch = (((s_panel_play_pitch_value + 3) * 2) + 1) / 5; + new_note_number = ary_major[index_pitch]; + } else if (index_scale == 2) { + const uint8_t ary_pentatonic[53] = + { 48, 48, 48, 48, 48, 50, 50, 50, 50, 52, 52, 52, 52, 52, 55, + 55, 55, 55, 55, 57, 57, 57, 57, 57, 60, 60, 60, + 60, 60, 62, 62, 62, 62, 64, 64, 64, 64, 64, 67, + 67, 67, 67, 67, 69, 69, 69, 69, 69, 72, 72, 72, 72, 72 }; + + uint32_t index_pitch = (((s_panel_play_pitch_value + 3) * 2) + 1) / 5; + new_note_number = ary_pentatonic[index_pitch]; + } + + bool panel_play_note_number_changed = false; + if (s_panel_play_note_number != new_note_number) { + s_panel_play_note_number = new_note_number; + panel_play_note_number_changed = true; + } + + if (s_play_key_current_value == 1) { + if (panel_play_note_number_changed) { + s_reserved_note_off = s_panel_playing_note_number; + s_reserved_note_on = s_panel_play_note_number; + PRA32_U_ControlPanel_process_reserved_note_off_on(); + } + } +} + static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_number) { uint8_t adc_control_value_candidate = PRA32_U_ControlPanel_adc_control_value_candidate(adc_number); @@ -119,6 +158,8 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe current_controller_value = g_synth.current_controller_value(s_adc_control_target[adc_number]); } else if (s_adc_control_target[adc_number] == PANEL_PITCH) { current_controller_value = s_panel_play_pitch_value; + } else if (s_adc_control_target[adc_number] == PANEL_SCALE) { + current_controller_value = s_panel_play_scale_value; } if ((s_adc_control_value_old <= current_controller_value) && @@ -153,22 +194,12 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe } else if (s_adc_control_target[adc_number] == PANEL_PITCH) { if (s_adc_control_catched[adc_number]) { s_panel_play_pitch_value = s_adc_control_value[adc_number]; - - uint8_t new_note_number = s_panel_play_pitch_value; - - bool panel_play_note_number_changed = false; - if (s_panel_play_note_number != new_note_number) { - s_panel_play_note_number = new_note_number; - panel_play_note_number_changed = true; - } - - if (s_play_key_current_value == 1) { - if (panel_play_note_number_changed) { - s_reserved_note_off = s_panel_playing_note_number; - s_reserved_note_on = s_panel_play_note_number; - PRA32_U_ControlPanel_process_reserved_note_off_on(); - } - } + PRA32_U_ControlPanel_update_pitch(); + } + } else if (s_adc_control_target[adc_number] == PANEL_SCALE) { + if (s_adc_control_catched[adc_number]) { + s_panel_play_scale_value = s_adc_control_value[adc_number]; + PRA32_U_ControlPanel_update_pitch(); } } @@ -383,23 +414,50 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta break; case PANEL_PITCH : { - char ary[12][5] = { " C", "C#", " D", "D#", " E", " F", "F#", " G", "G#", " A", "A#", " B" }; + uint32_t index_scale = ((s_panel_play_scale_value * 4) + 127) / 254; + if (index_scale == 0) { + char ary[12][5] = { " C", "C#", " D", "D#", " E", " F", "F#", " G", "G#", " A", "A#", " B" }; - uint32_t quotient = controller_value / 12; - uint32_t remainder = controller_value % 12; + uint32_t quotient = controller_value / 12; + uint32_t remainder = controller_value % 12; - value_display_text[0] = ary[remainder][0]; - value_display_text[1] = ary[remainder][1]; + value_display_text[0] = ary[remainder][0]; + value_display_text[1] = ary[remainder][1]; - if (quotient == 0) { - value_display_text[2] = '-'; - } else { - value_display_text[2] = '0' + quotient - 1; + if (quotient == 0) { + value_display_text[2] = '-'; + } else { + value_display_text[2] = '0' + quotient - 1; + } + } else if (index_scale == 1) { + char ary_major[53][5] = + { " C3", " C3", " C3", " C3", " C3", " D3", " D3", " D3", " D3", " E3", " E3", " E3", " F3", " F3", " F3", + " G3", " G3", " G3", " G3", " A3", " A3", " A3", " A3", " B3", " B3", " B3", " C4", + " C4", " C4", " D4", " D4", " D4", " D4", " E4", " E4", " E4", " F4", " F4", " F4", + " G4", " G4", " G4", " G4", " A4", " A4", " A4", " A4", " B4", " B4", " B4", " C5", " C5", " C5" }; + uint32_t index = (((s_panel_play_pitch_value + 3) * 2) + 1) / 5; + std::strcpy(value_display_text, ary_major[index]); + } else if (index_scale == 2) { + char ary_pentatonic[53][5] = + { " C3", " C3", " C3", " C3", " C3", " D3", " D3", " D3", " D3", " E3", " E3", " E3", " E3", " E3", " G3", + " G3", " G3", " G3", " G3", " A3", " A3", " A3", " A3", " A3", " C4", " C4", " C4", + " C4", " C4", " D4", " D4", " D4", " D4", " E4", " E4", " E4", " E4", " E4", " G4", + " G4", " G4", " G4", " G4", " A4", " A4", " A4", " A4", " A4", " C4", " C5", " C5", " C5", " C5" }; + uint32_t index = (((s_panel_play_pitch_value + 3) * 2) + 1) / 5; + std::strcpy(value_display_text, ary_pentatonic[index]); } result = true; } break; + case PANEL_SCALE : + { + char ary[3][5] = {"Ful"," M2"," P2"}; + uint32_t index = ((controller_value * 4) + 127) / 254; + std::strcpy(value_display_text, ary[index]); + result = true; + } + break; } return result; @@ -661,6 +719,8 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { current_controller_value = g_synth.current_controller_value(adc_control_target_0); } else if (adc_control_target_0 == PANEL_PITCH) { current_controller_value = s_panel_play_pitch_value; + } else if (adc_control_target_0 == PANEL_SCALE) { + current_controller_value = s_panel_play_scale_value; } s_display_buffer[7][ 0] = 'A'; @@ -696,6 +756,8 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { current_controller_value = g_synth.current_controller_value(adc_control_target_1); } else if (adc_control_target_1 == PANEL_PITCH) { current_controller_value = s_panel_play_pitch_value; + } else if (adc_control_target_1 == PANEL_SCALE) { + current_controller_value = s_panel_play_scale_value; } s_display_buffer[7][11] = 'B'; @@ -731,6 +793,8 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { current_controller_value = g_synth.current_controller_value(adc_control_target_2); } else if (adc_control_target_2 == PANEL_PITCH) { current_controller_value = s_panel_play_pitch_value; + } else if (adc_control_target_2 == PANEL_SCALE) { + current_controller_value = s_panel_play_scale_value; } s_display_buffer[3][11] = 'C'; From 98c75d0b1d06ab6a2dd5802266d07394036c2d07 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 14 Apr 2024 22:17:32 +0900 Subject: [PATCH 089/106] Implement panel functions (70) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 567adc9..f537564 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -452,7 +452,7 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta break; case PANEL_SCALE : { - char ary[3][5] = {"Ful"," M2"," P2"}; + char ary[3][5] = {"Ful","Maj","Pen"}; uint32_t index = ((controller_value * 4) + 127) / 254; std::strcpy(value_display_text, ary[index]); result = true; From 6bc086ac18e671cad3ef47a687fa4ebcd32ff241 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 14 Apr 2024 22:39:27 +0900 Subject: [PATCH 090/106] Implement panel functions (71) --- .../pra32-u-control-panel-page-table.h | 4 ++- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 36 +++++++++++++++---- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h index bcaaae0..8aac1e9 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h @@ -2,6 +2,7 @@ const uint8_t PANEL_PITCH = 128 + 0; const uint8_t PANEL_SCALE = 128 + 1; +const uint8_t PANEL_TRANSPOSE = 128 + 2; const uint8_t PC_BY_PANEL_0 = 128 + 64; const uint8_t PC_BY_PANEL_1 = 128 + 65; @@ -83,5 +84,6 @@ struct PRA32_U_ControlPanelPage { { "Page=29 ", "Read h ", "Read ", "Program 14", PC_BY_PANEL_14 , "Read ", "Program 15", PC_BY_PANEL_15 , " ", " ", 0xFF , }, { "Page=30 ", "Panel a ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Panel ", "Pitch ", PANEL_PITCH , }, { "Page=31 ", "Panel b ", "Modulation", " ", MODULATION , "Breath ", "Controller", BTH_CONTROLLER , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=31 ", "Panel c ", "Sustain ", "Pedal ", SUSTAIN_PEDAL , "Panel ", "Scale ", PANEL_SCALE , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=32 ", "Panel c ", "Sustain ", "Pedal ", SUSTAIN_PEDAL , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=33 ", "Panel d ", "Panel ", "Scale ", PANEL_SCALE , "Panel ", "Transpose ", PANEL_TRANSPOSE, "Panel ", "Pitch ", PANEL_PITCH , }, }; diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index f537564..b270a84 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -24,12 +24,13 @@ static uint32_t s_prev_key_current_value; static uint32_t s_next_key_current_value; static uint32_t s_play_key_current_value; -static volatile uint8_t s_panel_play_pitch_value = 60; -static volatile uint8_t s_panel_play_scale_value = 0; -static volatile uint8_t s_panel_play_note_number = 60; -static volatile uint8_t s_panel_playing_note_number = 0xFF; -static volatile uint8_t s_reserved_note_off = 0xFF; -static volatile uint8_t s_reserved_note_on = 0xFF; +static volatile uint8_t s_panel_play_pitch_value = 60; +static volatile uint8_t s_panel_play_scale_value = 0; +static volatile uint8_t s_panel_play_transpose_value = 64; +static volatile uint8_t s_panel_play_note_number = 60; +static volatile uint8_t s_panel_playing_note_number = 0xFF; +static volatile uint8_t s_reserved_note_off = 0xFF; +static volatile uint8_t s_reserved_note_on = 0xFF; static volatile uint32_t s_display_draw_counter = 0; @@ -109,7 +110,7 @@ static INLINE boolean PRA32_U_ControlPanel_process_reserved_note_off_on() { } static INLINE void PRA32_U_ControlPanel_update_pitch() { - uint32_t new_note_number = s_panel_play_pitch_value; + int32_t new_note_number = s_panel_play_pitch_value; uint32_t index_scale = ((s_panel_play_scale_value * 4) + 127) / 254; if (index_scale == 1) { @@ -131,6 +132,13 @@ static INLINE void PRA32_U_ControlPanel_update_pitch() { new_note_number = ary_pentatonic[index_pitch]; } + new_note_number += s_panel_play_transpose_value - 64; + if (new_note_number < 0) { + new_note_number = 0; + } else if (new_note_number > 127) { + new_note_number = 127; + } + bool panel_play_note_number_changed = false; if (s_panel_play_note_number != new_note_number) { s_panel_play_note_number = new_note_number; @@ -160,6 +168,8 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe current_controller_value = s_panel_play_pitch_value; } else if (s_adc_control_target[adc_number] == PANEL_SCALE) { current_controller_value = s_panel_play_scale_value; + } else if (s_adc_control_target[adc_number] == PANEL_TRANSPOSE) { + current_controller_value = s_panel_play_transpose_value; } if ((s_adc_control_value_old <= current_controller_value) && @@ -201,6 +211,11 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe s_panel_play_scale_value = s_adc_control_value[adc_number]; PRA32_U_ControlPanel_update_pitch(); } + } else if (s_adc_control_target[adc_number] == PANEL_TRANSPOSE) { + if (s_adc_control_catched[adc_number]) { + s_panel_play_transpose_value = s_adc_control_value[adc_number]; + PRA32_U_ControlPanel_update_pitch(); + } } return true; @@ -234,6 +249,7 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta case LFO_OSC_AMT : case LFO_FILTER_AMT : case BTH_FILTER_AMT : + case PANEL_TRANSPOSE : { std::sprintf(value_display_text, "%+3d", static_cast(controller_value) - 64); result = true; @@ -721,6 +737,8 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { current_controller_value = s_panel_play_pitch_value; } else if (adc_control_target_0 == PANEL_SCALE) { current_controller_value = s_panel_play_scale_value; + } else if (adc_control_target_0 == PANEL_TRANSPOSE) { + current_controller_value = s_panel_play_transpose_value; } s_display_buffer[7][ 0] = 'A'; @@ -758,6 +776,8 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { current_controller_value = s_panel_play_pitch_value; } else if (adc_control_target_1 == PANEL_SCALE) { current_controller_value = s_panel_play_scale_value; + } else if (adc_control_target_1 == PANEL_TRANSPOSE) { + current_controller_value = s_panel_play_transpose_value; } s_display_buffer[7][11] = 'B'; @@ -795,6 +815,8 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { current_controller_value = s_panel_play_pitch_value; } else if (adc_control_target_2 == PANEL_SCALE) { current_controller_value = s_panel_play_scale_value; + } else if (adc_control_target_2 == PANEL_TRANSPOSE) { + current_controller_value = s_panel_play_transpose_value; } s_display_buffer[3][11] = 'C'; From f115ca875c02ff1948a6814d69e4ed3ff34bce12 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sat, 20 Apr 2024 12:17:04 +0900 Subject: [PATCH 091/106] Implement panel functions (72) --- .../pra32-u-control-panel-page-table.h | 76 +++++++++++-------- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 16 ++-- 2 files changed, 51 insertions(+), 41 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h index 8aac1e9..f78bcc1 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h @@ -40,6 +40,8 @@ const uint8_t WR_BY_PANEL_13 = 128 + 93; const uint8_t WR_BY_PANEL_14 = 128 + 94; const uint8_t WR_BY_PANEL_15 = 128 + 95; +const uint8_t PAGE_INDEX_DEFAULT = 6; + struct PRA32_U_ControlPanelPage { char page_name_line_0 [10 + 1]; char page_name_line_1 [10 + 1]; @@ -53,37 +55,45 @@ struct PRA32_U_ControlPanelPage { char control_target_c_name_line_1[10 + 1]; uint8_t control_target_c; } g_control_panel_page_table[] = { - { "Page= 1 ", "Voice ", "Voice ", "Mode ", VOICE_MODE , "Portamento", " ", PORTAMENTO , "Pitch ", "Bend Range", P_BEND_RANGE , }, - { "Page= 2 ", "Osc 1 ", "Osc 1 ", "Wave ", OSC_1_WAVE , "Osc 1 ", "Shape ", OSC_1_SHAPE , "Osc 1 ", "Morph ", OSC_1_MORPH , }, - { "Page= 3 ", "Osc 2 ", "Osc 2 ", "Wave ", OSC_2_WAVE , "Osc 2 ", "Coarse ", OSC_2_COARSE , "Osc 2 ", "Pitch ", OSC_2_PITCH , }, - { "Page= 4 ", "Mixer ", "Mixer ", "Osc Mix ", MIXER_OSC_MIX , "Mixer ", "Noise/Sub ", MIXER_SUB_OSC , " ", " ", 0xFF , }, - { "Page= 5 ", "Filter a ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Filter ", "EG Amt ", FILTER_EG_AMT , }, - { "Page= 6 ", "Filter b ", "Filter ", "Key Track ", FILTER_KEY_TRK , "Filter ", "Mode ", FILTER_MODE , " ", " ", 0xFF , }, - { "Page= 7 ", "EG a ", "EG ", "Attack ", EG_ATTACK , "EG ", "Decay ", EG_DECAY , "EG ", "Sustain ", EG_SUSTAIN , }, - { "Page= 8 ", "EG b ", "EG ", "Release ", EG_RELEASE , "EG ", "Amp Mod ", EG_AMP_MOD , "Release ", "= Decay ", REL_EQ_DECAY , }, - { "Page= 9 ", "EG c ", "EG ", "Osc Amt ", EG_OSC_AMT , "EG ", "Osc Dst ", EG_OSC_DST , "EG ", "Velo Sens ", EG_VEL_SENS , }, - { "Page=10 ", "Amp a ", "Amp ", "Attack ", AMP_ATTACK , "Amp ", "Decay ", AMP_DECAY , "Amp ", "Sustain ", AMP_SUSTAIN , }, - { "Page=11 ", "Amp b ", "Amp ", "Release ", AMP_RELEASE , "Amp ", "Gain ", AMP_GAIN , "Amp ", "Velo Sens ", AMP_VEL_SENS , }, - { "Page=12 ", "LFO a ", "LFO ", "Wave ", LFO_WAVE , "LFO ", "Rate ", LFO_RATE , "LFO ", "Depth ", LFO_DEPTH , }, - { "Page=13 ", "LFO b ", "LFO ", "Fade Time ", LFO_FADE_TIME , " ", " ", 0xFF , " ", " ", 0xFF , }, - { "Page=14 ", "LFO c ", "LFO ", "Osc Amt ", LFO_OSC_AMT , "LFO ", "Osc Dst ", LFO_OSC_DST , "LFO ", "Filter Amt", LFO_FILTER_AMT , }, - { "Page=15 ", "Breath ", "Breath ", "Filter Amt", BTH_FILTER_AMT , "Breath ", "Amp Mod ", BTH_AMP_MOD , " ", " ", 0xFF , }, - { "Page=16 ", "Chorus ", "Chorus ", "Mix ", CHORUS_MIX , "Chorus ", "Rate ", CHORUS_RATE , "Chorus ", "Depth ", CHORUS_DEPTH , }, - { "Page=17 ", "Delay ", "Delay ", "Feedback ", DELAY_FEEDBACK , "Delay ", "Time ", DELAY_TIME , "Delay ", "Mode ", DELAY_MODE , }, - { "Page=18 ", "Write a ", "Write ", "Program 8", WR_BY_PANEL_8 , "Write ", "Program 9", WR_BY_PANEL_9 , " ", " ", 0xFF , }, - { "Page=19 ", "Write b ", "Write ", "Program 10", WR_BY_PANEL_10 , "Write ", "Program 11", WR_BY_PANEL_11 , " ", " ", 0xFF , }, - { "Page=20 ", "Write c ", "Write ", "Program 12", WR_BY_PANEL_12 , "Write ", "Program 13", WR_BY_PANEL_13 , " ", " ", 0xFF , }, - { "Page=21 ", "Write d ", "Write ", "Program 14", WR_BY_PANEL_14 , "Write ", "Program 15", WR_BY_PANEL_15 , " ", " ", 0xFF , }, - { "Page=22 ", "Read a ", "Read ", "Program 0", PC_BY_PANEL_0 , "Read ", "Program 1", PC_BY_PANEL_1 , " ", " ", 0xFF , }, - { "Page=23 ", "Read b ", "Read ", "Program 2", PC_BY_PANEL_2 , "Read ", "Program 3", PC_BY_PANEL_3 , " ", " ", 0xFF , }, - { "Page=24 ", "Read c ", "Read ", "Program 4", PC_BY_PANEL_4 , "Read ", "Program 5", PC_BY_PANEL_5 , " ", " ", 0xFF , }, - { "Page=25 ", "Read d ", "Read ", "Program 6", PC_BY_PANEL_6 , "Read ", "Program 7", PC_BY_PANEL_7 , " ", " ", 0xFF , }, - { "Page=26 ", "Read e ", "Read ", "Program 8", PC_BY_PANEL_8 , "Read ", "Program 9", PC_BY_PANEL_9 , " ", " ", 0xFF , }, - { "Page=27 ", "Read f ", "Read ", "Program 10", PC_BY_PANEL_10 , "Read ", "Program 11", PC_BY_PANEL_11 , " ", " ", 0xFF , }, - { "Page=28 ", "Read g ", "Read ", "Program 12", PC_BY_PANEL_12 , "Read ", "Program 13", PC_BY_PANEL_13 , " ", " ", 0xFF , }, - { "Page=29 ", "Read h ", "Read ", "Program 14", PC_BY_PANEL_14 , "Read ", "Program 15", PC_BY_PANEL_15 , " ", " ", 0xFF , }, - { "Page=30 ", "Panel a ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=31 ", "Panel b ", "Modulation", " ", MODULATION , "Breath ", "Controller", BTH_CONTROLLER , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=32 ", "Panel c ", "Sustain ", "Pedal ", SUSTAIN_PEDAL , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=33 ", "Panel d ", "Panel ", "Scale ", PANEL_SCALE , "Panel ", "Transpose ", PANEL_TRANSPOSE, "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 1 ", "Voice a ", "Voice ", "Mode ", VOICE_MODE , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 2 ", "Voice b ", "Portamento", " ", PORTAMENTO , "Pitch ", "Bend Range", P_BEND_RANGE , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 3 ", "Osc a ", "Osc 1 ", "Wave ", OSC_1_WAVE , "Mixer ", "Noise/Sub ", MIXER_SUB_OSC , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 4 ", "Osc b ", "Osc 1 ", "Shape ", OSC_1_SHAPE , "Osc 1 ", "Morph ", OSC_1_MORPH , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 5 ", "Osc c ", "Osc 2 ", "Wave ", OSC_2_WAVE , "Mixer ", "Osc Mix ", MIXER_OSC_MIX , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 6 ", "Osc d ", "Osc 2 ", "Coarse ", OSC_2_COARSE , "Osc 2 ", "Pitch ", OSC_2_PITCH , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 7 ", "Filter a ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 8 ", "Filter b ", "Filter ", "EG Amt ", FILTER_EG_AMT , "Filter ", "Key Track ", FILTER_KEY_TRK , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 9 ", "Filter c ", "Filter ", "Mode ", FILTER_MODE , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=10 ", "EG a ", "EG ", "Attack ", EG_ATTACK , "EG ", "Decay ", EG_DECAY , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=11 ", "EG b ", "EG ", "Sustain ", EG_SUSTAIN , "EG ", "Release ", EG_RELEASE , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=12 ", "EG c ", "EG ", "Amp Mod ", EG_AMP_MOD , "Release ", "= Decay ", REL_EQ_DECAY , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=13 ", "EG d ", "EG ", "Osc Amt ", EG_OSC_AMT , "EG ", "Osc Dst ", EG_OSC_DST , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=14 ", "EG e ", " ", " ", 0xFF , "EG ", "Velo Sens ", EG_VEL_SENS , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=15 ", "Amp a ", "Amp ", "Attack ", AMP_ATTACK , "Amp ", "Decay ", AMP_DECAY , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=16 ", "Amp c ", "Amp ", "Sustain ", AMP_SUSTAIN , "Amp ", "Release ", AMP_RELEASE , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=17 ", "Amp b ", "Amp ", "Gain ", AMP_GAIN , "Amp ", "Velo Sens ", AMP_VEL_SENS , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=18 ", "LFO a ", "LFO ", "Wave ", LFO_WAVE , "LFO ", "Fade Time ", LFO_FADE_TIME , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=19 ", "LFO b ", "LFO ", "Rate ", LFO_RATE , "LFO ", "Depth ", LFO_DEPTH , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=20 ", "LFO c ", "LFO ", "Osc Amt ", LFO_OSC_AMT , "LFO ", "Osc Dst ", LFO_OSC_DST , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=21 ", "LFO d ", "LFO ", "Filter Amt", LFO_FILTER_AMT , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=22 ", "Breath ", "Breath ", "Filter Amt", BTH_FILTER_AMT , "Breath ", "Amp Mod ", BTH_AMP_MOD , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=23 ", "Chorus a ", "Chorus ", "Mix ", CHORUS_MIX , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=24 ", "Chorus b ", "Chorus ", "Rate ", CHORUS_RATE , "Chorus ", "Depth ", CHORUS_DEPTH , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=25 ", "Delay a ", "Delay ", "Feedback ", DELAY_FEEDBACK , "Delay ", "Time ", DELAY_TIME , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=26 ", "Delay b ", "Delay ", "Mode ", DELAY_MODE , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=27 ", "Write a ", "Write ", "Program 8", WR_BY_PANEL_8 , "Write ", "Program 9", WR_BY_PANEL_9 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=28 ", "Write b ", "Write ", "Program 10", WR_BY_PANEL_10 , "Write ", "Program 11", WR_BY_PANEL_11 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=29 ", "Write c ", "Write ", "Program 12", WR_BY_PANEL_12 , "Write ", "Program 13", WR_BY_PANEL_13 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=30 ", "Write d ", "Write ", "Program 14", WR_BY_PANEL_14 , "Write ", "Program 15", WR_BY_PANEL_15 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=31 ", "Read a ", "Read ", "Program 0", PC_BY_PANEL_0 , "Read ", "Program 1", PC_BY_PANEL_1 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=32 ", "Read b ", "Read ", "Program 2", PC_BY_PANEL_2 , "Read ", "Program 3", PC_BY_PANEL_3 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=33 ", "Read c ", "Read ", "Program 4", PC_BY_PANEL_4 , "Read ", "Program 5", PC_BY_PANEL_5 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=34 ", "Read d ", "Read ", "Program 6", PC_BY_PANEL_6 , "Read ", "Program 7", PC_BY_PANEL_7 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=35 ", "Read e ", "Read ", "Program 8", PC_BY_PANEL_8 , "Read ", "Program 9", PC_BY_PANEL_9 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=36 ", "Read f ", "Read ", "Program 10", PC_BY_PANEL_10 , "Read ", "Program 11", PC_BY_PANEL_11 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=37 ", "Read g ", "Read ", "Program 12", PC_BY_PANEL_12 , "Read ", "Program 13", PC_BY_PANEL_13 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=38 ", "Read h ", "Read ", "Program 14", PC_BY_PANEL_14 , "Read ", "Program 15", PC_BY_PANEL_15 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=30 ", "Panel a ", "Modulation", " ", MODULATION , "Breath ", "Controller", BTH_CONTROLLER , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=40 ", "Panel b ", " ", " ", 0xFF , "Sustain ", "Pedal ", SUSTAIN_PEDAL , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=41 ", "Panel c ", "Panel ", "Scale ", PANEL_SCALE , "Panel ", "Transpose ", PANEL_TRANSPOSE, "Panel ", "Pitch ", PANEL_PITCH , }, }; diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index b270a84..518a9d7 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -13,7 +13,7 @@ #define NUMBER_OF_PAGES (sizeof(g_control_panel_page_table) / sizeof(g_control_panel_page_table[0])) -static volatile uint32_t s_current_page_index = 4; +static volatile uint32_t s_current_page_index = PAGE_INDEX_DEFAULT; static volatile int32_t s_adc_current_value[3]; static volatile uint8_t s_adc_control_value[3]; @@ -113,7 +113,7 @@ static INLINE void PRA32_U_ControlPanel_update_pitch() { int32_t new_note_number = s_panel_play_pitch_value; uint32_t index_scale = ((s_panel_play_scale_value * 4) + 127) / 254; - if (index_scale == 1) { + if (index_scale == 2) { const uint8_t ary_major[53] = { 48, 48, 48, 48, 48, 50, 50, 50, 50, 52, 52, 52, 53, 53, 53, 55, 55, 55, 55, 57, 57, 57, 57, 59, 59, 59, 60, @@ -121,7 +121,7 @@ static INLINE void PRA32_U_ControlPanel_update_pitch() { 67, 67, 67, 67, 69, 69, 69, 69, 71, 71, 71, 72, 72, 72 }; uint32_t index_pitch = (((s_panel_play_pitch_value + 3) * 2) + 1) / 5; new_note_number = ary_major[index_pitch]; - } else if (index_scale == 2) { + } else if (index_scale == 1) { const uint8_t ary_pentatonic[53] = { 48, 48, 48, 48, 48, 50, 50, 50, 50, 52, 52, 52, 52, 52, 55, 55, 55, 55, 55, 57, 57, 57, 57, 57, 60, 60, 60, @@ -420,8 +420,8 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta value_display_text[1] = 'x'; value_display_text[2] = 'e'; } else { - value_display_text[0] = '-'; - value_display_text[1] = '-'; + value_display_text[0] = ' '; + value_display_text[1] = ' '; value_display_text[2] = '-'; } @@ -445,7 +445,7 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta } else { value_display_text[2] = '0' + quotient - 1; } - } else if (index_scale == 1) { + } else if (index_scale == 2) { char ary_major[53][5] = { " C3", " C3", " C3", " C3", " C3", " D3", " D3", " D3", " D3", " E3", " E3", " E3", " F3", " F3", " F3", " G3", " G3", " G3", " G3", " A3", " A3", " A3", " A3", " B3", " B3", " B3", " C4", @@ -453,7 +453,7 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta " G4", " G4", " G4", " G4", " A4", " A4", " A4", " A4", " B4", " B4", " B4", " C5", " C5", " C5" }; uint32_t index = (((s_panel_play_pitch_value + 3) * 2) + 1) / 5; std::strcpy(value_display_text, ary_major[index]); - } else if (index_scale == 2) { + } else if (index_scale == 1) { char ary_pentatonic[53][5] = { " C3", " C3", " C3", " C3", " C3", " D3", " D3", " D3", " D3", " E3", " E3", " E3", " E3", " E3", " G3", " G3", " G3", " G3", " G3", " A3", " A3", " A3", " A3", " A3", " C4", " C4", " C4", @@ -468,7 +468,7 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta break; case PANEL_SCALE : { - char ary[3][5] = {"Ful","Maj","Pen"}; + char ary[3][5] = {"Ful","Pen","Maj"}; uint32_t index = ((controller_value * 4) + 127) / 254; std::strcpy(value_display_text, ary[index]); result = true; From 1518757c510f544ccec9c3e2b4d01508fd8ccda1 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sat, 20 Apr 2024 12:57:28 +0900 Subject: [PATCH 092/106] Implement panel functions (73) --- pra32-u-with-panel-prototype-1.jpg | Bin 0 -> 164994 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 pra32-u-with-panel-prototype-1.jpg diff --git a/pra32-u-with-panel-prototype-1.jpg b/pra32-u-with-panel-prototype-1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8d5d4db94ffe07ea9d9839ee3522bf7468a35fef GIT binary patch literal 164994 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�Jc20 z3z$v+P?v;I$j8-cbwANk(pK!9dJ&XRWRmn*-FXyC8|5oXw!3UUQMn{XvhbCYBP8C- zIPC6W+jH#@zA_u7U&l975?U-`56Jq9OW4wF#By+^mKSEH%8AjQGgKS_HYFfoeWSgS zGn*gyB4r7{H89LU!;{zq+~Ma(b6nJxdT%l*yCuhu-8h*zC)T;HGjh3&&kue5kE9}z zJ&!0*uPEEYXb{#b)K*JM#;JYW-v=o-j+s@|nheqj z)7?4X$7y?Su(L(>Scl9s&TH#yhg=uzdMhhee(Cb+@dWwW7csUt)hV0f7_JQiQ0JCo zQrZ-3vQqJsA0B6GBY8VX6VW=2WX-2apcw=y@!PD9)hVcQ%5uvjTE*JMddK2qW+hNy z?D$z#tN}h-$QLHAR9hdNEN!F`-A1)TAelZCiT~3xLM39{8ZeVcWht;UrC~~3l^H8N zMW?YgaO#F%9F#y+M-Up=hu2nP8+w7-?TmHJyv9sitO9d=LEg?@APQYLIe+Tf#33?^h!bv^Wm!4 z{?zT^N2^8}6K)4ei)Z|poAj%yGAcpIamhiLp++AcQiCXik@twSp0BKK5UDON3w5rH zev_26EqCSI)XR-)nO!(5Sy#D|9%XQd>b3MMvG7$bo-fnbQ>iP@yk+%DoB{w*1J8Op zsVDb7;l%?PS&sHiBn07Nnkp|FFa?G`Vo4~@Y!IMY{`Qo z#P-ugUQXM>XNxRDWIKRxf}C(e{cDyNhO?i!6P;s?V1(ZEz9cht4Eu3M)sDPU4mHoh zAWwOZ6-&X#{`l>;VG3L$tdFYpMearn)BfVN_(^i87^I(HckKpw`VYEZZHcCXWGe-f z`x|@C&Ry1YKdg_9vK~c>q$avQU4SRm4iXngale<6^LA;%M4jIXhZAQik(KAP z6ruk&N8rQ%AF|T7anY0c%tOU&uXz0NxX;cU$lDX&0TFyoz-~4vSZ5Qr7t6pc%c?pb zo3TS48?M>)OGASwUpJJ}ms98-umE^nEcYKt5ZBMdZUnK4folwy_mk)Vaa89(s5pN& zRaG{}1FIxZQZ?*#vWY|Xc2N@Sx`zuq!zuvq*`korS+>`t6Nwgv*W1`T zx+oEpEq;yNo4|mV4t-~{G?#rBP#0EMSK~DZ5zSRTa}6*Wd*?F$ZwAS8yS?|0jK$R# z!&AX$Po8BIjeOf>w1e(AEtrbZhQw9)`%9+WN7Mhj`Jngb%#6W z|03-<*Vb0jctX&%;k@j}bb!f4NSYz@NAj(aV8b_=%+vlUPU+P>bpyVhh<8*0*PT^L z0%tv~PYJcGexNANlXsrO)%n9}iCT@x8kwmtP`vBjV|n9J=D~qgci#6;$J}zdKl8|s zn}FDl9&BB-Usl|i&Kp)y-UzBgewcyCUtJe4So-0kDI z-_rm-X>4oTp9%gP9E&xdLD4*kzwibBAcH$YJq!QMMbB1NF%;W(IX~LSW@o?H${NYm zaTVA(a4(K|w3Q&sdk{;8R^ej$&JSMSy$3Oqc%V@p_8$eE-s2pMdlFwbuFQh6E+Oi#MP8JAsN6jN@%9n!A39=I(oReC#6=LbYXPd` zgaPL_jCK!qKTXSQ8!r8OKBnlfl^B$i7qf0|k+~VEwKrs5vIQifDs%>rfedC|{a>8DRa9GT z*tH84XbY4YE}^))TiQ~*xO;I4F2zDp+TswbK!E~naSiTLG!!ik!GjeiNC*(}{`tl~ z#vXege)}M&34^SaXWjFj^O`2-@MMSxm>!$F5$5Z10A@hN9ZP3&WFNefUj?5delQZ7 zbh1OcUl*Ss2AI6(tyI03DtZr6nrB4;{=c4$ERu=xEN#ONe!=P;9C$c1WT ztxOq-X?ecQ2Jpy}EAA5o?=SgSClk{2iD(*vDeaDnBH)B6XLE(O&V{SxiTW18-CmzI zgZ=)SurMDRk#CO8S@RKx&*M5Ot^=;v{*3TU{}g;@(&lme%O)6Yf}zY8SnkZEs=p=;StTA<6~@gYSgQ{%Ky7LOo6 zcV+_OEi!#Kx2Fu!4Lnh;)c0b-e%eRj6C~2o6SoAvr_&ec6V@4aHa_oCpXkb!%9USh zesaC_eBoUU%H#;xZ8^anY&@jmqALv%JKl9@o9J@T`BGj^ft*kj=u$$g+-_U5E+qPC3x|`?ebA#r(4nE2KH~K82DOPv-wrQ1R9G z&Fl9BDxVmBp_8W_tr~YABz{G&pg#$eeeNz9&e0n4wB~Q}R%)L4=0*ju7EOBBT1s2@ z>xX5InJX9nAm}%F1=I2Tkkz`sxVky8NI8DoranDx14_Aj83~}gKj+2Tn9!t5?t4X3 z;)9cqYh$uo7V_{+I$}2b9Fn@9qznP!r=>bs(2|)| zAbN#af@8v=NhBMSgJWj%cN(flLW?{=mj)Ng{*}TUz^-blc=;#B0Y0C}%t?UFCik9LdutO?Jt3qm)tWoVXF?8q0QCFf@ z$ez3pdEi7Z;@Fj{`7cRkfz;7k>uWLOq!J+dtl7 zm+k=b{(;bQm^5r?04i|-v)cb;v1|#eW8lFW9C+v|P^DKCqk#Fta7zp)6pO8WYE8uP z+bodv_1wa#H`WhQ)V?t0)qM>%k~t8bzn+7moTGxO*ng@rebl?|GwBGENtrv=0bS*v ztyUQP@q4ro=6s}LY~=ypgd}2}wmfZb5G;@YC`#p5t4+^hT#;FpT<|khL;cYv1s@xU zV%&@8>#N}cMsNwf{g^CbS!EA5i_!5{uzBOnCu;0>C^UTtV{r)9Icz;Uj${&Sdv~0y zx7l2Y&AJ)KYFbwbrGA5AuK(B+x}3EPx|wO3z3PT$_o>=TY@3xWBd#o}rRna4XW{Bkt zrN1^oq53mIEEI0Lp0SIxjymigY_CoBmZ*A74}MXJ;)dc1t%Xe0&DACHUC)sJ(NYolG4fmsSYy?s(zwq6Vx4iBHP-1|WG5%_4!Lq4pyAH_EuY!{q6upT)Z zPi4%U_H%t5RjIw8)zv%BU{yl&{QfV(9rU-{ug6@a@~8MQLDFbLq-gnw{gJu3BQ*kD zvx*37n%R3Jr8j+ZErYR%$uin67ii#Z>I(xJw4QN9QU^cSd9U}KNFhQEFEhE}_&?j1 zs8{7fiDRt~+Fyh7Lf4_NZ%vPYwW;CL1ni7?{p(Sh2mCSROH~5Umjdy4(jICv#rCo zo(H?D{&Dy=x()Ktv#6*gkbQIqEPC;2SQ{3NC#9zpcRfy2`9vMzf8x6?Vq3LBbrS^Y)p@ZJvx+wLjCA9~16cc;2(l%hS@}-+A^A zuyA8F-Tsomc5n_B$T^pE^Y@Q|@ z1JVdc^8bETvY zX|q4y`^@9_2%=n6B~C3V4OpiWqiA2v1`-MQkEqKCr4xBpI-F(d)ep@azc3#^$gv~5 zr4WnI!olxxqJ>REXG|12as!_TO8%o~CyO_V1g;f9pT{^PVw~qPmB0(LC>-LbHH?Sw zt$)e_>)F4wS!lARp#7s))lZNHEz5xy&Qcb(T~v7c>l{dpI9La5(4Y52ylCpEa^s2T za-*D90dpoP)ld+thvvFYMaN2rf@)c}xTcjv}GeG-iOoAWG95^%&3_h-7@UW@swvtw)9sPdg_P0LF zwl^>I1o*QZSS?^9l#I$D{K`%?bZTUU2Dx!0Nz9iQNKEl==P z-7#^!EBG3t3(Cbx-Mqu8VO4zuD}e{AB_M-FTXpu?4QBn%XGHS()0gKJKqMtj*AZpk-$f(Z|1z(Y1aR_ zyYHkh{Z{8TNc?s^7hDV(1Jd~qYnDT?My+9eDR;_tjP-RXTUF_P?-6*4pc^)@_l$@* z^zq>)`Mfu>wNzjB!UjQwPjduAds`rn(`g>HXa8!DF!eEMaPH1Z1b+)Lwh>(r`DkZ zhw7S2Ye34{l0RH#fZ`Vmip)5dPZ#-KQAo{NNhT9x#zgzrb0CVxJL^B9Z^zyL5hafj znl0yInHLCC_3sV5b7~$FHV%m1kyKUMWCm(%<6Hs~g602IR!IeNvH}akh)Zy?*ipL) zYHU~mJdXt?L0{s;jt5kl%yvEkyG|eE(#ca4{qnbK{kD{6&Bv${%gDv+A@7LS!NEqj zqQFMlWnX=_0E#ZTLhA`C$LmKKm{9dBzL-weOr2e`6@IjKG3r5kdCX3h^qBX8{9Mr@ z1OcFdXQ@+uKCmgh=T_d*MIL~uYV0M1O-F&f!;V}Z-RYbxoe#@KI(K5PkcwO<7b+VT zG{g66>!vS2LC$@KWxVJfztIjWRORJ&nuD&By^Vfm$?67^6snx=+}C+&VuKsgCc6XS z_RjfOPbQXO%K7zhqeuS{`Te+re}_8eEwp;wfnzeF^AokF0m=9DgI6p*+=BsmuSI83 zv+DNgZ(Rxpe2Kahza3`bz0jHoY`GiL!jqm6z^Ks+=X0G%920-`ojugAv=G?ozT0L>Hb*&h=F&nsPgKn?1FhZR)$^A1Z=xl7lNN>SXfB#$HZ8+pBv zu2!`Sx88A|+XGCgV1Ue`u?u^Hq7t{448zB;vi>vVxO??5KAHZ`S}ktj{CfIp`~=5D zZCgSCvQ~-Zek9QlBjrGxPc++qMBY$d36m(@$wHBV2?RO6*fPXmHX1lxe3O4=a(X;z zu=YEIaA+@5&dc*)Yk-*JJ=s`p_?8&v)vs7?qW|TK7_*8#qq*6~?Zao~xts&|{p2je ze%u+f_omXx55ZKa%*B;-ty(JtSD{cx(w^XfFL3tsfe*yf&Yhs^seg0-4~I4`h`^x* z7IeKC%LL)$XAf&tmel68UqJmS_l??>izOlsge}bx_a<4dJlU^a$qc;ur_&{2W7cxU zm2l|b(Bec+C2Kz&TjR=9UomOihl6vj zD+3$dW_wJ`PZEKRak50=&%bfNG@TM<>YM{vVY~%>G}J>#5wE1KCj3ZA)=i z!GEZv6AS4v)sssc_nr31`9=Af`X(C}j-1|Np6?r^e|=)>*0aq5IE4o)*vOd*lFks| za~!YOJ>e=(;YHZafaYEGV%}BDcjm^;4Q6)^o!Ex|y`sgp`>6a-Eq9Z2?(^PldS;~~ zFe&$|K&$!%{_Nbky z@@S&1pX|;L5h9<7jyen3nTCX_Dl%w!5*^9$*XJ;0r=yIJ0S{wWy2kjHp;9K&x!JUj zm5hD!=E#A?bWWlxXELsm>!}|Tp7oauCYSLCgGw8D!zE06gg%~u^h3s247!+O!)oNm z2f7`_3uA`3xOB%9Gt`;7+Ol_FqK(@t6ZOqmArE9&^&@2afa{|?lkIpaA&ZTU4OZZhuq`yw$g4rQwwGk47#Djrm8pHw&7`%P*$%i{NK)Q zB##aFrv&JGY`lEUBELxD6P_D13P}XN2^WAc?F;Z0-qwd0^)iq||3_4a|MxwN0!$c> z?tQ{?{lM;TB=#l7GILvus`lCtdmhkt`=7OV2JjeV=FBk^z}UMNe~&Aac?Zj*O=n^f zd$oAvt_w2Cop;TI==6uMcAbyQ0!w+`NG`W1FSnf=16A-`K{q-XeazfVoii2r_1{?C zEw8GZhdPfj-m2PHa58M^|3up2DkKCrb)L9l@PKKq*G%=sRp!#(Kd1igxZ?JQ2<{;O z5}0Mc@-b>@rMc74PlhSxt{C|OU!Hr z8XwsuQ_rmKFfzYFm|ug(g?gNZ#L+cf>|Zm=W&rW)js|2xAaz2w3nyei@hEiswXraK#(M5&Ra< ztJN(9C#OqJzsnOiSMSAj4>gg-FN&4x@~2vu(L>~MN^uDjNy zQTU1spFpSx=bF!^-Dj;a_T0I54zJiep$Uh&+raWD!3tCzTZuh{r{qSHtlV~FU1k2B zuR2ePvK$~${D96NsRVRtvte9Qgv9xyg)ml0Q(!5SX4_|1x2jR53i1)Qcrh@-ZO!4- zZxqbzmqL*C^&>f~)K|B2#!dJTs$|j{ytu}{2(0Y}D3N|8*v}GLpaxzr8y7tA)j|2a zLl;$s6$at0B&o9A$JX+_Eo??8w9%iafnThU=dSE}O1QGNTcO*BPRdSK+Xm&Ue|rtI zbwye8P0I_x8_T_D(kJf{eNcSwz3fYy_aBi}n5WG;a8}sHGU088L)Ti~Pdj|lMEBhF zuikS_6Gv$4P7#&?r7)1Q!S~^;;4H(J@w@Q2S8+pF@C`REq-zSyfqLLyKG4+Jmi1gb z8sZ$yN7Qn@oHx*=XkpSetth#?i0s_068!Sn&;GHu&IPJ-6 z~?Fq{&RTnY?LBPyB}+(;pUa!wY`fUWZkMkA_NgEO*AHV@`Fv z{Mnsd^WC2j%W1zj4Vhc3Sbc)ilen=$z(G&`_=st-XkHmYPEvwMX|GzC({66zU^T4f z3E$drL_2`M-QRD8G~}B>LDoTbM-MpCgIJ!XXI5*fX+BTiflJ(Q0Lgc~XUt8uK6v7LYxdczDF`n07Fk|RlXg_k4WgvYS4e+*)621TA! zAkPE6i#p_oT?NW2GDMmlXOksnl<50povg+~>A^;51g06^|JPr^Ubkj)Rzd9TB>&H6 zOBSxB&#v5VNJoB0a*Tg~|MZ70_zf7CDsjy9b^*-B{xp-+IY}cL0t|nz)fl~u>FbtF zT4*2)&U>Y^<*FK6#ZZN0av53hwu1JU4f(Q{~9%L%)l8Uj2c)?8nj7E4oALA9=NxG1PN@K~e;K zr-J{E^evx7-?JdEZXoGgch?gXnk&-y6n$hHaDsL{TIc=s*4eHgK0c7>snt-StZ)NW zscD53*h_pQz<~?pn%~d3HBRiV!`q zBJEzqa?1xYi^354)6}#xjUvI)YXs4W_nHi|i3P2B!2qN{7dVVQ{WDYVo9hn=Ym%+O zEa|`ds{5u8w6>{<8RU-=im9;uXkZToO~U%@&q!1M#a*+vm7GR9e*%$W-=B^bn_n@i z-kTUlKglHz-c^&~f#SE-_9&TrO2^hciMzH%$Gw1M)qmC(g zy!)yzZVRVAc>Xcta|2`azL(YcB`(yo-FOA1@AYml7kYTHSh!>vMx@nNx?5;^%OVSlI_}T< zD!V})2llq4LXMu+mix<}qq^#v6&v{5qJ#~r#V}u6p2g??0<~V{McC)xR%WBn&tv1S zs-|Yj53c}fU;ui%a6K^r_$VNty{XPZ%X8Mn$+lgrqSwW7M;^98bt6$3bUpst<}OYF zv_Xl@8uwx9Y&2JYl%8DWKwK-w!zB9wJ_x|F!Fv)P;wPa^xlzBctD21+C%2K=p-`4A zvzJYgK^vnjf)5^bU+L<|5q2f0x&B0=Acp>AOY3D2GU2kfL+(J=qOd@UKHxmPlE0?z zh&|28_Ph6+xvdorr%8BLHzH_Ye5dq!H7Xc58I;&HG7|0&hP2>3iO0E8V&b1BR&<_Gi1ZA;5@hK z?KWZP>s8%pp~|C?sb%@9*+!4epH53gZ{qLMtv&wKF(wo~K`w=RH(rIMrQEW~)g=8~ zZe&+{ZwF+JT%5k8j^yoRf;)0CcsK=ZjUP;%WZ0ZME?oyD-sNvqtPH$=F#uMz?RVOP=UYZJ4dIA?5VQP7UkoCJaNV(My=#nde7%2S|OBlwKY?indj0>ax3 zS?Mxa{73z{dBZy`6XQBxFXP1}oB=lGMtQkj@!>=RPrk~@QI6!d3QEE90G^$u`_UWK zR2dsW(W1jBJ~a;B;5 z9y_bEiu};E19Tupv_YFW^w--%%Ao<-6!DFx&^(Eo#5+DJoOD|9>_RRs5Uv46wy0cZ zd5_y&tA$F5t2|>cIoh@Zn_pB__!1QKXGMoYl@THiW~+@|C9IEPetf)2hPp3()m{Y8 z;v?JV2;xfBMILQ9>)?ty!~B0lj|pvys#zCZAFToHQJCl%YLsZL`iHqUq93l3>(UL9 z_b4@Rf&CTCyiHGfCH=P!wzNfj>*`W`CvT)YqxP7e&;5)V+H-^zgcUe!4F`lOT6uI- zLE`Y^kcZ7v?Q(#lBSGr*=e`4y5u`-V^WI%x;HuL&a(9$dL-XloQq>l>$=E)^y1`(r zw=r!^g+KjFWh7=N1{nN+FXs!h$|R-6kq}tbMlgYqSB82$#;!)a!OSn|;Stch7|vZgIg?J)l+<*z<+zj+tQ)3&(XYcQiCG@; zHNK#-O>voZyd7g?LVO-Xz}?X%=l7atcXG#eof3g<>8o;qRS=906#j-MRU_BlT7_N+ zcwf)Vi0!>hw_;~nL&*YUN2e)kTP~0L;TAi!~7}-bpy%sc-QJ?`XUxymInQHpfQi>enw!9?O zUO)JqdYWjbA}TW3gqju)_VmAisS7yQC5|T3zn4n>cpxek9*$sx&t`rtm-@xy(s?iI zvMA#81!sCgPeGbbW?#(V{yGcmvP!D)05_)PO_)$!M$^S;saHi5cfGrj1NNt zOfIJVx4s=>#EyhW`kdl=W;C$xvL;xh-hHI}a+CDg)5G}fA`8X~_N{!;W3T|nkP;;l zyl*o{K_+}vN!KrJZ0NFp$s*dCWfQ! z>Cz&C(N60Ri{VQAZS*dTCT!P{>>(cMoO|3h9qjH9D9Pg3fw{YMI`Ch{?p`c4xM`egwwN_BwM((De4gDqWe%lbSs++X7b%W(fXp&)qAih z@KL8r8Z~P{x-Ka#qcbo<+1Z1+m`rWr;51y$UJg7a5}$}~D%5;i@~y_jz>0n9E@PLo zj54X*15XRO%fsEtdhu~`M8)#5dWp`<_!2($w>jmvE4_ixfeIBiGR8>GNM+(T(pPsj zI64ic1Gck{1b12^t$xkEHDmSof?#DlV!ZkM8zb%u8*B+)b5u?|NZ=o)r3g=3A*BOO z`)N&qA9|E&H(vY4Ig2N&f2ibI_HGd@xMYKuG9_sK+^;Sy5}&zo@X_3YkJgjJelY74 z@mxxI1Z;JbI=Ree#Jti?$PE((h4|Fbh>Z2FJLVd~wg+DO5C^!j(kA@2S|DOfJ~Ws0 zjB*c;%4$3rj7jD^h&)hMytMY9)NfAMR5sRSW6NpT$6n9+XSM%QVoa{}K>kN0yvzWD z>|Br*1{CQCjJDLvY00T)f%59r&&syh&fMjthQc21@kt&lH{DP#N+T`I)Qz7xdxoAZ z0!OC(us!>hux(T0F^UD<(-wE;kKA{EUT&A{(nm~F*Xj5UZ`FeTRHs{qDJbx1`-Dog zyhExM*$i(kX%e`40FAfif>?`GcuM)krrk80PeGA3TvGntg^^atXb0x_7IFH56g9>;f?V9 z%+%R1urhy}HOn-C*dbkP4)8kLwfLYYX)&AZ#NTOlbt&bEWh=B>+QWoQ4kqKT>^&x` zeA@ngUb>m3;>SoPTxWDHN`4*A6jhO=0?6j(6VR0Jx^g#+T0!Og%zn3*{}JVWUYdzH zVx94i-aZAlG*+2)nqVl7k>!il!Fu3H5$}R0tNu4(AVFPD>M`P5)KTIpEmg>f`3iaM zzz6V36wvx2)!x>*^6k&$e28}&R{G++lqH3m&Bw#L`KGE(8mMGY#>)Yuamh77u26Y2 zNgk;i_w2Z$O1trez-7Qtqr6gK$3UE{Wm{O@A7^6~a&MSk?GLdGQw48em$= zo0$KI8UZyy2539z;p%O3zzaQ_A?Jf|FmohGcRxLWvLa2Ed{eMKuKC7sxEjF|l zRaZjPdB#7x@fTUjr*$L7DjfEPKJ`0tdVCX2c0z8aU>yNMp_CNWNBa zzvMILPo$QiMwJS1ew={Y+#Fw^LKek=3RNDRovOC^HyUvU$%%7Q`-EQ)t{#m++*4DC zOSc5>YNb>x@%Z{RDLh0#Umu#rNfuV^rq^+w9?`|!vkia11^+vHKswUd`=<7OlrQ=- z+h<%$IqZi6B`Kmz%f~MalPJhkWv((`ftX_cMnynpLESXwXe#L%zC05XTG3t#95tOe zENC<>Y*u`i^8QK#vK>~I3wO)Pw^%G#s()>Uv4v>|mu(Tn*nYhde%;bY{WasIx9t0C z`@69T<^pnhs&%KAS{XqtNQLnxjop_`Q~nf>QJRsJbBPP`Z5zia7WeojBSDdsAb>ya&~L__2d zww@dAs;O!#pnH7in`%+n_qt&5w2o*{6{6+Vk-ZPm>Vy6}Q&ZwkMt>9*Rw(DxY9f@f zK3X)t>d#5n8YfcjH9v%}Vbi6>|#HxDDjbEltvu@^?A6pE{heCpDt_0u(ZU zv!$7~ZMkyBpCrKb&GeXUt9W(wQ?-oUYaM`ADY1r21G@S|O@IZ=!RU1EuNB zS(p2=W+^X4Z$XD3-q8~^-AlD_tu^oUtlrF^px>+}-2L*CulX46r>IkNDBm%8|7hbU zp?Ph1@5ybh>7mJpUh>O$5?yIczM}!wewi}~EyINiYG z;SY>9;qX%ZHvG)0E|qM}o0wmBCtmm*Ue~qO#H`SCGS_=crc>9l7%VRKhK>6%w!lGu zW#mKi^&?!%$@muuU^FvFX;j##l>{-_Nx(zQZp%h+gtHER1A9{w{5n@=Nib*5g>bwZ2h+L!7hI4641T)$gkDMR4lXq^7PRlEone8%D5lYVXx%2g&aXwzqi1@=2pE@UT3Jw2{ z$PGxl2)=(ZJx71pb4$~oVyT^h=@guHp4yRgDQP^5Fm%tf81+~d&WC|AKleZ+(e>9E z{UAUz*?4vFr-HUTZP0KEHEq>afa#{(GgoqF!nPb+W6dlT;q%R6sMfO0=9G&v z*R~uf5`qERH$Vw6z|XdADUxU$KH%H!X|#i)=_Lc-&N%We2G@!$MQfnOUt=T6+#nBU z#U&bB!kJQ*J*8^vJqsv1oA;MYb}%s&K^y&fr1Bo8_KdbO_a?_1Ne}LnkO% z{7h5)?E!z%+k8^#GsD=kTLT1ybF!1h3Tyy7B@=q$)};II?-lhC^4-L1+Tcd`lBidT z@M>SNms{_xMdd^33oTU$+_00d|7a+Y2w3Q76)axVr>t8!a3oNxE~!p|hcqVxz1^!% zjJ50*EL26+6*?`sUB)f1Z4-B`iX$7KR9Ln(pK%e$`JiHqi8`?qB3RJ=i8>q>$XR- zfjwDa5m|%&B{R*&@vR$E+rXigWd@zd1$yqet>icdZqn56VSGQ^^KPUE4Xak`s^i$W ze0mbMwIG@D3`3$1dvr|uyRr$Yts<4^xsni6Hh%gS~&f{AU!* zaFUAgV19IhZKav5lsJDcm-(WR(INg0;V=vBLUc&=({tgTuK=mt2qw{v8gzOMX#GY( zV#l|}d?EPDlT0LyKMVKWh&x?r-sjBrxog!)dAtGk0n1z;y6#?k^+j)pt}yPzU$J=_ zw+`*io-bihGLj=~Hfi6e?lC?q{(Nn+3p}XYDCy({KRv-$z7XzZGylc`lU!mAib*8x z^!~ASHVP)a0pgy|bh*G|&7oh!Why-`1k^eFQ`VX?o+&e^9lZI3*i!oVBSnqsID{s# z9!elZdFHJVz_59U6&f@JrZ^a`T#6MO8`g*6C$bMp$+C--=+r%m!Q3oYKT>n~uDjwz z(_r}z^dUH#wec-$T0{ktnFf?Rt<$+RDA$zm@zy~=qimx@rCRj;+J*68fz<_lPUFRq zOa?!MfsKbbWO;=N`})VOtV&HK7ACWRoRz^1IDGr0)|y>TLOznU=Bq$%6HF#|(h~+*Vq%Q-#ci-a^kP4g-7z z3((Mb_Q^wIm(Xve-5y4;mb^SUj>l2JT_6CoNi2WE&8Xs<>mg72a;}lS$}HD0`G@Ux z9RqB41=#&WGB2QfADLUJ@a;?hHSI<3YNxv1Ln1Sz**d=f!PQ?Acj#@ zYqWnJS-ZGIG-up<8_IF1q1vW5K20U0M|mOVfQ83|2c&*z9nC;u{0b-9xDrL-ysnZ~ zFz-?k^F*z9TF6eFm9Hsh5Pn8(5AzoG|BuMn&A>O-4eeti+_QU-0UNHyr;7avTLcye{|h|`5W+SgUIGS{ zTf43zpPR2((Y=%^E0=jiWVH^_U3&Hk)fvaJ*6tuuU1{c9vfr|~&8QU_RCKR&_j?gq z?hO<1=WSM#Zu{HG>ziK-4ah8#7lz;B4uZYbpobe z8eCRvDO)2h9eiwP@cnt@7snrS<)`HxQEgVho>qaKPgO_!61PrL%~JyGEvNYnDYhh+ zRwLc77Mp1-KT-rD#}Az)bJp92vlA2Y?g-M)K3pBFp18;q6j~he;+5|0D=Ex-WLizj zj)C_#XS4JfA#|Q9t;E%xPuX9_M@i?CvvW^R5Za;PU2D1j5dpxjPn^4%sT$e|LHB}x zit520y>^73DiO;NR3|(e|A=N?LH^1Qr&*J*bVpx>7#8Af-1Rtbz=n!|Fv-!uKV=B* zZ@z)#xt6RTsul;&%(Bz0Z6E(GyZ3%bF%k}TMZ@EP&ICoD(Bl|Nc1Y8QG?Wrvq;R_8 z$lAZGVQoXal&gNM5g!02Pzp>$sAMc5lO7<#wVyIp^16YmPW`$gan>t7??e~)LJJ+J zG>IeK_{Z6hq2s!9BmQJG=4~@^6A#-KTPzxoV4gO5*?0Q}g?}xuHDPuHaIrdC6JvZ# zq8$YPvWCsuNPGkivWbKMJVb0eXAaN5HSCW|-Doc!3P#&}czs2->F`VeZQZhQoTzys zHL${RV%)L;CtC^1=w4yznv|fPUAZ_Cw2PS=%H)jYQeAo%YgBE>dNC>smW%V`eY)M+ z+Sq!pE?#uoH?74gue2B1ZQZU~>INjQPi(YWu~uS=KS5SpGCR$zeEFj9OT;T@(rf*q z`AmFkwfWPJDh1FAaP3Fl6A!41T05UaRn2-_X?^L|Qr5e}QV}xft{0mJqXPEv=Zc`Jtp_YLo zKN};+a95pRUI1EhW$zjk%3Z-?`bp)%v-cPBo8K8BRPY!&h`mYVjB%IW!{RIWXs#6T zM(vQi4zCdQ?6VD@^5Ti}zou~dF)zy3VRqG{t~IZMiCtOQ9jGnO##9SIuCfX#ds{~w zSu2z8V!&UC?PdPFRPRm9wi(;cQk>0J}Z#BC{L?Z+iOEjP$D%_xLiRxXC=iSd;0m&En|ok3uzd7RNiBjGby%>a^FfU9N@o zjV3AmT*IH)Ct4}RL+|3XSb&~nWEvAOuc;3#tX#HQ9%c;m$e0RNE@VH!Hs+{ zOu}UADcRZRE<%_)-npU;7q;Ree+Z>D6|@jFHCz8)$UmD*I`2wYoIj zBJA^OY<{p;0En#e4E}Y@?88qA*6YU~ePw60Y8j5KC$p46(MT@=qqtVmfsyY|<9(&~ zvl@1m)B_r&H#J?W8QX9b#5cVPVz8C8)cbRoQq#1b;Tx;~MWuQbi;wF6UX54Xcd^j| zEM(jObz@k=?{uD+OG@{0?@{`S4fv?Ly^Z4hh-}J`jvP}jTndk~t)^r=-~ApkW051E z@~f;?jLkN0%gFZAtN(~Ne}S42F$agXH-<@n0N)BDO~~TOPe>^3EiRFpH!NI>mS&0w9%lWP03nmr1*N9Xp@BXh~JHRJpG z%AeHsX{!R(O#%dr6*M(XJq2DayFaQNdXm5bT)F3$Xx&iEBPp{V?%@S$`;&Y~IOOe^ zjdxRC{qxK6C{qo4cEnp#f;8ql{L-cnZqXPeZ`8_x4x^i$3v*{m=KusN`~Nlx_c$>JlN#Jk1fo5 zf*Wb{T@_866G-$;Bkwxb;M20b-p@%U=>*XnimJRzc+mTj$s1VgR;gl^CRl$N(P{RJ zech6(d-q+-B(Q-a#)x|6^3D#{)V`5Ve-E{N{MK|k`!IPCaVkX|RipzQs2eMo`VqnA z6cA5(&%5)gjEt`7A!lOH$clT<-7{{>XL5j$nt)=2KzDP5^8+k_a6?(?!rM_RF0eJq z9`rI1&9$M9F+ImhmTNL-o|O#vwIy&$MRj;ipi;A83*~2r*1BZ}D>7#5+WFAEpyCx+m=6}f4nYWT_ zsde3E%L`ON#R!g~>D0upNpJG>bmdRos`>fk)Z)FXI_!ayKbJQ>qYe$U*zF@}S+2M1 zQY~Jnm%o|_c1g+ zgiO9sq-GnNf0wum5yV?1Gz4$-y^*-i+#KoV!Bk6u$Xk(AZ5}mDRCj2}teh~)^f^8E zraUV@b`z{1C8s0Vd>J}b$sxL1)6<{sunGCJbmeHxva9~>`{O`b_uIyN9s$9j<=0~V_VjT6 z$pUhI{7!>VCFiWIVNF_-`1|;xr96Vxsoa6aS%v>n_>L18>=l$ui6xCJi;u zt++pD4$k`O<6KiO=5g7f5hm(#I9F}3Wz%QiI=97kq4wDLvZ|H=EoqPoOeKGyKR zv3O3=pS5hU@!`)4VfnBFf9YLQ*`~+}u!QSvo;^k7cd7jpZ{NNPT{)jIKZ{A~wm5v| zVsgtW8~cUL?~ssL%Np@?Y$Qsi*vXD6!)qKT%_Ot?rs3mwTXkJSiX?2-^_dc*z$SE9 z+4=+X?||*5ipunBV&1A9n57Es?F`$82S+M$PB{gy8fUYe!fn&$1S7)9`~0xeSp?3} z73ZlS9h)Etk#Su79fhkG-{>G5G*W>hwOZ`y=m?*!A67>q*Z{nd9pATO=;RUJj4G{} zsCrwLf0b!3=P2zq=TQbMXmpB7;DzHS0$|$NG9P?K*xlo$KRPw^2E4l1MvfUqMJJ*5zyFDolFS zdIfGKWL{~-r+@+I1Li&J@xlW)T z83vwW0}WfIFFZuoDP98#FYlr_jwTq!l`Y3??B8ycS#r^h} zAaLDQzc$ z@Uvj5n+!_%0hv36{Bpmp>SHGsL)$LH#>cV0=)5q?|4_y+x%q|*4;`s?H%+jICy3sV z#NHw_Ney9Q40B!|bf=h3H+d2q`0+||FV+Gi8u@NVZm6ZA>x+43@kuDg0zDR2Xn|GK z0`_Yh@L%v$&F&vQ1SF*@dA*3E%@PrlZ7*AXuxs%b?9qTNMOi@4Z#9hwqz{JDpTd?1 z=O>Y@HHT+G{DI_82Op-+c6wniZ`7=V_EA)QS@czD#eI0K#w9xTxAsv^2!jJzVrwV4 z7>=mMM+Gv-I`Fu2tN90N8n%eHXyFWwb7PCD>)g`(pws~%3DmY!{JGbUJe-)F-==l~J ztt^$gf|y7LmfxJMAr5xeZ0=w`2KgD1xo1c|BgAl213{kl$cwse; z<)up8vb4Xl{N0!qpTCzL9_^dpIuACe~46HLj7^w^XV`Qwha=-F>r_nA?X zxb`%N?M89ikjyM@gDO}3!JM*@ys(#uXZ0F?2v$~UEw5h6buX$VGjSXLJZ@MZ&u(mL zuPaF#c=*Mzc>Fz18G!{i#n3KNp6?%7d!+<$c|cBt?Ec<2BR|zzc=abe7QN*1bbbdhHg>qp z)JSY;S5WO1td8d;~DPn)gPsGeHHV+zvp1YVN6u^;!0-x0xEh{oU z9-WyfeAx7sL1?G#0~&M=I|^{xx8J~kld7rp4tT^7j+@{?>9o8`=Kk}F|ICf{dmJS_Jm*Zk;ijQ++^V%wr*>nE6M?F(9zJX0F6o!v^>p@%y^-3gA#5MI zCGhkb1fYRn`>Pd}33*AO1}kGxFNp{IJMF?|-Hha9xa|j9nG21$wrG;hn90@tETK;o z0a_LaW|}z^`zQ*6gmg2N zl9uivq97t59V0|a7z61Z3epXd5+W^(NsjLB9u1?r8H2%o&;HNr^_)Cs|AX(@4z_)_ z`@TQd_qyJfUZVH?7U*4wzZxo#2|9!@ajIZjip@g>%u83*v{r+1p1>~W>V`x#B4~p? z$GJK&k!nu&GXRA!Y5TIrF+c#mHA5>}URyHRzS!Go#TXoA8{*`|D3AK4A1HQ}*aLN> z7Ny|7lpmxFzrn)v&pOl1&W%B1x5vaLNgaNC4rf*4{5T#pEElG71yz&XT&%Vhc)&7P zDt-9b61A_P5k=Nl7HZA+<6TM4v5=~%p$PVQV2Ad}DB1>-T&m1V@Ydae@%w%)_$bfFW5v&3dv9W5FutHV7WzWc8C)LzVoRm+_IvsCPY}6>bG|l*-#Asi*t&d@A|~x z?dP>E%-*u2D7#x4Exa2M`Or~9!^6@~*T#_>RKUy3^9wPYC>bXJb)|}b@;gye^&l9l z1_o3chRCZI?E`FonVuX7O_+&0(0dOga&mB7Lt?U;e>U_7Ej_I*@O-br#Co z5*M7Feq|@%#k!GW4sM+)Z&E$+QmW9R`of%@fqb?WWIx3>FqqRI>g#^XKX_}i7SUwv ze{Sk{ZbZ(CxX|T05RlTd*Yj>IR>|4s z0fLO~6}z*m6jf%n*hK5Az}3tZe3`nk3etTg6en3zlOm1mpQtfH_9w;4r(5CvBgkbu zPOy-Hw*5zdh{W{)8BU?WJi(J)f@@1HW{Zxc9)x^!RIG6sVu@d6slk4$VR%D49ds(E z`Y5<$#U5tGm9852EYJr+S^;$Ia<$0Hlh5gB&1llh)fFj;?A*TKAk{-2Ik*Xdcfo>} z`)&u7b(7j*(;&#L8EkuUvSb80mjiIb=T0LnsKpobJ!7$5$O(1dGt2weZRB+uC%^3q ze8LWvQ0jpI-1sv2xRW^MvNQms{jQ~lPX7Ck0 zYTI>{YN*TNx7LVij7g8A3v5uP@V->&_K7=ah412FC^)e%vbD_t9u&VUCAyLpm8cTc zokdBsne^ZBSjlEne3jm6bsJD9LVGgPI`GBo{d70!erpV#+3sEaI#se(TB7^a|Ekez zYiqi?0rUo%{&qDmf?X=CvxOB2rC0Vq4Qr{^jC(wClIN*2Qe|N>f4I2tC&v7R3IGJ9ZAx*-gUEDL^aJ zRWBFtH-94oqg%fWot;;VXab#HbyRvM8J-kHN|Z)e{hK2Hi6DQN|8ePWr@dSss;TrV#-QUShmOr zNd&T(iI2&33?9Uw59*^~){9M)>2 zC1iAUTU#QLeSQ(!+WhG>fBGJ~GHf16OC+BVqrb&2XdwkIQEsIcvV;(R8LQx4nbBP% zAdq>veyz`$=EGDuY_s-VqEVuHVd|%aBm}1iA@O{3Ec4n2!4IDc3`pr?l3GzE>n=jd zkwro1YVK{%Uk10DrRW7r!D?&de0CB~$e~ky267mTKgYbOnsgG55&$zfSKXc6XH7kF zmCd+bzM@jQ`o4hQk_%6x6IBB_#XyU5i=Z5#cXrYF2|2Ix?<+EIIdRJUEZds1<{N3Bazqdag0pxpKAxb46I3X$$A+jk9qm|CG5E^$X35j ziwy}m><%QG+c9|gEei^BTs}stVBm^T{&LQ2^Vdnzi)`QIz2@;HHzLR8TaJpA7r(ZC zI8AP_LQFCC z-t)_rX&(+0nhL7F<0p}<;R7w1&)bjxLu7GgNF>d@9*dKsK9A$*a28im9XH zxGEY4Z8*G?5`8cF)*}Z~G*p;Y(-Y;QeC|g# zjgu^v_F^CBW;EM~mK22NC+@AW82^a@+D6(F;$s%y_7t;h_e`AU%l+qg(lr0x%Y5%& zKYQVLNr-4RfvC_|AbhO+{Murul2V1zSHF4p_)%!6d14O?I`or`XA{pq&hP!$W#wQv9;QxKjXBdpydT<3w2`Zt`ly=F66@%kvb=&42pQ?7emE z$9g(z_K>;qGJ1wMZt0=!fud(d>#>>VBi@Cx4pIiprIPt2bj@qDvF|XBSADk)`Uf@x zy@FLrUgFdmJgLu&KXx_NJ@6o&%m!=v^_h5_t;b~0Ka{cqWAEN6hG@<&LfJwxK1NRv zRA^)-e{^ZP>f5Tn^TlWpE-Sa#BJc`QM=6@ovX?tSa_37pM-UCC26=1RCh0SILS&{p zPG6xg{b_<#j3s~nz-D-_JU*AmZnU6Vi3la{Luenm#tbVE}m?qqsgBMpbYI{ zYox;hneSSrwG9Ent{HnzRD{yhIJ0isvpTa^VzlV@$wgU8=$v4i4^>uKB}Fpt#1_4Z z4F{4f5ocGo3$c3a(B=U9q&a2h3M>0(F_kgdueXu&8Id&|OKLE8@oAg0L+en+wP@&` z@i*Jm6S3XhnbO@-+X`_v4fej#fndJAo*LL~`f4I-v)1zmUzKQFI>7;${Yb17lo}~% za4!8Z6R7a$jt~B6w#L3_p}Sa}t_cdV8op+UP}`e5a0rEi!H&^uDC9T)`^U!eIs!gxrRpY+rnsqvs<6GfOzEqnm?#1$UslJUWvn*{j0Y_&r0*-mV z?Vj}dSE{1OjzY*o*O+v>2`-g%11&C>Iy?>l&$Qm32`!;(DP@Co49tzn$$g(ABxKjnk-*3ysP{(&@ zaOHZPan6oqic&~HC4NCrxrNL9E@W5}&%s=oUc^LA`9+qh?gYfcCYHwj0hWOL-2F(g zCsn6qODixND|-rC+(ck*_nXujatLM z3v^Ct6k#Fd9W#?EQ}S{i9^%8!ek2cHDf$DHOk?wW*ego@c0^A=R$p{V%1()!dWv20 z4@N-BfBJyGj{jTKVxv&I{#4yMl>_*K4k@04M|{HqqGN%ES-(?dIsN8kN>I5R!ABXLzX zl7S8Dt=*IZs%tI$fh?4}!oy7c&!~qtZx>hwZ3#V3k&5rtLDB^t*h23G*WRbsM(1M} zjHQpkEK79}wlDgal{2Gb*C&~ZkB@}1SNe@Oes)Kz0pxvid~q30+Z*`}+lQWeS_y&9_a>h;bel;F(}o|>&s%hlghn@w8#-# zsvh81C4&(k%Zpr75(#W0jCsjmS>}%xkJv!uP+#3%8cqO5m+G{@CB?uXw#O3w?s+_Y zkFRxha+%;plFk>KjKk`EX|KBQQ{HVR8T5wx)}P60IO09PC6xPmilV2O)Fdpz{0LCh z3&;|GLs*AW_h`E@C`_RKqJ{3~4!g>;dJwR%Fb2>z5El1Shw#Y=ZXlXM8iKyg;mf^d zJ{azEVd|P{okdQa$s$!#lcwT2Stsw$R9Ra6wRk<=DQEujsht1sz)CGG-&h4oEP;>g z55FHH#xGG(6w@(l&(YZ&lQ>XBuGjTEO(Q7<2?v7btUOLTq+B>Jk#Xx7LrQ_%)r#13K=gB(lz-Bt~WCY0KSr`9muWf znS|!l-=Y&NpLudZc!u7wB3hjt@`@cSz+Ij=55yeQ>deYvJvPAi+@P#RJWL~2#I>S) z^89{+mA#q@$OPd zh|V$?B(e*)c11c=omrX$A7@wiI`h=peE9 z!ZGN{!xzwNF1=NbAH<%>E9LJb87*Lf^$-;qBW5zNL{wAmgUlvNx0te5oMd)%G4ke+ z_JkIUf?t3`0I*}*xLI9J&Ic|mBpu1fA*%N5f>cK04!Tb2-s*j!?incDkzWM50wF4a zXbjKkXlEdx<*~QAdc_GF{M$t<(E@jzho=NjW0FOhO70P-(BCH~Um2t+qcce{on0$L zT;oluWyX69RJ#af{h{!RA=HNoA~_}!#h3g+k48;y>{e&ssFfdq4+Z3(t%v)AP;8&q z9;XX^$dIvj?Yf3A%keC?>43f?vy+>hv6}u;HNRA8j4)9;^%GX4ac*|@FEoC?z_x8G zoLdad~Y?L<@CMpn`NVF zyL;}Ol@d3E=jPng3VlF~GP8T72n2DQFGhGRu5-z6T@|lKaR+~L0(OXw4`4Y-GVhBm zp1nHakBun;Wfz9;mXPQc+0FHH{z383aa z>mCslR{-vdB-AMOm&**kA5@+hkl#`}`s2e1KMO)sQWp`rMjxqr+X84Tk|Z_*oqBm(gWlVFTa? zy^S>l{jF(+l3_2~la(?Zrbi`Vs!=qE1OO)h4mZOzUa)u-llRRW1yHl*7B zat--op~=@*(Tuw~o!WWCwhMu|H!I`EJfXr8r6y%Qd5kdZ;#J%?0J)&Q3-;Bm%*k zhOTyfBbf>b_50B~@TNRzkwL9n6pZ`Y@)4YWKw|~@CKjIW`CMf93yR}UwBaQtO>AWT z#~^1{|MTB(Z8!dY|3>_e)o>C}fuE3zx)uLjb((1@pY#UdPn#y8u)pPS2z;M@QlrE^ z>ERoT7ZDGvg(hC{Pse(Z-8+|eK?Tn3X%+a^#$W|*UpJf_huywq2)b00S1eI?7Lfg} zjkZ;JHdSS}x!82~2)^U=H1;0qTBNpW+HC$1@Xba-q@s)W(`3uY0Qv(~7Y(1N0nCe` z`K>3B>UF338~8zAOSAd~f?Q1Ve5gXH6R$qHjD3&1-9Al;0~gGLlnVO2e9GQ`(6D{x zA|Raksc@+c%X~*XqX-5N-U?t!{$NVmWzAvSutI?npCa(g$7_*+9qm(2$2EO}kqLb@ zMow$PKW2gLw!^)_5Lh6Je2m2a`ytL7o@aa)UpT&5t>bu3m{ce2BofVDbGyqon122R zx^R$nx1{y6)dn8q+j`KCRlt-Qo<0zn1LH)0+$$Olc5!|b6U6Faz?GITYb9|u+Ibwu zj6C>{01GOLl9wHivC_=ioGe#t|7E4+iiK- z6q0f?^Z3Q2)~odSu|9y;kVx{2m#QWh{tkxeTMWy8(Dp-|LV36=s6GH_P~0-C zf^r@?WV1A$1XMm(FSaN<7q^s@SGrHg?9*XLP{H9tw=oD<7;j+;72|PS;a|UYfiLQx5I!m z-axvsi$=ePXFrl;g{(6}MvUWl3ZQJbL08cHt@p_yGW2ats@FYW6rb4EBM-Rz5!nuCOei+?QCAweLBZ7UOkmCP!cM4tBM&6 zM2*gsFE5|XBh4#Lsj>$LnjU71+ol-PzgsD`mgd-vybgV5B4ce}F*?x_jcJ7Z0nFue zR+yQ|Evwo+NC^fL*e;A5o0GsZHR{e0N07F4wozyt7;hQk2CSt~s*Pooolg#aWirAh*WO%PvcGCv1#{R3_Wd0~Hw(Jkao;_YOf`zZNehe04*h69PbwSZ@BNCJ!4kWGD#b&W zK&%38+7RtBJ6JlmS2#Za(uE4%7ihf4%fbIB&Dwuf8vYSu;4gvtkAMvP#KAD7)J?Rw zb^!Hm&qkof_cfc z#XOsRPd^2TEH{xeu*tcZ-{H4#at!u29&kW+(QKg#e8xaOqeXr??Fj4`*)p*9UR%cM z^&&Xpe#smDD2(#}+iyuUEx(gKC(UZj3Vgj;5&d%PhorjlX{Pl;DUZU!g#tg?c)Fb9 z6rF2F)62X^A0%Tf63i`w0%3g7aFx5l>UaJ!CvYvSJk+EU8ZxRgN1h_Fu~Maf;i*Um znOBobgOp zKO1)$KOGymkA5lO^Aq*OHH!vvv&Cm8vE@ppCt8~e%PngHPtQ4G%D3L|ZoLP5S-RWe zsg+~L@2PmK(spt=^UCJMTT(0@vV^>XkKZ3}FMN&EQ4{;blluJd{GZIyp6})DJ|?!j zatzn;qk+mEbpiIF*AjZ0=|liL%j4XRKG8ZWo!3agT8N5(|0)OV5eT;L<;k=ICh8#o zbBib5C8^Y}Q^u3&@vY8C{A2Ro0*__3Y4JLX!}w~T(a0yN_-j_`uYOdMOcJr7ssGem z$YIO-9=5UKi+khfUZwrEzrOzCfnNltyWF%m+tX-u9z0!rp}+GA-%8I*G{@LAYan9#t>egMmfw zI^qR?^)?fKkA|9;osWyhM%UcaYo9kH|9sCE^)yO`OZLfTq*BIvSwu}$`a0A=bt;F^ zb}JG!5QS3vC|0pnbX*?qbM0tW?8L?^O9#n>EESNSyn!!WFg~ zgSZ4RB=>r(v*k?w#e*YNPBgH0=J(Wr#!=1vVVakZj0W&6A{?Q;oY~EC9|^R#zD_3R-j!y~GKL131v$`;&|Ge!n`okO9_k4I#esxNz-{c%K6&wZYU0Cn zygi$}JaLWN6K9xg7d^{%5 zK(`HDlO+4}Ih2{AQml1HheUdv#B}ys$Rkgo6HXggy#$hUPuy|N5#VIkxXRwJ%6`0) z@X@9{g5iad<0VhFs>2xYS(0`P#4=hu>N~HZXqW1P=!?U)BIpKUw!%Jt(8Kb%n)nPF z2Dqy2Q`(K}pArv~b@vq9R9T1*UpcD0=ta_f1q~n{FfmJmia9*j6cqSktMc-Pgn-j7 ztYiP;D;_3SjDM92u>WF5-;kkWuWm%T9F;sBm;3ikzpV}*e%3z90@fTHJvr>GEqQFF%=zhlOsIhZBRhU< ze(Mx@6L32=S5xNJS3Bh2%ha|gt5-We#Nf4Twwb2ivmz=Xj|0}+?|j&$E1q=CKsxux z@Xp5Q-@m%4KzAe+tTOYElb4QlWOdwd=;th5FPZC;Z~>wX{tdBqrFIjbbuZu|QVwQXRJg-yF>^xcdr8pAR`6 zpw>0;@IlXhpWFYmHD5C$7kkvOM{`{nR%DS9v4(AHn~xy-`-TU`+z>!|=FO zPdhak*?Lin18k}CpGC#H3GuM)kD5z=u}GicvM=d_tt4Yx98;@I z`3|2;n)L#|Auq`kD(Og+y-(V9YNjg+o z%^LZ31geGFRsfTmPS3C`0SU<)n%Ei*-Oy#&85Z=ftgl+kg~M}?pa_q?(wg-ZX>Rp zW(~aDSJ^w09#65SJtF9)MqBjG{3==j)n}#WIjKmUZe({}z__?CKS%2rs04-`PR(lg z&%}IPww;cE;?{ei!3uj=hrJmc&^zo0SBCk~nvYa5^|%_Y>$I*y>D$pXk~Rc&765u~od-%1m(nTNhhS&ua?WKIk5MCXSB$I4p0* zUy-e`rn}2;tSx2Y+Vw5p_BQ2?>I3(-zv0yVzhBRIR#`YESyjnfZS0N#bOIW698#Yw zsoJ5P`5woVhxMCM*KztmJvi0Tg3^`-O7vdGzlL08?G&zY`Vu|y4K~R&T~KukF) zR^L9iZ^WMhFols32K;hh8RHCbGXw8Gr9j7XBr>b4%fH7{o^H9!oR<0UoeFj{V3)1TEe`+-; zaaLY`()bn=wni9G?vU{#mHl;xlMT_@TcfET0K5;f$oz8W1WAjkZ0i5Kr!<%>2WnZ_ z3J8_!FzuBblu;;)%(>$kg>!` z-)>gg>Q+VF6^!IO1InDVhF-9I9mo7xV+kLq?m3!xfr=Fy@gkN{kkzLQ2ap3U!h(xzp^cP9xIduXs<@$&Dg=(8B5Toj|Y>Z`ybXMmq8)z03U{- zPX!fy1REEHJIgXBS{;<(DJ?H!2fMNb;vPE}8!Za>f<=i99&$$4vaXiDkG}^`6^F@K zwuTre9F&oUtm0+%mPL#emKP(nW*7pi0pYzczR(neTmHn zbzpy{9oaGo$gaFab0vMpJEYBLhCZ{?1xqKm)1*ADJnH3()}03)+%M0cn$X= zUkjsLU6(a_@B03ZK5o>&$D@g4&D5f*G!mwH$X~?cvH9m5=r(bf+c=FNABgl4c7$wf zpOssz9!J`y_DEHRLMqib5DNDzw$I?+r*<8U0ir#qYK*>79(m_K4yN7ZVHM(pyY^W&i4?C_x#3OZUbYtHewvF4by3sSm#V3P0{Hh8De$)v4OT8>V%*+m`!ze zucScw@=*~vex=o}D&_k6QZ}KlIM{2j+IWs5IgSP+`*yOPOOnIb`g2Zq!^JY(oMTqs??k0wa9HOC&(u=QT z4)vSN0HL6+L$o5TG73xoxE86O!dpnb;#NL(@5V6s))rBR(TU&n)y%UgUU4Aa$R5xV zl}6UHog1}~VtmLmJoewqTOP!8K&BNxcFHYTy zd9C=Qq$UvwmqJyjIN~{s0ZTyz(u1F+__n&Sat3A{imJU`Pzztr?%JR<*~C4;Ex6$Z ze9gAfR|CoBdVSE-%D{irr%q)+!^9bzdzvOT#Qu&yUbMAuHD93&4}@XfD`-n(D~e@e zqr$d|A;JImQ*WH(y3EK}C!g4;?^z%@{vL_>2doFkLOzpJb0eJ2M*2DI>R#Ww=0_&RFM|I)pyYLPYbJ~uj93Aq(6 zaiBl#cC-J@IX*Y|JVj7)&Me)ye}gbq`q*68HKC_%@M(zADvd>PHa`Cn#OeRC^5kt< zHZLY2zz#nA$S+R#QzVZ<@>ebPivh3hcE zC(nJ#C!(t zgp~2O2Twe|shV!pfm*|pFwSe0y?FOpgGU!TLq$b*ez*Map~xpy<#@lyTW6-!&aQ0! z;DJ5Y;%{ZvXTSd4E%W#2 zsk(?f=5%GpYH9+LFR!{3gQ;%cpU@SCH)N$`)H-};{w(z*&k0!5Ig9HyaZ0e?QvGXR z`92T)o_i31%D`RpY*00(%xRd^d=6IB%$A>|$>C%_|=IYd1}gJ0oSgV*deS`2Of zC*|QeJA?5n+l9JPqTX7UXe@HaE~<643P5%XIRTrWz>3-g!JSg`U7qKi0hCeHCrWNK zyq~}4s>DjNw4jy}75FzSA{Fl+-U14k1Q$jc93A-sAZGf`0W4dnHan&-ELE$TQi;+R?1d-_hehx>-}`>OfNyE;a4(8J>m zELT@v%k#lcSQ-p69ygZ#_%!e!gsw@pOS0Ct7Dl4Z`#H<@EEf<^DJ!`i3-0&7hbkS7 zxVbU2Fm;gqIW$Mfc{D_cP#kEHl;=?g7+@a!l$G)d)bIqZ#rlMIpt2nOv#`eef$hMK z)1r1dC=$l*)!*ufjAX~0uXg^ zT2lg>55#^j`T2#cQW*PPuKmH-Tb7%8GvKHcRBj+zZ)fPr4nwf1Ij@_y`#&A_Mf@Ud z%OsdP)K^3y1L@0;Q8Cp^fYAoC)1HQE0aHKxc!7k!_UB1mr7Vg$2wZzv>J&MeCa`?`r1|y>~2}RF=d030n_79jl%|@cL zjXta>w156bvxRmuT_}Pa|2+ei;MW-^4ccMbN@d_o8oiNGiNei)1m@E>fPkXHJRA9x zy%_!v_jw@)c?9>hta?B4ueV~jbMWAy4th5YJBqp5#zv7o^F_+OJN`qa+HT==@}{xj zFM-~*x2dL|?klox&$q_x`Kw+AD8y>LK9RUJ=T7|?Bt!oW_t63%^T3rM_hPi1A4ZS1 zy>w!qS=&;R;*Iz`KQuSONbw4%l0WIV6}~9gG$9cEri@C;Q5z42X5VI9LkPmHGlrcw z>#zzVua(6e>AsE1HD)(A8u0OcvFDYlR{_gKNPHPu19=~6(p;qjujQ@X>F8VF@^V(O z>%;LVQKb=uir#hgHGBQGAoX=J2ijx8qv(xQH2bvN3P`o6^v|;Jypn|?m-qTs|L!Eb zzT_V6$+%G35EeGE=0p1>qYpd}BjFFHP;A-O5s^OLTGw9|@$S#y zJ1`I;`|cvtxVANA4yrn!rEJ`zyseT_RVXor)yXyHybeoFq;;2T$;RCl zQc_}SKMdYg{|%-VNbLD2So#_;Y9Fd>_viPBs$+K6-pyvp$)i zwsuF22Pb9>H`R02g$=!1|Jrui#{R=s?{q(voxK*(5UM4q4pj~zdv(FK$ELEZ;9)ye z&JL(n?_lhi(V=ivbvs^>Fl`{)6kk%*o2cOjNCHIXzc88|If^1q*4d=XpETPQ0CbLS&tuOaq&fZ%E%p41$O8j&lNd?FN^6L0}UA2;FaowE4r*gqs3P| zpitYF@oyAZ*q2*PlJp!M8h$inT_xI{)47G>gcQ1gkIne;i7@JjZIiIVtXSQcPFQh?-R6OgR1i8MDMJ=YLF_^F6we zgE8Uh2#oA`Ox@bdF{O|6uA@skwviKAg%4ww-;(4w{uk4v?Ce66!|FCn z@us-wPT4QgFMM$t-f4f@$(Auto=IdH_CKDw4?vCR*9v8mFBkQ0OBpY&O595l)n8=u z{JMHTLYuR8-0P@a_NJk%wc+zbNq-;SA+q;7KTNB1w$uJmtXz($p2#4Le}7{Y@8Lzs z#i6ZIQSDuOp1d=_i!KRWI{{A$7KO_wU4fkx>5>>}9`;CoCLY#>7Wgu`#;sicI!k1= zYDn4vzh-4QK%DA`E=s}Dee z0EBha?tI$tmMYVk171-O{GnoM?UQ~}i_&%NhUYDqUHFNLaRnz|KIBtV6_hR)Tnu{a zR4J7IX1%9XSx@3DxYj{?IeX9MI zmf(MR-4hI^ZAI`;z5hX}TW46h*oCB@&=S%2XMOf;%I=!^EQJ=|D}ZvkM>LVmzAa~Rwe-aKG;BC-%USH@h+TUxN?0TQpY1- z>$|@EO*E0Xt|5}{*N{p)ob9{(OiJ?aR7Bl*wnkH#cJNij^51t+zb*bDY7(`igB!6; z>v84|0p`o@)#r3G>f!x1#8+PkI5_q-mk1nv&B}8)A^by}brJehBmRHH#ym%Siq}Gf z?2?A&&_)YG)@}FRU*T1Lhyl`+kB)tdQ7h$#ji<RqWw`{?CYk>WLjUQX zEq<(+=%jQjB z*E&(QXD*t71G&*Pcl3SZA7mVPwL_r@`(&odRhu#)d+jEgLY1^KnPW0mT{n4g$UdSb zTu#4+el__zk4Zrq*g5k?ZkEP zB)k+5!@T#_#x{mnPV*6bl5#{TvL zD?%nXMZYpy@c_&p`mIDZiJ>5`d*0>7smaA#Io!^%$r*^0g4IhdF&|hhO|(n6YzoV6 z5Amn>^fh799WjeViS)=vGpgoZ_g6Y6lQ2^NlH14NHD{8215~nyy3KhWVEF@{3wa0L zJ)XBv!Pj_?_{ zMYeE3gj7NbXU#s?Jzc#(OYGk8gwo5cD{OA1yRf>Xh-kUBeq~%0hW~?8+~xZNc)kZZ zcq2Q#P8=G{t1B#&xym$HUse!~gl#d+7qxx`%Sy=nNsJgzv#I{PvGleITroZD(V)d^ z=x4?0YnUVT?Xp>U9Ukl<{Agjx96Vgoi)Qh&tlvlndA2FEIS(Pn@QJg6F^Kp=?q86S z3%@j9fmo2tzBwJt|?V z8&^&qK#pa>mtdL~oossKFpBPZ$#%dF7^EtgRtCJ04o3vpEMK2qbo*mZ*U_o4f;2&Hpa&$^$^w1g(fjm>XF~)CUF^?@mUfyb) zKnv^?kSVVrX9Gtge(U=d*@)JY_lgk~^f*56dVh|B1v8Mn6pOjvU>?~QMtmigfs<@@ z7C(9&?RRqZ%@AdtQw%mq{Q;LS(-D@{-RgE6+r}9m_Q{xs#n!{XVJGGZoP&9L*(?>I zwqoxpEMDg>;6spbHZbL7FilWW3LUt%m$p=+krVn1HN;qpR-0ZR;WIi6YWNah(2R6W70wpHQ!u9A7Xx51cJYq2>ouT;#j&v zsGWz5YZ^jThY_rH1)l2iW&1s~+)0V{X2ShcFQ&E{ReJ(YRJ7&^*ST9yi3X0%reT+q zgbvHrVn!0Jl6|zvDN=hcXBicg;4nOGgz|gFajyllx3;`g;otJ8QWj*3*bkB3K5vnn zUoy9fq`S9lQtbeOE~_y?@nLFu84=^%L#O)v%op9hc0b@3ECHk>;;{E4a%v#3 zKHuW|y!gfV-GMdexE^Q1ofTRj&HfYRl37G}%8Z*0=T&516=cAPr9tGL)=Ud4M)mZG zcWLMN09w-X>irLe#-bYp@dFB9JBi)ZQ!4o5Zj)Xck^${$NB8;EV4>e9dn@8mn?sr9 zFTa8}1IaKJS`#>K%wIN@oB5e99M%ZxH^!SBKQ(5hSu^csT2&MseEjiLMzmU-(fFbJ zoWv{?}z(mo}RAY2>H^^Xb zBdhZ?8NFl)2KV*mbvtL(DGW{&W^ALIEbE}rC?Qyeccpy$v{x3tCs0XbL%eM((=H)3 zOGjboTnr3qgz&dR0aG}3a|;JiaoI#=@uI6n{ffj^;Z^=o|7WF&;o{*7U(cBs2pNh0 zBY;^f`_wRf)HAhRD2BJ@Vu;B&J*PoON72p^%pQn{7QkN05T_4kZ9I>3 zCqx<^*CdBk#LS<~@b6sQ89;!d#s#69p|q}=Qe-X`1vi0h0bok+BVprQuV-z7jMmc}1=OAqACv;1VzOJ}CovxK+?!o)_B`3v{2m}hY`M4{~4O*cp-dq;zDjsXZM(X0EdrbXY1 zqOQPo{RJ>stA*zFhT_6RJ3f$WyQML3v-G9b+*cuhYBTjF$==@C%7wGrQa{?Q=d0}G z&^yidjN?z*A5Ukq+yro`C!!!OP z_^cSj{_I5R8?0P7-)Qce0D`krhGUZLVStjGk4vHb%Zg0X^7{=B$XTRZ;@%izGu4zo3Ed!@;DxV5q4)_zaGP`^I5 zn5|foMX^4Y6eu|D<0Dc~(fDFyPmg}fe44Vh{6yPCUTEe>?JzR?^OcZysLF)DD6qY# z)1_GT-dC>pkWX?|Wb1HKJ?bHj3IC;vYqG{EvBW+t%fpNcl!kC0awGU-ORC1?|LN>3 z;-c)seh;FebVx}GBS=d(h)9b_cSyr9G|bQ#fYb~O(k&fB!_Xn!JqSa0cbD%xpR+id zvpMhL-rdVPuK)Fm@A)&yRX~AJzx*D*7;DjjA-aFUA9{lF)xr7VxAIX~0QO$OOEBkI zS?4O7i)Bm z7rtO1@m=v14ZZkg>#~keFUy#9O#J+cby(7CKup~k_2qe?&nx}jsTL+vJD-VJv_;j~*UN=~7NK}^+w;7M($>igPesUl-JL9oV< zp#A9^(a*k62y2dGiusECb_aX6e=)Akm~@v1oKI&?35&O1eR^&(*{i&=eN$mUi@h^O zM*U;B7bC}(-4Lhn(6mZb;4@Rv8}05BRhn0Gn3GA91i_<@ZR4pqS2Hv3;5c2mMn2?x z5Av+=_vD(vqdAqxhzG=Rh>Vs}saDSM(=3N%mN_|m@8FO%+>B3gs_M}@@c}@-NM7pp zSHZT%a|-c~M+V9Xvb{vy+Y3uPlX$pN_F^^}IlqpnV*=Q-Z6NoY-PO6VtJ`pBV%&> zdfZ#qAer)@2aB>cJ+12=gKH2 zqe1;)y=@G0L7@!O&AfIQ69L(PuJgeIw)f;Usdz2aSdSe^XOdEedL?afZghZeSYmQg z25s@yp8Z`~ozyjLe6l`Ny2V4lHB?uWinE`b@M&`6VU*-PDxHx_ppo$xBSQ6Wiv#fm}M0iOreK!Uk}8dIfjyiT{^eEx|1 zQax9l8%Y>GYufy}@WfE9#Y@$_t?<>*E+){)aUh?4vf+V5;VFQOPkxYrYwOxzdE{jq!gfeq9I~)GJ1B|7K0zvDRW`T`S!gbvdtoxqp3~&HKT(_&g@N#vgTHd94@n_^VzSSEOBwmCfr& z#v};VMC&pSv_t)b`}AeM%K$7z`pjh4)g*%(G4;ynHTuCUYV_ojoB=$hok7tVb;N`T#6C)#{!&vj~TRJ7jw9e9JEPJE2LP@*a`a~4rhDy+Uip4c|`Z2xM?*A<+%eQ~L~%Xmm` zQNYN5>wf>{QA=^Ia<(jebJM7@2tn30&4}0?C!-=Tv?*h_F8s5y!FTB?>MiV>ON!zm z2mYN}RksKE>Ts`K727~i5w81=y+vh3MOZe_oem!JCaNM@3Ktc`4s6hA$(EF;dJdEL zEWNH3`H1-RJP+bFm#q&H}>6zSY)(*;&YMAe%I}uzkXZS)iV`d!W zyHdJsN(TknJ2_d;ntb?)O`~40FJE&e0xp;U5dvgC>8+y|VTSNd^x}fT#e-Wz?^t5b zf^09Y6p_yuJ@^r=QKO0Bg}__8mG5hjaBv;nk<^ekRgd!wZ$}1M4Y!IqmtDg~E{n=E zi683Z&FaRdl%Kbq;4%|&x9#LV@2lR%db4lT0oGP!R7P$6^|W95_g5Abe;M<(kRopW zxYg}2E=53O{j+`YqRw8lm1V_W4ZLpY4fk|Xl1uP`A*B^TzM_fJMY=h z5Rkps0bp4;LE6tRE=#O`;}aJ=)o55CiE!4?l`&PSuW>*Fbn ze%NE<033JCxC*Y?Skcb8#vE1uu(B)4KR@>V6MJaZXhsr1XRp=nfMhV6=lZR5iG@wA zm9Z>&YD^b^H{s;0H#qKb_3$Sp8=nNU>9x0cGo{u3hiGfIm1@=XIeViK(9TcbRwAH_ zLHg?ZvPZ0OLrwV2^5gK6jtVMh2Je+_DdP6g-N*Qa596yx5BGy%f|s`z7R^_hfy55C z3;v2K6Y-0C7Y{lk3U=h2r!LPKnu`rVU{!TOBct3Z!v%JJ5DPvVZY0r<^G$@_RN=yf zSmCj>C9$Xaxs0?^pn2fWmrqk{o!z}NcVCwMlAl4w?)3s_0B-`DyT$1JIr{?b7r!y^ zTboxHPV@?vRq)Y}!x4-r(;6>6Bw@l3WMx;ubzVD(7isUd&Vy1h}MM(*aPv`O~?wHl9VZwUUj}2J(1n%uTpPyDPHXHP$ zk8wfh(kpbSS$b+!W=1&5rR zI|IYyIWLJ?*1Vm_Q1x4**hfFVnkE4@pVl;ij}9LwN>isB&XZ^U##F~L?0u7ZL4Kn* zF^e0VrMwpF;Z$k8^0zB&Q}i*kWhNif_x{K~M7I%+3Y1hRZwL3S-3`G^r`9KzBL#Ck zX3s=(zeBg~T#xm-of#lhD>jAsSL%N*zztj?QIr|3JQ*T4AFW$-*_gm*)Q?)a?o$G2 z@8mGg=yTpCx!i5kKP;Yg%CSn0HUDwy^uU)lvMr2Tv()JO2xoT7Q;~SQZ-JrIOaHLM zcm2c)XaCC5y-r4nw(C6ae|nIE-M&BM^$+XIa;mpg>tI>&AC$D!v^43}uDTXI?EATD z*c606aWypkN6UlE&AD7#2ELzv(c%sXa1`PrA0@(N2#K!d{p%g+(n;{WZKGupmmfr)~wI6B524`~NJ*>c6um16n`khDgS_MS{84-Cf!b{>fLd)4`rZD+LNI56UO z#Ij}C9Y9ktJ4A+U_EX#amC$Ki!v1q$)}7u|3FyrKlac;mxc;JnkzlzgCyDI-x92^% z0dZH0?GLoa!u8JdsFeFcTasS#(v@euSUzu7!*lcQNXHH^S;Emf-u#Z&jewsBvO-

ZwM{i{aAz5F)Gcqx~~YMe66^KoaPfS;?0pbm*r)El$T& zZLlz(jGn2Q$?9eykM&AnEj4@E61PXo9b}#9#OjEEvTX)@BNK6aZ4e6V##Px9Rb0o* z27N0Lz+7)ebw#V(IL(uN%iT~J_gRy_D3qzN_W-!qdvx5t%WNj;=i7lEe=&#%>D-3I3q$s%d` zrEOG{elvMEX_YUu?sb~K!aIuXmlzV^>VQ1}hOx6) zEOoKP5516>6uIpPzdc-@{w@gOXe&*P_o^*E%^~?p?&9mZe>JT|6|s-mfFX|8m4!Fw z@t;2FYbVG*BubOo9r|-yHrH`#<{60TB` zmv`MK<5q6CWnQ@0NYk%Fl2uYI?RgMpH}%&n#f!pmzcDyR!E}=*H5O2;*8-8E;W);4 zid*VuG_m4Lyd_>*faI|aa1l$t@eT}ye3TN?)Eqms zin(?_-d)ZQZ+X$&+`JfinAcR7F`!SfIncHgJ3?`oQLet1hM5=CLlU%`s(z|JwAiz0 zL=W|Kdykx8lDNkbZQ{J)+>+bex*I@HF~ChhpUN6Q;XYvdHDoKCuKUFaAKY3wFU4bhisq}G;=640jds7vZ0w-^xAViPY^~m2F1b0Umo9?waiLbKOP)1VBm*1mtY!%ujLkzvPKrZMkk<{5<)zF?_9O9rorGPg+Z9SgtXpgQR$vk9rA*j=^M`H zajRnHTMBx4viTjp>!v*f%aWDtsuiRqknN0hUBPA_nzDQ^b@927FaW*Q1a4hU+U08p z#R8MQY>FrrU8Em2=NX2U=@r`*C^#UQf|#@n9biAFFf*!c{3ZON&#}%VyZkVDU~+GD z0+IU6P-fW^CL=?~_|VK;63b;zZcNXx(`|$N(eujABr$RQ^CElCXLVPdi=nJ}S^9D2 z!2mZMBoE(&bowtvd(Q%+KfT2l`t5pif!;`Z2Mj14{%4kP&i^+}hMl+BMwp`dpPX?( z20FsiWw8;i1KWUqu76BEaa2qOWUxqlRO0CnZ*GY~AZ;MevX$N9rlRN^r!b*`(2}{n6%x*h4qdnEc`sdK zI;>Y-4PWt=+{zI%PIui^8#_eoli6hOZjfow@&CiRDXO7j7pm+=U7A`sBJfvf&d*Au zEV`9#!kV@pJGvqEUU;aRH@82>&)ivtJ5XdjcyJz6O9 zYsiapri+zO`teQRq#|3jnXeNyE;9I(%6u)oyKuzG{A;q%$rLQlM`O9!i&M(Vgio0@ z(prS*`2nGXbf&6PMal-$eug?Vo8hg)VD#WvW#3!#>~FsJ9I&5$?^>9qB?o@Scx5cp z(M|n4ute6Jto53H4b5fx5D$(baAOvSu92cjcC?J`(^n@VY%Lt^ zK+e2*7{5u8k_Q|$m=knUy#3pbla76;IlJ?8gYyT>p;p9WSe_QT{*XSjV$39VB=95k^bdQoVZPE6#hgr6V#3K zJvBLm-jrT*SgquEuMewC%Rt1PCwtwT`rS_P?!Klx{RrF^zF0UnBV5@ zQ?+#DbJI>4t^wcbhWIc0CIFhtalaxNR5B1=z)Pwv&THH4*GEe-2W%Jsd_3wFuGS12OymMeZa8;?GTlIy6_HwGl=k#=;i|DYed52c3* z2~cY()SU{6qI?C3AH9{~13ZoN5efX0S6`95(3b<>b$=%Uh=8S6o*nY9YQdHBzP333 zN_@~A7L{HJVvUN$ZxCHDcs7d|CPwh@4AVyGXs!q^GT#Lo(e!*wpR(ClncMwX`KL5I ze~^zbA6${GGqqRBOj1+V8SxFg*4dN4u7(W*|a;K8)7X z!1hM>Nq;UV)h+nDAATHjyo-a2n7YVSAthYXr3#T`LdbY7U6iWb`@64I)t+n&=Otb^ z^kW ze~5Fhjm~rSU=g^uV5%Uocciv&(iUf{&1)Z&l9%;4gJ}q4nm_0StxFP1nsNXmg5$sj z!xrAuBE$D8-+Wfls9MDNRCVldiU%)wwI7e(1xg>f3P-x^}QG z(_osLTzil;Uvg8EO@4{!f=T)Wu=v;|dB4EQe3*|jQY~t}8F^D!J(UN1%NG-MK6xV; z(ICEcsHf=(zj`5W{*2{d6FFY#r|gL-W5I9s*sfH;^jAXtw9gKBlzb5=3k{~;e^^?~Coc2;6^8$?j*@;N z0tP%?8E0{btJaC*{ju4;YjH=er7&fDsvG5kr3vorvkJfxq{8T;rMm3o-7nT79Ucwu zx>32(@UA^s7swc{zn4>KP%UJGuLw!_b$>P@aFL~!(o3JTZ(&j+R*CUzjI-9v`r|SP z!KkdcwgWa62S^^Hh3#9OquY3+})}(E%7uxkab$N2545T=z&6zHGQSW%xIU` zx0HLt6qusuCLb23cq!=RRB~@iEkLy|cUx zipBnQ^fML(Sf7ok|Gb+N;p<;V_7@S1v#j>aatv0yG>3C8e;KN`&q5{+vSKi)1T#*@ zunh{kNe>ybGUG`UgH3BGp>PkVYqIoJBoD1uz}B#+;K2o8>ZoRDQkV3;XhZD9KuCf) zH#3>26p^o$)zmG9XE%^5HON<%0?_2|+^3|$buM#?8*=dB$;#ak5f8{4V#u=UObI-9 zERi5HiBcO!B~BTUb{FHw-)5KCSQ2z{zdKb^gxc#LG&Y!ZRd1TXH$3n zsOn6T2|w+g%a;^cxLLk$q-f5e=7Fkp?V;}+uEKtZE(__StDPe{>)rot7XvuW z*I&QJz!zC2piSZ7sO|k4i70eVWU;r}AD9#IM_;;^;XA6ZS6^J$`yjbJaJdReC)`E4 z8&qnWCw#Fw84&&fOgi+2sB;xbFB6fgQ$1~!?uHj-}=7xV*l?npMVquYvYJryS_MWdN6iSv` zz$f8~yiVz9b&@*%Z0aHSjS+>fVoVq0*4vq$s2o8ow;Z^ISL8J zT#`G*diKXWnjB=3YP?q5Ic;+w-fNyV4{!ieJkX@oP97PemLt6%o?nS{mNSeu<@sU{ zIG&TUDSc~+J1~puxLOtfOgcJKUgHv}jDW1s*1qZcMQnM`ev?*hstwBPbDE}ouv-tS zRc3VWYjd>4ovu-TYuKY&0{MnEtg(I=HLF!nuw=7yg?)i?W|W8f656QNzYd|TXTkB4 zgXdU^Za2+eU)y2-B5&)Euv<{JX3ZWamY)avqgG;a(Ngb3+q-lriGhWxLd_*( zwWF1pKMUN5Z@SJfMshvX?5nJjL(^@m=bnNPf~(g(@1+D5!*h$T!cSI~z2@FR-?oo> z0xmBzZKb&4YfYJqd?QAZl{((YX1tB(|Sb~a6=4E~EoOCw9eznpP94^z}?k{sQmHInTf2bK5d=TqdU&o~+%XaKLNxI`T z%NH%ljG|D3(G_1RNhw}UzP=%lkT!kRIHFDc?pQj6FN`AWGq=BlXs% zsC|Wox!PG2BbAcgTzE$vONrvF)ZfV7>n0AWq~d^I!SANgj-tUCTvi0 z@nfB3N~yw)`69er#MkgRy6 zOP&LjxN9{mF(J+fBX1o8l}#3$8adYA0}NwCCo?vELvli>u2cLct4tnGi|~_j$&~99 zaF1_@&J$OLBtULz;@b=#_mX^xM1RXr8!I9>3-Jp7#IzT2Gr`~d!&=XQtp9RP-YNl9 zjPH{=b5Hx;&(P+t%KFeajXQ`4C^fn*iiy$hs(xyuq~!1_7LgmWz5437*7OhSgAN+% z<-w?uJgw%t{|H#Oc&|+J7&iRP3jo~JZ`vf?n^U&p?ml!V`{Gakceb_Bxfyvol>q4O zmSe?F*d3P5-%dzs?JOdN;dNvdw7Qkep+lanWn4zB_YE&ViY{aOo=m){>!DZ7&y}a2 zOp9N6?tDw6m-bJF0EEoKGYSIz(*-zjjIyT6`NJs9(!-B2 zsAfkD`r_JooBjVD`aYHYcj)_vwcq|Owxjj?s8Ino--+{PWNYSO8~P9Hg$z4m#1-Ps zQQ{yoh)j+l#ER0?4fxY7*PmtSg^VnViu?4IuaHEdso)heD`#HW9pl-!oE~JU zbpU*AcKFc0q>OI=|pno1+B$iTS3Lac{EuhZ~+254j^_CxXr>*g~~Ad+mM@52!P{HH9O z!@p(UC+==1aDU`c!X09&If3P0Vp@*3IN5Z)UfNj<4kor+#%}AL0~2b;xIt5`t}F@& z#-sA0lShT#minu}IH=g`$B&o$9=4@Js@H@sTO3%}K}%wm@s?ZCAw}|dT{+w9I@*06 z8p8thZjgdVWvB7(qPLZnQW%9v7)Ksqq|gBL)#X43SrNv$LTfbFF{B!OgB%@W>F1l1 zsF0Z3TSlSKL*ZJZ`gYL*&jQrS%{(;^Z9J2kH$vPPALO5h@e@WwL_wRQ%cOkqhUzMk zZ;Y}V#Fqb*gEA?4+*+mzMte^3;~TYuM9)jEL6pPYtid@^2iQ;rU8cIZz} zXU%iZX*F3x(HY@`NNX?X4@|85_qU#r@#VK@bZ(QkGyjK9xb640?OokFMQe)SxQt)n zC7E}Buc3UA$;j4yQaN_K5=)KXWq%*-+(P47n#+;RRG}BZZ9WKx<5Iz9Xv}&wFJ_cc$Pl=D&hscO>hm6!? z_xUL6;UkwpIh<^mOyPsP&gdE1S4|_kMc_#T*NVabpJ?}-7ae(*gF}Od4>Torh;^Ao zB(ckgMyyDDSGWr_RPRG~B9_x;|h@UYL`F3q}`O_bqwu8!gZ_E?Vc8#o-nIF)43WWi^tCVq)JZm&=iV zx=oQ)*Aq`FZRI|}J5Z@l}H^g7q>FBgfi3y+53B?a9@o%D!b@ICw z5(k(MuB%d0PchR)rkZgK?*saUS6Ai?01f-4u{ zK0bX|#PE`TKIrVCfZl3~XZd6UYMr>Rtrhy%O+o7Zo+CZqmHQzB0!UVGn2RJJsw-i9 z9#YlVsi~A<7vb@PZ-4}{k!M8W1!mkz{vmvel2&4dwCH@FDvAg@T z3(%N!f5CH)mt;0un;aoPyI(^Z>U{!Y|{ z@d{k2D8P?Pz?HMrj?({5)djI4Vc97-RzIvf+s_f%o|*fI zkQs=yzcWUg4575AXgeWswmWTGa^vK@<=E&y2C>yNP?1&%`YO#)yZPSeW&4rWh=_Y- zmIv?{q$`WqqiT`; zDVtD-%HgjwKd(cGaimkztBEbCG{Tjebm+j84jHyIQTuECRi2_WtCGjMg7;GAv{$CW zW-IKpsT3??BdvyIulM3BO%xdi*2_5-J4MeCgo_s6P)gl2(PEc^gv~sx#hwic@***u ziYJL}R`a8qbuuawN0S;Ykx2N*1ij~pV|9JTZhFZ5p$NEhoK_gFDTNLe&S8_7co>1=uE2k02(lp1nNE-U3OMtH1gNHf$w1JldH zY#M^Sf*OOCd{BpBO}zFL!Ku9^m1O*~yXn>Sq5U4J#~c#s*cj?me~U$Tj#27e(y%u} z<}_wuxiD8fdQC;f@eM(?KL8dL($e>;fb()EI=TF?jWkbBZ_*8_2>nFn&BweytH@A8 zUdXO&mczXTf?Z8=dL*27c{RG_ixNhwzh}=ks)MQ3)h#y2 zb6uP~R%J1Fos!vVS=x)QD%Vx!~P z?;7OqQ1c7F*reZfppvj{vsr80QyGd71QbRoErs_aMnpw-x3d7ji5%xRm{-0`%Yg%m zS}+DOW;_d*BOO*Rq=!w6$8YFD@5ArvB(X=`9IBCO&IJksH3n(!UD{skFLfI-k5Iu< zQC(@xmx(f-l0QnyD-NDLDAeCxw=6pC(M)9<>9JO3uuBprV{dJ#dUYY<+ z^~U^^ckfO>O%k}E?}ckou(7bXKL^8iF3Fg7^ReFF3fuoxCt-MQ+xc7ZU`l@c5OYIq zwo43Z#7yft2dciZDt!j(yuO`-5V7>s=~mrc_nXt*dxMJO!1d?Il?1htJ!4TM{0@GI~F=%yGgqe!%ORcWo_O`w$^rJ5J zb!AM*gw;uq#3*q4DXhv49H{ED!DSiZ?X zW5KZ}Y_#>FIqF7LDkgIKBz<&WwVdU4wGYQ3j*?f3N!3<7;#0J~+qT^G7)+mTe1?m4 zrH*-{o8ozHe^4^*)*NRgGKm@XD>B-jBQH46w`4@XxVv^kj9T&3_KkRekoFE4S5|`hEHR_dou}G8czC7!z(FCu8N47aH&WUl-%Qng0QCYsV1) literal 0 HcmV?d00001 From 410171c7cd8868a6fb5cd224baad88df6a8d26f0 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sat, 20 Apr 2024 12:57:36 +0900 Subject: [PATCH 093/106] Update README.md --- README.md | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 8d1ec78..df35560 100644 --- a/README.md +++ b/README.md @@ -120,13 +120,6 @@ ``` -#### PRA32-U with Panel (Optional) (Experimental) - -- This option requires 3 tactile switches, 3 ADCs, and SSD1306 monochrome 128x64 OLED -- Tested with Seeed Studio's Grove Shield for Pi Pico, Buttons, Rotary Angle Sensors, and a OLED Display 0.96 inch -- Uncomment out `//#define PRA32_U_USE_CONTROL_PANEL` in "Digital-Synth-PRA32-U.ino" and modify options - - ## Files - "Digital-Synth-PRA32-U.ino" is a Arduino sketch for Raspberry Pi Pico/RP2040 core @@ -261,6 +254,33 @@ graph LR - This image was created with Fritzing. +## PRA32-U with Panel, Prototype 1 (Experimental) (Optional) + +![PRA32-U with Panel, Prototype 1](./pra32-u-with-panel-prototype-1.jpg) + +- Uncomment out `//#define PRA32_U_USE_CONTROL_PANEL` in "Digital-Synth-PRA32-U.ino" and modify options +- This option requires 3 tactile switches, 3 ADCs, and SSD1306 monochrome 128x64 OLED + - Tested with Seeed Studio's Grove Shield for Pi Pico, Buttons, Rotary Angle Sensors, and a OLED Display 0.96 inch +- Inputs + - SW0: Prev Key + - SW1: Next Key + - SW2: Play Key (play notes) + - ADC0: Parameter A + - ADC1: Parameter B + - ADC2: Parameter C +- Panel Parameters + - Panel Pitch + - Panel Scale [Ful|Pen|Maj] + - Full = Chromatic, 10 + 7/12 octaves + - Major Pentatonic, 2 octaves + - Major, 2 octaves + - Panel Transpose [-|+] +- Other Operations + - Write Program 8-15 + - Read Program 1-7, 8-15 +- NOTE: Specifications may change significantly in the future + + ## License ![CC0](http://i.creativecommons.org/p/zero/1.0/88x31.png) From 9b431f12f4751a1b5f2a61c12771634ed00c16bd Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sat, 20 Apr 2024 12:57:39 +0900 Subject: [PATCH 094/106] Update PRA32-U-Change-History.md --- PRA32-U-Change-History.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRA32-U-Change-History.md b/PRA32-U-Change-History.md index e6bfbb4..47203fa 100644 --- a/PRA32-U-Change-History.md +++ b/PRA32-U-Change-History.md @@ -4,7 +4,7 @@ - Allow user programs to be written to the flash when using I2S DAC without mute-off pin - Add the option to write user programs to the flash when using PWM audio (for Raspberry Pi Pico/H/W/WH) - Add the option PRA32_U_I2S_SWAP_LEFT_AND_RIGHT - - Add the option **PRA32-U with Panel** (experimental) + - Add the option PRA32-U with Panel, Prototype 1 (experimental) - Change the default program #0 to #8 - Use core 1 for Debug Print - Tested with Arduino-Pico version 3.7.2 From 41b99bd8ee98d85883c3bc60f0f5d4df8a93569f Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sat, 20 Apr 2024 13:09:08 +0900 Subject: [PATCH 095/106] Implement panel functions (74) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 518a9d7..312165c 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -92,13 +92,6 @@ static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t } static INLINE boolean PRA32_U_ControlPanel_process_reserved_note_off_on() { - if (s_reserved_note_off <= 127) { - g_synth.note_off(s_reserved_note_off); - s_panel_playing_note_number = 0xFF; - s_reserved_note_off = 0xFF; - return true; - } - if (s_reserved_note_on <= 127) { g_synth.note_on(s_reserved_note_on, 100); s_panel_playing_note_number = s_reserved_note_on; @@ -106,6 +99,15 @@ static INLINE boolean PRA32_U_ControlPanel_process_reserved_note_off_on() { return true; } + if (s_reserved_note_off <= 127) { + g_synth.note_off(s_reserved_note_off); + if (s_panel_playing_note_number == s_reserved_note_off) { + s_panel_playing_note_number = 0xFF; + } + s_reserved_note_off = 0xFF; + return true; + } + return false; } From 6ad32c82a529c2f4a5500f05a84290e3657360ca Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sat, 20 Apr 2024 13:11:20 +0900 Subject: [PATCH 096/106] Implement panel functions (75) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index df35560..83df5b9 100644 --- a/README.md +++ b/README.md @@ -276,8 +276,8 @@ graph LR - Major, 2 octaves - Panel Transpose [-|+] - Other Operations - - Write Program 8-15 - - Read Program 1-7, 8-15 + - Write Program 8-15: Change the value from 0 [Rdy] to 127 [Exe] + - Read Program 1-7, 8-15: Change the value from 0-63 [Rdy] to 64-127 [Exe] - NOTE: Specifications may change significantly in the future From 7f8c916e5800ad66a6e9af5e22968bf4668026e6 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sat, 20 Apr 2024 13:53:56 +0900 Subject: [PATCH 097/106] Implement panel functions (76) --- .../pra32-u-control-panel-page-table.h | 82 +++++++++---------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h index f78bcc1..b0a9ee4 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h @@ -55,45 +55,45 @@ struct PRA32_U_ControlPanelPage { char control_target_c_name_line_1[10 + 1]; uint8_t control_target_c; } g_control_panel_page_table[] = { - { "Page= 1 ", "Voice a ", "Voice ", "Mode ", VOICE_MODE , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page= 2 ", "Voice b ", "Portamento", " ", PORTAMENTO , "Pitch ", "Bend Range", P_BEND_RANGE , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page= 3 ", "Osc a ", "Osc 1 ", "Wave ", OSC_1_WAVE , "Mixer ", "Noise/Sub ", MIXER_SUB_OSC , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page= 4 ", "Osc b ", "Osc 1 ", "Shape ", OSC_1_SHAPE , "Osc 1 ", "Morph ", OSC_1_MORPH , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page= 5 ", "Osc c ", "Osc 2 ", "Wave ", OSC_2_WAVE , "Mixer ", "Osc Mix ", MIXER_OSC_MIX , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page= 6 ", "Osc d ", "Osc 2 ", "Coarse ", OSC_2_COARSE , "Osc 2 ", "Pitch ", OSC_2_PITCH , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page= 7 ", "Filter a ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page= 8 ", "Filter b ", "Filter ", "EG Amt ", FILTER_EG_AMT , "Filter ", "Key Track ", FILTER_KEY_TRK , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page= 9 ", "Filter c ", "Filter ", "Mode ", FILTER_MODE , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=10 ", "EG a ", "EG ", "Attack ", EG_ATTACK , "EG ", "Decay ", EG_DECAY , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=11 ", "EG b ", "EG ", "Sustain ", EG_SUSTAIN , "EG ", "Release ", EG_RELEASE , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=12 ", "EG c ", "EG ", "Amp Mod ", EG_AMP_MOD , "Release ", "= Decay ", REL_EQ_DECAY , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=13 ", "EG d ", "EG ", "Osc Amt ", EG_OSC_AMT , "EG ", "Osc Dst ", EG_OSC_DST , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=14 ", "EG e ", " ", " ", 0xFF , "EG ", "Velo Sens ", EG_VEL_SENS , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=15 ", "Amp a ", "Amp ", "Attack ", AMP_ATTACK , "Amp ", "Decay ", AMP_DECAY , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=16 ", "Amp c ", "Amp ", "Sustain ", AMP_SUSTAIN , "Amp ", "Release ", AMP_RELEASE , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=17 ", "Amp b ", "Amp ", "Gain ", AMP_GAIN , "Amp ", "Velo Sens ", AMP_VEL_SENS , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=18 ", "LFO a ", "LFO ", "Wave ", LFO_WAVE , "LFO ", "Fade Time ", LFO_FADE_TIME , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=19 ", "LFO b ", "LFO ", "Rate ", LFO_RATE , "LFO ", "Depth ", LFO_DEPTH , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=20 ", "LFO c ", "LFO ", "Osc Amt ", LFO_OSC_AMT , "LFO ", "Osc Dst ", LFO_OSC_DST , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=21 ", "LFO d ", "LFO ", "Filter Amt", LFO_FILTER_AMT , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=22 ", "Breath ", "Breath ", "Filter Amt", BTH_FILTER_AMT , "Breath ", "Amp Mod ", BTH_AMP_MOD , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=23 ", "Chorus a ", "Chorus ", "Mix ", CHORUS_MIX , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=24 ", "Chorus b ", "Chorus ", "Rate ", CHORUS_RATE , "Chorus ", "Depth ", CHORUS_DEPTH , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=25 ", "Delay a ", "Delay ", "Feedback ", DELAY_FEEDBACK , "Delay ", "Time ", DELAY_TIME , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=26 ", "Delay b ", "Delay ", "Mode ", DELAY_MODE , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=27 ", "Write a ", "Write ", "Program 8", WR_BY_PANEL_8 , "Write ", "Program 9", WR_BY_PANEL_9 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=28 ", "Write b ", "Write ", "Program 10", WR_BY_PANEL_10 , "Write ", "Program 11", WR_BY_PANEL_11 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=29 ", "Write c ", "Write ", "Program 12", WR_BY_PANEL_12 , "Write ", "Program 13", WR_BY_PANEL_13 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=30 ", "Write d ", "Write ", "Program 14", WR_BY_PANEL_14 , "Write ", "Program 15", WR_BY_PANEL_15 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=31 ", "Read a ", "Read ", "Program 0", PC_BY_PANEL_0 , "Read ", "Program 1", PC_BY_PANEL_1 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=32 ", "Read b ", "Read ", "Program 2", PC_BY_PANEL_2 , "Read ", "Program 3", PC_BY_PANEL_3 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=33 ", "Read c ", "Read ", "Program 4", PC_BY_PANEL_4 , "Read ", "Program 5", PC_BY_PANEL_5 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=34 ", "Read d ", "Read ", "Program 6", PC_BY_PANEL_6 , "Read ", "Program 7", PC_BY_PANEL_7 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=35 ", "Read e ", "Read ", "Program 8", PC_BY_PANEL_8 , "Read ", "Program 9", PC_BY_PANEL_9 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=36 ", "Read f ", "Read ", "Program 10", PC_BY_PANEL_10 , "Read ", "Program 11", PC_BY_PANEL_11 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=37 ", "Read g ", "Read ", "Program 12", PC_BY_PANEL_12 , "Read ", "Program 13", PC_BY_PANEL_13 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=38 ", "Read h ", "Read ", "Program 14", PC_BY_PANEL_14 , "Read ", "Program 15", PC_BY_PANEL_15 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=30 ", "Panel a ", "Modulation", " ", MODULATION , "Breath ", "Controller", BTH_CONTROLLER , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=40 ", "Panel b ", " ", " ", 0xFF , "Sustain ", "Pedal ", SUSTAIN_PEDAL , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=41 ", "Panel c ", "Panel ", "Scale ", PANEL_SCALE , "Panel ", "Transpose ", PANEL_TRANSPOSE, "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 0 ", "Voice a ", "Voice ", "Mode ", VOICE_MODE , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 1 ", "Voice b ", "Portamento", " ", PORTAMENTO , "Pitch ", "Bend Range", P_BEND_RANGE , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 2 ", "Osc a ", "Osc 1 ", "Wave ", OSC_1_WAVE , "Mixer ", "Noise/Sub ", MIXER_SUB_OSC , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 3 ", "Osc b ", "Osc 1 ", "Shape ", OSC_1_SHAPE , "Osc 1 ", "Morph ", OSC_1_MORPH , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 4 ", "Osc c ", "Osc 2 ", "Wave ", OSC_2_WAVE , "Mixer ", "Osc Mix ", MIXER_OSC_MIX , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 5 ", "Osc d ", "Osc 2 ", "Coarse ", OSC_2_COARSE , "Osc 2 ", "Pitch ", OSC_2_PITCH , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 6 ", "Filter a ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 7 ", "Filter b ", "Filter ", "EG Amt ", FILTER_EG_AMT , "Filter ", "Key Track ", FILTER_KEY_TRK , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 8 ", "Filter c ", "Filter ", "Mode ", FILTER_MODE , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 9 ", "EG a ", "EG ", "Attack ", EG_ATTACK , "EG ", "Decay ", EG_DECAY , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=10 ", "EG b ", "EG ", "Sustain ", EG_SUSTAIN , "EG ", "Release ", EG_RELEASE , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=11 ", "EG c ", "EG ", "Amp Mod ", EG_AMP_MOD , "Release ", "= Decay ", REL_EQ_DECAY , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=12 ", "EG d ", "EG ", "Osc Amt ", EG_OSC_AMT , "EG ", "Osc Dst ", EG_OSC_DST , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=13 ", "EG e ", " ", " ", 0xFF , "EG ", "Velo Sens ", EG_VEL_SENS , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=14 ", "Amp a ", "Amp ", "Attack ", AMP_ATTACK , "Amp ", "Decay ", AMP_DECAY , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=15 ", "Amp c ", "Amp ", "Sustain ", AMP_SUSTAIN , "Amp ", "Release ", AMP_RELEASE , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=16 ", "Amp b ", "Amp ", "Gain ", AMP_GAIN , "Amp ", "Velo Sens ", AMP_VEL_SENS , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=17 ", "LFO a ", "LFO ", "Wave ", LFO_WAVE , "LFO ", "Fade Time ", LFO_FADE_TIME , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=18 ", "LFO b ", "LFO ", "Rate ", LFO_RATE , "LFO ", "Depth ", LFO_DEPTH , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=19 ", "LFO c ", "LFO ", "Osc Amt ", LFO_OSC_AMT , "LFO ", "Osc Dst ", LFO_OSC_DST , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=20 ", "LFO d ", "LFO ", "Filter Amt", LFO_FILTER_AMT , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=21 ", "Breath ", "Breath ", "Filter Amt", BTH_FILTER_AMT , "Breath ", "Amp Mod ", BTH_AMP_MOD , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=22 ", "Chorus a ", "Chorus ", "Mix ", CHORUS_MIX , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=23 ", "Chorus b ", "Chorus ", "Rate ", CHORUS_RATE , "Chorus ", "Depth ", CHORUS_DEPTH , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=24 ", "Delay a ", "Delay ", "Feedback ", DELAY_FEEDBACK , "Delay ", "Time ", DELAY_TIME , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=25 ", "Delay b ", "Delay ", "Mode ", DELAY_MODE , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=26 ", "Write a ", "Write ", "Program 8", WR_BY_PANEL_8 , "Write ", "Program 9", WR_BY_PANEL_9 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=27 ", "Write b ", "Write ", "Program 10", WR_BY_PANEL_10 , "Write ", "Program 11", WR_BY_PANEL_11 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=28 ", "Write c ", "Write ", "Program 12", WR_BY_PANEL_12 , "Write ", "Program 13", WR_BY_PANEL_13 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=29 ", "Write d ", "Write ", "Program 14", WR_BY_PANEL_14 , "Write ", "Program 15", WR_BY_PANEL_15 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=30 ", "Read a ", "Read ", "Program 0", PC_BY_PANEL_0 , "Read ", "Program 1", PC_BY_PANEL_1 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=31 ", "Read b ", "Read ", "Program 2", PC_BY_PANEL_2 , "Read ", "Program 3", PC_BY_PANEL_3 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=32 ", "Read c ", "Read ", "Program 4", PC_BY_PANEL_4 , "Read ", "Program 5", PC_BY_PANEL_5 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=33 ", "Read d ", "Read ", "Program 6", PC_BY_PANEL_6 , "Read ", "Program 7", PC_BY_PANEL_7 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=34 ", "Read e ", "Read ", "Program 8", PC_BY_PANEL_8 , "Read ", "Program 9", PC_BY_PANEL_9 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=35 ", "Read f ", "Read ", "Program 10", PC_BY_PANEL_10 , "Read ", "Program 11", PC_BY_PANEL_11 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=36 ", "Read g ", "Read ", "Program 12", PC_BY_PANEL_12 , "Read ", "Program 13", PC_BY_PANEL_13 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=37 ", "Read h ", "Read ", "Program 14", PC_BY_PANEL_14 , "Read ", "Program 15", PC_BY_PANEL_15 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=38 ", "Panel a ", "Modulation", " ", MODULATION , "Breath ", "Controller", BTH_CONTROLLER , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=39 ", "Panel b ", " ", " ", 0xFF , "Sustain ", "Pedal ", SUSTAIN_PEDAL , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=40 ", "Panel c ", "Panel ", "Scale ", PANEL_SCALE , "Panel ", "Transpose ", PANEL_TRANSPOSE, "Panel ", "Pitch ", PANEL_PITCH , }, }; From bf2c09ce79dc5e654312bc49954ad15163b73e0a Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sat, 20 Apr 2024 14:00:53 +0900 Subject: [PATCH 098/106] Implement panel functions (77) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 83df5b9..e3995bf 100644 --- a/README.md +++ b/README.md @@ -259,7 +259,7 @@ graph LR ![PRA32-U with Panel, Prototype 1](./pra32-u-with-panel-prototype-1.jpg) - Uncomment out `//#define PRA32_U_USE_CONTROL_PANEL` in "Digital-Synth-PRA32-U.ino" and modify options -- This option requires 3 tactile switches, 3 ADCs, and SSD1306 monochrome 128x64 OLED +- This option requires 3 tactile switches, 3 ADCs, and SSD1306 compatible monochrome 128x64 OLED Display - Tested with Seeed Studio's Grove Shield for Pi Pico, Buttons, Rotary Angle Sensors, and a OLED Display 0.96 inch - Inputs - SW0: Prev Key From 90931a9e7f95ca332b0d77647cec66757ff0c958 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sat, 20 Apr 2024 17:03:47 +0900 Subject: [PATCH 099/106] Implement panel functions (78) --- .../pra32-u-control-panel-page-table.h | 6 +- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 75 +++++-------------- 2 files changed, 24 insertions(+), 57 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h index b0a9ee4..fe72e57 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h @@ -3,6 +3,7 @@ const uint8_t PANEL_PITCH = 128 + 0; const uint8_t PANEL_SCALE = 128 + 1; const uint8_t PANEL_TRANSPOSE = 128 + 2; +const uint8_t PANEL_VELOCITY = 128 + 3; const uint8_t PC_BY_PANEL_0 = 128 + 64; const uint8_t PC_BY_PANEL_1 = 128 + 65; @@ -93,7 +94,8 @@ struct PRA32_U_ControlPanelPage { { "Page=35 ", "Read f ", "Read ", "Program 10", PC_BY_PANEL_10 , "Read ", "Program 11", PC_BY_PANEL_11 , "Panel ", "Pitch ", PANEL_PITCH , }, { "Page=36 ", "Read g ", "Read ", "Program 12", PC_BY_PANEL_12 , "Read ", "Program 13", PC_BY_PANEL_13 , "Panel ", "Pitch ", PANEL_PITCH , }, { "Page=37 ", "Read h ", "Read ", "Program 14", PC_BY_PANEL_14 , "Read ", "Program 15", PC_BY_PANEL_15 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=38 ", "Panel a ", "Modulation", " ", MODULATION , "Breath ", "Controller", BTH_CONTROLLER , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=39 ", "Panel b ", " ", " ", 0xFF , "Sustain ", "Pedal ", SUSTAIN_PEDAL , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=38 ", "Panel a ", "Modulation", " ", MODULATION , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=39 ", "Panel b ", "Breath ", "Controller", BTH_CONTROLLER , "Sustain ", "Pedal ", SUSTAIN_PEDAL , "Panel ", "Pitch ", PANEL_PITCH , }, { "Page=40 ", "Panel c ", "Panel ", "Scale ", PANEL_SCALE , "Panel ", "Transpose ", PANEL_TRANSPOSE, "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=41 ", "Panel b ", "Panel ", "Velocity ", PANEL_VELOCITY , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, }; diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index 312165c..c5dd37a 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -24,9 +24,6 @@ static uint32_t s_prev_key_current_value; static uint32_t s_next_key_current_value; static uint32_t s_play_key_current_value; -static volatile uint8_t s_panel_play_pitch_value = 60; -static volatile uint8_t s_panel_play_scale_value = 0; -static volatile uint8_t s_panel_play_transpose_value = 64; static volatile uint8_t s_panel_play_note_number = 60; static volatile uint8_t s_panel_playing_note_number = 0xFF; static volatile uint8_t s_reserved_note_off = 0xFF; @@ -112,16 +109,16 @@ static INLINE boolean PRA32_U_ControlPanel_process_reserved_note_off_on() { } static INLINE void PRA32_U_ControlPanel_update_pitch() { - int32_t new_note_number = s_panel_play_pitch_value; + int32_t new_note_number = g_synth.current_controller_value(PANEL_PITCH); - uint32_t index_scale = ((s_panel_play_scale_value * 4) + 127) / 254; + uint32_t index_scale = ((g_synth.current_controller_value(PANEL_SCALE) * 4) + 127) / 254; if (index_scale == 2) { const uint8_t ary_major[53] = { 48, 48, 48, 48, 48, 50, 50, 50, 50, 52, 52, 52, 53, 53, 53, 55, 55, 55, 55, 57, 57, 57, 57, 59, 59, 59, 60, 60, 60, 62, 62, 62, 62, 64, 64, 64, 65, 65, 65, 67, 67, 67, 67, 69, 69, 69, 69, 71, 71, 71, 72, 72, 72 }; - uint32_t index_pitch = (((s_panel_play_pitch_value + 3) * 2) + 1) / 5; + uint32_t index_pitch = (((g_synth.current_controller_value(PANEL_PITCH) + 3) * 2) + 1) / 5; new_note_number = ary_major[index_pitch]; } else if (index_scale == 1) { const uint8_t ary_pentatonic[53] = @@ -130,11 +127,11 @@ static INLINE void PRA32_U_ControlPanel_update_pitch() { 60, 60, 62, 62, 62, 62, 64, 64, 64, 64, 64, 67, 67, 67, 67, 67, 69, 69, 69, 69, 69, 72, 72, 72, 72, 72 }; - uint32_t index_pitch = (((s_panel_play_pitch_value + 3) * 2) + 1) / 5; + uint32_t index_pitch = (((g_synth.current_controller_value(PANEL_PITCH) + 3) * 2) + 1) / 5; new_note_number = ary_pentatonic[index_pitch]; } - new_note_number += s_panel_play_transpose_value - 64; + new_note_number += g_synth.current_controller_value(PANEL_TRANSPOSE) - 64; if (new_note_number < 0) { new_note_number = 0; } else if (new_note_number > 127) { @@ -164,14 +161,8 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe s_adc_control_value[adc_number] = adc_control_value_candidate; uint8_t current_controller_value = s_adc_control_value[adc_number]; - if (s_adc_control_target[adc_number] <= 0x7F) { + if (s_adc_control_target[adc_number] < 128 + 64) { current_controller_value = g_synth.current_controller_value(s_adc_control_target[adc_number]); - } else if (s_adc_control_target[adc_number] == PANEL_PITCH) { - current_controller_value = s_panel_play_pitch_value; - } else if (s_adc_control_target[adc_number] == PANEL_SCALE) { - current_controller_value = s_panel_play_scale_value; - } else if (s_adc_control_target[adc_number] == PANEL_TRANSPOSE) { - current_controller_value = s_panel_play_transpose_value; } if ((s_adc_control_value_old <= current_controller_value) && @@ -184,10 +175,17 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe s_adc_control_catched[adc_number] = true; } - if (s_adc_control_target[adc_number] <= 0x7F) { + if (s_adc_control_target[adc_number] < 128) { if (s_adc_control_catched[adc_number]) { g_synth.control_change(s_adc_control_target[adc_number], s_adc_control_value[adc_number]); } + } else if ((s_adc_control_target[adc_number] == PANEL_PITCH) || + (s_adc_control_target[adc_number] == PANEL_SCALE) || + (s_adc_control_target[adc_number] == PANEL_TRANSPOSE)) { + if (s_adc_control_catched[adc_number]) { + g_synth.control_change(s_adc_control_target[adc_number], s_adc_control_value[adc_number]); + PRA32_U_ControlPanel_update_pitch(); + } } else if ((s_adc_control_target[adc_number] >= PC_BY_PANEL_0) && (s_adc_control_target[adc_number] <= PC_BY_PANEL_15)) { if ((s_adc_control_value_old < 64) && (s_adc_control_value[adc_number] >= 64)) { g_synth.program_change(s_adc_control_target[adc_number] - PC_BY_PANEL_0); @@ -203,21 +201,6 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe g_synth.write_parameters_to_program(program_number_to_write); s_ready_to_write[program_number_to_write] = false; } - } else if (s_adc_control_target[adc_number] == PANEL_PITCH) { - if (s_adc_control_catched[adc_number]) { - s_panel_play_pitch_value = s_adc_control_value[adc_number]; - PRA32_U_ControlPanel_update_pitch(); - } - } else if (s_adc_control_target[adc_number] == PANEL_SCALE) { - if (s_adc_control_catched[adc_number]) { - s_panel_play_scale_value = s_adc_control_value[adc_number]; - PRA32_U_ControlPanel_update_pitch(); - } - } else if (s_adc_control_target[adc_number] == PANEL_TRANSPOSE) { - if (s_adc_control_catched[adc_number]) { - s_panel_play_transpose_value = s_adc_control_value[adc_number]; - PRA32_U_ControlPanel_update_pitch(); - } } return true; @@ -432,7 +415,7 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta break; case PANEL_PITCH : { - uint32_t index_scale = ((s_panel_play_scale_value * 4) + 127) / 254; + uint32_t index_scale = ((g_synth.current_controller_value(PANEL_SCALE) * 4) + 127) / 254; if (index_scale == 0) { char ary[12][5] = { " C", "C#", " D", "D#", " E", " F", "F#", " G", "G#", " A", "A#", " B" }; @@ -453,7 +436,7 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta " G3", " G3", " G3", " G3", " A3", " A3", " A3", " A3", " B3", " B3", " B3", " C4", " C4", " C4", " D4", " D4", " D4", " D4", " E4", " E4", " E4", " F4", " F4", " F4", " G4", " G4", " G4", " G4", " A4", " A4", " A4", " A4", " B4", " B4", " B4", " C5", " C5", " C5" }; - uint32_t index = (((s_panel_play_pitch_value + 3) * 2) + 1) / 5; + uint32_t index = (((g_synth.current_controller_value(PANEL_PITCH) + 3) * 2) + 1) / 5; std::strcpy(value_display_text, ary_major[index]); } else if (index_scale == 1) { char ary_pentatonic[53][5] = @@ -461,7 +444,7 @@ static INLINE boolean PRA32_U_ControlPanel_calc_value_display(uint8_t control_ta " G3", " G3", " G3", " G3", " A3", " A3", " A3", " A3", " A3", " C4", " C4", " C4", " C4", " C4", " D4", " D4", " D4", " D4", " E4", " E4", " E4", " E4", " E4", " G4", " G4", " G4", " G4", " G4", " A4", " A4", " A4", " A4", " A4", " C4", " C5", " C5", " C5", " C5" }; - uint32_t index = (((s_panel_play_pitch_value + 3) * 2) + 1) / 5; + uint32_t index = (((g_synth.current_controller_value(PANEL_PITCH) + 3) * 2) + 1) / 5; std::strcpy(value_display_text, ary_pentatonic[index]); } @@ -733,14 +716,8 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { if (adc_control_target_0 < 0xFF) { uint8_t adc_control_value = s_adc_control_value[0]; uint8_t current_controller_value = adc_control_value; - if (adc_control_target_0 <= 0x7F) { + if (adc_control_target_0 < 128 + 64) { current_controller_value = g_synth.current_controller_value(adc_control_target_0); - } else if (adc_control_target_0 == PANEL_PITCH) { - current_controller_value = s_panel_play_pitch_value; - } else if (adc_control_target_0 == PANEL_SCALE) { - current_controller_value = s_panel_play_scale_value; - } else if (adc_control_target_0 == PANEL_TRANSPOSE) { - current_controller_value = s_panel_play_transpose_value; } s_display_buffer[7][ 0] = 'A'; @@ -772,14 +749,8 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { if (adc_control_target_1 < 0xFF) { uint8_t adc_control_value = s_adc_control_value[1]; uint8_t current_controller_value = adc_control_value; - if (adc_control_target_1 <= 0x7F) { + if (adc_control_target_1 < 128 + 64) { current_controller_value = g_synth.current_controller_value(adc_control_target_1); - } else if (adc_control_target_1 == PANEL_PITCH) { - current_controller_value = s_panel_play_pitch_value; - } else if (adc_control_target_1 == PANEL_SCALE) { - current_controller_value = s_panel_play_scale_value; - } else if (adc_control_target_1 == PANEL_TRANSPOSE) { - current_controller_value = s_panel_play_transpose_value; } s_display_buffer[7][11] = 'B'; @@ -811,14 +782,8 @@ INLINE void PRA32_U_ControlPanel_update_display_buffer(uint32_t loop_counter) { if (adc_control_target_2 < 0xFF) { uint8_t adc_control_value = s_adc_control_value[2]; uint8_t current_controller_value = adc_control_value; - if (adc_control_target_2 <= 0x7F) { + if (adc_control_target_2 < 128+64) { current_controller_value = g_synth.current_controller_value(adc_control_target_2); - } else if (adc_control_target_2 == PANEL_PITCH) { - current_controller_value = s_panel_play_pitch_value; - } else if (adc_control_target_2 == PANEL_SCALE) { - current_controller_value = s_panel_play_scale_value; - } else if (adc_control_target_2 == PANEL_TRANSPOSE) { - current_controller_value = s_panel_play_transpose_value; } s_display_buffer[3][11] = 'C'; From 03ac5dbf0c65cc7986fb850a8435371e6020acc4 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sat, 20 Apr 2024 17:13:04 +0900 Subject: [PATCH 100/106] Implement panel functions (79) --- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index c5dd37a..fea4e80 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -90,7 +90,12 @@ static INLINE uint8_t PRA32_U_ControlPanel_adc_control_value_candidate(uint32_t static INLINE boolean PRA32_U_ControlPanel_process_reserved_note_off_on() { if (s_reserved_note_on <= 127) { - g_synth.note_on(s_reserved_note_on, 100); + uint8_t velocity = g_synth.current_controller_value(PANEL_VELOCITY); + if (velocity == 0) { + velocity = 1; + } + + g_synth.note_on(s_reserved_note_on, velocity); s_panel_playing_note_number = s_reserved_note_on; s_reserved_note_on = 0xFF; return true; @@ -175,16 +180,16 @@ static INLINE boolean PRA32_U_ControlPanel_update_control_adc(uint32_t adc_numbe s_adc_control_catched[adc_number] = true; } - if (s_adc_control_target[adc_number] < 128) { + if ((s_adc_control_target[adc_number] == PANEL_PITCH) || + (s_adc_control_target[adc_number] == PANEL_SCALE) || + (s_adc_control_target[adc_number] == PANEL_TRANSPOSE)) { if (s_adc_control_catched[adc_number]) { g_synth.control_change(s_adc_control_target[adc_number], s_adc_control_value[adc_number]); + PRA32_U_ControlPanel_update_pitch(); } - } else if ((s_adc_control_target[adc_number] == PANEL_PITCH) || - (s_adc_control_target[adc_number] == PANEL_SCALE) || - (s_adc_control_target[adc_number] == PANEL_TRANSPOSE)) { + } else if (s_adc_control_target[adc_number] < 128 + 64) { if (s_adc_control_catched[adc_number]) { g_synth.control_change(s_adc_control_target[adc_number], s_adc_control_value[adc_number]); - PRA32_U_ControlPanel_update_pitch(); } } else if ((s_adc_control_target[adc_number] >= PC_BY_PANEL_0) && (s_adc_control_target[adc_number] <= PC_BY_PANEL_15)) { if ((s_adc_control_value_old < 64) && (s_adc_control_value[adc_number] >= 64)) { From 05f26c2be8163f021e8f7ef77991fef9f3e77853 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 21 Apr 2024 09:13:37 +0900 Subject: [PATCH 101/106] Implement panel functions (80) --- .../Digital-Synth-PRA32-U.ino | 4 + .../pra32-u-control-panel-page-table.h | 87 ++++++++++--------- Digital-Synth-PRA32-U/pra32-u-control-panel.h | 9 ++ PRA32-U-MIDI-Implementation-Chart.md | 11 ++- README.md | 1 + 5 files changed, 67 insertions(+), 45 deletions(-) diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 2be4ac7..4b50d57 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -2,6 +2,8 @@ * Digital Synth PRA32-U */ +#define PRA32_U_VERSION "v2.2.2 " + //#define PRA32_U_USE_DEBUG_PRINT // Serial1 #define PRA32_U_USE_USB_MIDI // Select USB Stack: "Adafruit TinyUSB" in the Arduino IDE "Tools" menu @@ -244,6 +246,8 @@ void __not_in_flash_func(setup)() { g_synth.initialize(); + PRA32_U_ControlPanel_initialize_parameters(); + delay(100); } diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h index fe72e57..5640457 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel-page-table.h @@ -41,7 +41,7 @@ const uint8_t WR_BY_PANEL_13 = 128 + 93; const uint8_t WR_BY_PANEL_14 = 128 + 94; const uint8_t WR_BY_PANEL_15 = 128 + 95; -const uint8_t PAGE_INDEX_DEFAULT = 6; +const uint8_t PAGE_INDEX_DEFAULT = 7; struct PRA32_U_ControlPanelPage { char page_name_line_0 [10 + 1]; @@ -56,46 +56,47 @@ struct PRA32_U_ControlPanelPage { char control_target_c_name_line_1[10 + 1]; uint8_t control_target_c; } g_control_panel_page_table[] = { - { "Page= 0 ", "Voice a ", "Voice ", "Mode ", VOICE_MODE , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page= 1 ", "Voice b ", "Portamento", " ", PORTAMENTO , "Pitch ", "Bend Range", P_BEND_RANGE , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page= 2 ", "Osc a ", "Osc 1 ", "Wave ", OSC_1_WAVE , "Mixer ", "Noise/Sub ", MIXER_SUB_OSC , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page= 3 ", "Osc b ", "Osc 1 ", "Shape ", OSC_1_SHAPE , "Osc 1 ", "Morph ", OSC_1_MORPH , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page= 4 ", "Osc c ", "Osc 2 ", "Wave ", OSC_2_WAVE , "Mixer ", "Osc Mix ", MIXER_OSC_MIX , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page= 5 ", "Osc d ", "Osc 2 ", "Coarse ", OSC_2_COARSE , "Osc 2 ", "Pitch ", OSC_2_PITCH , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page= 6 ", "Filter a ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page= 7 ", "Filter b ", "Filter ", "EG Amt ", FILTER_EG_AMT , "Filter ", "Key Track ", FILTER_KEY_TRK , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page= 8 ", "Filter c ", "Filter ", "Mode ", FILTER_MODE , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page= 9 ", "EG a ", "EG ", "Attack ", EG_ATTACK , "EG ", "Decay ", EG_DECAY , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=10 ", "EG b ", "EG ", "Sustain ", EG_SUSTAIN , "EG ", "Release ", EG_RELEASE , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=11 ", "EG c ", "EG ", "Amp Mod ", EG_AMP_MOD , "Release ", "= Decay ", REL_EQ_DECAY , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=12 ", "EG d ", "EG ", "Osc Amt ", EG_OSC_AMT , "EG ", "Osc Dst ", EG_OSC_DST , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=13 ", "EG e ", " ", " ", 0xFF , "EG ", "Velo Sens ", EG_VEL_SENS , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=14 ", "Amp a ", "Amp ", "Attack ", AMP_ATTACK , "Amp ", "Decay ", AMP_DECAY , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=15 ", "Amp c ", "Amp ", "Sustain ", AMP_SUSTAIN , "Amp ", "Release ", AMP_RELEASE , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=16 ", "Amp b ", "Amp ", "Gain ", AMP_GAIN , "Amp ", "Velo Sens ", AMP_VEL_SENS , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=17 ", "LFO a ", "LFO ", "Wave ", LFO_WAVE , "LFO ", "Fade Time ", LFO_FADE_TIME , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=18 ", "LFO b ", "LFO ", "Rate ", LFO_RATE , "LFO ", "Depth ", LFO_DEPTH , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=19 ", "LFO c ", "LFO ", "Osc Amt ", LFO_OSC_AMT , "LFO ", "Osc Dst ", LFO_OSC_DST , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=20 ", "LFO d ", "LFO ", "Filter Amt", LFO_FILTER_AMT , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=21 ", "Breath ", "Breath ", "Filter Amt", BTH_FILTER_AMT , "Breath ", "Amp Mod ", BTH_AMP_MOD , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=22 ", "Chorus a ", "Chorus ", "Mix ", CHORUS_MIX , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=23 ", "Chorus b ", "Chorus ", "Rate ", CHORUS_RATE , "Chorus ", "Depth ", CHORUS_DEPTH , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=24 ", "Delay a ", "Delay ", "Feedback ", DELAY_FEEDBACK , "Delay ", "Time ", DELAY_TIME , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=25 ", "Delay b ", "Delay ", "Mode ", DELAY_MODE , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=26 ", "Write a ", "Write ", "Program 8", WR_BY_PANEL_8 , "Write ", "Program 9", WR_BY_PANEL_9 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=27 ", "Write b ", "Write ", "Program 10", WR_BY_PANEL_10 , "Write ", "Program 11", WR_BY_PANEL_11 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=28 ", "Write c ", "Write ", "Program 12", WR_BY_PANEL_12 , "Write ", "Program 13", WR_BY_PANEL_13 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=29 ", "Write d ", "Write ", "Program 14", WR_BY_PANEL_14 , "Write ", "Program 15", WR_BY_PANEL_15 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=30 ", "Read a ", "Read ", "Program 0", PC_BY_PANEL_0 , "Read ", "Program 1", PC_BY_PANEL_1 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=31 ", "Read b ", "Read ", "Program 2", PC_BY_PANEL_2 , "Read ", "Program 3", PC_BY_PANEL_3 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=32 ", "Read c ", "Read ", "Program 4", PC_BY_PANEL_4 , "Read ", "Program 5", PC_BY_PANEL_5 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=33 ", "Read d ", "Read ", "Program 6", PC_BY_PANEL_6 , "Read ", "Program 7", PC_BY_PANEL_7 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=34 ", "Read e ", "Read ", "Program 8", PC_BY_PANEL_8 , "Read ", "Program 9", PC_BY_PANEL_9 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=35 ", "Read f ", "Read ", "Program 10", PC_BY_PANEL_10 , "Read ", "Program 11", PC_BY_PANEL_11 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=36 ", "Read g ", "Read ", "Program 12", PC_BY_PANEL_12 , "Read ", "Program 13", PC_BY_PANEL_13 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=37 ", "Read h ", "Read ", "Program 14", PC_BY_PANEL_14 , "Read ", "Program 15", PC_BY_PANEL_15 , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=38 ", "Panel a ", "Modulation", " ", MODULATION , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=39 ", "Panel b ", "Breath ", "Controller", BTH_CONTROLLER , "Sustain ", "Pedal ", SUSTAIN_PEDAL , "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=40 ", "Panel c ", "Panel ", "Scale ", PANEL_SCALE , "Panel ", "Transpose ", PANEL_TRANSPOSE, "Panel ", "Pitch ", PANEL_PITCH , }, - { "Page=41 ", "Panel b ", "Panel ", "Velocity ", PANEL_VELOCITY , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 0 ", "Info ", "PRA32-U ", "with Panel", 0xFF , " ",PRA32_U_VERSION, 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 1 ", "Voice a ", "Voice ", "Mode ", VOICE_MODE , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 2 ", "Voice b ", "Portamento", " ", PORTAMENTO , "Pitch ", "Bend Range", P_BEND_RANGE , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 3 ", "Osc a ", "Osc 1 ", "Wave ", OSC_1_WAVE , "Mixer ", "Noise/Sub ", MIXER_SUB_OSC , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 4 ", "Osc b ", "Osc 1 ", "Shape ", OSC_1_SHAPE , "Osc 1 ", "Morph ", OSC_1_MORPH , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 5 ", "Osc c ", "Osc 2 ", "Wave ", OSC_2_WAVE , "Mixer ", "Osc Mix ", MIXER_OSC_MIX , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 6 ", "Osc d ", "Osc 2 ", "Coarse ", OSC_2_COARSE , "Osc 2 ", "Pitch ", OSC_2_PITCH , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 7 ", "Filter a ", "Filter ", "Cutoff ", FILTER_CUTOFF , "Filter ", "Resonance ", FILTER_RESO , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 8 ", "Filter b ", "Filter ", "EG Amt ", FILTER_EG_AMT , "Filter ", "Key Track ", FILTER_KEY_TRK , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page= 9 ", "Filter c ", " ", " ", 0xFF , "Filter ", "Mode ", FILTER_MODE , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=10 ", "EG a ", "EG ", "Attack ", EG_ATTACK , "EG ", "Decay ", EG_DECAY , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=11 ", "EG b ", "EG ", "Sustain ", EG_SUSTAIN , "EG ", "Release ", EG_RELEASE , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=12 ", "EG c ", "EG ", "Amp Mod ", EG_AMP_MOD , "Release ", "= Decay ", REL_EQ_DECAY , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=13 ", "EG d ", "EG ", "Osc Amt ", EG_OSC_AMT , "EG ", "Osc Dst ", EG_OSC_DST , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=14 ", "EG e ", " ", " ", 0xFF , "EG ", "Velo Sens ", EG_VEL_SENS , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=15 ", "Amp a ", "Amp ", "Attack ", AMP_ATTACK , "Amp ", "Decay ", AMP_DECAY , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=16 ", "Amp c ", "Amp ", "Sustain ", AMP_SUSTAIN , "Amp ", "Release ", AMP_RELEASE , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=17 ", "Amp b ", "Amp ", "Gain ", AMP_GAIN , "Amp ", "Velo Sens ", AMP_VEL_SENS , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=18 ", "LFO a ", "LFO ", "Wave ", LFO_WAVE , "LFO ", "Fade Time ", LFO_FADE_TIME , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=19 ", "LFO b ", "LFO ", "Rate ", LFO_RATE , "LFO ", "Depth ", LFO_DEPTH , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=20 ", "LFO c ", "LFO ", "Osc Amt ", LFO_OSC_AMT , "LFO ", "Osc Dst ", LFO_OSC_DST , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=21 ", "LFO d ", "LFO ", "Filter Amt", LFO_FILTER_AMT , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=22 ", "Breath ", "Breath ", "Filter Amt", BTH_FILTER_AMT , "Breath ", "Amp Mod ", BTH_AMP_MOD , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=23 ", "Chorus a ", "Chorus ", "Mix ", CHORUS_MIX , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=24 ", "Chorus b ", "Chorus ", "Rate ", CHORUS_RATE , "Chorus ", "Depth ", CHORUS_DEPTH , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=25 ", "Delay a ", "Delay ", "Feedback ", DELAY_FEEDBACK , "Delay ", "Time ", DELAY_TIME , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=26 ", "Delay b ", "Delay ", "Mode ", DELAY_MODE , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=27 ", "Write a ", "Write ", "Program 8", WR_BY_PANEL_8 , "Write ", "Program 9", WR_BY_PANEL_9 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=28 ", "Write b ", "Write ", "Program 10", WR_BY_PANEL_10 , "Write ", "Program 11", WR_BY_PANEL_11 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=29 ", "Write c ", "Write ", "Program 12", WR_BY_PANEL_12 , "Write ", "Program 13", WR_BY_PANEL_13 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=30 ", "Write d ", "Write ", "Program 14", WR_BY_PANEL_14 , "Write ", "Program 15", WR_BY_PANEL_15 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=31 ", "Read a ", "Read ", "Program 0", PC_BY_PANEL_0 , "Read ", "Program 1", PC_BY_PANEL_1 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=32 ", "Read b ", "Read ", "Program 2", PC_BY_PANEL_2 , "Read ", "Program 3", PC_BY_PANEL_3 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=33 ", "Read c ", "Read ", "Program 4", PC_BY_PANEL_4 , "Read ", "Program 5", PC_BY_PANEL_5 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=34 ", "Read d ", "Read ", "Program 6", PC_BY_PANEL_6 , "Read ", "Program 7", PC_BY_PANEL_7 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=35 ", "Read e ", "Read ", "Program 8", PC_BY_PANEL_8 , "Read ", "Program 9", PC_BY_PANEL_9 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=36 ", "Read f ", "Read ", "Program 10", PC_BY_PANEL_10 , "Read ", "Program 11", PC_BY_PANEL_11 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=37 ", "Read g ", "Read ", "Program 12", PC_BY_PANEL_12 , "Read ", "Program 13", PC_BY_PANEL_13 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=38 ", "Read h ", "Read ", "Program 14", PC_BY_PANEL_14 , "Read ", "Program 15", PC_BY_PANEL_15 , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=39 ", "Panel a ", "Modulation", " ", MODULATION , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=40 ", "Panel b ", "Breath ", "Controller", BTH_CONTROLLER , "Sustain ", "Pedal ", SUSTAIN_PEDAL , "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=41 ", "Panel c ", "Panel ", "Scale ", PANEL_SCALE , "Panel ", "Transpose ", PANEL_TRANSPOSE, "Panel ", "Pitch ", PANEL_PITCH , }, + { "Page=42 ", "Panel b ", "Panel ", "Velocity ", PANEL_VELOCITY , " ", " ", 0xFF , "Panel ", "Pitch ", PANEL_PITCH , }, }; diff --git a/Digital-Synth-PRA32-U/pra32-u-control-panel.h b/Digital-Synth-PRA32-U/pra32-u-control-panel.h index fea4e80..bfb0f1d 100644 --- a/Digital-Synth-PRA32-U/pra32-u-control-panel.h +++ b/Digital-Synth-PRA32-U/pra32-u-control-panel.h @@ -518,6 +518,15 @@ INLINE void PRA32_U_ControlPanel_setup() { #endif // defined(PRA32_U_USE_CONTROL_PANEL) } +INLINE void PRA32_U_ControlPanel_initialize_parameters() { +#if defined(PRA32_U_USE_CONTROL_PANEL) + g_synth.control_change(PANEL_PITCH , 64 ); + g_synth.control_change(PANEL_SCALE , 127); + g_synth.control_change(PANEL_TRANSPOSE , 64 ); + g_synth.control_change(PANEL_VELOCITY , 100); +#endif // defined(PRA32_U_USE_CONTROL_PANEL) +} + INLINE void PRA32_U_ControlPanel_update_analog_inputs(uint32_t loop_counter) { static_cast(loop_counter); diff --git a/PRA32-U-MIDI-Implementation-Chart.md b/PRA32-U-MIDI-Implementation-Chart.md index 6671b77..17dbff8 100644 --- a/PRA32-U-MIDI-Implementation-Chart.md +++ b/PRA32-U-MIDI-Implementation-Chart.md @@ -88,11 +88,18 @@ | | | | | | 87 | x | o | Program Number to Write to $$$$ | | 106 | x | o | Write Parameters to Program $$$$ | -| 112-119 | | | Program Change #8-15 by CC | +| 112 | | | Program Change #8 by CC | +| 113 | | | Program Change #9 by CC | +| 114 | | | Program Change #10 by CC | +| 115 | | | Program Change #11 by CC | +| 116 | | | Program Change #12 by CC | +| 117 | | | Program Change #13 by CC | +| 118 | | | Program Change #14 by CC | +| 119 | | | Program Change #15 by CC | | 111 | x | x | [Reserved] | +-------------------------------+---------------+---------------+-------------------------------------+ | Program | x | o | | -| Change : True # | ************* | 0-15 | Default 0 | +| Change : True # | ************* | 0-15 | Default 8 | +-------------------------------+---------------+---------------+-------------------------------------+ | System Exclusive | x | x | | +-------------------------------+---------------+---------------+-------------------------------------+ diff --git a/README.md b/README.md index e3995bf..dae7c34 100644 --- a/README.md +++ b/README.md @@ -275,6 +275,7 @@ graph LR - Major Pentatonic, 2 octaves - Major, 2 octaves - Panel Transpose [-|+] + - Panel Velocity - Other Operations - Write Program 8-15: Change the value from 0 [Rdy] to 127 [Exe] - Read Program 1-7, 8-15: Change the value from 0-63 [Rdy] to 64-127 [Exe] From fb60e430ef03f16fbc7175dffdf1d02e54860329 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 21 Apr 2024 09:26:05 +0900 Subject: [PATCH 102/106] Implement panel functions (81) --- Digital-Synth-PRA32-U/pra32-u-synth.h | 16 +++++++++------- PRA32-U-Change-History.md | 1 + 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Digital-Synth-PRA32-U/pra32-u-synth.h b/Digital-Synth-PRA32-U/pra32-u-synth.h index f61bd57..1d2d427 100644 --- a/Digital-Synth-PRA32-U/pra32-u-synth.h +++ b/Digital-Synth-PRA32-U/pra32-u-synth.h @@ -567,7 +567,7 @@ class PRA32_U_Synth { } } - void all_sound_off() { + void all_notes_off() { m_sustain_pedal = false; m_note_on_number[0] = NOTE_NUMBER_INVALID; m_note_on_number[1] = NOTE_NUMBER_INVALID; @@ -594,13 +594,15 @@ class PRA32_U_Synth { m_eg[5].note_off(); m_eg[6].note_off(); m_eg[7].note_off(); + + control_change(SUSTAIN_PEDAL , 0 ); } INLINE void reset_all_controllers() { pitch_bend(0, 64); - set_modulation(0); - set_breath_controller(0); - set_sustain_pedal(0); + control_change(MODULATION , 0 ); + control_change(BTH_CONTROLLER , 0 ); + control_change(SUSTAIN_PEDAL , 0 ); } /* INLINE */ void control_change(uint8_t control_number, uint8_t controller_value) { @@ -840,11 +842,11 @@ class PRA32_U_Synth { case OMNI_MODE_ON : case MONO_MODE_ON : case POLY_MODE_ON : - all_sound_off(); // Strictly speaking, this is a violation of MIDI 1.0 Specification... + all_notes_off(); // Strictly speaking, this is a violation of MIDI 1.0 Specification... break; case ALL_SOUND_OFF : - all_sound_off(); + all_notes_off(); break; case RESET_ALL_CTRLS: @@ -1234,7 +1236,7 @@ class PRA32_U_Synth { #endif if (m_voice_mode != new_voice_mode) { m_voice_mode = new_voice_mode; - all_sound_off(); + all_notes_off(); m_osc.set_gate_enabled(m_voice_mode == VOICE_PARAPHONIC); } } diff --git a/PRA32-U-Change-History.md b/PRA32-U-Change-History.md index 47203fa..8e32cea 100644 --- a/PRA32-U-Change-History.md +++ b/PRA32-U-Change-History.md @@ -7,6 +7,7 @@ - Add the option PRA32-U with Panel, Prototype 1 (experimental) - Change the default program #0 to #8 - Use core 1 for Debug Print + - Other changes - Tested with Arduino-Pico version 3.7.2 - v2.2.2 (2024-02-10): - Fix a bug that the parameters are not written to the flash when using I2S DAC, even if PRA32_U_I2S_DAC_MUTE_OFF_PIN is defined From 22f2998e09f7e5b6145ef4e4d61c8482a234f739 Mon Sep 17 00:00:00 2001 From: Ryo Ishigaki Date: Sun, 21 Apr 2024 09:31:56 +0900 Subject: [PATCH 103/106] v2.3.0 --- .../Digital-Synth-PRA32-U.ino | 2 +- PRA32-U-Change-History.md | 2 +- PRA32-U-MIDI-Implementation-Chart.md | 4 ++-- PRA32-U-Parameter-Guide.md | 4 ++-- README.md | 10 +++++----- ...-PRA32-U-2.2.2-Pimoroni-Pico-Audio-Pack.uf2 | Bin 522240 -> 0 bytes ...-PRA32-U-2.3.0-Pimoroni-Pico-Audio-Pack.uf2 | Bin 0 -> 502784 bytes pra32-u-ctrl.html | 2 +- pra32-u-prog-preset.json | 2 +- pra32-u-prog-sample-saw-pulse.json | 2 +- pra32-u-prog-sample-sine-pm-piano.json | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) delete mode 100644 bin/Digital-Synth-PRA32-U-2.2.2-Pimoroni-Pico-Audio-Pack.uf2 create mode 100644 bin/Digital-Synth-PRA32-U-2.3.0-Pimoroni-Pico-Audio-Pack.uf2 diff --git a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino index 4b50d57..6e87d8c 100644 --- a/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino +++ b/Digital-Synth-PRA32-U/Digital-Synth-PRA32-U.ino @@ -2,7 +2,7 @@ * Digital Synth PRA32-U */ -#define PRA32_U_VERSION "v2.2.2 " +#define PRA32_U_VERSION "v2.3.0 " //#define PRA32_U_USE_DEBUG_PRINT // Serial1 diff --git a/PRA32-U-Change-History.md b/PRA32-U-Change-History.md index 8e32cea..955d266 100644 --- a/PRA32-U-Change-History.md +++ b/PRA32-U-Change-History.md @@ -1,6 +1,6 @@ ## Digital Synth PRA32-U Change History -- v2.3.0 (2024-04-**): +- v2.3.0 (2024-04-21): - Allow user programs to be written to the flash when using I2S DAC without mute-off pin - Add the option to write user programs to the flash when using PWM audio (for Raspberry Pi Pico/H/W/WH) - Add the option PRA32_U_I2S_SWAP_LEFT_AND_RIGHT diff --git a/PRA32-U-MIDI-Implementation-Chart.md b/PRA32-U-MIDI-Implementation-Chart.md index 17dbff8..80a72d1 100644 --- a/PRA32-U-MIDI-Implementation-Chart.md +++ b/PRA32-U-MIDI-Implementation-Chart.md @@ -1,6 +1,6 @@ ``` - [Polyphonic/Paraphonic Synthesizer] Date: 2024-02-10 - Model: Digital Synth PRA32-U MIDI Implementation Chart Version: 2.2.2 + [Polyphonic/Paraphonic Synthesizer] Date: 2024-04-21 + Model: Digital Synth PRA32-U MIDI Implementation Chart Version: 2.3.0 +-------------------------------+---------------+---------------+-------------------------------------+ | Function... | Transmitted | Recognized | Remarks | +-------------------------------+---------------+---------------+-------------------------------------+ diff --git a/PRA32-U-Parameter-Guide.md b/PRA32-U-Parameter-Guide.md index 10ef168..e7f8a70 100644 --- a/PRA32-U-Parameter-Guide.md +++ b/PRA32-U-Parameter-Guide.md @@ -1,6 +1,6 @@ -# Digital Synth PRA32-U Parameter Guide v2.2.2 +# Digital Synth PRA32-U Parameter Guide v2.3.0 -- 2024-02-10 ISGK Instruments +- 2024-04-21 ISGK Instruments - ## Control Change Parameters diff --git a/README.md b/README.md index dae7c34..91e0c07 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Digital Synth PRA32-U v2.2.2 +# Digital Synth PRA32-U v2.3.0 -- 2024-02-10 ISGK Instruments +- 2024-04-21 ISGK Instruments - @@ -14,7 +14,7 @@ - An **I2S DAC** hardware (e.g. Pimoroni Pico Audio Pack) is required - PWM Audio can also be used instead of I2S (PWM Audio does not require an I2S DAC hardware) - Prebuilt UF2 files ("bin") - - "Digital-Synth-PRA32-U-2.2.2-Pimoroni-Pico-Audio-Pack.uf2" is for Raspberry Pi Pico and Pimoroni Pico Audio Pack + - "Digital-Synth-PRA32-U-2.3.0-Pimoroni-Pico-Audio-Pack.uf2" is for Raspberry Pi Pico and Pimoroni Pico Audio Pack ## [Change History](/PRA32-U-Change-History.md) @@ -286,11 +286,11 @@ graph LR ![CC0](http://i.creativecommons.org/p/zero/1.0/88x31.png) -**Digital Synth PRA32-U v2.2.2 by ISGK Instruments (Ryo Ishigaki)** +**Digital Synth PRA32-U v2.3.0 by ISGK Instruments (Ryo Ishigaki)** To the extent possible under law, ISGK Instruments (Ryo Ishigaki) has waived all copyright and related or neighboring rights -to Digital Synth PRA32-U v2.2.2. +to Digital Synth PRA32-U v2.3.0. You should have received a copy of the CC0 legalcode along with this work. If not, see . diff --git a/bin/Digital-Synth-PRA32-U-2.2.2-Pimoroni-Pico-Audio-Pack.uf2 b/bin/Digital-Synth-PRA32-U-2.2.2-Pimoroni-Pico-Audio-Pack.uf2 deleted file mode 100644 index 0af2334f56fb2585a5f4453ae3b6ebe86d6bf172..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 522240 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 diff --git a/bin/Digital-Synth-PRA32-U-2.3.0-Pimoroni-Pico-Audio-Pack.uf2 b/bin/Digital-Synth-PRA32-U-2.3.0-Pimoroni-Pico-Audio-Pack.uf2 new file mode 100644 index 0000000000000000000000000000000000000000..3e64e06ea6df4a6410f8c59992b06020bed82d79 GIT binary patch literal 502784 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