Jump to content

Banks and if_equal selections


jjonas
 Share

Recommended Posts

Hi,

I have the following idea for a controller that I've tried to configure over the past week or so:  one 2x40 LCD and 16 encoders to control synth parameters that are displayed on the screen. There's 3-4 "pages" of parameters that I should be able to change between, and each parameter (or most of them anyway) in turn has four separate addresses, depending on the "tone" (oscillator) in the patch you want to edit.

I'm able to change the "pages" if I just bank them, and then use a button to cycle through the banks. But I haven't been able to configure how to select which tone I can edit within each bank.

I've tried using bank and if_equal in combination to choose the bank with one button and then choose parameter tone to be edited with another one, but I haven't managed to get it working.

Here's some config where I've tried to change the tone to be edited with if_equal. MIOS Studio debugging shows that the button is cycling through the values defined in MAP1, but if_equal=Button:33:xx seems to do nothing; what's displayed on the screen is the last entry listed for that lcd_pos, but I would have expected that the if_equal would select only that line where the current button value matches.

Most of the config below is not immediately relevant to this particular question, but hopefully it provides some context for what I'm trying to do, and how I'm trying to do it. (Label text such as "1_2%B " should be read as "first parameter, second tone, with value bar".) Can someone point out what I'm doing wrong?

MAP1 1 2
EVENT_BUTTON id=33 hw_id=33  button_mode=Toggle range=map1

# First page
EVENT_ENC id=1  hw_id=1  bank=1  if_equal=Button:33:1 lcd_pos=1:1:1  label="1_1%B "
EVENT_ENC id=2  hw_id=1  bank=1  if_equal=Button:33:2 lcd_pos=1:1:1  label="1_2%B "
#EVENT_ENC id=3  hw_id=1  bank=1   lcd_pos=1:1:1  label="1_3%B "
#EVENT_ENC id=4  hw_id=1  bank=1   lcd_pos=1:1:1  label="1_4%B "

EVENT_ENC id=5  hw_id=2  bank=1   lcd_pos=1:6:1  label="2_1%B "
#EVENT_ENC id=6  hw_id=2  bank=1   lcd_pos=1:6:1  label="2_2%B "
#EVENT_ENC id=7  hw_id=2  bank=1   lcd_pos=1:6:1  label="2_3%B "
#EVENT_ENC id=8  hw_id=2  bank=1   lcd_pos=1:6:1  label="2_4%B "

EVENT_ENC id=9  hw_id=3  bank=1   lcd_pos=1:11:1 label="3_1%B "
#EVENT_ENC id=10 hw_id=3  bank=1   lcd_pos=1:11:1 label="3_2%B "
#EVENT_ENC id=11 hw_id=3  bank=1   lcd_pos=1:11:1 label="3_3%B "
#EVENT_ENC id=12 hw_id=3  bank=1   lcd_pos=1:11:1 label="3_4%B "

EVENT_ENC id=13 hw_id=4  bank=1   lcd_pos=1:16:1 label="4_1%B "
#EVENT_ENC id=14 hw_id=4  bank=1   lcd_pos=1:16:1 label="4_2%B "
#EVENT_ENC id=15 hw_id=4  bank=1   lcd_pos=1:16:1 label="4_3%B "
#EVENT_ENC id=16 hw_id=4  bank=1   lcd_pos=1:16:1 label="4_4%B "

EVENT_ENC id=17 hw_id=5  bank=1   lcd_pos=1:21:1  label="5_1%B "
#EVENT_ENC id=18 hw_id=5  bank=1   lcd_pos=1:21:1  label="5_2%B "
#EVENT_ENC id=19 hw_id=5  bank=1   lcd_pos=1:21:1  label="5_3%B "
#EVENT_ENC id=20 hw_id=5  bank=1   lcd_pos=1:21:1  label="5_4%B "

EVENT_ENC id=21 hw_id=6  bank=1   lcd_pos=1:26:1  label="6_1%B "
#EVENT_ENC id=22 hw_id=6  bank=1   lcd_pos=1:26:1  label="6_2%B "
#EVENT_ENC id=23 hw_id=6  bank=1   lcd_pos=1:26:1  label="6_3%B "
#EVENT_ENC id=24 hw_id=6  bank=1   lcd_pos=1:26:1  label="6_4%B "

EVENT_ENC id=25 hw_id=7  bank=1   lcd_pos=1:31:1 label="7_1%B "
#EVENT_ENC id=26 hw_id=7  bank=1   lcd_pos=1:31:1 label="7_2%B "
#EVENT_ENC id=27 hw_id=7  bank=1   lcd_pos=1:31:1 label="7_3%B "
#EVENT_ENC id=28 hw_id=7  bank=1   lcd_pos=1:31:1 label="7_4%B "

EVENT_ENC id=29 hw_id=8  bank=1   lcd_pos=1:36:1 label="8_1%B "
#EVENT_ENC id=30 hw_id=8  bank=1   lcd_pos=1:36:1 label="8_2%B "
#EVENT_ENC id=31 hw_id=8  bank=1   lcd_pos=1:36:1 label="8_3%B "
#EVENT_ENC id=32 hw_id=8  bank=1   lcd_pos=1:36:1 label="8_4%B "

### Second page
EVENT_ENC id=33 hw_id=1  bank=2   lcd_pos=1:1:1  label="9_1%B "
#EVENT_ENC id=34 hw_id=1  bank=2   lcd_pos=1:1:1  label="9_2%B "
#EVENT_ENC id=35 hw_id=1  bank=2   lcd_pos=1:1:1  label="9_3%B "
#EVENT_ENC id=36 hw_id=1  bank=2   lcd_pos=1:1:1  label="9_4%B "

