V4.0 testing [was V3.7]

HI @martin - I would like to try this new mechanism out (to experiment with saving and restoring user settings) in a E-1 preset. Is it supported in the 4.0.0a firmware? If so, I would be grateful if you could summarise the LUA API ?

Regards

@rkram53, @Phommed, @Kaltar Next feature, persisting and recalling the preset data.

The Lua API has been extended with two functions:

persist(table) to save a Lua table to a non-volatile storage
recall(table) to load a previously loaded table

Note, only one table can be stored per preset. Also, there is a limit on the size of persisted data. It is now 20kB.

An example can be seen at:
Persist data

When persisted, the data is serialized to a JSON format. There are SysEx calls to query and upload the data too. I will share info about these later.

yes, I have using ST / Score as the main sequencer for quite some time now. The mouse, even though it looks cool, is the weakest part of the system.

1 Like

Martin, what’s the best source of info to check on all release notes/changes since version x? I’d like to review them rather holistically to see what has become useful for me, and test these out specifically.
Reason, I haven’t followed up on each separate release, and fear to be a bit behind on what is now possible and what not.

2 Likes

That looks like it links to same “Custom pot functions” preset link above ? I opened that preset again but does not contain calls to persist or recall. (but it does contain a useful assert codeblock which I will use!)

link fixed.

1 Like

I think I have found a possible bug with the events.onPotTouch callback with firmware 4.0.0a. It appears to be firing additional callback events that has a controlId argument = 0 for every pot touch event (touched or not touched).

function events.onPotTouch(potId, controlId, touched)
  log("potId: " .. potId .. ", controlId: " .. controlId .. ", touched: " .. (touched and "yes" or "no"))
end

Tapping a single pot once shows this log:

20:22:58.380 lua: potId: 1.0, controlId: 0.0, touched: yes
20:22:58.390 lua: potId: 1.0, controlId: 3.0, touched: yes
20:22:58.395 lua: potId: 1.0, controlId: 0.0, touched: yes
20:22:58.510 lua: potId: 1.0, controlId: 0.0, touched: no
20:22:58.520 lua: potId: 1.0, controlId: 3.0, touched: no
20:22:58.525 lua: potId: 1.0, controlId: 0.0, touched: no
1 Like

Experimenting with the persist and recall.

It seems that persisted boolean table properties are being recalled as numeric 1 or 0 values, instead of lua booleans

Here’s my log from the persist data example preset:

21:21:52.951 ---- START ----
21:21:52.963 lua: -- table to be persisted --
21:21:52.964 lua: {
21:21:52.964 lua:   number = 1.42
21:21:52.964 lua:   objArray = 
21:21:52.964 lua:   {
21:21:52.964 lua:     1 = 
21:21:52.965 lua:     {
21:21:52.965 lua:       key1 = text
21:21:52.965 lua:     }
21:21:52.966 lua:     2 = 
21:21:52.966 lua:     {
21:21:52.966 lua:       key2 = 1.2
21:21:52.966 lua:     }
21:21:52.966 lua:     3 = 
21:21:52.966 lua:     {
21:21:52.967 lua:       key3 = true
21:21:52.967 lua:     }
21:21:52.967 lua:   }
21:21:52.968 lua:   boolean = true
21:21:52.968 lua:   text = hello table
21:21:52.968 lua:   array = 
21:21:52.968 lua:   {
21:21:52.968 lua:     1 = 1
21:21:52.969 lua:     2 = 2
21:21:52.969 lua:     3 = 3
21:21:52.970 lua:   }
21:21:52.970 lua: }
21:21:52.991 lua: -- modified table --
21:21:52.992 lua: {
21:21:52.992 lua:   key = value
21:21:52.993 lua: }
21:21:52.996 lua: -- recalled table --
21:21:52.997 lua: {
21:21:52.997 lua:   number = 1.42
21:21:52.997 lua:   objArray = 
21:21:52.997 lua:   {
21:21:52.997 lua:     1 = 
21:21:52.998 lua:     {
21:21:52.998 lua:       key1 = text
21:21:52.999 lua:     }
21:21:52.999 lua:     2 = 
21:21:52.999 lua:     {
21:21:52.999 lua:       key2 = 1.2
21:21:52.999 lua:     }
21:21:53.000 lua:     3 = 
21:21:53.000 lua:     {
21:21:53.000 lua:       key3 = 1
21:21:53.001 lua:     }
21:21:53.001 lua:   }
21:21:53.001 lua:   array = 
21:21:53.001 lua:   {
21:21:53.002 lua:     1 = 1
21:21:53.002 lua:     2 = 2
21:21:53.003 lua:     3 = 3
21:21:53.003 lua:   }
21:21:53.003 lua:   boolean = 1
21:21:53.003 lua:   text = hello table
21:21:53.004 lua: }
1 Like

