Skip to content

Feature: Performance View - #711

Merged
PaulFreund merged 126 commits into
communityfrom
feature/performance-session-view
Dec 11, 2023
Merged

Feature: Performance View#711
PaulFreund merged 126 commits into
communityfrom
feature/performance-session-view

Conversation

@seangoodvibes

@seangoodvibes seangoodvibes commented Nov 11, 2023

Copy link
Copy Markdown
Collaborator

Performance View

20907a86d7c1dbc258b98cb31aced7b2fd7a8055_2_1332x1000

Description:

Polyend Play inspired Performance View for the Deluge.

Each column represents a different "FX" and each pad/row in the column corresponds to a different FX value.

Specifications:

  • Perform FX menu to edit Song level parameters and enable/disable editing mode.
  • 16 FX columns
    • 1 Param assigned to each column
  • 8 FX values per column
    • Long press pads in a column to change value momentarily and reset it (to the value before the pad was pressed) upon pad release
    • Short press pads in a column to the change value until you press the pad again (resetting it to the value before the pad was pressed)
  • Editing mode to edit the FX values assigned to each pad and the parameter assigned to each FX column
  • Save defaults as PerformanceView.xml file
    • Adjustable default Values assigned to each FX column via "Value" editing mode or PerformanceView.xml
    • Adjustable default Param assigned to each FX column via "Param" editing mode or PerformanceView.xml
    • Adjustable default "held pad" settings for each FX column via Performance View or PerformanceView.xml (simply change a held pad in Performance View and save the layout to save the layout with the held pads).
  • Load defaults from PerformanceView.xml file

Usage:

1) Enter performance view from song view / grid view / arranger view by pressing keyboard button

2) Short press a pad in the columns to hold that pad's value (parameter and held value is displayed on the screen)

  • Note: If you save the layout while pad's are in a "held" state, the next time you re-load that layout it will re-load the held pad's and change the associated parameter's value based on the previous held state.

3) Long press a pad in the columns to play the FX but not hold it (when you let go of the pad it will snap back to previous value).

4) You can edit the default values for each pad in the Performance View by entering a "Value Editing Mode." Here are the instructions for Value Editing mode:

Enter using Shift + Keyboard button

or

Enter using the menu

  • Enter/Exit Editing Mode by pressing down on the Select Encoder to open up the Perform FX Menu
  • In the Perform FX menu, select the "Editing Mode" sub menu and press down on Select Encoder to enter the menu
  • Change Editing Mode to "Value"

Value Editing Mode:

  • While in the Value Editor, pressing any pad on the grid will open up the menu corresponding to the parameter for that pad. It will display the current value assigned to that pad when you pressed it.
  • You can edit that pad's value by turning the select encoder while selecting a single pad (so it's highlighted white) or holding down on that pad. The updated value will be reflected on the display.
  • After you have edited a value, the Save button will start flashing to indicate that you have "Unsaved" changes. Press the save button to save your changes. Once saved, the Save button will stop blinking. To avoid being distracting, the save button will only blink when you are in editing mode. If you exit editing mode it will stop blinking and if you re-enter editing mode it will blink again to remind you that you have unsaved changes.
  • You can re-load saved changes using the Load button. This will cause you to lose unsaved changes and the Save button will stop blinking.
  • Defaults are saved in an XML file on your SD card called "PerformanceView.XML" - deleting this file will cause the PerformanceView to revert back to its regular default values for each pad.
  • Once you are done with editing mode, repeat the steps above to set editing mode back to "Disabled" and exit out of the menu to use Performance View in its regular state

5) You can edit the Parameter assigned to each FX column by entering a "Param Editing Mode." Here are the instructions for Param Editing mode:

Enter using Shift + Keyboard button. You will need to cycle passed the Value Editing Mode to enter the Param Editing Mode.

or

Enter using the menu

  • Enter/Exit Editing Mode by pressing down on the Select Encoder to open up the Perform FX Menu
  • In the Perform FX menu, select the "Editing Mode" sub menu and press down on Select Encoder to enter the menu
  • Change Editing Mode to "Param"