EVENT_ENC id=37 hw_id=2  bank=2   lcd_pos=1:6:1  label="A_1%B "
#EVENT_ENC id=38 hw_id=2  bank=2   lcd_pos=1:6:1  label="A_2%B "
#EVENT_ENC id=39 hw_id=2  bank=2   lcd_pos=1:6:1  label="A_3%B "
#EVENT_ENC id=40 hw_id=2  bank=2   lcd_pos=1:6:1  label="A_4%B "

EVENT_ENC id=41 hw_id=3  bank=2   lcd_pos=1:11:1 label="B_1%B "
#EVENT_ENC id=42 hw_id=3  bank=2   lcd_pos=1:11:1 label="B_2%B "
#EVENT_ENC id=43 hw_id=3  bank=2   lcd_pos=1:11:1 label="B_3%B "
#EVENT_ENC id=44 hw_id=3  bank=2   lcd_pos=1:11:1 label="B_4%B "

EVENT_ENC id=45 hw_id=4  bank=2   lcd_pos=1:16:1 label="C_1%B "
#EVENT_ENC id=46 hw_id=4  bank=2   lcd_pos=1:16:1 label="C_2%B "
#EVENT_ENC id=47 hw_id=4  bank=2   lcd_pos=1:16:1 label="C_3%B "
#EVENT_ENC id=48 hw_id=4  bank=2   lcd_pos=1:16:1 label="C_4%B "

EVENT_ENC id=49 hw_id=5  bank=2   lcd_pos=1:21:1  label="D_1%B "
#EVENT_ENC id=50 hw_id=5  bank=2   lcd_pos=1:21:1  label="D_2%B "
#EVENT_ENC id=51 hw_id=5  bank=2   lcd_pos=1:21:1  label="D_3%B "
#EVENT_ENC id=52 hw_id=5  bank=2   lcd_pos=1:21:1  label="D_4%B "

EVENT_ENC id=53 hw_id=6  bank=2   lcd_pos=1:26:1  label="E_1%B "
#EVENT_ENC id=54 hw_id=6  bank=2   lcd_pos=1:26:1  label="E_2%B "
#EVENT_ENC id=55 hw_id=6  bank=2   lcd_pos=1:26:1  label="E_3%B "
#EVENT_ENC id=56 hw_id=6  bank=2   lcd_pos=1:26:1  label="E_4%B "

EVENT_ENC id=57 hw_id=7  bank=2   lcd_pos=1:31:1 label="F_1%B "
#EVENT_ENC id=58 hw_id=7  bank=2   lcd_pos=1:31:1 label="F_2%B "
#EVENT_ENC id=59 hw_id=7  bank=2   lcd_pos=1:31:1 label="F_3%B "
#EVENT_ENC id=60 hw_id=7  bank=2   lcd_pos=1:31:1 label="F_4%B "

EVENT_ENC id=61 hw_id=8  bank=2   lcd_pos=1:36:1 label="G_1%B "
#EVENT_ENC id=62 hw_id=8  bank=2   lcd_pos=1:36:1 label="G_2%B "
#EVENT_ENC id=63 hw_id=8  bank=2   lcd_pos=1:36:1 label="G_3%B "
#EVENT_ENC id=64 hw_id=8  bank=2   lcd_pos=1:36:1 label="G_4%B "

 

Edited by jjonas
typo
Link to comment
Share on other sites

Hi,

if_equal will match the EVENT value, not the bank, therefore this function won't help for the intended purpose.

For complex banking schemes I introduced the NGR command "set_active", where the script can activate/deactivate EVENTs based on your own rules.

E.g. following example shows how to activate/deactivate based on the variable ^bank:

https://github.com/midibox/mios32/blob/master/apps/controllers/midibox_ng_v1/cfg/tests/multibnk.ngc
https://github.com/midibox/mios32/blob/master/apps/controllers/midibox_ng_v1/cfg/tests/multibnk.ngr

In your case, you would add BUTTON:33 with an additional "if" condition to activate/deactivate (id)ENC:1 and (id)ENC:2 

It will result into a very long NGR script - but it should work (and should be fast enough)

Best Regards, Thorsten.

Link to comment
Share on other sites

Thanks for the reply. Below the relevant parts of what I have now, a kind of mini version of what I have in mind. Four parameters, two per page, each parameter has two tones (so eight different "operations" altogether, and eight different enc id's). One button should change the bank ("page"), the other one should change the tone (tone1 or tone2).

What the config does at the moment: After startup, display shows 9_2 and A_2, but changes soon to 1_2 and 2_2, i.e. page 1, edit parameter 1, tone2, and parameter 2, tone 2. If I press button 35 (change tone), nothing happens (MIOS Studio does show the button value alternates between 1 and 2). If I press button 36 (cycle banks), display shows to 9_2 and A_2, i.e. page 2, edit parameter 9 (tone2) and parameter A (tone2).

I'm able to change the bank once, from page one to page two, but after that not anymore. Pressing the tone button seems to do nothing at any point (even though still registering with MIOS Studio debug). I don't understand what is wrong, though I think it's the script file that's not working. If I remove meta=RunSection:1 from Button36's function, bank change works ok (but I get only tone2 for each parameter, because that's the last entry for the given lcd_pos I guess).

DEFAULT.NGC:

# select tone 1-2
MAP1 1 2
EVENT_BUTTON id=35  hw_id=35 range=map1 button_mode=Toggle
# select bank
EVENT_BUTTON id=36 hw_id=36 type=Meta meta=CycleBank meta=RunSection:1 button_mode=OnOnly