Can the persist data be stored in a snapshot? Or are snapshots limited just to onscreen controls? Follow-up question to that would be is there any additional configuration for snapshot functionality in the new implementation? I’m working on a preset for a Roland R8m that handles its own internal state in Lua and reuses onscreen controls depending on what note is being edited. Would any of the new features in 4.0 simplify this at all? Thanks!

I am having trouble with replicating this issue.

I’ve made this simple preset to test it out: pot touch test

I am getting the callbacks as I expect them. Can you try to run this preset on your side? I guess there must be some “else” that is happening on your side (in your preset I mean).

I will try and isolate / reproduce it - might take some time.

(Edited)
I have noticed maybe a related issue. After clicking the “Send To Electra” button on the Lua page from the browser app, the onPotTouch stops firing if the control specifically set to invisible

Steps:

  1. Try adding the fader visibility lines below to the pot touch test preset.
  2. Reset the E-1
  3. Press pot 0, the log line prints (with ControlId = 0)
  4. Press the “Send to Electra” button on the lua page
  5. Press pot 0, the log line does not print

But if you touch pots 4,5,6 etc, which do not have a control, they still fire onPotTouch with controlId = 0.

events.subscribe(PAGES | POTS)

 local fader = controls.get(1)
  fader:setVisible(false)


function events.onPotTouch(potId, controlId, touched)
  print ("potId: " .. potId .. ", controlId: " .. controlId .. ", touched: " .. (touched and "yes" or "no"))
end
12:48:59.242 ---- START ----
12:48:59.242 loadLuaModule: Lua extension file initialized: file=ctrlv2/slots/b00/p06/main.lua
12:48:59.242 ----- END -----
12:49:04.731 lua: potId: 0.0, controlId: 0.0, touched: yes
12:49:04.897 lua: potId: 0.0, controlId: 0.0, touched: no
12:49:05.292 lua: potId: 0.0, controlId: 0.0, touched: yes
12:49:05.456 lua: potId: 0.0, controlId: 0.0, touched: no
12:49:05.602 lua: potId: 0.0, controlId: 0.0, touched: yes
12:49:05.751 lua: potId: 0.0, controlId: 0.0, touched: no
12:49:12.193 lua: transport disabled
12:49:12.316 loadLua debug output:
12:49:12.317 ---- START ----
12:49:12.319 loadLuaModule: Lua extension file initialized: file=ctrlv2/slots/b00/p06/main.lua
12:49:12.320 ----- END -----
1 Like

An updated version firmware-v4.0.0b.srec.zip (1.7 MB)

I was able to reproduce it and I hope it is fixed now.

fixed

fixed.

Finished features:

  • The Electra’s USB Host can now handle up to 16 MIDI ports (MIDI cables) on connected USB devices. Each of those ports can be routed to Electra’s internal port PORT 1 and PORT 2, or ignored. Here’s an example of MioXL and MRCC connected to Electra:

@Songsta I’ve made changes here that I hope will help to successfully recognize the LinnStrument. If you are not a developer, I suggest you wait for the official release though.

  • Electra’s internal router has been extended so that it supports routing between any port of any interface (it has been done in v 3.7 already). Now, the router can be configured using the controller’s UI. Please note, it is not possible to save adjusted config yet. I am working on it now. The router configuration is accessible via the new Main Menu.

  • Preset devices (their MIDI port and channel) can now be modified directly on the controller using the Device List editor. All changes stay saved until the preset slot is not reloaded with a new preset. This means that users do not have to copy and modify existing presets if they need to change MIDI port and channel only.

Router configurations, USB assignments, and the Device list overrides can be, of course, also modified using the SysEx calls. Examples will follow soon.

  • Snapshots have been reworked and improved. I fixed reported issues as well as I added an option to morph (linear interpolation) between two saved snapshots. There is also an option to randomize data with boundaries given by two saved snapshots.

The morphing and randomization is available for top 12 snapshot slots. There is an indicator of interpolation/randomization underneath each pair of “morphable” snapshots. The morphing and randomization is controlled with the pots.

Note:

  • Snapshots parameters with the identical value are ignored (that way you have control over what is being modified)
  • Randomization uses left snapshots as one boundary, the second boundary is set by the current morphed sound. That way, you have control over range of random values generated.
  • Newly generated values can be saved as a new snapshot at any time.

