|
|
|
04-25-2024, 10:15 PM
|
#25801
|
Human being with feelings
Join Date: Aug 2017
Location: Ottawa, Canada
Posts: 665
|
Quote:
Originally Posted by Geoff Waddington
|
Geoff,
Fix for Reaper <--> Surface "Master Track" solo not working.
Fix below tested and working
Code:
class TrackSolo : public Action
{
....
virtual void Do(ActionContext *context, double value) override
{
if (value == 0.0) return; // ignore button releases
if (MediaTrack *track = context->GetTrack())
{
MediaTrack *masterTrack = GetMasterTrack(NULL);
if (track != masterTrack)
{
double trackSolo = GetMediaTrackInfo_Value(track, "I_SOLO");
CSurf_SetSurfaceSolo(track, CSurf_OnSoloChange(track, ! GetMediaTrackInfo_Value(track, "I_SOLO")), NULL);
}
else
{
int muteSoloFlags = GetMasterMuteSoloFlags();
if (muteSoloFlags & 2)
muteSoloFlags &= !2;
else
muteSoloFlags |= 2;
CSurf_OnSoloChange(masterTrack, muteSoloFlags);
}
}
}
};
__________________
AKA: Roy Wallingford
|
|
|
04-26-2024, 03:39 AM
|
#25802
|
Human being with feelings
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,569
|
Quote:
Originally Posted by jacksoonbrowne
Geoff,
Fix for Reaper <--> Surface "Master Track" solo not working.
Fix below tested and working
Code:
class TrackSolo : public Action
{
....
virtual void Do(ActionContext *context, double value) override
{
if (value == 0.0) return; // ignore button releases
if (MediaTrack *track = context->GetTrack())
{
MediaTrack *masterTrack = GetMasterTrack(NULL);
if (track != masterTrack)
{
double trackSolo = GetMediaTrackInfo_Value(track, "I_SOLO");
CSurf_SetSurfaceSolo(track, CSurf_OnSoloChange(track, ! GetMediaTrackInfo_Value(track, "I_SOLO")), NULL);
}
else
{
int muteSoloFlags = GetMasterMuteSoloFlags();
if (muteSoloFlags & 2)
muteSoloFlags &= !2;
else
muteSoloFlags |= 2;
CSurf_OnSoloChange(masterTrack, muteSoloFlags);
}
}
}
};
|
Could you please test the following and see if it does the same thing:
Code:
virtual void Do(ActionContext *context, double value) override
{
if (value == 0.0) return; // ignore button releases
if (MediaTrack *track = context->GetTrack())
{
if (track != GetMasterTrack(NULL))
CSurf_SetSurfaceSolo(track, CSurf_OnSoloChange(track, ! GetMediaTrackInfo_Value(track, "I_SOLO")), NULL);
else
{
int muteSoloFlags = GetMasterMuteSoloFlags();
if (muteSoloFlags & 2)
muteSoloFlags &= !2;
else
muteSoloFlags |= 2;
CSurf_SetSurfaceSolo(track, CSurf_OnSoloChange(track, muteSoloFlags), NULL);
}
}
}
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
|
|
|
04-26-2024, 09:41 AM
|
#25803
|
Human being with feelings
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,569
|
Just an FYI regarding the Learn redesign.
The template files will be renamed:
Code:
FXLayouts.zon becomes FXRowLayout.zon
SurfaceFXLayout.zone becomes FXWidgetLayout.zon
Code:
Zone FXRowLayout
Channels 8
"" ""
"Shift" ""
"Control" ""
"Option" ""
ZoneEnd
Code:
Zone FXWidgetLayout
Rotary FXParam RingStyle=Dot
DisplayUpper FixedTextDisplay
DisplayLower FXParamValueDisplay
ZoneEnd
#WidgetTypes Rotary RotaryPush Fader
#DisplayRows DisplayUpper DisplayLower
#RingStyles Dot Fill BoostCut Spread
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
|
|
|
04-26-2024, 11:01 AM
|
#25804
|
Human being with feelings
Join Date: Sep 2023
Posts: 752
|
I just tried Freex suggestion for the Master Track and I got to something that I like and that works fine however this made me wonder about something.
Is it possible to enter an associated zone on a surface by pressing a button on another surface?
My buttons are on my first surface but I'd like the MasterTrack zone to be activated on the second surface.
Also, related to the Master, is there an action to toggle between Mono or Mid/Side Mode?
Thanks guys
|
|
|
04-26-2024, 12:06 PM
|
#25805
|
Human being with feelings
Join Date: Jun 2021
Posts: 23
|
Quote:
Originally Posted by TheFancyWolf
Appreciate it! That makes sense, sorry I'm new. Yes this now works and I can assign different actions and we have them fill both Display 1 and 2 Upper and Lower.
The lower display is offset, but I believe this is due to the bug I reported they are fixing in firmware next week, so I wouldn't worry about it for now. I experienced similar bugs using DrivenByMoss. If it's not fixed in their firmware, looks straightforward like we just have some of the values wrong, as Snare Btm on track 8 isn't shown in Display1 and has kicked down to Display2 offsetting everything.
Let me know what I can do next, thanks!
|
Quote:
Originally Posted by Geoff Waddington
Great news !!
Let's wait until they fix the firmware, then look at supporting colour.
Then you could go ahead and rename MCU.mst to Icon.mst and post it here, so that we can include it in the support files.
|
Any update on this? I think I must have done something wrong with my config file. TheFancyWolf Could you please upload your files?
|
|
|
04-26-2024, 12:16 PM
|
#25806
|
Human being with feelings
Join Date: Jul 2007
Location: New Joisey
Posts: 6,143
|
Quote:
Originally Posted by fourdogslong
I just tried Freex suggestion for the Master Track and I got to something that I like and that works fine however this made me wonder about something.
Is it possible to enter an associated zone on a surface by pressing a button on another surface?
My buttons are on my first surface but I'd like the MasterTrack zone to be activated on the second surface.
Also, related to the Master, is there an action to toggle between Mono or Mid/Side Mode?
Thanks guys
|
For AssociatedZones, this is possible with the Broadcast/Listen functionality found in the Advanced panel. However, the MasterTrack zone is not an associated zone from what I understand. But you could, for instance, use one surface to open an FXMenu on another, or a Send zone on another. You'd just setup the first surface as a Broadcaster, not set it to Listen to itself for that zone type (e.g. the FXMenu's), then setup the second surface as a Listener for the FXMenu's. That functionality is already there.
|
|
|
04-26-2024, 12:22 PM
|
#25807
|
Human being with feelings
Join Date: Sep 2023
Posts: 752
|
Quote:
Originally Posted by Funkybot
For AssociatedZones, this is possible with the Broadcast/Listen functionality found in the Advanced panel. However, the MasterTrack zone is not an associated zone from what I understand. But you could, for instance, use one surface to open an FXMenu on another, or a Send zone on another. You'd just setup the first surface as a Broadcaster, not set it to Listen to itself for that zone type (e.g. the FXMenu's), then setup the second surface as a Listener for the FXMenu's. That functionality is already there.
|
Thanks Funkybot, I'll look into that!
|
|
|
04-26-2024, 01:44 PM
|
#25808
|
Human being with feelings
Join Date: Jul 2007
Location: New Joisey
Posts: 6,143
|
This may be an esoteric feature request, but I'm sure others will be able to find use for it beyond this specific plugin/use-case...
Background: The Strymon Big Sky reverb has 12 different reverb modes, but they did it in a way where each reverb mode has it's own unique decay, pre-delay, low-end, modulation, etc. settings. Example: Room_Decay, Hall_Decay, Plate_Decay, etc.
Issue: Now, multiply 8 or so parameters across 12 different modes, and you have a mapping nightmare. SubZones don't work great because you'd need 12 of them and it would be difficult to activate the correct one. Mapping them any other way makes it difficult to find the parameter you're looking for.
Proposed Solution: Automatically trigger SubZones based on an on-screen action. Something like an IF THEN for FX Params that could be combined to trigger CSI actions. Example:
Code:
Zone "VST3: BigSky (Strymon)" "BigSky"
IF FXParam 1 = 0.0 THEN GoSubzone "BigSky_Room"
IF FXparam 1 = 0.09 THEN GoSubZone "BigSky_Hall"
IF FXparam 1 = 0.17 THEN GoSubZone "BigSky_Plate"
etc.
...so I could have that text in all the zones for that plugin, turn the FXParam1 knob on-screen in the plugin, and the appropriate SubZone would automatically load.
I'm sure that syntax could be expanded for other clever uses.
|
|
|
04-26-2024, 02:43 PM
|
#25809
|
Human being with feelings
Join Date: Aug 2017
Location: Ottawa, Canada
Posts: 665
|
Quote:
Originally Posted by Geoff Waddington
Could you please test the following and see if it does the same thing:
Code:
virtual void Do(ActionContext *context, double value) override
{
if (value == 0.0) return; // ignore button releases
if (MediaTrack *track = context->GetTrack())
{
if (track != GetMasterTrack(NULL))
CSurf_SetSurfaceSolo(track, CSurf_OnSoloChange(track, ! GetMediaTrackInfo_Value(track, "I_SOLO")), NULL);
else
{
int muteSoloFlags = GetMasterMuteSoloFlags();
if (muteSoloFlags & 2)
muteSoloFlags &= !2;
else
muteSoloFlags |= 2;
CSurf_SetSurfaceSolo(track, CSurf_OnSoloChange(track, muteSoloFlags), NULL);
}
}
}
|
Confirmed working
__________________
AKA: Roy Wallingford
|
|
|
04-26-2024, 03:02 PM
|
#25810
|
Human being with feelings
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,569
|
Quote:
Originally Posted by jacksoonbrowne
Confirmed working
|
Thanks for testing !
Just a tad more compact.
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
|
|
|
04-26-2024, 03:08 PM
|
#25811
|
Human being with feelings
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,569
|
Quote:
Originally Posted by Funkybot
This may be an esoteric feature request, but I'm sure others will be able to find use for it beyond this specific plugin/use-case...
Background: The Strymon Big Sky reverb has 12 different reverb modes, but they did it in a way where each reverb mode has it's own unique decay, pre-delay, low-end, modulation, etc. settings. Example: Room_Decay, Hall_Decay, Plate_Decay, etc.
Issue: Now, multiply 8 or so parameters across 12 different modes, and you have a mapping nightmare. SubZones don't work great because you'd need 12 of them and it would be difficult to activate the correct one. Mapping them any other way makes it difficult to find the parameter you're looking for.
Proposed Solution: Automatically trigger SubZones based on an on-screen action. Something like an IF THEN for FX Params that could be combined to trigger CSI actions. Example:
Code:
Zone "VST3: BigSky (Strymon)" "BigSky"
IF FXParam 1 = 0.0 THEN GoSubzone "BigSky_Room"
IF FXparam 1 = 0.09 THEN GoSubZone "BigSky_Hall"
IF FXparam 1 = 0.17 THEN GoSubZone "BigSky_Plate"
etc.
...so I could have that text in all the zones for that plugin, turn the FXParam1 knob on-screen in the plugin, and the appropriate SubZone would automatically load.
I'm sure that syntax could be expanded for other clever uses.
|
Are you saying that Room_Decay, Hall_Decay, Plate_Decay, all have different param numbers ?
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
|
|
|
04-26-2024, 05:05 PM
|
#25812
|
Human being with feelings
Join Date: Jul 2007
Location: New Joisey
Posts: 6,143
|
Quote:
Originally Posted by Geoff Waddington
Are you saying that Room_Decay, Hall_Decay, Plate_Decay, all have different param numbers ?
|
Yessir! That's exactly it. Highly annoying.
See below:
Code:
ZoneEnd
0 MIX
1 EFFECT TYPE
2 Input
3 Output
4 BLOOM_Decay
5 BLOOM_PreDelay
6 BLOOM_Tone
7 BLOOM_MOD
8 BLOOM LowEnd
9 BLOOM_Length
10 BLOOM_Feedback
11 BLOOM_Hold
12 BLOOM_InfFreeze
13 CLOUD_Decay
14 CLOUD_PreDelay
15 CLOUD_Tone
16 CLOUD_MOD
17 CLOUD_LowEnd
18 CLOUD_Diffusion
19 CLOUD_Hold
20 CLOUD_InfFreeze
21 CHORALE_Decay
22 CHORALE_PreDelay
23 CHORALE_Tone
24 CHORALE_MOD
25 CHORALE_Resonance
26 CHORALE_Vowel
27 CHORALE_Hold
28 CHORALE_InfFreeze
29 SHIMMER_Decay
30 SHIMMER_PreDelay
31 SHIMMER_Tone
32 SHIMMER_MOD
33 SHIMMER_LowEnd
34 SHIMMER_Mode
35 SHIMMER_Shift1
36 SHIMMER_Shift2
37 SHIMMER_Amount
38 SHIMMER_Hold
39 SHIMMER_InfFreeze
40 MAGNETO_DelayTime
41 MAGNETO_Feedback
42 MAGNETO_Tone
43 MAGNETO_WowAndFlutter
44 MAGNETO_LowEnd
45 MAGNETO_Diffusion
46 MAGNETO_Heads
47 MAGNETO_Spacing
48 MAGNETO_Hold
49 MAGNETO_InfFreeze
50 NONLINEAR_Time
51 NONLINEAR_Feedback
52 NONLINEAR_Tone
53 NONLINEAR_MOD
54 NONLINEAR_LowEnd
55 NONLINEAR_Shape
56 NONLINEAR_Diffusion
57 NONLINEAR_Decay
58 NONLINEAR_Level
59 NONLINEAR_ModSpeed
60 NONLINEAR_Hold
61 NONLINEAR_InfFreeze
62 REFLECTIONS_RoomSize
63 REFLECTIONS_PreDelay
64 REFLECTIONS_Damping
65 REFLECTIONS_MOD
66 REFLECTIONS_LowEnd
67 REFLECTIONS_RoomShape
68 REFLECTIONS_X
69 REFLECTIONS_Y
70 REFLECTIONS_Hold
71 REFLECTIONS_InfFreeze
72 ROOM_Decay
73 ROOM_PreDelay
74 ROOM_Tone
75 ROOM_MOD
76 ROOM_LowEnd
77 ROOM_Diffusion
78 ROOM_Size
79 ROOM_Hold
80 ROOM_InfFreeze
81 HALL_Decay
82 HALL_PreDelay
83 HALL_Tone
84 HALL_MOD
85 HALL_LowEnd
86 HALL_MidEQ
87 HALL_Size
88 HALL_Hold
89 HALL_InfFreeze
90 PLATE_Decay
91 PLATE_PreDelay
92 PLATE_Tone
93 PLATE_MOD
94 PLATE_LowEnd
95 PLATE_Size
96 PLATE_Hold
97 PLATE_InfFreeze
98 SPRING_Decay
99 SPRING_PreDelay
100 SPRING_Tone
101 SPRING_MOD
102 SPRING_LowEnd
103 SPRING_Dwell
104 SPRING_Springs
105 SPRING_Hold
106 SPRING_InfFreeze
107 SWELL_Decay
108 SWELL_PreDelay
109 SWELL_Tone
110 SWELL_MOD
111 SWELL_LowEnd
112 SWELL_RiseTime
113 SWELL_Mode
114 SWELL_Hold
115 SWELL_InfFreeze
116 BYPASS
117 Bypass
118 Wet
119 Delta
I didn't even notice until now that they stuck them in alphabetical order too! It doesn't even follow the algorithm order on the GUI.
Last edited by Funkybot; 04-26-2024 at 05:31 PM.
|
|
|
04-27-2024, 05:15 AM
|
#25813
|
Human being with feelings
Join Date: Sep 2017
Location: London, England.
Posts: 5,003
|
Quote:
Originally Posted by Geoff Waddington
Are you saying that Room_Decay, Hall_Decay, Plate_Decay, all have different param numbers ?
|
There are lots of plugins like this. They usually have some "mode" or "model" parameter that determines which other parameters are active.
My approach has been to create a single plugin FX chain for each mode/model, renaming the FX instance within and using that to load the appropriate map.
If there was a way to have it work with a single map, that would be cool though
|
|
|
04-27-2024, 07:52 AM
|
#25814
|
Human being with feelings
Join Date: Jul 2007
Location: New Joisey
Posts: 6,143
|
Quote:
Originally Posted by MixMonkey
There are lots of plugins like this. They usually have some "mode" or "model" parameter that determines which other parameters are active.
My approach has been to create a single plugin FX chain for each mode/model, renaming the FX instance within and using that to load the appropriate map.
If there was a way to have it work with a single map, that would be cool though
|
Yeah, I was thinking auto-launch subzones for each based on some other FXParam value. I think an If/Then syntax would be easy enough for everyone to understand and potentially open up a lot of doors for more advanced users that we haven't even thought about yet.
The FX Chain approach is a good workaround as long as you know which mode you'll ultimately land on. It wouldn't always work for me because I may actually not know which mode I'll land on. Example: with Big Sky, sometimes I'll start out thinking I want Hall, but I'll land on a Room with a long decay, or even a Plate - just trying things out until I land on what sounds good.
I even thought about putting all the decay params on 8 faders, then all the pre-delays on Shift modified versions, then tone on Alt, etc. But that would only work up to 8 modes and this has 12.
|
|
|
04-27-2024, 04:59 PM
|
#25815
|
Human being with feelings
Join Date: Sep 2017
Location: London, England.
Posts: 5,003
|
Quote:
Originally Posted by Funkybot
I was thinking auto-launch subzones for each based on some other FXParam value.
|
It would allow the surface to configure itself based on the choices made by the user, and most importantly, it would recall them when the plugin is closed and re-opened.
This is something that has bugged me for ages. I put together an awesome editor for the DIVA VSTi. I can pick oscillator, filter and envelope types with SubZones tailored to each model, configuring the surface accordingly.
It works beautifully.... until I switch to another track and then return. When I come back to the DIVA track, the synth itself is configured how I left it, but the surface has reverted to the default selection of oscillator, filter and envelope types as set in the FX.zon. So I have to manually reset the selections so that the surface controls match the synth once more.
Needless to say, this is a rubbish workflow that was quickly abandoned in favor of a few preset DIVA configurations stored as FX chains.
@funkybot's suggestion would allow the appropriate SubZones to be recalled when the plugin is re-opened, because the module types appear in the plugin parameters. Thus the surface would always match the changes made to the plugin's configuration.
|
|
|
04-27-2024, 05:48 PM
|
#25816
|
Human being with feelings
Join Date: Jan 2022
Location: Unifield
Posts: 397
|
Quote:
Originally Posted by Funkybot
Yeah, I was thinking auto-launch subzones for each based on some other FXParam value. I think an If/Then syntax would be easy enough for everyone to understand and potentially open up a lot of doors for more advanced users that we haven't even thought about yet.
The FX Chain approach is a good workaround as long as you know which mode you'll ultimately land on. It wouldn't always work for me because I may actually not know which mode I'll land on. Example: with Big Sky, sometimes I'll start out thinking I want Hall, but I'll land on a Room with a long decay, or even a Plate - just trying things out until I land on what sounds good.
I even thought about putting all the decay params on 8 faders, then all the pre-delays on Shift modified versions, then tone on Alt, etc. But that would only work up to 8 modes and this has 12.
|
What I do, (having 16 tracks) is add Buttons that set the FXParam value to a particular value and goto an FX SubZone mapped for that case.
Code:
DisplayUpper3 FixedTextDisplay "SingEch"
Select3 FXParam 4 [ 0.00 ] Feedback=No
InvertFB+Select3 GoSubZone "VST: MyEcho-2" Feedback=Yes
//
DisplayUpper4 FixedTextDisplay "DoubEch"
Select4 FXParam 4 [ 1.00 ] Feedback=No
InvertFB+Select4 GoSubZone "VST: MyEcho-3" Feedback=Yes
It would be great to be able to have an Encoder navigate to each SubZone depending on it's own value, but I believe (and I've been hoping for this for ages) it would be more important to be able to Broadcast that FX SubZone navigation to other surfaces so that moving that Encoder could reconfigure the whole surface set and not just the one where the encoder is moved.
|
|
|
04-29-2024, 11:43 AM
|
#25817
|
Human being with feelings
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,569
|
There are 6 buttons on the new Learn Window.
Code:
Delete Map
Erase Control
Edit Alias
Auto Map
Save
Done
If there is a focused FX, launching the new Learn Window places you in Learn mode immediately.
Design question.
If there is already a map, seems like it might be prudent to disable the "Auto Map" button, so that you can't easily clobber the existing map.
If you really want to auto map, you would have to press "Delete Map", then "Auto Map".
Make sense ?
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
|
|
|
04-29-2024, 11:44 AM
|
#25818
|
Human being with feelings
Join Date: Sep 2023
Posts: 752
|
Quote:
Originally Posted by Geoff Waddington
Make sense ?
|
Yes it does.
|
|
|
04-29-2024, 11:47 AM
|
#25819
|
Human being with feelings
Join Date: Sep 2017
Location: London, England.
Posts: 5,003
|
Quote:
Originally Posted by Geoff Waddington
If you really want to auto map, you would have to press "Delete Map", then "Auto Map".
Make sense ?
|
Absolutely
|
|
|
04-29-2024, 12:29 PM
|
#25820
|
Human being with feelings
Join Date: Jul 2007
Location: New Joisey
Posts: 6,143
|
Agree.
|
|
|
04-29-2024, 01:08 PM
|
#25821
|
Human being with feelings
Join Date: Jul 2011
Location: Northern Ireland
Posts: 923
|
Sound sensible.
Should there not be an Edit Map? for existing maps or tweaking them?
Or how do you see that going?
|
|
|
04-29-2024, 01:12 PM
|
#25822
|
Human being with feelings
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,569
|
Quote:
Originally Posted by Freex
Sound sensible.
Should there not be an Edit Map? for existing maps or tweaking them?
Or how do you see that going?
|
Just opening the Window puts you into edit mode if there is an existing map.
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
|
|
|
04-29-2024, 01:16 PM
|
#25823
|
Human being with feelings
Join Date: Jul 2011
Location: Northern Ireland
Posts: 923
|
Quote:
Originally Posted by Geoff Waddington
Just opening the Window puts you into edit mode if there is an existing map.
|
Sweet
|
|
|
04-29-2024, 06:01 PM
|
#25824
|
Human being with feelings
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,569
|
Another design question.
We can eliminate those #Cell markers (and others that it would be necessary to add with the new Learn Window) in the auto generated Zones if we can assume that the following are stable:
Code:
Zone FXRowLayout
Channels 8
"" ""
"Shift" ""
"Control" ""
"Option" ""
ZoneEnd
Code:
Zone FXWidgetLayout
Rotary FXParam RingStyle=Dot
DisplayUpper FixedTextDisplay
DisplayLower FXParamValueDisplay
ZoneEnd
#WidgetTypes Rotary RotaryPush Fader
#DisplayRows DisplayUpper DisplayLower
#RingStyles Dot Fill BoostCut Spread
They actually provide all of the meta data we need to read and write the .zon files without any markers.
I think it's fair to say that folks would expect these files to be stable, it's intuitive.
If you changed one or both, Learn would incorrectly read the files that were generated with prior versions.
The fix is simple, delete the Zone and remap.
I think this is a totally reasonable and minor restriction, it vastly simplifies the coding and improves the visual layout of the Zones.
What say you good folk ?
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
|
|
|
04-29-2024, 06:12 PM
|
#25825
|
Human being with feelings
Join Date: Jul 2007
Location: New Joisey
Posts: 6,143
|
Quote:
Originally Posted by Geoff Waddington
Another design question.
We can eliminate those #Cell markers (and others that it would be necessary to add with the new Learn Window) in the auto generated Zones if we can assume that the following are stable:
Code:
Zone FXRowLayout
Channels 8
"" ""
"Shift" ""
"Control" ""
"Option" ""
ZoneEnd
Code:
Zone FXWidgetLayout
Rotary FXParam RingStyle=Dot
DisplayUpper FixedTextDisplay
DisplayLower FXParamValueDisplay
ZoneEnd
#WidgetTypes Rotary RotaryPush Fader
#DisplayRows DisplayUpper DisplayLower
#RingStyles Dot Fill BoostCut Spread
They actually provide all of the meta data we need to read and write the .zon files without any markers.
I think it's fair to say that folks would expect these files to be stable, it's intuitive.
If you changed one or both, Learn would incorrectly read the files that were generated with prior versions.
The fix is simple, delete the Zone and remap.
I think this is a totally reasonable and minor restriction, it vastly simplifies the coding and improves the visual layout of the Zones.
What say you good folk ?
|
I can't imagine those changing regularly under normal circumstances.
|
|
|
04-29-2024, 08:16 PM
|
#25826
|
Human being with feelings
Join Date: Aug 2017
Location: Ottawa, Canada
Posts: 665
|
Hey Geoff,
I have added a "Jog by 1 measure" Rotary action for the X32.
Tested and working
Can you commit it please
Code:
actions_.Insert("X32TrackVolume", new X32TrackVolume());
actions_.Insert("X32JogByMeasure", new X32JogByMeasure());
actions_.Insert("TrackToggleVCASpill", new TrackToggleVCASpill());
Code:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class X32JogByMeasure : public Action
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{
private:
int lastValue;
public:
virtual const char *GetName() override { return "X32JogByMeasure"; }
X32JogByMeasure() { lastValue = 64; }
virtual void Do(ActionContext *context, double value) override
{
// DEFAULT TO NO ACTION
int reaperAction = 0;
// WHEN JOG RIGHT 1 MEASURE
if (value > lastValue)
reaperAction = 41042;
// WHEN JOG LEFT 1 MEASURE
else if (value < lastValue)
reaperAction = 41043;
// GO JOGGING - RDW :)
if (reaperAction)
DAW::SendCommandMessage(reaperAction);
// CENTER THE ROTARY - MAKE IT APPEAR THAT THE X32 ROTARY IS ENDLESS
lastValue = 64;
ControlSurface *surface = context->GetSurface();
surface->SendOSCMessage("/-stat/userpar/33/value", 64);
}
};
__________________
AKA: Roy Wallingford
|
|
|
04-30-2024, 01:22 AM
|
#25827
|
Human being with feelings
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,569
|
Quote:
Originally Posted by jacksoonbrowne
Hey Geoff,
I have added a "Jog by 1 measure" Rotary action for the X32.
Tested and working
Can you commit it please
Code:
actions_.Insert("X32TrackVolume", new X32TrackVolume());
actions_.Insert("X32JogByMeasure", new X32JogByMeasure());
actions_.Insert("TrackToggleVCASpill", new TrackToggleVCASpill());
Code:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class X32JogByMeasure : public Action
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{
private:
int lastValue;
public:
virtual const char *GetName() override { return "X32JogByMeasure"; }
X32JogByMeasure() { lastValue = 64; }
virtual void Do(ActionContext *context, double value) override
{
// DEFAULT TO NO ACTION
int reaperAction = 0;
// WHEN JOG RIGHT 1 MEASURE
if (value > lastValue)
reaperAction = 41042;
// WHEN JOG LEFT 1 MEASURE
else if (value < lastValue)
reaperAction = 41043;
// GO JOGGING - RDW :)
if (reaperAction)
DAW::SendCommandMessage(reaperAction);
// CENTER THE ROTARY - MAKE IT APPEAR THAT THE X32 ROTARY IS ENDLESS
lastValue = 64;
ControlSurface *surface = context->GetSurface();
surface->SendOSCMessage("/-stat/userpar/33/value", 64);
}
};
|
CSI Actions cannot hold state.
Is this equivalent ?
Code:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class X32JogByMeasure : public Action
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{
public:
virtual const char *GetName() override { return "X32JogByMeasure"; }
virtual void Do(ActionContext *context, double value) override
{
// WHEN JOG RIGHT 1 MEASURE
if (value > 64)
DAW::SendCommandMessage(41042);
// WHEN JOG LEFT 1 MEASURE
else if (value < 64)
DAW::SendCommandMessage(41043);
// CENTER THE ROTARY - MAKE IT APPEAR THAT THE X32 ROTARY IS ENDLESS
context->GetSurface()->SendOSCMessage("/-stat/userpar/33/value", 64);
}
};
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
|
|
|
04-30-2024, 05:37 AM
|
#25828
|
Human being with feelings
Join Date: Sep 2017
Location: London, England.
Posts: 5,003
|
Quote:
Originally Posted by jacksoonbrowne
I have added a "Jog by 1 measure" Rotary action for the X32.
Tested and working
|
What was wrong with the Reaper Action?
|
|
|
04-30-2024, 05:41 AM
|
#25829
|
Human being with feelings
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,569
|
Quote:
Originally Posted by MixMonkey
What was wrong with the Reaper Action?
|
Nothing, but the X32 control needs to be "reset" to 64 after each invocation, it's not an encoder.
Code:
// CENTER THE ROTARY - MAKE IT APPEAR THAT THE X32 ROTARY IS ENDLESS
context->GetSurface()->SendOSCMessage("/-stat/userpar/33/value", 64);
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
|
|
|
04-30-2024, 05:42 AM
|
#25830
|
Human being with feelings
Join Date: Sep 2017
Location: London, England.
Posts: 5,003
|
Quote:
Originally Posted by Geoff Waddington
Nothing, but the X32 control needs to be "reset" to 64 after each invocation.
Code:
// CENTER THE ROTARY - MAKE IT APPEAR THAT THE X32 ROTARY IS ENDLESS
context->GetSurface()->SendOSCMessage("/-stat/userpar/33/value", 64);
|
Ah, tricky
|
|
|
04-30-2024, 04:39 PM
|
#25831
|
Human being with feelings
Join Date: Jul 2011
Location: Northern Ireland
Posts: 923
|
Quote:
Originally Posted by Geoff Waddington
Code:
Zone FXRowLayout
Channels 8
"" ""
"Shift" ""
"Control" ""
"Option" ""
ZoneEnd
|
Should "ALT" be in there too?
|
|
|
04-30-2024, 04:51 PM
|
#25832
|
Human being with feelings
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,569
|
Quote:
Originally Posted by Freex
Should "ALT" be in there too?
|
Sure, that's just an example.
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
|
|
|
04-30-2024, 10:27 PM
|
#25833
|
Human being with feelings
Join Date: Aug 2017
Location: Ottawa, Canada
Posts: 665
|
oops, posted to soon
__________________
AKA: Roy Wallingford
|
|
|
04-30-2024, 10:33 PM
|
#25834
|
Human being with feelings
Join Date: Aug 2017
Location: Ottawa, Canada
Posts: 665
|
Opps posted too soon again
__________________
AKA: Roy Wallingford
|
|
|
04-30-2024, 10:59 PM
|
#25835
|
Human being with feelings
Join Date: Aug 2017
Location: Ottawa, Canada
Posts: 665
|
Quote:
Originally Posted by Geoff Waddington
CSI Actions cannot hold state.
Is this equivalent ?
Code:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class X32JogByMeasure : public Action
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{
public:
virtual const char *GetName() override { return "X32JogByMeasure"; }
virtual void Do(ActionContext *context, double value) override
{
// WHEN JOG RIGHT 1 MEASURE
if (value > 64)
DAW::SendCommandMessage(41042);
// WHEN JOG LEFT 1 MEASURE
else if (value < 64)
DAW::SendCommandMessage(41043);
// CENTER THE ROTARY - MAKE IT APPEAR THAT THE X32 ROTARY IS ENDLESS
context->GetSurface()->SendOSCMessage("/-stat/userpar/33/value", 64);
}
};
|
Yes, but now I am modifying it to not use hard coded "/-stat/userpar/ 33/value", 64)"
IE: " 33"
But, to parse the widget name "UserAssignable_Rotary xx".
Or to use an action parameter xx supplied the in the zone file.
Here's what I am thinking:
Parse .ost
Code:
// DO NOT MODIFY THESE WIDGETS NAMES
....
Widget UserAssignable_Rotaryxx
Control /-stat/userpar/xx/value
WidgetEnd
....
Or parse .zon file action
Code:
UserAssignable_RotaryC1 X32Jog xx // Move edit cursor +- 1 measure
Where the "UserAssignable_Rotary xx" or action parameter xx can be any of the following
(NOTE: any parsing problems will default to " C1")
Bank letters can be upper or lower case letters
Code:
"A1" - Assignable bank A rotary 1 - SendOSCMessage("/-stat/userpar/25/value"
"A2" - Assignable bank A rotary 2 - SendOSCMessage("/-stat/userpar/26/value"
"A3" - Assignable bank A rotary 3 - SendOSCMessage("/-stat/userpar/27/value"
"A4" - Assignable bank A rotary 4 - SendOSCMessage("/-stat/userpar/28/value"
"B1" - Assignable bank B rotary 1 - SendOSCMessage("/-stat/userpar/29/value"
"B2" - Assignable bank B rotary 2 - SendOSCMessage("/-stat/userpar/30/value"
"B3" - Assignable bank B rotary 3 - SendOSCMessage("/-stat/userpar/31/value"
"B4" - Assignable bank B rotary 4 - SendOSCMessage("/-stat/userpar/32/value"
"C1" - Assignable bank C rotary 1 - SendOSCMessage("/-stat/userpar/33/value"
"C2" - Assignable bank C rotary 2 - SendOSCMessage("/-stat/userpar/34/value"
"C3" - Assignable bank C rotary 3 - SendOSCMessage("/-stat/userpar/35/value"
"C4" - Assignable bank C rotary 4 - SendOSCMessage("/-stat/userpar/36/value"
I am leaning towards "Action" parameter option, as I think this would negate any constraint required by naming the widget in the .ost file
Which approach would you suggest Geoff?
And BTW you can get rid of the commented out section "void GenerateX32SurfaceFile()"
__________________
AKA: Roy Wallingford
Last edited by jacksoonbrowne; 05-01-2024 at 12:08 AM.
|
|
|
05-01-2024, 04:11 AM
|
#25836
|
Human being with feelings
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,569
|
Quote:
Originally Posted by jacksoonbrowne
Yes, but now I am modifying it to not use hard coded "/-stat/userpar/ 33/value", 64)"
IE: " 33"
But, to parse the widget name "UserAssignable_Rotary xx".
Or to use an action parameter xx supplied the in the zone file.
Here's what I am thinking:
Parse .ost
Code:
// DO NOT MODIFY THESE WIDGETS NAMES
....
Widget UserAssignable_Rotaryxx
Control /-stat/userpar/xx/value
WidgetEnd
....
Or parse .zon file action
Code:
UserAssignable_RotaryC1 X32Jog xx // Move edit cursor +- 1 measure
Where the "UserAssignable_Rotary xx" or action parameter xx can be any of the following
(NOTE: any parsing problems will default to " C1")
Bank letters can be upper or lower case letters
Code:
"A1" - Assignable bank A rotary 1 - SendOSCMessage("/-stat/userpar/25/value"
"A2" - Assignable bank A rotary 2 - SendOSCMessage("/-stat/userpar/26/value"
"A3" - Assignable bank A rotary 3 - SendOSCMessage("/-stat/userpar/27/value"
"A4" - Assignable bank A rotary 4 - SendOSCMessage("/-stat/userpar/28/value"
"B1" - Assignable bank B rotary 1 - SendOSCMessage("/-stat/userpar/29/value"
"B2" - Assignable bank B rotary 2 - SendOSCMessage("/-stat/userpar/30/value"
"B3" - Assignable bank B rotary 3 - SendOSCMessage("/-stat/userpar/31/value"
"B4" - Assignable bank B rotary 4 - SendOSCMessage("/-stat/userpar/32/value"
"C1" - Assignable bank C rotary 1 - SendOSCMessage("/-stat/userpar/33/value"
"C2" - Assignable bank C rotary 2 - SendOSCMessage("/-stat/userpar/34/value"
"C3" - Assignable bank C rotary 3 - SendOSCMessage("/-stat/userpar/35/value"
"C4" - Assignable bank C rotary 4 - SendOSCMessage("/-stat/userpar/36/value"
I am leaning towards "Action" parameter option, as I think this would negate any constraint required by naming the widget in the .ost file
Which approach would you suggest Geoff?
And BTW you can get rid of the commented out section "void GenerateX32SurfaceFile()"
|
Thanks, will remove that commented code.
The CSI design/architecture is based on each Widget having a unique handle.
Therefore, if each of the user defined Widgets is indeed unique, this is the CSI way:
Code:
Widget UserAssignableRotary25
Control /-stat/userpar/25/value
WidgetEnd
Widget UserAssignableRotary26
Control /-stat/userpar/26/value
WidgetEnd
...
or
Widget UserAssignableRotaryA1
Control /-stat/userpar/25/value
WidgetEnd
Widget UserAssignableRotaryA2
Control /-stat/userpar/26/value
WidgetEnd
...
etc.
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Last edited by Geoff Waddington; 05-01-2024 at 04:56 AM.
|
|
|
05-01-2024, 08:44 PM
|
#25837
|
Human being with feelings
Join Date: Aug 2017
Location: Ottawa, Canada
Posts: 665
|
Quote:
Originally Posted by Geoff Waddington
Thanks, will remove that commented code.
The CSI design/architecture is based on each Widget having a unique handle.
Therefore, if each of the user defined Widgets is indeed unique, this is the CSI way:
Code:
Widget UserAssignableRotary25
Control /-stat/userpar/25/value
WidgetEnd
Widget UserAssignableRotary26
Control /-stat/userpar/26/value
WidgetEnd
...
or
Widget UserAssignableRotaryA1
Control /-stat/userpar/25/value
WidgetEnd
Widget UserAssignableRotaryA2
Control /-stat/userpar/26/value
WidgetEnd
...
etc.
|
I've gone the route of using the widget name string
I named the action "X32Jog" prior.
But I changed it "X32MoveEditCurser" as that what it actually does.
The "X32MoveEditCurser" action will parse the last two characters of the widget name to determine the rotary bank (A,B,C) and the rotary within the bank (1,2,3,4)
.ost:
Code:
Widget UserAssignableRotaryC1
Control /-stat/userpar/33/value
WidgetEnd
.zon:
Code:
UserAssignableRotaryC1 X32MoveEditCurser// Move edit cursor +- 1 measure
And the new code:
Code:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class X32MoveEditCurser: public Action
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{
public:
virtual const char *GetName() override { return "X32MoveEditCurser"; }
virtual void Do(ActionContext *context, double value) override
{
// DEBOUNCE
if (value == 64)
return;
// GET WIDGET NAME
string widgetName = context->GetWidget()->GetName();
int widgetNameLength = widgetName.length();
// BANK MUST BE ONE OF A,B,C,D
unsigned char bank = toupper(widgetName[widgetNameLength-2]);
if (bank < 'A' || bank > 'C')
return;
bank -= 'A';
// ROTARY MUST BE ONE OF 1,2,3,4
unsigned char rotary = widgetName[widgetNameLength-1];
if (rotary < '1' || rotary > '4')
return;
rotary -= '1';
// WHEN MEASURE RIGHT
if (value > 64)
DAW::SendCommandMessage(41042);
// WHEN MEASURE LEFT
else if (value < 64)
DAW::SendCommandMessage(41043);
// CENTER THE ROTARY - MAKE IT APPEAR THAT THE X32 ROTARY IS ENDLESS
int rotaryIndex = 25 + 4*bank + 4*rotary;
string oscMessage = "/-stat/userpar/" + int_to_string(rotaryIndex) + "/value";
context->GetSurface()->SendOSCMessage(oscMessage.c_str(), 64);
}
};
Code:
ActionContext::ActionContext(CSurfIntegrator *const csi, Action *action, Widget *widget, Zone *zone, int paramIndex, const string_list *paramsAndProperties, const string *stringParam): csi_(csi), action_(action), widget_(widget), zone_(zone)
{
....
if (!strcmp(actionName, "X32MoveEditCurser"))
{
rangeMinimum_ = 0.0;
rangeMaximum_ = 127.0;
}
....
}
Code:
actions_.Insert("X32MoveEditCurser", new X32MoveEditCurser());
Please commit the code above and clean it up to your preferences if needed.
I will later ponder on modifying it by adding and action parameter to specify the type cursor movement, for example:
Code:
UserAssignableRotaryC2 X32MoveEditCurser // +- measure -> default when no param
UserAssignableRotaryC2 X32MoveEditCurser ByMeasure // +- measure
UserAssignableRotaryC3 X32MoveEditCurser ByMarker // +- marker
UserAssignableRotaryC4 X32MoveEditCurser ByRegion // +- region
__________________
AKA: Roy Wallingford
Last edited by jacksoonbrowne; 05-01-2024 at 09:49 PM.
|
|
|
05-02-2024, 02:27 AM
|
#25838
|
Human being with feelings
Join Date: Mar 2009
Location: Dartmouth, Nova Scotia
Posts: 11,569
|
Quote:
Originally Posted by jacksoonbrowne
I've gone the route of using the widget name string
I named the action "X32Jog" prior.
But I changed it "X32MoveEditCurser" as that what it actually does.
The "X32MoveEditCurser" action will parse the last two characters of the widget name to determine the rotary bank (A,B,C) and the rotary within the bank (1,2,3,4)
|
Apologies for sending you down the wrong road, starting with X32TrackVolume.
A fundamental CSI design principle is keeping Reaper specific stuff in Actions, and surface specific stuff in Widgets.
X32TrackVolume has surface specific code.
That belongs in an OSC Widget.
If you take a look at control_surface_midi_widgets.h, you will see code very similar to the X32TrackVolume that deals with the differences between surface Widgets.
The code for the db adjustments needs to be encapsulated in an OSC Widget -- X32Fader_OSC_FeedbackProcessor ? -- not in a CSI Action.
Wondering if it is time to add a new file -- control_surface_OSC_widgets.h -- to deal with these issues -- let me think about that for a bit, leaning more and more that way, especially considering the contributions you are providing -- thanks again for all of your hard work!
Similarly, the surface specific code for X32MoveEditCursor needs to be in a Widget, not in an Action.
The ForceValue override in the X32 Widget would then handle all of the surface specific code.
[edit]
Added control_surface_OSC_widgets.h, X32_Fader_OSC_MessageGenerator, OSC_X32FaderFeedbackProcessor
usage:
Code:
Widget Fader1
X32Fader oscAddress
FB_X32FaderProcessor oscAddress
WidgetEnd
Then just use TrackVolume in the Zone definition.
Let me know if it works
__________________
To install you need the CSI Software and Support Files
For installation instructions and documentation see the Wiki
Donate -- via PayPal to waddingtongeoff@gmail.com
Last edited by Geoff Waddington; 05-02-2024 at 04:46 AM.
|
|
|
05-02-2024, 03:31 PM
|
#25839
|
Human being with feelings
Join Date: Aug 2017
Location: Ottawa, Canada
Posts: 665
|
Quote:
Originally Posted by Geoff Waddington
Apologies for sending you down the wrong road, starting with X32TrackVolume.
A fundamental CSI design principle is keeping Reaper specific stuff in Actions, and surface specific stuff in Widgets.
X32TrackVolume has surface specific code.
That belongs in an OSC Widget.
If you take a look at control_surface_midi_widgets.h, you will see code very similar to the X32TrackVolume that deals with the differences between surface Widgets.
The code for the db adjustments needs to be encapsulated in an OSC Widget -- X32Fader_OSC_FeedbackProcessor ? -- not in a CSI Action.
Wondering if it is time to add a new file -- control_surface_OSC_widgets.h -- to deal with these issues -- let me think about that for a bit, leaning more and more that way, especially considering the contributions you are providing -- thanks again for all of your hard work!
Similarly, the surface specific code for X32MoveEditCursor needs to be in a Widget, not in an Action.
The ForceValue override in the X32 Widget would then handle all of the surface specific code.
[edit]
Added control_surface_OSC_widgets.h, X32_Fader_OSC_MessageGenerator, OSC_X32FaderFeedbackProcessor
usage:
Code:
Widget Fader1
X32Fader oscAddress
FB_X32FaderProcessor oscAddress
WidgetEnd
Then just use TrackVolume in the Zone definition.
Let me know if it works
|
Will be checking it out tonight
__________________
AKA: Roy Wallingford
|
|
|
05-02-2024, 04:34 PM
|
#25840
|
Human being with feelings
Join Date: Aug 2017
Location: Ottawa, Canada
Posts: 665
|
Moving an X32 physical fader has gone gone back to fighting with the Reaper feedback because the faders don't support "Touch".
We used to use:
Code:
Widget Fader1
MotorizedFaderWithoutTouch oscAddress
FB_X32Processor oscAddress
WidgetEnd
So I will attempt to duplicate the "MotorizedFaderWithoutTouch" timing in "X32Fader"
Code:
Widget Fader1
X32Fader oscAddress
FB_X32FaderProcessor oscAddress
WidgetEnd
__________________
AKA: Roy Wallingford
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 11:06 PM.
|