### First page
EVENT_ENC id=1   bank=1  hw_id=1  lcd_pos=1:1:1   label="1_1%B "
EVENT_ENC id=2   bank=1  hw_id=1  lcd_pos=1:1:1   label="1_2%B "
EVENT_ENC id=3   bank=1  hw_id=2  lcd_pos=1:6:1   label="2_1%B "
EVENT_ENC id=4   bank=1  hw_id=2  lcd_pos=1:6:1   label="2_2%B "
### Second page
EVENT_ENC id=5   bank=2  hw_id=1  lcd_pos=1:1:1   label="9_1%B "
EVENT_ENC id=6   bank=2  hw_id=1  lcd_pos=1:1:1   label="9_2%B "
EVENT_ENC id=7   bank=2  hw_id=2  lcd_pos=1:6:1   label="A_1%B "
EVENT_ENC id=8   bank=2  hw_id=2  lcd_pos=1:6:1   label="A_2%B "

DEFAULT.NGR:

### First page of parameters
if ^bank == 1
    LOG "First Bank"
    ### tone 1
    if (id)BUTTON:35 == 1
        set_active (id)ENC:1 1
        set_active (id)ENC:2 0
        set_active (id)ENC:3 1
        set_active (id)ENC:4 0
        set_active (id)ENC:5 0
        set_active (id)ENC:6 0
        set_active (id)ENC:7 0
        set_active (id)ENC:8 0
    endif
    ### tone 2
    elsif (id)BUTTON:35 == 2
        set_active (id)ENC:1 0
        set_active (id)ENC:2 1
        set_active (id)ENC:3 0
        set_active (id)ENC:4 1
        set_active (id)ENC:5 0
        set_active (id)ENC:6 0
        set_active (id)ENC:7 0
        set_active (id)ENC:8 0
    endif
endif

### Second page of parameters
elsif ^bank == 2
    LOG "Second Bank"
    ### tone 1
    if (id)BUTTON:35 == 1
        set_active (id)ENC:1 0
        set_active (id)ENC:2 0
        set_active (id)ENC:3 0
        set_active (id)ENC:4 0
        set_active (id)ENC:5 1
        set_active (id)ENC:6 0
        set_active (id)ENC:7 1
        set_active (id)ENC:8 0
    endif
    ### tone 2
    elsif (id)BUTTON:35 == 2
        set_active (id)ENC:1 0
        set_active (id)ENC:2 0
        set_active (id)ENC:3 0
        set_active (id)ENC:4 0
        set_active (id)ENC:5 0
        set_active (id)ENC:6 1
        set_active (id)ENC:7 0
        set_active (id)ENC:8 1
    endif
endif
exit

Link to comment
Share on other sites

The EVENTs which are controlled via NGR script shouldn't be assigned to a bank, otherwise concurrent changes on the "active" flag will happen.

Therefore just write:

# select tone 1-2 and trigger NGR script
MAP1 1 2
EVENT_BUTTON id=35  hw_id=35 range=map1 button_mode=Toggle type=meta meta=RunSection:1

# select bank and trigger NGR script
EVENT_BUTTON id=36 hw_id=36 type=Meta meta=CycleBank meta=RunSection:1 button_mode=OnOnly

# dummies to define bank1/2
# can be removed if banks are defined for other events (not controlled from NGR script)
EVENT_BUTTON id=3001 bank=1
EVENT_BUTTON id=3002 bank=2


### First page
EVENT_ENC id=1   hw_id=1  lcd_pos=1:1:1   label="1_1%B "
EVENT_ENC id=2   hw_id=1  lcd_pos=1:1:1   label="1_2%B "
EVENT_ENC id=3   hw_id=2  lcd_pos=1:6:1   label="2_1%B "
EVENT_ENC id=4   hw_id=2  lcd_pos=1:6:1   label="2_2%B "

### Second page
EVENT_ENC id=5   hw_id=1  lcd_pos=1:1:1   label="9_1%B "
EVENT_ENC id=6   hw_id=1  lcd_pos=1:1:1   label="9_2%B "
EVENT_ENC id=7   hw_id=2  lcd_pos=1:6:1   label="A_1%B "
EVENT_ENC id=8   hw_id=2  lcd_pos=1:6:1   label="A_2%B "

And in the NGR script I noticed some wrong "endif" statements.
"elsif" will only work for the previous "if" condition if you don't terminate it with "endif":

### First page of parameters
if ^bank == 1
    LOG "First Bank"
    ### tone 1
    if (id)BUTTON:35 == 1
        set_active (id)ENC:1 1
        set_active (id)ENC:2 0
        set_active (id)ENC:3 1
        set_active (id)ENC:4 0
        set_active (id)ENC:5 0
        set_active (id)ENC:6 0
        set_active (id)ENC:7 0
        set_active (id)ENC:8 0
    ### tone 2
    elsif (id)BUTTON:35 == 2
        set_active (id)ENC:1 0
        set_active (id)ENC:2 1
        set_active (id)ENC:3 0
        set_active (id)ENC:4 1
        set_active (id)ENC:5 0
        set_active (id)ENC:6 0
        set_active (id)ENC:7 0
        set_active (id)ENC:8 0
    endif

