From 4c959c6608b9fd18d7858b3e6d93b11d907a21c7 Mon Sep 17 00:00:00 2001 From: Paul Freund Date: Thu, 23 Nov 2023 02:33:28 +0100 Subject: [PATCH 1/8] Fix #741 and #743 - Horizontal encoder button in Grid mode (#748) --- src/deluge/gui/views/session_view.cpp | 38 ++++++++++++++++++++------- src/deluge/gui/views/session_view.h | 2 +- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/deluge/gui/views/session_view.cpp b/src/deluge/gui/views/session_view.cpp index ed9e9aeab5..0ba541e916 100644 --- a/src/deluge/gui/views/session_view.cpp +++ b/src/deluge/gui/views/session_view.cpp @@ -128,6 +128,7 @@ bool SessionView::opened() { } void SessionView::focusRegained() { + horizontalEncoderPressed = false; selectLayout(0); // Make sure we get a valid layout from the loaded file bool doingRender = (currentUIMode != UI_MODE_ANIMATION_FADE); @@ -360,6 +361,28 @@ ActionResult SessionView::buttonAction(deluge::hid::Button b, bool on, bool inCa return ActionResult::NOT_DEALT_WITH; // Make the MatrixDriver do its normal thing with it too } + // Overwrite to allow not showing zoom level in grid + else if (b == X_ENC) { + horizontalEncoderPressed = on; + if (on) { + // Show current zoom level + if (isNoUIModeActive() && (currentSong->sessionLayout != SessionLayoutType::SessionLayoutTypeGrid)) { + displayZoomLevel(); + } + + enterUIMode(UI_MODE_HOLDING_HORIZONTAL_ENCODER_BUTTON); + } + + else { + if (isUIModeActive(UI_MODE_HOLDING_HORIZONTAL_ENCODER_BUTTON)) { + if (currentSong->sessionLayout != SessionLayoutType::SessionLayoutTypeGrid) { + display->cancelPopup(); + } + exitUIMode(UI_MODE_HOLDING_HORIZONTAL_ENCODER_BUTTON); + } + } + } + // If save / delete button pressed, delete the Clip! else if (b == SAVE && (currentUIMode == UI_MODE_CLIP_PRESSED_IN_SONG_VIEW || gridFirstPadActive())) { if (on) { @@ -3525,7 +3548,7 @@ ActionResult SessionView::gridHandlePadsLaunchWithSelection(int32_t x, int32_t y void SessionView::gridHandlePadsLaunchToggleArming(Clip* clip, bool immediate) { if (immediate) { - if (currentUIMode == UI_MODE_HOLDING_HORIZONTAL_ENCODER_BUTTON) { + if (horizontalEncoderPressed) { session.soloClipAction(clip, kInternalButtonPressLatency); } else { @@ -3533,7 +3556,10 @@ void SessionView::gridHandlePadsLaunchToggleArming(Clip* clip, bool immediate) { } } else { - if (currentUIMode == UI_MODE_VIEWING_RECORD_ARMING) { + if (horizontalEncoderPressed) { + session.soloClipAction(clip, kInternalButtonPressLatency); + } + else if (currentUIMode == UI_MODE_VIEWING_RECORD_ARMING) { // Here I removed the overdubbing settings clip->armedForRecording = !clip->armedForRecording; PadLEDs::reassessGreyout(true); @@ -3546,18 +3572,10 @@ void SessionView::gridHandlePadsLaunchToggleArming(Clip* clip, bool immediate) { || currentUIMode == UI_MODE_STUTTERING)) { gridToggleClipPlay(clip, false); } - else if (currentUIMode == UI_MODE_HOLDING_HORIZONTAL_ENCODER_BUTTON) { - session.soloClipAction(clip, kInternalButtonPressLatency); - // Make sure we can mute additional pads after this and don't loose UI_MODE_HOLDING_HORIZONTAL_ENCODER_BUTTON - } } } ActionResult SessionView::gridHandleScroll(int32_t offsetX, int32_t offsetY) { - if (isUIModeActive(UI_MODE_HOLDING_HORIZONTAL_ENCODER_BUTTON)) { - display->cancelPopup(); - } - if (currentUIMode == UI_MODE_CLIP_PRESSED_IN_SONG_VIEW && offsetY != 0) { auto track = gridTrackFromX(gridFirstPressedX, gridTrackCount()); if (track != nullptr) { diff --git a/src/deluge/gui/views/session_view.h b/src/deluge/gui/views/session_view.h index ce0b0b48b0..f967621a0f 100644 --- a/src/deluge/gui/views/session_view.h +++ b/src/deluge/gui/views/session_view.h @@ -130,7 +130,7 @@ class SessionView final : public ClipNavigationTimelineView { bool sessionButtonActive = false; bool sessionButtonUsed = false; - + bool horizontalEncoderPressed = false; // Members for grid layout private: bool gridRenderSidebar(uint32_t whichRows, uint8_t image[][kDisplayWidth + kSideBarWidth][3], From ca097278bff301af6a449cf3acc0461d511d8db7 Mon Sep 17 00:00:00 2001 From: Paul Freund Date: Sun, 26 Nov 2023 03:47:45 +0100 Subject: [PATCH 2/8] Default disable Grain FX (#752) --- .gitignore | 1 + contrib/debug/Debug.jdebug | 334 ++++++++++++++++++ contrib/debug/RelWithDebInfo.jdebug | 334 ++++++++++++++++++ contrib/debug/Release.jdebug | 334 ++++++++++++++++++ src/definitions_cxx.hpp | 3 +- src/deluge/gui/l10n/english.cpp | 1 + src/deluge/gui/l10n/seven_segment.cpp | 1 + src/deluge/gui/l10n/strings.h | 1 + src/deluge/gui/menu_item/mod_fx/type.h | 11 + .../menu_item/runtime_feature/settings.cpp | 3 +- .../global_effectable/global_effectable.cpp | 6 +- .../settings/runtime_feature_settings.cpp | 5 + .../model/settings/runtime_feature_settings.h | 1 + 13 files changed, 1032 insertions(+), 3 deletions(-) create mode 100644 contrib/debug/Debug.jdebug create mode 100644 contrib/debug/RelWithDebInfo.jdebug create mode 100644 contrib/debug/Release.jdebug diff --git a/.gitignore b/.gitignore index cffb749050..3bb8c48b2c 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ __pycache__ /tests/RunAllTests /tests/_deps/* *.a +*.jdebug.user diff --git a/contrib/debug/Debug.jdebug b/contrib/debug/Debug.jdebug new file mode 100644 index 0000000000..b7b86ecaf5 --- /dev/null +++ b/contrib/debug/Debug.jdebug @@ -0,0 +1,334 @@ +/********************************************************************* +* (c) SEGGER Microcontroller GmbH * +* The Embedded Experts * +* www.segger.com * +********************************************************************** + +File : C:/Data/Downloads/Deluge.jdebug +Created : 29 Sep 2023 10:11 +Ozone Version : V3.30b +*/ + +/********************************************************************* +* +* OnProjectLoad +* +* Function description +* Project load routine. Required. +* +********************************************************************** +*/ +void OnProjectLoad (void) { + // + // Dialog-generated settings + // + Project.AddPathSubstitute ("C:/Data/Downloads", "$(ProjectDir)"); + Project.AddPathSubstitute ("c:/data/downloads", "$(ProjectDir)"); + Project.SetTraceSource ("Trace Buffer"); + Project.SetDevice ("R7S721020"); + Project.SetHostIF ("USB", "600000832"); + Project.SetTargetIF ("SWD"); + Project.SetTIFSpeed ("4 MHz"); + Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-A9.svd"); + // + // User settings + // + Edit.Preference (PREF_TIMESTAMP_FORMAT, TIMESTAMP_FORMAT_INST_CNT); + File.Open ("../../build/Debug/deluge.elf"); + Edit.SysVar (VAR_TRACE_CORE_CLOCK, 400000000); +} + +/********************************************************************* +* +* OnStartupComplete +* +* Function description +* Called when program execution has reached/passed +* the startup completion point. Optional. +* +********************************************************************** +*/ +//void OnStartupComplete (void) { +//} + +/********************************************************************* +* +* TargetReset +* +* Function description +* Replaces the default target device reset routine. Optional. +* +* Notes +* This example demonstrates the usage when +* debugging an application in RAM on a Cortex-M target device. +* +********************************************************************** +*/ +//void TargetReset (void) { +// +// unsigned int SP; +// unsigned int PC; +// unsigned int VectorTableAddr; +// +// VectorTableAddr = Elf.GetBaseAddr(); +// // +// // Set up initial stack pointer +// // +// if (VectorTableAddr != 0xFFFFFFFF) { +// SP = Target.ReadU32(VectorTableAddr); +// Target.SetReg("SP", SP); +// } +// // +// // Set up entry point PC +// // +// PC = Elf.GetEntryPointPC(); +// +// if (PC != 0xFFFFFFFF) { +// Target.SetReg("PC", PC); +// } else if (VectorTableAddr != 0xFFFFFFFF) { +// PC = Target.ReadU32(VectorTableAddr + 4); +// Target.SetReg("PC", PC); +// } else { +// Util.Error("Project file error: failed to set entry point PC", 1); +// } +//} + +/********************************************************************* +* +* BeforeTargetReset +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetReset (void) { +//} + +/********************************************************************* +* +* AfterTargetReset +* +* Function description +* Event handler routine. Optional. +* The default implementation initializes SP and PC to reset values. +** +********************************************************************** +*/ +void AfterTargetReset (void) { + _SetupTarget(); +} + +/********************************************************************* +* +* DebugStart +* +* Function description +* Replaces the default debug session startup routine. Optional. +* +********************************************************************** +*/ +//void DebugStart (void) { +//} + +/********************************************************************* +* +* TargetConnect +* +* Function description +* Replaces the default target IF connection routine. Optional. +* +********************************************************************** +*/ +//void TargetConnect (void) { +//} + +/********************************************************************* +* +* BeforeTargetConnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetConnect (void) { +//} + +/********************************************************************* +* +* AfterTargetConnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetConnect (void) { +//} + +/********************************************************************* +* +* TargetDownload +* +* Function description +* Replaces the default program download routine. Optional. +* +********************************************************************** +*/ +//void TargetDownload (void) { +//} + +/********************************************************************* +* +* BeforeTargetDownload +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetDownload (void) { +//} + +/********************************************************************* +* +* AfterTargetDownload +* +* Function description +* Event handler routine. Optional. +* The default implementation initializes SP and PC to reset values. +* +********************************************************************** +*/ +void AfterTargetDownload (void) { + _SetupTarget(); +} + +/********************************************************************* +* +* BeforeTargetDisconnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetDisconnect (void) { +//} + +/********************************************************************* +* +* AfterTargetDisconnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetDisconnect (void) { +//} + +/********************************************************************* +* +* AfterTargetHalt +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetHalt (void) { +//} + +/********************************************************************* +* +* BeforeTargetResume +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetResume (void) { +//} + +/********************************************************************* +* +* OnSnapshotLoad +* +* Function description +* Called upon loading a snapshot. Optional. +* +* Additional information +* This function is used to restore the target state in cases +* where values cannot simply be written to the target. +* Typical use: GPIO clock needs to be enabled, before +* GPIO is configured. +* +********************************************************************** +*/ +//void OnSnapshotLoad (void) { +//} + +/********************************************************************* +* +* OnSnapshotSave +* +* Function description +* Called upon saving a snapshot. Optional. +* +* Additional information +* This function is usually used to save values of the target +* state which can either not be trivially read, +* or need to be restored in a specific way or order. +* Typically use: Memory Mapped Registers, +* such as PLL and GPIO configuration. +* +********************************************************************** +*/ +//void OnSnapshotSave (void) { +//} + +/********************************************************************* +* +* OnError +* +* Function description +* Called when an error ocurred. Optional. +* +********************************************************************** +*/ +//void OnError (void) { +//} + +/********************************************************************* +* +* AfterProjectLoad +* +* Function description +* After Project load routine. Optional. +* +********************************************************************** +*/ +//void AfterProjectLoad (void) { +//} + +/********************************************************************* +* +* _SetupTarget +* +* Function description +* Setup the target. +* Called by AfterTargetReset() and AfterTargetDownload(). +* +* Auto-generated function. May be overridden by Ozone. +* +********************************************************************** +*/ +void _SetupTarget(void) { + // + // this function is intentionally empty because both inital PC and + // initial SP were chosen not to be set + // +} diff --git a/contrib/debug/RelWithDebInfo.jdebug b/contrib/debug/RelWithDebInfo.jdebug new file mode 100644 index 0000000000..defc3379be --- /dev/null +++ b/contrib/debug/RelWithDebInfo.jdebug @@ -0,0 +1,334 @@ +/********************************************************************* +* (c) SEGGER Microcontroller GmbH * +* The Embedded Experts * +* www.segger.com * +********************************************************************** + +File : C:/Data/Downloads/Deluge.jdebug +Created : 29 Sep 2023 10:11 +Ozone Version : V3.30b +*/ + +/********************************************************************* +* +* OnProjectLoad +* +* Function description +* Project load routine. Required. +* +********************************************************************** +*/ +void OnProjectLoad (void) { + // + // Dialog-generated settings + // + Project.AddPathSubstitute ("C:/Data/Downloads", "$(ProjectDir)"); + Project.AddPathSubstitute ("c:/data/downloads", "$(ProjectDir)"); + Project.SetTraceSource ("Trace Buffer"); + Project.SetDevice ("R7S721020"); + Project.SetHostIF ("USB", "600000832"); + Project.SetTargetIF ("SWD"); + Project.SetTIFSpeed ("4 MHz"); + Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-A9.svd"); + // + // User settings + // + Edit.Preference (PREF_TIMESTAMP_FORMAT, TIMESTAMP_FORMAT_INST_CNT); + File.Open ("../../build/RelWithDebInfo/deluge.elf"); + Edit.SysVar (VAR_TRACE_CORE_CLOCK, 400000000); +} + +/********************************************************************* +* +* OnStartupComplete +* +* Function description +* Called when program execution has reached/passed +* the startup completion point. Optional. +* +********************************************************************** +*/ +//void OnStartupComplete (void) { +//} + +/********************************************************************* +* +* TargetReset +* +* Function description +* Replaces the default target device reset routine. Optional. +* +* Notes +* This example demonstrates the usage when +* debugging an application in RAM on a Cortex-M target device. +* +********************************************************************** +*/ +//void TargetReset (void) { +// +// unsigned int SP; +// unsigned int PC; +// unsigned int VectorTableAddr; +// +// VectorTableAddr = Elf.GetBaseAddr(); +// // +// // Set up initial stack pointer +// // +// if (VectorTableAddr != 0xFFFFFFFF) { +// SP = Target.ReadU32(VectorTableAddr); +// Target.SetReg("SP", SP); +// } +// // +// // Set up entry point PC +// // +// PC = Elf.GetEntryPointPC(); +// +// if (PC != 0xFFFFFFFF) { +// Target.SetReg("PC", PC); +// } else if (VectorTableAddr != 0xFFFFFFFF) { +// PC = Target.ReadU32(VectorTableAddr + 4); +// Target.SetReg("PC", PC); +// } else { +// Util.Error("Project file error: failed to set entry point PC", 1); +// } +//} + +/********************************************************************* +* +* BeforeTargetReset +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetReset (void) { +//} + +/********************************************************************* +* +* AfterTargetReset +* +* Function description +* Event handler routine. Optional. +* The default implementation initializes SP and PC to reset values. +** +********************************************************************** +*/ +void AfterTargetReset (void) { + _SetupTarget(); +} + +/********************************************************************* +* +* DebugStart +* +* Function description +* Replaces the default debug session startup routine. Optional. +* +********************************************************************** +*/ +//void DebugStart (void) { +//} + +/********************************************************************* +* +* TargetConnect +* +* Function description +* Replaces the default target IF connection routine. Optional. +* +********************************************************************** +*/ +//void TargetConnect (void) { +//} + +/********************************************************************* +* +* BeforeTargetConnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetConnect (void) { +//} + +/********************************************************************* +* +* AfterTargetConnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetConnect (void) { +//} + +/********************************************************************* +* +* TargetDownload +* +* Function description +* Replaces the default program download routine. Optional. +* +********************************************************************** +*/ +//void TargetDownload (void) { +//} + +/********************************************************************* +* +* BeforeTargetDownload +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetDownload (void) { +//} + +/********************************************************************* +* +* AfterTargetDownload +* +* Function description +* Event handler routine. Optional. +* The default implementation initializes SP and PC to reset values. +* +********************************************************************** +*/ +void AfterTargetDownload (void) { + _SetupTarget(); +} + +/********************************************************************* +* +* BeforeTargetDisconnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetDisconnect (void) { +//} + +/********************************************************************* +* +* AfterTargetDisconnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetDisconnect (void) { +//} + +/********************************************************************* +* +* AfterTargetHalt +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetHalt (void) { +//} + +/********************************************************************* +* +* BeforeTargetResume +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetResume (void) { +//} + +/********************************************************************* +* +* OnSnapshotLoad +* +* Function description +* Called upon loading a snapshot. Optional. +* +* Additional information +* This function is used to restore the target state in cases +* where values cannot simply be written to the target. +* Typical use: GPIO clock needs to be enabled, before +* GPIO is configured. +* +********************************************************************** +*/ +//void OnSnapshotLoad (void) { +//} + +/********************************************************************* +* +* OnSnapshotSave +* +* Function description +* Called upon saving a snapshot. Optional. +* +* Additional information +* This function is usually used to save values of the target +* state which can either not be trivially read, +* or need to be restored in a specific way or order. +* Typically use: Memory Mapped Registers, +* such as PLL and GPIO configuration. +* +********************************************************************** +*/ +//void OnSnapshotSave (void) { +//} + +/********************************************************************* +* +* OnError +* +* Function description +* Called when an error ocurred. Optional. +* +********************************************************************** +*/ +//void OnError (void) { +//} + +/********************************************************************* +* +* AfterProjectLoad +* +* Function description +* After Project load routine. Optional. +* +********************************************************************** +*/ +//void AfterProjectLoad (void) { +//} + +/********************************************************************* +* +* _SetupTarget +* +* Function description +* Setup the target. +* Called by AfterTargetReset() and AfterTargetDownload(). +* +* Auto-generated function. May be overridden by Ozone. +* +********************************************************************** +*/ +void _SetupTarget(void) { + // + // this function is intentionally empty because both inital PC and + // initial SP were chosen not to be set + // +} diff --git a/contrib/debug/Release.jdebug b/contrib/debug/Release.jdebug new file mode 100644 index 0000000000..9f1a90b4f0 --- /dev/null +++ b/contrib/debug/Release.jdebug @@ -0,0 +1,334 @@ +/********************************************************************* +* (c) SEGGER Microcontroller GmbH * +* The Embedded Experts * +* www.segger.com * +********************************************************************** + +File : C:/Data/Downloads/Deluge.jdebug +Created : 29 Sep 2023 10:11 +Ozone Version : V3.30b +*/ + +/********************************************************************* +* +* OnProjectLoad +* +* Function description +* Project load routine. Required. +* +********************************************************************** +*/ +void OnProjectLoad (void) { + // + // Dialog-generated settings + // + Project.AddPathSubstitute ("C:/Data/Downloads", "$(ProjectDir)"); + Project.AddPathSubstitute ("c:/data/downloads", "$(ProjectDir)"); + Project.SetTraceSource ("Trace Buffer"); + Project.SetDevice ("R7S721020"); + Project.SetHostIF ("USB", "600000832"); + Project.SetTargetIF ("SWD"); + Project.SetTIFSpeed ("4 MHz"); + Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-A9.svd"); + // + // User settings + // + Edit.Preference (PREF_TIMESTAMP_FORMAT, TIMESTAMP_FORMAT_INST_CNT); + File.Open ("../../build/Release/deluge.elf"); + Edit.SysVar (VAR_TRACE_CORE_CLOCK, 400000000); +} + +/********************************************************************* +* +* OnStartupComplete +* +* Function description +* Called when program execution has reached/passed +* the startup completion point. Optional. +* +********************************************************************** +*/ +//void OnStartupComplete (void) { +//} + +/********************************************************************* +* +* TargetReset +* +* Function description +* Replaces the default target device reset routine. Optional. +* +* Notes +* This example demonstrates the usage when +* debugging an application in RAM on a Cortex-M target device. +* +********************************************************************** +*/ +//void TargetReset (void) { +// +// unsigned int SP; +// unsigned int PC; +// unsigned int VectorTableAddr; +// +// VectorTableAddr = Elf.GetBaseAddr(); +// // +// // Set up initial stack pointer +// // +// if (VectorTableAddr != 0xFFFFFFFF) { +// SP = Target.ReadU32(VectorTableAddr); +// Target.SetReg("SP", SP); +// } +// // +// // Set up entry point PC +// // +// PC = Elf.GetEntryPointPC(); +// +// if (PC != 0xFFFFFFFF) { +// Target.SetReg("PC", PC); +// } else if (VectorTableAddr != 0xFFFFFFFF) { +// PC = Target.ReadU32(VectorTableAddr + 4); +// Target.SetReg("PC", PC); +// } else { +// Util.Error("Project file error: failed to set entry point PC", 1); +// } +//} + +/********************************************************************* +* +* BeforeTargetReset +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetReset (void) { +//} + +/********************************************************************* +* +* AfterTargetReset +* +* Function description +* Event handler routine. Optional. +* The default implementation initializes SP and PC to reset values. +** +********************************************************************** +*/ +void AfterTargetReset (void) { + _SetupTarget(); +} + +/********************************************************************* +* +* DebugStart +* +* Function description +* Replaces the default debug session startup routine. Optional. +* +********************************************************************** +*/ +//void DebugStart (void) { +//} + +/********************************************************************* +* +* TargetConnect +* +* Function description +* Replaces the default target IF connection routine. Optional. +* +********************************************************************** +*/ +//void TargetConnect (void) { +//} + +/********************************************************************* +* +* BeforeTargetConnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetConnect (void) { +//} + +/********************************************************************* +* +* AfterTargetConnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetConnect (void) { +//} + +/********************************************************************* +* +* TargetDownload +* +* Function description +* Replaces the default program download routine. Optional. +* +********************************************************************** +*/ +//void TargetDownload (void) { +//} + +/********************************************************************* +* +* BeforeTargetDownload +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetDownload (void) { +//} + +/********************************************************************* +* +* AfterTargetDownload +* +* Function description +* Event handler routine. Optional. +* The default implementation initializes SP and PC to reset values. +* +********************************************************************** +*/ +void AfterTargetDownload (void) { + _SetupTarget(); +} + +/********************************************************************* +* +* BeforeTargetDisconnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetDisconnect (void) { +//} + +/********************************************************************* +* +* AfterTargetDisconnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetDisconnect (void) { +//} + +/********************************************************************* +* +* AfterTargetHalt +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetHalt (void) { +//} + +/********************************************************************* +* +* BeforeTargetResume +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetResume (void) { +//} + +/********************************************************************* +* +* OnSnapshotLoad +* +* Function description +* Called upon loading a snapshot. Optional. +* +* Additional information +* This function is used to restore the target state in cases +* where values cannot simply be written to the target. +* Typical use: GPIO clock needs to be enabled, before +* GPIO is configured. +* +********************************************************************** +*/ +//void OnSnapshotLoad (void) { +//} + +/********************************************************************* +* +* OnSnapshotSave +* +* Function description +* Called upon saving a snapshot. Optional. +* +* Additional information +* This function is usually used to save values of the target +* state which can either not be trivially read, +* or need to be restored in a specific way or order. +* Typically use: Memory Mapped Registers, +* such as PLL and GPIO configuration. +* +********************************************************************** +*/ +//void OnSnapshotSave (void) { +//} + +/********************************************************************* +* +* OnError +* +* Function description +* Called when an error ocurred. Optional. +* +********************************************************************** +*/ +//void OnError (void) { +//} + +/********************************************************************* +* +* AfterProjectLoad +* +* Function description +* After Project load routine. Optional. +* +********************************************************************** +*/ +//void AfterProjectLoad (void) { +//} + +/********************************************************************* +* +* _SetupTarget +* +* Function description +* Setup the target. +* Called by AfterTargetReset() and AfterTargetDownload(). +* +* Auto-generated function. May be overridden by Ozone. +* +********************************************************************** +*/ +void _SetupTarget(void) { + // + // this function is intentionally empty because both inital PC and + // initial SP were chosen not to be set + // +} diff --git a/src/definitions_cxx.hpp b/src/definitions_cxx.hpp index 1d91fdda0f..5d5c748357 100644 --- a/src/definitions_cxx.hpp +++ b/src/definitions_cxx.hpp @@ -623,9 +623,10 @@ enum class ModFXType { CHORUS, PHASER, CHORUS_STEREO, - GRAIN, + GRAIN, // Look below if you want to add another one }; +// Warning: Currently GRAIN can be disabled and kNumModFXTypes might need to be used - 1 constexpr int32_t kNumModFXTypes = util::to_underlying(ModFXType::GRAIN) + 1; constexpr int32_t SAMPLE_MAX_TRANSPOSE = 24; diff --git a/src/deluge/gui/l10n/english.cpp b/src/deluge/gui/l10n/english.cpp index 56de967153..b03ecacf65 100644 --- a/src/deluge/gui/l10n/english.cpp +++ b/src/deluge/gui/l10n/english.cpp @@ -506,6 +506,7 @@ PLACE_SDRAM_DATA Language english{ {STRING_FOR_COMMUNITY_FEATURE_SYNC_SCALING_ACTION, "Sync Scaling Action"}, {STRING_FOR_COMMUNITY_FEATURE_HIGHLIGHT_INCOMING_NOTES, "Highlight Incoming Notes"}, {STRING_FOR_COMMUNITY_FEATURE_NORNS_LAYOUT, "Display Norns Layout"}, + {STRING_FOR_COMMUNITY_FEATURE_GRAIN_FX, "Enable Grain FX"}, {STRING_FOR_TRACK_STILL_HAS_CLIPS_IN_SESSION, "Track still has clips in session"}, {STRING_FOR_DELETE_ALL_TRACKS_CLIPS_FIRST, "Delete all track's clips first"}, diff --git a/src/deluge/gui/l10n/seven_segment.cpp b/src/deluge/gui/l10n/seven_segment.cpp index c16e43e8a5..0c19c83031 100644 --- a/src/deluge/gui/l10n/seven_segment.cpp +++ b/src/deluge/gui/l10n/seven_segment.cpp @@ -348,6 +348,7 @@ PLACE_SDRAM_DATA Language seven_segment{ {STRING_FOR_COMMUNITY_FEATURE_SYNC_SCALING_ACTION, "SCAL"}, {STRING_FOR_COMMUNITY_FEATURE_HIGHLIGHT_INCOMING_NOTES, "HIGH"}, {STRING_FOR_COMMUNITY_FEATURE_NORNS_LAYOUT, "NORN"}, + {STRING_FOR_COMMUNITY_FEATURE_GRAIN_FX, "GRFX"}, {STRING_FOR_TRACK_STILL_HAS_CLIPS_IN_SESSION, "CANT"}, {STRING_FOR_DELETE_ALL_TRACKS_CLIPS_FIRST, "CANT"}, diff --git a/src/deluge/gui/l10n/strings.h b/src/deluge/gui/l10n/strings.h index 8c312c8d22..0834b6055c 100644 --- a/src/deluge/gui/l10n/strings.h +++ b/src/deluge/gui/l10n/strings.h @@ -412,6 +412,7 @@ enum class String : size_t { STRING_FOR_COMMUNITY_FEATURE_SYNC_SCALING_ACTION, STRING_FOR_COMMUNITY_FEATURE_HIGHLIGHT_INCOMING_NOTES, STRING_FOR_COMMUNITY_FEATURE_NORNS_LAYOUT, + STRING_FOR_COMMUNITY_FEATURE_GRAIN_FX, STRING_FOR_TRACK_STILL_HAS_CLIPS_IN_SESSION, STRING_FOR_DELETE_ALL_TRACKS_CLIPS_FIRST, diff --git a/src/deluge/gui/menu_item/mod_fx/type.h b/src/deluge/gui/menu_item/mod_fx/type.h index ec593afe8d..615ef69e09 100644 --- a/src/deluge/gui/menu_item/mod_fx/type.h +++ b/src/deluge/gui/menu_item/mod_fx/type.h @@ -20,6 +20,7 @@ #include "gui/menu_item/selection.h" #include "gui/ui/sound_editor.h" #include "model/mod_controllable/mod_controllable_audio.h" +#include "model/settings/runtime_feature_settings.h" #include "util/misc.h" namespace deluge::gui::menu_item::mod_fx { @@ -37,6 +38,16 @@ class Type : public Selection { std::vector getOptions() override { using enum l10n::String; + if (runtimeFeatureSettings.get(RuntimeFeatureSettingType::EnableGrainFX) == RuntimeFeatureStateToggle::Off) { + return { + l10n::getView(STRING_FOR_DISABLED), //< + l10n::getView(STRING_FOR_FLANGER), //< + l10n::getView(STRING_FOR_CHORUS), //< + l10n::getView(STRING_FOR_PHASER), //< + l10n::getView(STRING_FOR_STEREO_CHORUS), //< + }; + } + return { l10n::getView(STRING_FOR_DISABLED), //< l10n::getView(STRING_FOR_FLANGER), //< diff --git a/src/deluge/gui/menu_item/runtime_feature/settings.cpp b/src/deluge/gui/menu_item/runtime_feature/settings.cpp index 15a4bc2c65..4d50c10df1 100644 --- a/src/deluge/gui/menu_item/runtime_feature/settings.cpp +++ b/src/deluge/gui/menu_item/runtime_feature/settings.cpp @@ -51,6 +51,7 @@ Setting menuHighlightIncomingNotes(RuntimeFeatureSettingType::HighlightIncomingN Setting menuDisplayNornsLayout(RuntimeFeatureSettingType::DisplayNornsLayout); ShiftIsSticky menuShiftIsSticky{}; Setting menuLightShiftLed(RuntimeFeatureSettingType::LightShiftLed); +Setting menuEnableGrainFX(RuntimeFeatureSettingType::EnableGrainFX); Submenu subMenuAutomation{ l10n::String::STRING_FOR_COMMUNITY_FEATURE_AUTOMATION, @@ -79,7 +80,7 @@ std::array((util::to_underlying(modFXType) + 1) % kNumModFXTypes); + auto modTypeCount = (runtimeFeatureSettings.get(RuntimeFeatureSettingType::EnableGrainFX) + == RuntimeFeatureStateToggle::Off) + ? (kNumModFXTypes - 1) + : kNumModFXTypes; + modFXType = static_cast((util::to_underlying(modFXType) + 1) % modTypeCount); if (modFXType == ModFXType::NONE) { modFXType = static_cast(1); } diff --git a/src/deluge/model/settings/runtime_feature_settings.cpp b/src/deluge/model/settings/runtime_feature_settings.cpp index cb54d983ca..04738e1b9e 100644 --- a/src/deluge/model/settings/runtime_feature_settings.cpp +++ b/src/deluge/model/settings/runtime_feature_settings.cpp @@ -155,6 +155,11 @@ void RuntimeFeatureSettings::init() { // LightShiftLed SetupOnOffSetting(settings[RuntimeFeatureSettingType::LightShiftLed], "Light Shift", "lightShift", RuntimeFeatureStateToggle::Off); + + // EnableGrainFX + SetupOnOffSetting(settings[RuntimeFeatureSettingType::EnableGrainFX], + deluge::l10n::getView(STRING_FOR_COMMUNITY_FEATURE_GRAIN_FX), "enableGrainFX", + RuntimeFeatureStateToggle::Off); } void RuntimeFeatureSettings::readSettingsFromFile() { diff --git a/src/deluge/model/settings/runtime_feature_settings.h b/src/deluge/model/settings/runtime_feature_settings.h index 8d00980584..12f67a4976 100644 --- a/src/deluge/model/settings/runtime_feature_settings.h +++ b/src/deluge/model/settings/runtime_feature_settings.h @@ -57,6 +57,7 @@ enum RuntimeFeatureSettingType : uint32_t { DisplayNornsLayout, ShiftIsSticky, LightShiftLed, + EnableGrainFX, MaxElement // Keep as boundary }; From 87f997388aefc452c21fcadef4f1d49d64d169de Mon Sep 17 00:00:00 2001 From: Mark Adams <52469396+m-m-adams@users.noreply.github.com> Date: Sun, 26 Nov 2023 12:42:42 -0500 Subject: [PATCH 3/8] Synth presets sometimes loading incorrectly (#719) * add additional logging * log fp from better position * improve logging and error detection * move logs to better spot * Null filePointer on init and add additional logging * check null pointer before load, set file pointer from instrument * comment out unnecessary FP check * just use later return --------- Co-authored-by: Paul Freund --- src/deluge/gui/ui/browser/browser.cpp | 38 ++++++++++++++++++- src/deluge/gui/ui/browser/browser.h | 18 +++++++++ .../gui/ui/load/load_instrument_preset_ui.cpp | 11 +++++- src/deluge/model/song/song.cpp | 2 + src/deluge/storage/file_item.cpp | 11 ++++++ src/deluge/storage/storage_manager.cpp | 20 +++++++++- 6 files changed, 95 insertions(+), 5 deletions(-) diff --git a/src/deluge/gui/ui/browser/browser.cpp b/src/deluge/gui/ui/browser/browser.cpp index 9db7925a31..8431211550 100644 --- a/src/deluge/gui/ui/browser/browser.cpp +++ b/src/deluge/gui/ui/browser/browser.cpp @@ -86,6 +86,35 @@ bool Browser::opened() { return QwertyUI::opened(); } +//returns true if the FP for the filepath is correct +bool Browser::checkFP() { + FileItem* currentFileItem = getCurrentFileItem(); + String filePath; + int32_t error = getCurrentFilePath(&filePath); + if (error != 0) { + Debug::println("couldn't get filepath"); + return false; + } + + FilePointer tempfp; + bool fileExists = storageManager.fileExists(filePath.get(), &tempfp); + if (!fileExists) { + Debug::println("couldn't get filepath"); + return false; + } + else if (tempfp.sclust != currentFileItem->filePointer.sclust) { + Debug::print("FPs don't match: correct is "); + Debug::print(tempfp.sclust); + Debug::print(" but the browser has "); + Debug::println(currentFileItem->filePointer.sclust); +#if ALPHA_OR_BETA_VERSION + display->freezeWithError("B001"); +#endif + return false; + } + return true; +} + void Browser::close() { emptyFileItems(); QwertyUI::close(); @@ -518,6 +547,7 @@ int32_t Browser::readFileItemsFromFolderAndMemory(Song* song, InstrumentType ins } } } + return NO_ERROR; } @@ -934,7 +964,7 @@ void Browser::selectEncoderAction(int8_t offset) { if (thisSlot.slot < 0) { goto nonNumeric; } - + Debug::println("treating as numeric"); thisSlot.subSlot = -1; switch (numberEditPosNow) { case 0: @@ -983,6 +1013,7 @@ void Browser::selectEncoderAction(int8_t offset) { if (thisSlot.slot < 0) { goto nonNumeric; } + Debug::println("treating as numeric"); thisSlot.slot += offset; char searchString[9]; @@ -1012,6 +1043,7 @@ void Browser::selectEncoderAction(int8_t offset) { int32_t error; if (newFileIndex < 0) { + Debug::println("index below 0"); if (numFileItemsDeletedAtStart) { scrollPosVertical = 9999; @@ -1021,12 +1053,15 @@ void Browser::selectEncoderAction(int8_t offset) { NULL, true, Availability::ANY, CATALOG_SEARCH_BOTH); if (error) { gotErrorAfterAllocating: + Debug::println("error while reloading, emptying file items"); emptyFileItems(); return; // TODO - need to close UI or something? } newFileIndex = fileItems.search(enteredText.get()) + offset; + Debug::print("new file Index is "); + Debug::println(newFileIndex); } else if (!shouldWrapFolderContents && display->have7SEG()) { @@ -1057,6 +1092,7 @@ void Browser::selectEncoderAction(int8_t offset) { } else if (newFileIndex >= fileItems.getNumElements()) { + Debug::println("out of file items"); if (numFileItemsDeletedAtEnd) { scrollPosVertical = 0; goto tryReadingItems; diff --git a/src/deluge/gui/ui/browser/browser.h b/src/deluge/gui/ui/browser/browser.h index b8188be386..936d1c2fd2 100644 --- a/src/deluge/gui/ui/browser/browser.h +++ b/src/deluge/gui/ui/browser/browser.h @@ -86,6 +86,7 @@ class Browser : public QwertyUI { int32_t getUnusedSlot(InstrumentType instrumentType, String* newName, char const* thingName); bool opened(); void cullSomeFileItems(); + bool checkFP(); void renderOLED(uint8_t image[][OLED_MAIN_WIDTH_PIXELS]); @@ -142,3 +143,20 @@ class Browser : public QwertyUI { char const* filePrefix; bool shouldInterpretNoteNamesForThisBrowser; }; + +#include "io/debug/print.h" +inline void printInstrumentFileList(const char* where) { + Debug::print("\n"); + Debug::print(where); + Debug::print(" List: \n"); + for (uint32_t idx = 0; idx < Browser::fileItems.getNumElements(); ++idx) { + FileItem* fileItem = (FileItem*)Browser::fileItems.getElementAddress(idx); + Debug::print(" - "); + Debug::print(fileItem->displayName); + Debug::print(" ("); + Debug::print(fileItem->filePointer.sclust); + Debug::print(")\n"); + } + + Debug::print("\n"); +} diff --git a/src/deluge/gui/ui/load/load_instrument_preset_ui.cpp b/src/deluge/gui/ui/load/load_instrument_preset_ui.cpp index 08730200ec..9b1fc0a22e 100644 --- a/src/deluge/gui/ui/load/load_instrument_preset_ui.cpp +++ b/src/deluge/gui/ui/load/load_instrument_preset_ui.cpp @@ -260,7 +260,12 @@ void LoadInstrumentPresetUI::enterKeyPress() { else { if (currentInstrumentLoadError) { - currentInstrumentLoadError = performLoad(); + if (loadingSynthToKitRow) { + currentInstrumentLoadError = performLoadSynthToKit(); + } + else { + currentInstrumentLoadError = performLoad(); + } if (currentInstrumentLoadError) { display->displayError(currentInstrumentLoadError); return; @@ -796,6 +801,7 @@ int32_t LoadInstrumentPresetUI::performLoad(bool doClone) { if (currentFileItem->instrument == instrumentToReplace && !doClone) { return NO_ERROR; // Happens if navigate over a folder's name (Instrument stays the same), } + // then back onto that neighbouring Instrument - you'd incorrectly get a "USED" error without this line. // Work out availabilityRequirement. This can't change as presets are navigated through... I don't think? @@ -854,7 +860,8 @@ int32_t LoadInstrumentPresetUI::performLoad(bool doClone) { } } int32_t error; - + //check if the file pointer matches the current file item + //Browser::checkFP(); error = storageManager.loadInstrumentFromFile(currentSong, instrumentClipToLoadFor, instrumentTypeToLoad, false, &newInstrument, ¤tFileItem->filePointer, &enteredText, ¤tDir); diff --git a/src/deluge/model/song/song.cpp b/src/deluge/model/song/song.cpp index 0028323006..775a27a4d2 100644 --- a/src/deluge/model/song/song.cpp +++ b/src/deluge/model/song/song.cpp @@ -5390,11 +5390,13 @@ int32_t Song::addInstrumentsToFileItems(InstrumentType instrumentType) { } FileItem* thisItem = loadInstrumentPresetUI.getNewFileItem(); + if (!thisItem) { return ERROR_INSUFFICIENT_RAM; } int32_t error = thisItem->setupWithInstrument(thisInstrument, doingHibernatingOnes); + if (error) { return error; } diff --git a/src/deluge/storage/file_item.cpp b/src/deluge/storage/file_item.cpp index 467568fbab..e0d0a234cc 100644 --- a/src/deluge/storage/file_item.cpp +++ b/src/deluge/storage/file_item.cpp @@ -16,10 +16,12 @@ */ #include "storage/file_item.h" #include "hid/display/display.h" +#include "io/debug/print.h" #include "model/instrument/instrument.h" #include FileItem::FileItem() { + filePointer = {0}; instrument = NULL; filenameIncludesExtension = true; instrumentAlreadyInSong = false; @@ -36,6 +38,15 @@ int32_t FileItem::setupWithInstrument(Instrument* newInstrument, bool hibernatin isFolder = false; instrumentAlreadyInSong = !hibernating; displayName = filename.get(); + String tempFilePath; + tempFilePath.set(newInstrument->dirPath.get()); + tempFilePath.concatenate("/"); + tempFilePath.concatenate(filename.get()); + bool fileExists = storageManager.fileExists(tempFilePath.get(), &filePointer); + if (!fileExists) { + Debug::print("couldn't get filepath for file"); + Debug::println(filename.get()); + } return NO_ERROR; } diff --git a/src/deluge/storage/storage_manager.cpp b/src/deluge/storage/storage_manager.cpp index 7fe19b8e29..77d7480295 100644 --- a/src/deluge/storage/storage_manager.cpp +++ b/src/deluge/storage/storage_manager.cpp @@ -1356,7 +1356,9 @@ void StorageManager::openFilePointer(FilePointer* fp) { int32_t StorageManager::openInstrumentFile(InstrumentType instrumentType, FilePointer* filePointer) { AudioEngine::logAction("openInstrumentFile"); - + if (!filePointer->sclust) { + return ERROR_FILE_NOT_FOUND; + } char const* firstTagName; char const* altTagName = ""; @@ -1379,9 +1381,16 @@ int32_t StorageManager::loadInstrumentFromFile(Song* song, InstrumentClip* clip, FilePointer* filePointer, String* name, String* dirPath) { AudioEngine::logAction("loadInstrumentFromFile"); + Debug::print("opening instrument file - "); + Debug::print(dirPath->get()); + Debug::print(name->get()); + Debug::print(" from FP "); + Debug::println((int32_t)filePointer->sclust); int32_t error = openInstrumentFile(instrumentType, filePointer); if (error) { + Debug::print("opening instrument file failed - "); + Debug::println(name->get()); return error; } @@ -1390,6 +1399,8 @@ int32_t StorageManager::loadInstrumentFromFile(Song* song, InstrumentClip* clip, if (!newInstrument) { closeFile(); + Debug::print("Allocating instrument file failed - "); + Debug::println(name->get()); return ERROR_INSUFFICIENT_RAM; } @@ -1399,12 +1410,15 @@ int32_t StorageManager::loadInstrumentFromFile(Song* song, InstrumentClip* clip, // If that somehow didn't work... if (error || !fileSuccess) { - + Debug::print("reading instrument file failed - "); + Debug::println(name->get()); if (!fileSuccess) { error = ERROR_SD_CARD; } deleteInstrumentAndGetOut: + Debug::print("abandoning load - "); + Debug::println(name->get()); newInstrument->deleteBackedUpParamManagers(song); void* toDealloc = static_cast(newInstrument); newInstrument->~Instrument(); @@ -1432,6 +1446,8 @@ int32_t StorageManager::loadInstrumentFromFile(Song* song, InstrumentClip* clip, } else { paramManagersMissing: + Debug::print("creating param manager failed - "); + Debug::println(name->get()); error = ERROR_FILE_CORRUPTED; goto deleteInstrumentAndGetOut; } From bfca6fcd899fa8df57c582ea8c59c372fd0f2c13 Mon Sep 17 00:00:00 2001 From: Mark Adams <52469396+m-m-adams@users.noreply.github.com> Date: Sun, 26 Nov 2023 17:28:23 -0500 Subject: [PATCH 4/8] update community features with ux changes (#765) --- docs/community_features.md | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/docs/community_features.md b/docs/community_features.md index d4b0365f82..7903cba473 100644 --- a/docs/community_features.md +++ b/docs/community_features.md @@ -55,7 +55,7 @@ Here is a list of features that have been added to the firmware as a list, group ### 4.1 - Song View Features #### 4.1.1 - Master Compressor -- ([#630]) In the Song view, select "AFFECT ENTIRE" and "SIDECHAIN" modulation button, and adjust the upper gold knob for a single knob compressor with auto makeup gain. For detailed editing, press the sidechain gold knob. The top LED will become a compression meter, and the bottom LED level will show the compressor input level. The bottom (reverb) knob will adjust the ratio in this mode, from 1:8 to infinity/brick wall. The compressor attack and release are editable on the affect entire attack and release buttons if desired. +- ([#630]) In the Song view, select "AFFECT ENTIRE" and "SIDECHAIN" modulation button, and adjust the upper gold knob for a single knob compressor with auto makeup gain. For detailed editing, press the sidechain gold knob. The top LED will become a compression meter. Clicking the bottom knob will cycle through additional params: ratio (displays actual ratio), attack/release (shown in ms) and sidechain HPF (shown in Hz). The sidechain HPF is useful to remove some bass from the compressor level detection, which sounds like an increase in bass allowed through the compression. #### 4.1.2 - Change Row Colour @@ -104,25 +104,10 @@ Here is a list of features that have been added to the firmware as a list, group ### 4.2 - Clip View - General Features (Instrument and Audio Clips) #### 4.2.1 - Filters - - ([#103]) Adds a new filter in the low-pass slot, a state-variable filter. This filter has significantly less distortion than the ladder filters, think sequential vs. moog. Cutoff and resonance ranges are subject to change with further testing. + - ([#103] and [#336]) Adds 2 new state variable filters to both high and lowpass slots. This filter has significantly less distortion than the ladder filters, think sequential vs. moog. The morph parameter (pad under db/oct) adjusts smoothly from lowpass -> bandpass/notch -> highpass. The knob is inverted in the HPF slot so that at 0 the filter is highpass and at 50 it is lowpassed. + - The morph param is also added to the ladders, in 12/24/drive filters it smoothly increases drive and in the HPF ladder it adds filter FM. This param is modulatable and automatable - - Follow-up PR's: ([#125] and [#212]) Various SVF fixes - -- ([#336]) Morphable and Driveable Parallel Filters - - Add an SVF option to the HPF slot, set for HPF mode by default. This can be modified through the menu, shortcuts, or clicking the lower knob while HPF is selected. - - - Follow-up PR: ([#339]) SVF Notch Filter - - Adds an SVF notch mode (SV_Notch) alongside the SVF Band mode (SV_Band) - - Changes SVF morph in HP slot to go HP-band/notch-LP (HP by default) - - Tweaks default ladder saturation to match original firmware - - Applies ladder gain on input instead of feedback, avoiding interaction with resonance - - Tweaks SVF level to match ladder volumes - - Removes distinction between high and lowpass SVF enums so they can now be used in either slot -adds HP ladder morph to filter FM - - - Adds a 3rd filter paramater called morph, placed in the menu and on the pads under the db/oct on filters. Morph smoothly morphs the SVF through LP-BP-HP, and smoothly increases drive in the ladder filters. This param is modulatable and automatable - - - Adds a setting to switch the filter order or run them in parallel. This setting is menu only and named ROUTE + - Also adds a setting to switch the filter order or run them in parallel. This setting is menu only and named ROUTE #### 4.2.2 - Stereo Chorus - ([#120]) New Stereo Chorus type added to Mod FX. The recommended settings are OFFSET=30, DEPTH=17, and RATE=15. @@ -193,9 +178,10 @@ Synchronization modes accessible through the "LFO SYNC" shortcut. #### 4.3.3 - Quantize & Humanize - ([#129]) - - Press and hold a note in clip view and turn the tempo knob right or left to apply quantize or humanize respectively to that row. - - Press and hold a note and press and turn the tempo knob to apply quantize or humanize to all rows. + - Press and hold an audition pad in clip view and turn the tempo knob right or left to apply quantize or humanize respectively to that row. + - Press and hold an audition pad and press and turn the tempo knob to apply quantize or humanize to all rows. - The amount of quantization/humanization is shown in the display. + - This is destructive (your original note positions are not saved) The implementation of this feature is likely to change in the future - This feature can be turned ON/OFF in the Runtime Settings (Community Features) Menu (accessed by pressing "SHIFT" + "SELECT"). #### 4.3.4 - Fill Mode @@ -297,8 +283,6 @@ In the main menu of the deluge (accessed by pressing "SHIFT" + the "SELECT" knob * Drum Randomizer (DRUM) * When On, the "AUDITION + RANDOM" shortcut is enabled. -* Master Compressor (COMP) - * When On, the Master Compressor is enabled. * Fine Tempo Knob (TEMP) * When On, the Fine Tempo change option is enabled. * Quantize (QUAN) From 7c2368d7ce6de22fac0566bec28fecead0333eb7 Mon Sep 17 00:00:00 2001 From: Mark Adams <52469396+m-m-adams@users.noreply.github.com> Date: Sun, 26 Nov 2023 18:00:10 -0500 Subject: [PATCH 5/8] swap delay rate and amount (#764) --- src/deluge/gui/ui/menus.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/deluge/gui/ui/menus.cpp b/src/deluge/gui/ui/menus.cpp index 648695b7a3..b91674622e 100644 --- a/src/deluge/gui/ui/menus.cpp +++ b/src/deluge/gui/ui/menus.cpp @@ -564,10 +564,10 @@ Submenu audioClipModFXMenu{ }; // Delay Menu -UnpatchedParam audioClipDelayRateMenu{STRING_FOR_AMOUNT, STRING_FOR_DELAY_AMOUNT, - ::Param::Unpatched::GlobalEffectable::DELAY_AMOUNT}; -UnpatchedParam audioClipDelayFeedbackMenu{STRING_FOR_RATE, STRING_FOR_DELAY_RATE, - ::Param::Unpatched::GlobalEffectable::DELAY_RATE}; +UnpatchedParam audioClipDelayFeedbackMenu{STRING_FOR_AMOUNT, STRING_FOR_DELAY_AMOUNT, + ::Param::Unpatched::GlobalEffectable::DELAY_AMOUNT}; +UnpatchedParam audioClipDelayRateMenu{STRING_FOR_RATE, STRING_FOR_DELAY_RATE, + ::Param::Unpatched::GlobalEffectable::DELAY_RATE}; Submenu audioClipDelayMenu{ STRING_FOR_DELAY, From aa471d81d504316c7eaf8771d271438784be056a Mon Sep 17 00:00:00 2001 From: Mark Adams <52469396+m-m-adams@users.noreply.github.com> Date: Mon, 27 Nov 2023 10:10:22 -0500 Subject: [PATCH 6/8] only convert cc74 to y axis if saved from old firmware (#763) --- src/deluge/model/clip/instrument_clip.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/deluge/model/clip/instrument_clip.cpp b/src/deluge/model/clip/instrument_clip.cpp index 3cf5988c3a..3a0fa5c297 100644 --- a/src/deluge/model/clip/instrument_clip.cpp +++ b/src/deluge/model/clip/instrument_clip.cpp @@ -2688,7 +2688,7 @@ int32_t InstrumentClip::readFromFile(Song* song) { } } - // These next 3 - only created by alpha testers for a few weeks. Could eventually remove. + // These are the expression params for MPE else if (!strcmp(tagName, "pitchBend")) { temp = 0; doReadExpressionParam: @@ -2900,8 +2900,11 @@ int32_t InstrumentClip::readMIDIParamsFromFile(int32_t readAutomationUpToPos) { paramId = stringToInt(contents); if (paramId < kNumRealCCNumbers) { if (paramId == 74) { - paramId = 1; - goto expressionParam; + if (storageManager.firmwareVersionOfFileBeingRead + < FirmwareVersion::FIRMWARE_3P2P0_ALPHA) { + paramId = 1; + goto expressionParam; + } } MIDIParam* midiParam = paramManager.getMIDIParamCollection()->params.getOrCreateParamFromCC(paramId, 0); From 853f85ce857c99d5b7b3609620e7928d293c848d Mon Sep 17 00:00:00 2001 From: Sean Ditny <138174805+seangoodvibes@users.noreply.github.com> Date: Mon, 27 Nov 2023 10:10:58 -0500 Subject: [PATCH 7/8] Fix popup values displayed on 7SEG (#766) * Fix values displayed on 7SEG - Fixed mod encoder value popups to align values to the right of the 7Seg display - Fixed automation instrument clip view value popups which were not displaying the correct amounts since the change to 0-50. * Dbt Format --- .../gui/views/automation_instrument_clip_view.cpp | 15 ++++++++++----- src/deluge/gui/views/view.cpp | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/deluge/gui/views/automation_instrument_clip_view.cpp b/src/deluge/gui/views/automation_instrument_clip_view.cpp index 1625f81767..c4998e7856 100644 --- a/src/deluge/gui/views/automation_instrument_clip_view.cpp +++ b/src/deluge/gui/views/automation_instrument_clip_view.cpp @@ -815,8 +815,12 @@ void AutomationInstrumentClipView::renderDisplay(int32_t knobPosLeft, int32_t kn //if you're not in a MIDI instrument clip, convert the knobPos to the same range as the menu (0-50) if (instrument->type != InstrumentType::MIDI_OUT) { - knobPosLeft = view.calculateKnobPosForDisplay(instrument->type, clip->lastSelectedParamID, knobPosLeft); - knobPosRight = view.calculateKnobPosForDisplay(instrument->type, clip->lastSelectedParamID, knobPosRight); + if (knobPosLeft != kNoSelection) { + knobPosLeft = view.calculateKnobPosForDisplay(instrument->type, clip->lastSelectedParamID, knobPosLeft); + } + if (knobPosRight != kNoSelection) { + knobPosRight = view.calculateKnobPosForDisplay(instrument->type, clip->lastSelectedParamID, knobPosRight); + } } //OLED Display @@ -945,7 +949,8 @@ void AutomationInstrumentClipView::renderDisplay7SEG(InstrumentClip* clip, Instr lastPadSelectedKnobPos = knobPosLeft; } else if (lastPadSelectedKnobPos != kNoSelection) { - knobPosLeft = lastPadSelectedKnobPos; + knobPosLeft = view.calculateKnobPosForDisplay(instrument->type, clip->lastSelectedParamID, + lastPadSelectedKnobPos); } } @@ -956,10 +961,10 @@ void AutomationInstrumentClipView::renderDisplay7SEG(InstrumentClip* clip, Instr intToString(knobPosLeft, buffer); if (isUIModeActive(UI_MODE_NOTES_PRESSED)) { - display->setText(buffer, false, 255, false); + display->setText(buffer, true, 255, false); } else if (modEncoderAction || padSelectionOn) { - display->displayPopup(buffer); + display->displayPopup(buffer, 3, true); } } //display parameter name diff --git a/src/deluge/gui/views/view.cpp b/src/deluge/gui/views/view.cpp index 9b0d549b15..439725cd5a 100644 --- a/src/deluge/gui/views/view.cpp +++ b/src/deluge/gui/views/view.cpp @@ -943,7 +943,7 @@ void View::displayModEncoderValuePopup(InstrumentType instrumentType, int32_t pa valueForDisplay = calculateKnobPosForDisplay(instrumentType, paramID, newKnobPos + kKnobPosOffset); } intToString(valueForDisplay, buffer); - display->displayPopup(buffer); + display->displayPopup(buffer, 3, true); } //if turning stutter mod encoder and stutter quantize is enabled From 7ab16d6315cb23d06479e4721b092ae1d277c586 Mon Sep 17 00:00:00 2001 From: Paul Freund Date: Mon, 27 Nov 2023 16:12:44 +0100 Subject: [PATCH 8/8] Update build toolchain to RC --- .github/workflows/build.yml | 20 +++++++++---------- .../{beta-build.yml => rc-build.yml} | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) rename .github/workflows/{beta-build.yml => rc-build.yml} (83%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 788f8d4726..62c5702b52 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,15 +16,15 @@ jobs: runs-on: ubuntu-latest steps: - name: normal check out repo - if: inputs.build-type != 'nightly' && inputs.build-type != 'beta' + if: inputs.build-type != 'nightly' && inputs.build-type != 'rc' uses: actions/checkout@v3 - name: nightly check out repo if: inputs.build-type == 'nightly' uses: actions/checkout@v3 with: ref: 'community' - - name: beta check out repo - if: inputs.build-type == 'beta' + - name: rc check out repo + if: inputs.build-type == 'rc' uses: actions/checkout@v3 with: ref: 'release/1.0' @@ -82,19 +82,19 @@ jobs: asset_name: deluge-nightly.zip # name to upload the release as, use $$ to insert date (YYYYMMDD) and 6 letter commit hash asset_content_type: application/zip # required by GitHub API max_releases: 30 # optional, if there are more releases than this matching the asset_name, the oldest ones are going to be deleted - - name: Create beta archive - if: inputs.build-type == 'beta' + - name: Create rc archive + if: inputs.build-type == 'rc' run: | - zip -j ./beta.zip build/Release/deluge*.bin - - name: Deploy beta zip to releases - if: inputs.build-type == 'beta' + zip -j ./rc.zip build/Release/deluge*.bin + - name: Deploy rc zip to releases + if: inputs.build-type == 'rc' uses: WebFreak001/deploy-nightly@v2.0.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # automatically provided by github actions with: upload_url: https://uploads.github.com/repos/SynthstromAudible/DelugeFirmware/releases/123368988/assets{?name,label} # find out this value by opening https://api.github.com/repos///releases in your browser and copy the full "upload_url" value including the {?name,label} part release_id: 123368988 # same as above (id can just be taken out the upload_url, it's used to find old releases) - asset_path: ./beta.zip # path to archive to upload - asset_name: deluge-beta.zip # name to upload the release as, use $$ to insert date (YYYYMMDD) and 6 letter commit hash + asset_path: ./rc.zip # path to archive to upload + asset_name: deluge-rc.zip # name to upload the release as, use $$ to insert date (YYYYMMDD) and 6 letter commit hash asset_content_type: application/zip # required by GitHub API max_releases: 30 # optional, if there are more releases than this matching the asset_name, the oldest ones are going to be deleted diff --git a/.github/workflows/beta-build.yml b/.github/workflows/rc-build.yml similarity index 83% rename from .github/workflows/beta-build.yml rename to .github/workflows/rc-build.yml index c847dbcdb9..c3d9ea9cc3 100644 --- a/.github/workflows/beta-build.yml +++ b/.github/workflows/rc-build.yml @@ -1,4 +1,4 @@ -name: Beta Build +name: RC Build on: workflow_dispatch: # allows manual triggering @@ -12,8 +12,8 @@ on: - 'release/1.0' jobs: - beta-build: + rc-build: uses: ./.github/workflows/build.yml with: firmware-retention-days: 30 - build-type: 'beta' + build-type: 'rc'