Param Editing Mode:

  • Param Editing will show you an overview of the parameters that are assignable to the FX columns in Performance View by lighting dimly the shortcut pads for these parameters.
  • Parameters that have been assigned to one or more columns will have their shortcut pads lit up bright white.
  • Press on a shortcut pad to illuminate the FX columns that that parameter has been assigned to.
  • While holding a shortcut pad, press on the FX columns to assign or unassign a parameter to/from a column.
  • Press <> + back to clear all existing Parameter assignments.
  • When a Parameter has not been assigned to a column, that column will be lit grey and be unusable in Performance View until you assign a Parameter. This applies to editing the values for that FX column as well (assign a Parameter first, then you can edit the values).
  • Parameters are saved to PerformanceView.xml. You can manually edit the Parameters in the xml as well, but you must use the exact Parameter names. It is recommended to save a fresh PerformanceView.xml and back it up so you have a record of the Parameter Names.

6) You can Undo/Redo your changes in Performance View

Default FX and Colour Assignments

  • The default Param and Colour Assignments for each FX column in Performance View are as follows
  • Note: if you re-arrange the parameters to different FX columns, they will bring the colours noted below with them.

Columns:

Red:
1 = LPF Cutoff
2 = LPF Resonance

Orange:
3 = HPF Cutoff
4 = HPF Resonance

Yellow:
5 = Bass EQ
6 = Treble EQ

Light Green:
7 = Reverb

Light Blue:
8 = Delay Amount
9 = Delay Rate

Light Pink:
10 = MOD-FX Rate
11 = MOD-FX Depth
12 = MOD-FX Feedback
13 = MOD-FX Offset

Dark Pink:
14 = Decimation
15 = Bitcrush

Dark Blue:
16 = Stutter Rate + Stutter Trigger

PR Summary

Summary of additions provided as part of this PR:

  • New performance view (accessible using the Keyboard button from Song View and Arranger View)
  • Render "Song View" on the display in Song View
  • Render "Arranger View" on the display in Arranger View
  • Add new Song FX menu to Song View and Arranger View (accessed by pressing Select Encoder)
  • Adjusted Quantized Stutter implementation from PR Quantized Stutter FX #357 so that it does not need to change the value of the stutter rate parameter in order to do it's quantized stutter calculation

Reduced performance session view code to barebones components of session view so that the view could be built up from there
- Assigned params to each column on the grid
- Pressing a pad in a column changes the value and releasing and releasing the pad sets the value back to previous value before pad was pressed
- Rendered colours on the grid
- Rendered pressed pad a blur colour
- Updated param assignments to column