### Second page of parameters
elsif ^bank == 2
    LOG "Second Bank"
    ### tone 1
    if (id)BUTTON:35 == 1
        set_active (id)ENC:1 0
        set_active (id)ENC:2 0
        set_active (id)ENC:3 0
        set_active (id)ENC:4 0
        set_active (id)ENC:5 1
        set_active (id)ENC:6 0
        set_active (id)ENC:7 1
        set_active (id)ENC:8 0
    ### tone 2
    elsif (id)BUTTON:35 == 2
        set_active (id)ENC:1 0
        set_active (id)ENC:2 0
        set_active (id)ENC:3 0
        set_active (id)ENC:4 0
        set_active (id)ENC:5 0
        set_active (id)ENC:6 1
        set_active (id)ENC:7 0
        set_active (id)ENC:8 1
    endif
endif
exit

With these changes it works at my side :)

Best Regards, Thorsten. 

Link to comment
Share on other sites

I continue this thread rather than start a new one even though the subject line doesn't describe the content so well anymore...

I have now a controller that has four banks with 16 × 4 parameters each, and parameter change with sysex works ok. The next step is to request a parameter dump, capture the relevant values and allocate them to the right events. At the moment request works but capture and/or allocation doesn't.

This is the dump that I receive (verified with MIDI Ox):

                                                         f0  41  10  00  10  12  1f  00  00  00  27  3a  f7
#  This mostly synth specific stuff is always the same---^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^|^^^^^^  ^|  ^|  |^
#  Parameter address (1st character of the patch name, if you're interested ;-)---------×         |   |  ×--- sysex end
#  Value. This is what I need --------------------------------------------------------------------×   ×------ checksum

I try to capture it with this:

EVENT_RECEIVER id=1 type=SysEx stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^ignore ^ignore ^ignore ^ignore ^dump ^ignore 0xf7" fwd_to_lcd=1 lcd_pos=1:1:2 label="* Received SyxDump *"

...and allocate the captured byte with this:

EVENT_ENC id=193 hw_id=1  lcd_pos=1:1:1   label="Nm01 "   range=32:127   type=SysEx stream="0xF0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1F 0x00 0x00 0x00 ^val ^chk_roland 0xf7" syxdump_pos=1:1

I have tried to replicate the Blofeld example given in the docs, but byte 11 of the requested dump (the current parameter value) is not allocated; whether it's captured but not allocated I don't know. Instead the screen freezes. Everything still works in the background (changing banks, changing values with encoders etc.), only the screen won't update anymore, and I have to reset. Sending the request doesn't cause the problem, it's only when something is received that the screen freezes (=unplug the MIDI in cable and request the dump -> everything is ok; plug it back in and request the dump -> screen freeze).

Link to comment
Share on other sites

I'm troubleshooting this by simplifying the setup. This is my NGC file:

RESET_HW

ENC n=1   sr=1 pins=0:1   type=detented3
ENC n=2   sr=1 pins=2:3   type=detented3

EVENT_RECEIVER id=  1  type=SysEx  stream="0xf0 ^dump 0xf7"  fwd_to_lcd=1  lcd_pos=1:1:2 label="* Received SyxDump *"

EVENT_ENC id=1   hw_id=1  lcd_pos=1:1:1   label="Prm1 "  range=0:127  syxdump_pos=1:1
EVENT_ENC id=1   hw_id=1  lcd_pos=1:1:2   label="%d   "
EVENT_ENC id=2   hw_id=2  lcd_pos=1:6:1   label="Prm2 "  range=0:127  syxdump_pos=1:2
EVENT_ENC id=2   hw_id=2  lcd_pos=1:6:2   label="%d   "

I'm sending "f0 25 f7" from MidiOX to MBNG. MBNG tells me syxdump was received, but the sent value (25) is not captured. Can anyone help?

Link to comment
Share on other sites

There are some problems with this configuration:

  • syxdump_pos=1:x --- x starts counting from 0, not 1
    Means: with syxdump_pos=1:0 you should get the expected "25" of "f0 25 f7"
  • the value will be put into the first ENC event with ID 1, the second one with the same ID won't get the value
  • I think that you defined two events with the same ID since you wanted to print out something at a second line. This can also be done with a single event, just use the "@(lcd:x:y)" keyword
  • it makes sense to use "%3d" instead of "%d" to ensure that the decimal value (overwrites) 3 characters
  • by adding fwd_to_lcd=1 the received SysEx value will be displayed immediately

So, just replace the 4 EVENT_ENC lines by following 2 lines:

EVENT_ENC id=1   hw_id=1  fwd_to_lcd=1  lcd_pos=1:1:1   label="Prm1 @(1:1:2)%3d  "  range=0:127  syxdump_pos=1:0
EVENT_ENC id=2   hw_id=2  fwd_to_lcd=1  lcd_pos=1:6:1   label="Prm2 @(1:6:2)%3d  "  range=0:127  syxdump_pos=1:1

Best Regards, Thorsten.

Link to comment
Share on other sites

Ok, this helped me to understand the logic. In the Blofeld example that's linked to in the NGC documentation the first syxdump_pos is 1:1, which led me to think counting starts from 1.

I've also made some progress in finding out what freezes the screen after requesting parameter data from the synth. If I'm capturing the following:

EVENT_RECEIVER id=  1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 ^ignore ^ignore ^ignore ^ignore ^ignore ^dump ^ignore 0xf7"

...and send the following to MBNG to be captured:

f0 41 10 00 10 10 00 00 00 00 50 [some checksum] f7

It works and captures the value 0x50 for the event I want. However, if I change the 6th sent byte (highlighted above) to 0x12, the screen freezes. (The receiver is set to ignore byte 6). I've tried some other values than 0x12 as byte 6th, and what I've tried works, only 0x12 doesn't.

The 6th byte (the command ID byte) makes the sysex message either a data request (0x11) or data transmission (0x12) message. When I request parameter data from the synth, the answer will have 0x12 as the 6th byte, and it will freeze the screen. This sounds like I cannot request parameter values from a (Roland?) synth, even though handmade test dumps work ok.

Here's the formula from the Roland XV-5080 manual on what the answer to data request will contain:

f0 — sysex start
41 — roland ID
dev — device id
00 — model ID 1
10 — model ID 2
12 — command ID (DT1)
aa — address MSB
bb — address, upper middle byte
cc — address, lower middle byte
dd — address LSB
ee — data

..
ff — data
sum — checksum
f7 — sysex end

And BTW it seems this fix for an NRPN number issue is not yet in the 1.037-pre6 that I'm using, is it going to be included at some point?

Link to comment
Share on other sites

Here's my complete test configuration, with only the STM32F4 + display + SD card as hardware.

RESET_HW

EVENT_RECEIVER id=  1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 ^ignore ^ignore ^ignore ^ignore ^ignore ^dump ^ignore 0xf7"

EVENT_ENC id=1   hw_id=1  lcd_pos=1:1:1   fwd_to_lcd=1   label="FtT1%B"  range=0:127 type=SysEx stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x55 ^val ^chk_roland 0xf7" syxdump_pos=1:0
EVENT_ENC id=2   hw_id=2  lcd_pos=1:6:1   fwd_to_lcd=1   label="FtT2%B"  range=0:127   type=SysEx stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x56 ^val ^chk_roland 0xf7" syxdump_pos=1:1

I already figured out that somehow the combination of the encoder event receiving the sysex dumpi (via syxdump_pos), on the one hand, and the sysex the same encoder event is sending, on the other, cause the problem. See the byte highlighted in red above. If the data received and dumped by EVENT_RECEIVER contains that byte (whether it's ^ignored or not), the screen freezes. But if I change the highlighted byte to something else, EVENT_RECEIVER can receive and dump 0x12  as the 6th byte without problems. If I changed the highlighted byte to 0x11, for example, now the EVENT_RECEIVER receiving and dumping 0x11 will freeze the screen. (And of course, removing the stream element from the EVENT_ENC completely has the same effect.)

Link to comment
Share on other sites

An interesting case - it seems that I never tested incoming SysEx streams while parsing ^chk_start - this was causing the endless loop and it's fixed now:

-> http://www.ucapps.de/mios32/midibox_ng_v1_037_pre8.zip

Note that with this change the EVENT_ENCs will update their value according to the specified SysEx stream.
Which means, that the EVENT_RECEIVER is not required anymore.

And the way it's currently used it causes a problem with EVENT_ENC id=2 (which picks up the checksum via syxdump_pos=1:1)

So, just remove EVENT_RECEIVER and maybe also the syxdump_pos arguments - they are intended to pick up values from "patch dumps"

Best Regards, Thorsten.

Link to comment
Share on other sites

Thanks for this!

Below is my current complete test setup, which tries to request three parameter values.

If I request two parameter values, they are both received, meaning the value change is reflected on the screen, but only the second value is actually saved; even though the first one does show the received new value, if I turn the encoder, the "old" value (no longer visible) gets sent instead.

If I request three parameters, the first two are received (= value on the screen changes to that sent from the synth), and sometimes the third as well (sometimes = I didn't see a regularity there). Whether two or three are received, only the last one is actually saved.

Maybe requesting several parameters this way is not how you intended it to work. However, as I was originally trying to request and save several parameters (with EVENT_RECEIVER and syxdump_pos), I kind of tried to use this most recent fix that way. I thought that what I'm trying to do would actually qualify as a patch dump, even though I would be requesting only a specified address range of parameters in the patch (still around 200-300), not all of them.

I did try to request several parameters with one EVENT_BUTTON request command — starting address (0x1f 0x00 0x20 0x55) and then how many bytes of data to expect (0x00 0x00 0x00 0x03) from that address onwards. What happened was that the first parameter (=the starting address that's explicitly mentioned) is saved, but this is not shown on the screen. The new value appears on the screen only when I turn the encoder. The other requested values don't appear to be received or saved.

The "three parameters with one command" setup differs from the config below only in that there's just one EVENT_BUTTON line, and the number highlighted in red is changed to 0x03 (the number of expected bytes).

RESET_HW

ENC n=1 sr=1 pins=0:1 type=detented3
ENC n=2 sr=1 pins=2:3 type=detented3
ENC n=3 sr=1 pins=4:5 type=detented3

EVENT_BUTTON id=1 hw_id=33 button_mode=OnOnly type=SysEx stream="0xf0 0x41 0x10 0x00 0x10 0x11 ^chk_start 0x1f 0x00 0x20 0x55 0x00 0x00 0x00 0x01 ^chk_roland 0xf7"
EVENT_BUTTON id=2 hw_id=33 button_mode=OnOnly type=SysEx stream="0xf0 0x41 0x10 0x00 0x10 0x11 ^chk_start 0x1f 0x00 0x20 0x56 0x00 0x00 0x00 0x01 ^chk_roland 0xf7"
EVENT_BUTTON id=3 hw_id=33 button_mode=OnOnly type=SysEx stream="0xf0 0x41 0x10 0x00 0x10 0x11 ^chk_start 0x1f 0x00 0x20 0x57 0x00 0x00 0x00 0x01 ^chk_roland 0xf7"

EVENT_ENC id=1   hw_id=1  lcd_pos=1:1:1   fwd_to_lcd=1 label="P1%B %03d"  range=0:127   type=SysEx stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x55 ^val ^chk_roland 0xf7"
EVENT_ENC id=2   hw_id=2  lcd_pos=1:9:1   fwd_to_lcd=1 label="P2%B %03d"  range=0:127   type=SysEx stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x56 ^val ^chk_roland 0xf7"
EVENT_ENC id=3   hw_id=3  lcd_pos=1:17:1  fwd_to_lcd=1 label="P3%B %03d"  range=0:127   type=SysEx stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x57 ^val ^chk_roland 0xf7"

Thanks!

Link to comment
Share on other sites

This is definitely not the intended behaviour!

I started to debug this at my side - the received values will be taken over as expected, but somehow they got lost (set to 0) *before* they are print out by the LCD.

Need more time to debug this...

Best Regards, Thorsten.

Link to comment
Share on other sites

Found it! :-)

This was an "unintended intended overwrite" of the value whenever F0 is received - stupid! -> https://github.com/midibox/mios32/commit/3982027d66f473b191d55898788872232dcf7cd2
Your input is really helpful to nail down such scenarios, thank you for this! :-)

Updated version: http://www.ucapps.de/mios32/midibox_ng_v1_037_pre9.zip

Best Regards, Thorsten.

Link to comment
Share on other sites

Wow, that was fast! :-) Without having tried the new version yet, I'd like to ask: if I want to request lots of parameters with an EVENT_BUTTON, is the preferred way to do it:

  1. one EVENT_BUTTON hw_id and lots of id's per parameter, or
  2. one EVENT_BUTTON hw_id and one id for each continuous address range of parameters (most received values are one byte, but some might be spread across two or more bytes, not sure if that's in a Roland specific way or in some standardised "MIDI way"), or
  3. something else?

And if I may request a small feature in order to make the NGR file cleaner: could there be a command to deactivate all events of a particular type, rather than using set_active (id)ENC:xx 0 one by one? Something like set_active_all (id)ENC 0, which would deactivate all encoder events.

At the moment I'm using NGR to first deactivate all events for each bank and then activate only the 16 that I actually need for each bank/tone combination, like this, only with lots more events (the syntax might not be 100% correct, I wrote this from memory, but hopefully you get the idea):

if ^bank == 1
    set_active (id)ENC:1 0
    set_active (id)ENC:2 0
    set_active (id)ENC:3 0
    set_active (id)ENC:4 0

    if (id)BUTTON:1 == 1
        set_active (id)ENC:1 1
    elsif (id)BUTTON:1 == 2
        set_active (id)ENC:2 1
    elsif (id)BUTTON:1 == 3
        set_active (id)ENC:3 1
    elsif (id)BUTTON:1 == 4
        set_active (id)ENC:4 1
    endif
endif

Edited by jjonas
add request
Link to comment
Share on other sites

Here's my test setup:

# Sysex test file 2
# Reset to default

RESET_HW

# Encoder hardware settings
# =========================
ENC n=1   sr=1 pins=0:1   type=detented3
ENC n=2   sr=1 pins=2:3   type=detented3
ENC n=3   sr=1 pins=4:5   type=detented3
ENC n=4   sr=1 pins=6:7   type=detented3

# Menu settings
SCS soft1_button_emu_id=2000 \
    soft2_button_emu_id=2001 \
    soft3_button_emu_id=2002 \
    soft4_button_emu_id=2003 \
    shift_button_emu_id=2004 \
    enc_emu_id=2000

# request a one-byte value
EVENT_BUTTON id=51 hw_id=51    button_mode=OnOnly  type=SysEx  fwd_to_lcd=1  stream="0xf0 0x41 0x10 0x00 0x10 0x11 ^chk_start 0x1f 0x00 0x20 0x55 0x00 0x00 0x00 0x01 ^chk_roland 0xf7"
# request three one-byte values
EVENT_BUTTON id=52 hw_id=52    button_mode=OnOnly  type=SysEx  fwd_to_lcd=1  stream="0xf0 0x41 0x10 0x00 0x10 0x11 ^chk_start 0x1f 0x00 0x20 0x55 0x00 0x00 0x00 0x03 ^chk_roland 0xf7"

EVENT_ENC id=1   hw_id=1  label="@(1:1:1)Prm1 @(1:1:2)%03d"    range=0:127  fwd_to_lcd=1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x55 ^val ^chk_roland 0xf0"
EVENT_ENC id=2   hw_id=2  label="@(1:6:1)Prm2 @(1:6:2)%03d"    range=0:127  fwd_to_lcd=1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x56 ^val ^chk_roland 0xf0"
EVENT_ENC id=3   hw_id=3  label="@(1:11:1)Prm3 @(1:11:2)%03d"  range=0:127  fwd_to_lcd=1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x57 ^val ^chk_roland 0xf0"
EVENT_ENC id=4   hw_id=4  label="@(1:16:1)Prm4 @(1:16:2)%03d"  range=0:127  fwd_to_lcd=1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x58 ^val ^chk_roland 0xf0"

Results:

fwd_to_lcd is not working. I think it should go into the receiving event, but above I've inserted it in both EVENT_BUTTON and EVENT_ENC because I wanted to check if I had misunderstood how it works, because the value wasn't updated.

For example, let's say at start MBNG has these four values: 10 10 10 10, and the synth's parameters are 50 50 50 50. Now I push the button to request the one value. MBNG now shows the same as before, 10 10 10 10, but in reality the values are now 50 10 10 10 (which is revealed when I turn encoder 1).

But there's a further related thing that's happening, which I'll bring up here, even though I noticed it already about a week ago when I was testing just sending sysex. In the situation above, the synth's values are changed too (which shouldn't happen when just requesting a value). If on the MBNG I turned the third encoder last before requesting parameters, the synth's values will be: 50 50 10 50. If it was the second encoder, the synth's values are 50 10 50 50.

It might connected with the following:

If we leave requesting data on one side for the moment, and I just use the MBNG to change synth parameters, here's what happens: I turn encoder 1 to change param 1. Ok. Now I turn encoder 2 to change param 2, but when I turn encoder 2, parameter 1 keeps changing for two more degrees before enc2 starts changing param 2. After changing from enc1 to enc2, the next two moves of enc2, to whatever direction, seem to replicate the two last moves of enc1. If I turn enc1 one degree clockwise, then one degree anti-clockwise, and then turn enc2 to whatever direction, param1 will first increase one, then decrease one degree.

Edited by jjonas
add emphasis
Link to comment
Share on other sites

(I've to think about your proposal about "bulk operations" on the active flags (and maybe others...)

To the problem: the reason, why the event doesn't update the LCD is because of the "0xf0" at the end of the SysEx strings, e.g.:
EVENT_ENC id=1   hw_id=1  label="@(1:1:1)Prm1 @(1:1:2)%03d"    range=0:127  fwd_to_lcd=1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x55 ^val ^chk_roland 0xf0"

Just write 0xf7 instead, and the LCD will be refreshed, because this is what your synth will send.

It could be, that the same typo already caused other side effects, also on your synth.

Concerning the encoder value problem: check again with the updated definition, if it still happens I need a concrete configuration to test it at my side.

Best Regards, Thorsten.

Link to comment
Share on other sites

Aaaarrgh what a dumb mistake!! Sorry about that! With the correction, requesting a single value and then changing the parameter at the MBNG side does work. (And requesting & sending two-byte values [with ^val_n1 and val_n2] works as well!)

Assigning several sysex data requests to one button press retrieves only the first two values. This is the case whether you send the request by listing the individual requests in NGC or by running
a ^section in NRG to send the same sysex requests.

Adding a 20ms delay in the script in between the requests for single parameters retrieves at least eight values I've requested in this test config (see below), and this works the way I want. However, it seems ^chk_start and/or ^chk_roland don't work in the script, the checksum has to be calculated and added manually.

Before I start typing in all my parameter requests one by one into a script ^section, I'd like to ask whether you think this is a good way to do it. It certainly seems to work for at least eight consecutive requests with the added 20ms delay, so from my point of view I don't see why it wouldn't work with a couple hundred.

* * *

The reason I asked about the bulk deactivation command was not just because of aesthetic reasons: with 8 banks x 16 parameters per bank x (mostly) 4 tones per parameter you end up with 512 events — not a huge amount in itself, but they have to be deactivated for each of the eight banks — that's 4096 lines of deactivation in the NGR file all put together. I can of course fold the huge deactivation litany in my editor into one line, so that's not the problem, but I think there's a limitation to the size of the NRG file somewhere around 4000 lines; I think I've already hit that when I've tried out stuff in a "stupid" way (just multiplying the script code to more and more banks).

The following is something I haven't tried yet, but based on a quick glance it would seem possible to run a new ^section from inside a ^section (exec_meta RunSection:xx). So if I have called ^section == 5 from NGC and then run an exec_meta inside it to call another section (to deactivate all encoder events, for example), this should work if after the second has run its course the program returns to the section which called it and continues from there. If this works, there might not be a need to add any new bulk deactivation commands, if there's complications to consider.

* * *

Here's my test config (NGC, NGR) just for reference.

# Sysex test file 3 (with NGR)
# Reset to default

RESET_HW

# Encoder hardware settings
# =========================

ENC n=1   sr=1 pins=0:1   type=detented3
ENC n=2   sr=1 pins=2:3   type=detented3
ENC n=3   sr=1 pins=4:5   type=detented3
ENC n=4   sr=1 pins=6:7   type=detented3
ENC n=5   sr=2 pins=0:1   type=detented3
ENC n=6   sr=2 pins=2:3   type=detented3
ENC n=7   sr=2 pins=4:5   type=detented3
#ENC8 emulated by the menu encoder

# Menu settings
SCS soft1_button_emu_id=2000 \
    soft2_button_emu_id=2001 \
    soft3_button_emu_id=2002 \
    soft4_button_emu_id=2003 \
    shift_button_emu_id=2004 \
    enc_emu_id=2000

# request one-byte values
EVENT_BUTTON id=51  hw_id=51  button_mode=OnOnly  type=Meta  meta=RunSection:1

EVENT_ENC id=1      hw_id=1  label="@(1:1:1)Prm1 @(1:1:2)%03d"    range=0:127  fwd_to_lcd=1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x55 ^val ^chk_roland 0xf7"
EVENT_ENC id=2      hw_id=2  label="@(1:6:1)Prm2 @(1:6:2)%03d"    range=0:127  fwd_to_lcd=1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x56 ^val ^chk_roland 0xf7"
EVENT_ENC id=3      hw_id=3  label="@(1:11:1)Prm3 @(1:11:2)%03d"  range=0:127  fwd_to_lcd=1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x57 ^val ^chk_roland 0xf7"
EVENT_ENC id=4      hw_id=4  label="@(1:16:1)Prm4 @(1:16:2)%03d"  range=0:127  fwd_to_lcd=1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x58 ^val ^chk_roland 0xf7"
EVENT_ENC id=5      hw_id=5  label="@(1:21:1)Prm5 @(1:21:2)%03d"  range=0:127  fwd_to_lcd=1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x59 ^val ^chk_roland 0xf7"
EVENT_ENC id=6      hw_id=6  label="@(1:26:1)Prm6 @(1:26:2)%03d"  range=0:127  fwd_to_lcd=1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x5a ^val ^chk_roland 0xf7"
EVENT_ENC id=7      hw_id=7  label="@(1:31:1)Prm7 @(1:31:2)%03d"  range=0:127  fwd_to_lcd=1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x5b ^val ^chk_roland 0xf7"
EVENT_ENC id=2000            label="@(1:36:1)Prm8 @(1:36:2)%03d"  range=0:127  fwd_to_lcd=1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x5c ^val ^chk_roland 0xf7"

################

# NGR file for the above

if ^section == 0
  exit
endif

if ^section == 1
    send SysEx OUT1 0xf0 0x41 0x10 0x00 0x10 0x11 0x1f 0x00 0x20 0x55 0x00 0x00 0x00 0x01 0x6b 0xf7
    delay_ms 20
    send SysEx OUT1 0xf0 0x41 0x10 0x00 0x10 0x11 0x1f 0x00 0x20 0x56 0x00 0x00 0x00 0x01 0x6a 0xf7
    delay_ms 20
    send SysEx OUT1 0xf0 0x41 0x10 0x00 0x10 0x11 0x1f 0x00 0x20 0x57 0x00 0x00 0x00 0x01 0x69 0xf7
    delay_ms 20
    send SysEx OUT1 0xf0 0x41 0x10 0x00 0x10 0x11 0x1f 0x00 0x20 0x58 0x00 0x00 0x00 0x01 0x68 0xf7
    delay_ms 20
    send SysEx OUT1 0xf0 0x41 0x10 0x00 0x10 0x11 0x1f 0x00 0x20 0x59 0x00 0x00 0x00 0x01 0x67 0xf7
    delay_ms 20
    send SysEx OUT1 0xf0 0x41 0x10 0x00 0x10 0x11 0x1f 0x00 0x20 0x5a 0x00 0x00 0x00 0x01 0x66 0xf7
    delay_ms 20
    send SysEx OUT1 0xf0 0x41 0x10 0x00 0x10 0x11 0x1f 0x00 0x20 0x5b 0x00 0x00 0x00 0x01 0x65 0xf7
    delay_ms 20
    send SysEx OUT1 0xf0 0x41 0x10 0x00 0x10 0x11 0x1f 0x00 0x20 0x5c 0x00 0x00 0x00 0x01 0x64 0xf7
    delay_ms 20
endif

Link to comment
Share on other sites

Ok. I tried to do that at first (with EVENT_RECEIVER and syxdump_pos), but I guess my attempt at describing what I wanted to do was not that good. I started with something simple so I was trying to get a single value first and allocate that to the right place, maybe that led to the impression that I just need one value.

I have a Roland XV-5080 and the MIDI implementation for it (p. 290-304),  I know how to come up with the sysex needed for requesting a range of parameters, and the order in which the parameters come in. I know how to send the request, so the question is how to parse the incoming data and allocate it to the right events. My attemps (described above in earlier posts) with EVENT_RECEIVER and syxdump_pos didn't work, and I (mis)understood from your replies that that's not the right way to go.

Edited by jjonas
add parenthetical clarification
Link to comment
Share on other sites

But it should work with EVENT_RECEIVER

When we take following configuration:

RESET_HW

EVENT_RECEIVER id=1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^ignore ^ignore ^ignore ^ignore ^dump 0xf7"

EVENT_ENC id=1   hw_id=1  label="@(1:1:1)Prm1 @(1:1:2)%03d"    range=0:127  fwd_to_lcd=1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x55 ^val ^chk_roland 0xf7"  syxdump_pos=1:0
EVENT_ENC id=2   hw_id=2  label="@(1:6:1)Prm2 @(1:6:2)%03d"    range=0:127  fwd_to_lcd=1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x56 ^val ^chk_roland 0xf7"  syxdump_pos=1:1
EVENT_ENC id=3   hw_id=3  label="@(1:11:1)Prm3 @(1:11:2)%03d"  range=0:127  fwd_to_lcd=1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x57 ^val ^chk_roland 0xf7"  syxdump_pos=1:2
EVENT_ENC id=4   hw_id=4  label="@(1:16:1)Prm4 @(1:16:2)%03d"  range=0:127  fwd_to_lcd=1  type=SysEx  stream="0xf0 0x41 0x10 0x00 0x10 0x12 ^chk_start 0x1f 0x00 0x20 0x58 ^val ^chk_roland 0xf7"  syxdump_pos=1:3

and send (e.g. via the MIOS Studio SysEx window):

f0 41 10 00 10 12 00 00 00 00 10 20 30 40 f7

the LCD will show the expected values 016, 032, 048, 064

It's important that the ^ignore statements in the receivers SysEx string will be replaced by concrete values, otherwise the receiver will respond on any matching SysEx strings which don't transfer the intended information.

So, after 0x12, what is normally sent back by your synth if these 4 parameters are requested?

Note also, that checksums are not relevant for receivers, therefore I just wrote 0xf7 after the ^dump

Best Regards, Thorsten.

 

Link to comment
Share on other sites

You're right, it does work now! I didn't try EVENT_RECEIVER after I got the impression it's not needed. The synth sends back a message that's identical to one that you'd send to the synth if you wanted to change a parameter value, so the four ignored bytes is the address of the first requested parameter (above, 0x1f 0x00 0x20 0x55), and what follows is as many bytes as you requested from that address onwards (including the start address).

THIS CALLS FOR A BEER!!!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...