I have tested the feature using the MidiMonitor only. I still need to do real-world tests with synthesizers. I do expect that things will keep evolving here…

  • The Main Menu can be opened by swiping the right side of the screen (see above). It provides access to all features listed above. The main menu can be also mapped to external MIDI control.

ps: I am busy with updating the documentation too.

11 Likes

woow. Now that is pretty INCREDIBLE

This will bring the E1 to a new level :slight_smile:

3 Likes

Woho!! That looks really god! Thanks a lot for all the Effort! I really need to dive into that asap!

Short Question: did i see it right, that for now, only internal Functions can be triggered by the HW Buttons? Or is there a way to have a Custom Function triggered by the HW Buttons as well?

Is it possible to control the font size of custom text as printed by graphics.print?

If it isn’t, please do consider providing this option as the default font size for custom text is very small.

1 Like

Hi @martin . OK I think I have a reproduceable test case now, using 4.0.0b
TLDR; If a previously invisible control is made visible, the onPotTouch fires additional events with controlId = 0 in addition to the (correct) non-zero controlId of the control.

See my slightly modified pot touch test preset (it adds a 3rd button to toggle visibility of the first fader): Electra One App

LUA code (the changeVisibility function is set as the “Function” of the toggle-button:

events.subscribe(PAGES | POTS)

function events.onPotTouch(potId, controlId, touched)
  print ("potId: " .. potId .. ", controlId: " .. controlId .. ", touched: " .. (touched and "yes" or "no"))
end

function changeVisibility(valueObject, value)

  local fader = controls.get(1)
  fader:setVisible(not fader:isVisible())

end

Steps:

  1. Load this preset
  2. Reset the unit (avoids the additional issue I found described in the thread above to do with sending an updated preset from the app) to start fresh.
  3. The preset loads - the first fader is not visible, the second fader is visible and the 3rd control, a button, is visible. Look at the LUA log.
  4. Tap Pot 0. See single pair of logged touch events:
17:10:35.702 lua: potId: 0.0, controlId: 0.0, touched: yes
17:10:35.837 lua: potId: 0.0, controlId: 0.0, touched: no
  1. Now tap the “TOG VISIBLE” button. Fader 1 now appears

  2. Tap Pot 0. See multiple onPotTouch events (two “controlId=0” events for each non-zero-controlId event:

17:10:46.501 lua: potId: 0.0, controlId: 0.0, touched: yes
17:10:46.511 lua: potId: 0.0, controlId: 1.0, touched: yes
17:10:46.516 lua: potId: 0.0, controlId: 0.0, touched: yes
17:10:46.631 lua: potId: 0.0, controlId: 0.0, touched: no
17:10:46.641 lua: potId: 0.0, controlId: 1.0, touched: no
17:10:46.647 lua: potId: 0.0, controlId: 0.0, touched: no
2 Likes

@martin. In both the 4.0.0a and 4.0.0b, it seems if the hardware.useDefaultLayout = false, then the button combo to go to sleep (bottom right hand then bottom left hand buttons) but also resume from sleep (holding down bottom right-hand button ) no longer work.

2 Likes

I am crying with joy!!! Wowowow!!! I will wait until the final firmware is stably released. I can imagine things like using the Mini Electra One to morph between Electra’s snapshots. I already have a morphing system with Clyphx… Then I will be able to morph… groups of morphing knobs. :star_struck::star_struck::star_struck::star_struck: That’s something I always wanted to do with an external gear… AND now it will be possible sooon! . And my Syntakt… AAAHHHH! I could directly connect the E1 or E1 Mini to the Syntakt, assign, snap… And morph the Syntakt parameters from the E1!!! :santa::santa: The E1 is such a genius hardware! THANK YOU SO MUCH!!!
Tweak

3 Likes

I tested morphing and randomization with a real synth—and it completely derailed my productivity for the rest of the day! :smile:

snapshots

9 Likes

Oh!! I fully understand what you’re experiencing! It’s like opening the gate and… the first side effect: time becomes truly relative! What exists between two sounds? New, unintended possibilities and even more doors to open! You can spend hours just enjoying the sound and discovering incredible textures. :rocket::artificial_satellite::heart_eyes::santa: And it’s just the beginning of all the new abilities that morphing can bring to your creativity and workflow. I’ve always wondered why morphing wasn’t used more often. It’s such an incredible way to both discover and control.

And now the E1 comes to the morphing realm! I’m so excited to see how my Syntakt will react. And the E1 UI… :star_struck::star_struck::star_struck::star_struck::star_struck: Sooo good!!!

Thank you, Martin, and everyone involved in this amazing project and piece of gear! :heart_eyes:

3 Likes