- Assigned colours to columns (but the blur and full colour aren't exactly right) - tail colour is good

- Some bugs with values - I think it's accidentally changing the original value in some cases

- Pitch and Portamento don't work (should probably remove / replace - maybe added EQ instead)

- Need to get stutter trigger working from pad press
- Fixed bug that accidentally changed original param value
- Fixed bug that de-selected column if you pressed more than one pad
- Shifted LPF and HPF left and inserted EQ Bass and Treble in place of Pitch and Portamento
- Attempted to get stutter working (not working yet)
- Fixed colour shading of pressed pad (changed it from blur colour to white)
- Removed blurColour constant array definition
Stutter is working now!
- Updated rendering of pads when entering performance view
- Updated affect entire selection when entering performance view
- Updated display to render "Performance Mode" when entering performance view
- Removed other functions that remained from session view that are not needed
- Distinguished between short and long presses in order to enable locking FX
- Add tracking of what pads are locked
- Updated pad rendering to not be lit "bright" when column is locked and not currently being held

Some bugs identified (to be fixed):
- can't quickly switch performance mode locks
- need to make sure to exit stuttering if stuttering lock is enabled and you are leaving the performance view
Activated keyboard button LED when in performance mode

bug to fix:
- disabling locks when exiting performance mode
- Fixed bug which wouldnt allow quick switching of held fx pads in a column.

- Fixed bug which wouldnt allow quick toggling of a single fx pad in a column
Fixed bug where if playback cursor is running in session view and you switch to performance view that the cursor gets stuck on the grid.

Simple fix is to just clear the playhead.
- Fixed a bug where stutter didn't disable and re-enable properly if you were doing quick stutter switches in the stutter column
- Cleaned up the code.
 - Removed excess functions and variables not used.
 - Re-ordered functions to group them together in a more meaningful order
 - Removed unnecessary includes
@seangoodvibes
seangoodvibes marked this pull request as draft November 11, 2023 19:59
Refactored some of the display code to have less duplication

Renamed display functions to be more descriptive.

Added some code documentation.
Fixed a bug whereby stutter was going back to previous value when you were using the quantized stutter community feature
Broke padAction into two sub-functions: padPressAction and padReleaseAction
clean up of padPressAction and padReleaseAction functions so that they can be called to reset/erase grid.
- Added press <> + back combo to clear changed values and reset them back to original values before changes were made
- Renamed "Performance Mode" to "Performance View" on the display
Just a quick function name change reference that was forgotten
<> + back now clears stutter also
Added code to enable you to leave performance view when stutter is enabled by first disabling stutter
Added ability to load and save default FX values for each column and row in the deluge grid by using the Load and Save buttons.

Still work to do to clean up the code and load defaults at run-time.

Also considering a UX for setting defaults directly on the deluge.
Refactoring of code to read/write default FX values from PerformanceView.XML

Implemented changes to XML structure per advice from dev team.
- Some updates to rendering of display

- Started work on editing mode for performance view
- Added editing mode so you can edit default values assigned to each pad on the grid
- Enter/Exit Editing mode by pressing Select encoder
- In Editing Mode, press and hold a pad or select the pad (white) and turn select encoder to adjust value
- When changes have been made, the Save button will flash to indicate unsaved changes.
- Pressing Load/Save will stop save button from flashing
- Load button loads defaults previously saved
- Save button saves your changes
- Defaults are loaded when the view is opened

- Also disabled Horizontal and Vertical encoder button actions
- Also disabled Back button action as undo doesn't work well in this view (at the moment)
Accidentally removed ability to clear performance effects using the horizontal encoder button and back button in previous commit

This commit fixes that
Fixed issue where select encoder might reduce knobPos < 0 or increase knobPos > 128
Fixed bug where you couldn't disable stutter after triggering it with stutter pads

@sapphire-arches sapphire-arches left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm somewhat concerned about the memory use of this feature but it's probably worth the squeeze. For posterity after this change, we're 23712 bytes larger than the nightly from yesterday.

Comment thread src/deluge/model/action/action_logger.cpp Outdated
@seangoodvibes seangoodvibes changed the title [Ready for Review] Feature: Performance View Feature: Performance View Dec 2, 2023
- Bug fix in song view: fixed an issue where a popup would overlap with the "Song View" display behind it
As part of performance view the implementation of quantized stutter was adjusted so that the stutter rate parameter didn't need to be changed to 0 prior to doing the quantized stutter calculation.

@m-m-adams m-m-adams left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't looked at performance_session_view yet

Comment thread src/deluge/gui/views/performance_session_view.h Outdated
Comment thread src/deluge/model/mod_controllable/mod_controllable_audio.cpp Outdated
Adjusted default value range for delay amount to be 0 - 63 with each pad increasing in increment values of 9.
Per suggestions from @soymonitus I have updated the defaults values for stutter when quantized stutter is enabled such that pads are staggered as follows:

Row 0 = 4th = Stutter Rate -52
Row 1-2 = 8ths = Stutter Rate -37 and -22
Row 3-4 = 16ths = Stutter Rate -7 and +8
Row 5-6 = 32nds = Stutter Rate +23 and +38
Row 7 = 64ths = Stutter Rate +53

I also updated the display to show the quantized stutter strings instead of the quantize stutter rate when quantized stutter is enabled
Undoing changes previously made to quantized stutter.

Disabled starting stutter when in default editing mode.
Comment thread src/deluge/model/mod_controllable/mod_controllable_audio.h Outdated

@m-m-adams m-m-adams left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is looking pretty good! I'd like to see the change from using knob pos to directly using param values instead for future compatibility, no reason to limit the internal resolution of performance view to 7 bits

Comment thread src/deluge/gui/views/performance_session_view.cpp Outdated
if (fxPress[xDisplay].previousKnobPosition == kNoSelection) {
int32_t oldParameterValue =
modelStackWithParam->autoParam->getValuePossiblyAtPos(view.modPos, modelStackWithParam);
fxPress[xDisplay].previousKnobPosition =

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should be storing the param value and not the knob pos - params have higher accuracy than knob position allows and this could cause issues in the future

Also you're converting the knob pos back to a param value before using it anyway

@seangoodvibes seangoodvibes Dec 5, 2023

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this change need to be a part of this PR? As much as I want to make it, I don't know if I have the energy atm to go through and change everything from knobPos to value. I know it's not a complex change, but I do use the knobPos for the value displayed on the screen, for quantized stutter calculations, for delay calculations, etc so I would want to make sure I'm not breaking things.

/// if you're in the value editor, pressing a column and changing the value will also open the sound editor
/// menu for the parameter to show you the current value in the menu
/// in regular performance view, this function will also update the parameter value shown on the display
bool PerformanceSessionView::setParameterValue(ModelStackWithThreeMainThings* modelStack, Param::Kind paramKind,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function should work on param values instead of knob pos - will allow greater accuracy in the future (particularly for things like stutter where the knob pos is very coarse)


if (modelStackWithParam && modelStackWithParam->autoParam) {

if (modelStackWithParam->getTimelineCounter()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a sanity check to make sure the timeline counter is the song level global effectable?

@seangoodvibes seangoodvibes Dec 5, 2023

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea it's a sanity check to make sure you're dealing with the same model stack as the active mod controllable stack. I've seen it used elsewhere in the codebase so I just adopted the same practice.


/// converts grid pad press yDisplay into a knobPosition value default
/// this will likely need to be customized based on the parameter to create some more param appropriate ranges
int32_t PerformanceSessionView::calculateKnobPosForSinglePadPress(int32_t xDisplay, int32_t yDisplay) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should use the param value range instead of knobpos

/// if no XML file exists, load default layout (paramKind, paramID, xDisplay, yDisplay, rowColour, rowTailColour)
void PerformanceSessionView::loadDefaultLayout() {
for (int32_t xDisplay = 0; xDisplay < kDisplayWidth; xDisplay++) {
memcpy(&layoutForPerformance[xDisplay], &defaultLayoutForPerformance[xDisplay], sizeParamsForPerformance);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should implement a copy method instead of using memcpy - memcpy is brittle and any speed differences won't matter here

@seangoodvibes seangoodvibes Dec 5, 2023

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you mean like this?

copyLayout(layoutForPerformance[xDisplay], defaultLayoutForPerformance[xDisplay]);

PerformanceSessionView::copyLayout(ParamForPerformance& layoutTo, ParamForPerformance& layoutFrom) {

layoutTo.paramKind = layoutFrom.paramKind;
layoutTo.paramID = layoutFrom.paramID;
layoutTo.xDisplay = layoutFrom.xDisplay;
layoutTo.yDisplay = layoutFrom.yDisplay;
layoutTo.rowColour[0] = layoutFrom.rowColour[0];
layoutTo.rowColour[1] = layoutFrom.rowColour[1];
layoutTo.rowColour[2] = layoutFrom.rowColour[2];
layoutTo.rowTailColour[0] = layoutFrom.rowTailColour[0];
layoutTo.rowTailColour[1] = layoutFrom.rowTailColour[1];
layoutTo.rowTailColour[2] = layoutFrom.rowTailColour[2];

}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to look in more detail but this would generate a lot more code compared to memcpy and is more error prone, any particular reason?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to look in more detail but this would generate a lot more code compared to memcpy and is more error prone, any particular reason?

Yea cause I'd need to create copy functions for each type of struct I'm trying to copy (so 3 copy functions). I initially thought of this but thought memcpy was cleaner so I went with memcpy.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to look in more detail but this would generate a lot more code compared to memcpy and is more error prone, any particular reason?

In case something is added to the type that requires re initialization, or otherwise wouldn't be valid following a memcpy. I don't have super strong opinions but memcpy on a class makes me nervous

Using memcpy to move over the colour arrays individually would make sense to me

- Changed strings from const to #define
- Changed const definitions to constexpr
- Changed ParamsForPerformance(){} constructor to initialize the struct variables
- Removed orphaned variable from mod_controllable_audio bool beginQuantizedStutter
Reduced the scope of undo-redo actions in performance view to just undo/re-do held presses.

You can no longer undo/redo loading a layout, changing layout values or re-assigning params. Reason being the memory cost was too high.
Moved more code out of the consequence into performance session view ui
Disabled saving logs while in performance view editing mode

Cleared any logs created by sound editor while editing values in editing mode to not create any conflict with undo and the pad's held on the grid
When entering value editing mode, previously held pads get reset and the user needs to select one pad at a time to edit values.
Fixed issue with backed up XML file when saving XML backup of saved changes to param assignments in the param editor.
@PaulFreund
PaulFreund added this pull request to the merge queue Dec 11, 2023
Merged via the queue into community with commit 4501bbf Dec 11, 2023
@m-m-adams
m-m-adams deleted the feature/performance-session-view branch December 24, 2023 22:08
@sapphire-arches sapphire-arches added this to the Release 1.1 milestone Jan 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants