Read an Effect Block's Parameter value when it's attached to a Controller/Modifier

bossredman

Inspired
Hi,

For the AxeFx 2, is it possible to read a block's parameter value (via sysex msg) when the parameter in question is attached to a controller/ modifier?

Specifics:
External 1 pedal is attached to the TREMELO block's RATE parameter.
Such that when moving the pedal, the rate changes dynamically.

But when I move the pedal, I would like to be able to read the value as it changes & display it on my home made MFC.

Current attempts are just yielding a static value - which is the value of the parameter (Rate) that was set before the modifier/Controller was attached.

I appreciate the controller/modifier applies a percentage to the parameter's range (defined by the MIN to MAX set in the modifier) & as such some mathematics my also be needed.
But if I could just be able to read a dynamic value I can look at teh maths later.
 
Another question pls.
The wiki states that if I send a GET/SET_MODIFIER_VALUE sysex (ie Function ID 0x07) then the response will be of Function ID 0x02.
Is that correct?
Why would it return a msg of a different Function ID?

Message format:

HEADER BYTES
0x07 Function ID (0x07)
0xdd effect ID bits 6-0
0xdd effect ID bits 13-7
0xdd parameter ID bits 6-0
0xdd parameter ID bits 13-7
0xdd modifier parameter selector ID bits 6-0
0xdd 00xdd modifier value bits 6-0
0xdd modifier value bits 13-7
0xdd modifier value bits 15-14
0x00 0=query value, 1=set value
0xdd Checksum
0xF7 SysEx End

Response format:

HEADER BYTES
0x02 Function ID (0x02)
0xdd effect ID bits 6-0
0xdd effect ID bits 13-7
0xdd parameter ID bits 6-0
0xdd parameter ID bits 13-7
0xdd modifier parameter selector ID bits 6-0
0xdd 00xdd modifier value bits 6-0
0xdd modifier value bits 13-7
0xdd modifier value bits 15-14
0xdd null-terminated string byte0
0xdd byte1...
0x00 null character
0xdd Checksum
0xF7 SysEx End

But when I send an 0x07 msg to read the MAX modifier value of the TREMELO's Rating Parameter, I just get a load of responses which appear to relate to the AMP1 block (ie 106 dec / 0x6A).

Code:
byte EffIdBit6_0 = 0x00;
byte EffIdBit13_7 = 0x01;
byte ParmIdBit6_0 = 0x02;
byte ParmIdBit13_7 = 0x00;
byte ModParamSelId = 0x2;
byte QuerySet = 0x00; //(ie 0 = query)
                    
byte sysex_1st_chunk = (0xF0 ^ 0x00 ^ 0x01 ^ 0x74 ^ 0x03 ^ 0x07 ^ EffIdBit6_0 ^ EffIdBit13_7 ^ ParmIdBit6_0 ^ ParmIdBit13_7 ^ ModParamSelId ^ 0x00 ^ 0x00 ^ 0x00 ^ 0x00 ^ QuerySet);
byte CheckSum = ((sysex_1st_chunk) & 0x7F);
byte Modifier_sysex[18] = {0xF0, 0x00, 0x01, 0x74, 0x03, 0x07, EffIdBit6_0, EffIdBit13_7, ParmIdBit6_0, ParmIdBit13_7, ModParamSelId, 0x00, 0x00, 0x00, 0x00, QuerySet, CheckSum, 0xF7};
                    
MIDI.sendSysEx( 18, Modifier_sysex, 1 );
 
BTW - I do understand that the Front panel & Axe Edit only displays the static (pre modifier) value due to the PC RESET feature.
So I'm not asking why it doesn't change on either of those - that's been asked/answered/discussed before.
https://forum.fractalaudio.com/threads/modifier-value-vs-mix-value.74192/
no, when the modifier is linked to the parameter, you won't see the parameter change as the modifier changes. it's always been like this

The parameter value CAN'T change, because it has a role. Refer to PC RESET for details on why...


But the AxeFx must know what value it needs to use for the Block's parameter that is using the Modifier/Controller.
So what i'm trying to determine is this:
- is there a way to read this via sysex - either directly (the actual parameter value) or indirectly (%age of modifier & then calc'd value based on the modifier range).​
I did get the 0x07 (GET/SET_MODIFIER_VALUE) sysex msg to work in my MFC code***, but there is no Modifier Parameter Selector ID for the Modifier value.

Modifier Parameter Selector IDs:

0x0 modifier source
0x1 min
0x2 max
0x3 start
0x4 mid
0x5 end
0x6 slope
0x7 damping
0x8 ?
0x9 ?
0xA auto engage
0xB pc reset
0xC off val
0xD scale
0xE offset

***: NOTE: a 0x07 request does actually return a 0x07 response (contrary to what the wiki states).
 
Well this particular subject doesn't seem to have drawn much attention. (maybe its because of the Euro's [European Championships - that's real football btw] currently being on the TV every day.
The silence is deafening :D.

So just on the off-chance that someone in the future tries to do something similar, I'll document where I've got to so far in trying to achieve this.

  1. DERIVED CONCLUSION (not confirmed): There doesn't appear to be any way to read a "modified" parameter's value either directly or indirectly via the available sysex functions/msgs set by EXTERNAL 1.
  2. However, my MFC also has an EXTERNAL 2, which uses an expression pedal connected to an Analogue Input of the Board of my MFC (a Teensy 3.6).
  3. This works by converting/mapping the output voltage sent from the pedal to the analogue input pin of the Teensy (0 to 3.3V or 0 to 1023 after A/D conversion) to a value between 0 & 127.
    Code:
    int MappedValue = map(CurrentPotValue, 0, 1023, 0, 127);
  4. I use that mapped value to then send a CC command to the AxeFx
    Code:
    MIDI.sendControlChange( 17, MappedValue, 1 );                       // CC#17 = External Controller 2
  5. This controls whatever Block's parameter is attached to the EXT2 Modifier/Controller.
  6. So .... with this existing code/function, I effectively know the EXT2 pedal position.
  7. For my new use-case, I then use the 0x07 sysex msg (GET/SET_MODIFIER_VALUE) to request & read the Tremolo Block's Modifier Min & Max values.
  8. A quick calculation then yields me the actual parameter value (or close enough):
  9. Code:
    float fMin = ModMin.toFloat();  //bits 15+ of the 0x07 MIN response converted from a string to a float
    float fMax = ModMax.toFloat();  //bits 15+ of the 0x07 MAX response converted from a string to a float
                
    float ModParamValue = ( (float(MappedValue)/float(127))*(fMax-fMin) ) + fMin;  // ie: Param Value = (Pedal Position % * Modifier Range) + Modifier Min
  10. Which I can then send to my MFC's display.

Not Ideal - but OK considering the limitations.
Whilst it seems to work for a defined Block & Parameter which has a Modifier attached, ideally I'd like to be able to write some code to extract the Blocks in a Preset that have Modifiers attached & to which parameters.
That's the next challenge I guess (any suggestions are extremely welcome pls).
 
Back
Top Bottom