Recent web app updates broke my templates

I have several templates with patch parsing that stopped working.
I am pretty sure its due to updates to the webapp and/or json schema.

To all the templates there was added a “deviceid 1”, automaticly.
Where I used a different id in the template.
I am not a person to complain so easily but man this is frustrating.
I spend long hours making it work and now again long hours to make something work that already used to work.
I have other templates I need to fix but have not investigated yet.

The first issue is that getPatchNumberByte() stopped working.
After creating a new json and amending the device id to 1 and migrate the patch data it now works.

Here is the .epr and .lua for the version i try to fix.
In the bottom i will describe the issue and why I consider this a bug.

Here is the LUA code:

mirageSoundProcessDeviceId = 1

incCount1 = 1

incCount2 = 1

 device = devices.get (mirageSoundProcessDeviceId)

-- getPatchNumberByte function is added in the patch request and reponse in the json
-- it fetches the value from parameterNumber 40 (patch select) on the moment the patch request button is pressed
-- so that the same patch is requested as parameterNumber 40 (patch select) is set to.
function getPatchNumberByte()
local parameterNumber = 40
patchNumber = parameterMap.get (mirageSoundProcessDeviceId, PT_SYSEX, parameterNumber )
return (patchNumber)
end


-- SetMidiChannel callback added in json
function setMidiChannel (control, value)
    device = devices.get (mirageSoundProcessDeviceId)
    device:setChannel (value +1)
end

-- oscPairSelect1 and oscPairSelect2 send a osc pair select message once, after that the counter of the other function 
-- is reset so if we switch to that page the corresponding osc pair select message is send out again.
-- controls belonging to osc pair 1 have the function oscPairSelect1 added in the json .epr file and controls osc pair 2 
-- oscPairSelect2

function oscPairSelect1()

if incCount1 == 1 then
-- device = devices.get (mirageSoundProcessDeviceId)
 midi.sendSysex (PORT_1, {  0, 0, 35, 1, 67, 60, 1, 0 })
 incCount1 = incCount1 + 1

-- reset the other counter so the message will be send for pair 2 once we switch to that controls 
incCount2 = 1

 end
end

function oscPairSelect2()

if incCount2 == 1 then

 device = devices.get (mirageSoundProcessDeviceId)
 midi.sendSysex (PORT_1, {  0, 0, 35, 1, 67, 60, 2, 0 })
 incCount2 = incCount2 + 1

incCount1 = 1
 end
end


function fetchProgram (control, value)

    device = devices.get (mirageSoundProcessDeviceId)

midi.sendSysex (PORT_1, {  0, 0, 35, 1, 2 })

print(value +1)



midi.sendSysex (PORT_1, { 1, 2, 3, 4, value +1 } )
end

Here is the preset
edit.epr (239.3 KB)

Byte 0 = AMP envelope attack
So I am pretty sure I have that correct.

The patch request goes out.


   "responses": [
      {
        "header": [
          "00",
          "00",
          "23",
          "01",
          "44",
          {
            "type": "function",
            "name": "getPatchNumberByte"
          }
        ],
        "rules": [
          {
            "type": "sysex",
            "parameterNumber": 49,
            "parameterBitPosition": 0,
            "byte": 0,
            "byteBitPosition": 0,
            "bitWidth": 4
          },

The patch parameter 40 is set to 10:
The amp attack value is 8 and in the dump coming back I can see the 2 nybbles 08 00

Why are no parameters updated?




Now the old template:

link: Electra One App

After the update the patch parse section is not visible in the webapp.

If you look in the json you will see a “general midi device” was added with id:1
And you can see my device with "id": 9,
See lua: mirageSoundProcessDeviceId = 9
None of my calls work. I always get no results for getPatchNumberByte()
It always returns 0.0

Here is the old patch parse section. I removed some bytes the full one you can see in the template.

What is "instrumentId": "generic-midi" its added in the bottom.
This should be for " “id”: 9," I think this is the issue of the updates and how it broke the template.
Ok no problem. But what is missing in my fixed .epr on top?
The old template contains 2 different request and responses.
The new one is only 1 for now.
I cannot see why it does not work.

Is there a way to use the latest json schema and validate my template against it?

  "devices": [
    {
      "id": 1,
      "name": "Generic MIDI",
      "port": 1,
      "channel": 1,
      "instrumentId": "generic-midi"
    },
    {
      "id": 9,
      "name": "Ensoniq Mirage Soundprocess",
      "port": 1,
      "channel": 1,
      "patch": [
        {
          "request": [
            "00",
            "00",
            "23",
            "01",
            "04",
            {
              "type": "function",
              "name": "getPatchNumberByte"
            }
          ],
          "responses": [
            {
              "header": [
                "00",
                "00",
                "23",
                "01",
                "44",
                {
                  "type": "function",
                  "name": "getPatchNumberByte"
                }
              ],
              "rules": [
                {
                  "type": "sysex",
                  "parameterNumber": 49,
                  "parameterBitPosition": 0,
                  "byte": 0,
                  "byteBitPosition": 0,
                  "bitWidth": 4
                },
                {
                  "type": "sysex",
                  "parameterNumber": 49,
                  "parameterBitPosition": 4,
                  "byte": 1,
                  "byteBitPosition": 0,
                  "bitWidth": 4
                },
                {
                  "type": "sysex",
                  "parameterNumber": 120,
                  "parameterBitPosition": 0,
                  "byte": 122,
                  "byteBitPosition": 0,
                  "bitWidth": 4
                },
                {
                  "type": "sysex",
                  "parameterNumber": 120,
                  "parameterBitPosition": 4,
                  "byte": 123,
                  "byteBitPosition": 0,
                  "bitWidth": 4
                }
              ]
            }
          ]
        },
        {
          "request": [
            "00",
            "00",
            "23",
            "01",
            "07"
          ],
          "responses": [
            {
              "header": [
                "00",
                "00",
                "23",
                "01",
                "47"
              ],
              "rules": [	
                {
                  "type": "sysex",
                  "parameterNumber": 794,
                  "parameterBitPosition": 0,
                  "byte": 5,
                  "byteBitPosition": 0,
                  "bitWidth": 4
                },
                {
                  "type": "sysex",
                  "parameterNumber": 794,
                  "parameterBitPosition": 4,
                  "byte": 6,
                  "byteBitPosition": 0,
                  "bitWidth": 4
                }
              ]
            }
          ]
        }
      ],
      "instrumentId": "generic-midi"
    }
  ],

EDIT:

See here trying to get the bytes in the webapp.
The dump comes in.
But notice the lua byte: ANH NaN
Not that I care for this functionality in this case as the patch parsing has done already by hand.
But I am not able to fix my template.

EDIT:
The last thing i noticed a some * and - chars in the template on some groupnames.
I do not remember I put them there.

Hi Tim,

I am looking at it. The first question. The following preset. Is that the original version of the preset or have you made any modifications to it in the latest web app version?

I have copied the preset to my account. And I am now checking the request part. There is device #1 added indeed, but there is also your original device #9. The getPatchNumberByte refers to it by variable mirageSoundProcessDeviceId. When I press the Patch request button, I can see that settings of the PATCH SELECT (which refers to SysEx parameter 40 in the parameterMap) control is reflected.

Pls take in account that I just started observing what is happening. I still do not understand full context of the preset. I shared my observation to find common grounds that we can use to debug it further.

Hi Martin, that link is the original preset.

I made a newer version trying to fix it.

I now see the getPatchNumberByte is working even in the old preset.
Hmmm very strange. Not sure how I can explain that.

But ok the patch data comes in but nothing is parsed.

It did not work so I was debugging via the console. Always got 0.0
Tried device id:1 and id:9 the correct one.

I just made a mock of Mirage response and I am going to review the parsing part. I will keep you updated on what I find there.

1 Like

Ok thanks. If needed I can past some responses here. let me know

if you share syx data that do not work for you, I can test with exactly the same data as you have.

edit: hmm, maybe web app could one day just forward data between Electras over inet :slight_smile:

That would be quite cool.
Please also add some DDOS functionality so you can hack people that make shitty music so you can inject some better sounding patches :slight_smile:

Request: for patch 10 dec 0Ah
F0h 00h 00h 23h 01h 04h 0Ah F7h

Here is the dump for patch 10 dec 0Ah. the value of byte 0 of the data block, and 1 is 8. Its AMP attack.

F0h 00h 00h 23h 01h 44h 0Ah 08h 00h 00h 00h 0Fh 01h 00h 00h 00h 01h 00h 00h 0Fh 01h 00h 00h 03h 00h 00h 00h 03h 00h 03h 00h 0Dh 40h 02h 0Dh 02h 01h 00h 01h 01h 0Ch 00h 03h 00h 03h 00h 0Fh 03h 0Fh 03h 0Fh 01h 00h 00h 00h 00h 09h 00h 00h 00h 0Fh 01h 00h 00h 00h 40h 01h 00h 00h 0Fh 01h 00h 00h 03h 00h 05h 00h 03h 00h 0Fh 0Fh 0Dh 02h 0Dh 02h 01h 00h 00h 00h 00h 00h 00h 00h 03h 00h 0Fh 03h 0Fh 40h 03h 0Fh 01h 00h 00h 00h 00h 00h 00h 03h 02h 0Ch 00h 08h 02h 0Ah 01h 00h 00h 0Fh 01h 00h 00h 0Fh 01h 00h 00h 0Fh 01h 00h 00h 0Ch 40h 00h 06h 03h 04h 05h 02h 05h 09h 04h 04h 05h 0Fh 04h 0Eh 04h 01h 03h 00h 03h F7h
1 Like

I think I understand what is happening. The getPatchNumberByte is called in the request but not when the response header bytes are compared with the incoming SysEx message. That results in skipping the patch parsing functions. I will verify that and will prepare a fix. I’d say when this is fixed your preset should work just fine.

2 Likes

Oooh that would be great! Thanks already.

@Flyweight There is a new release available on beta. Your preset (the one you reported above) works just fine for me. If I select patch 10 and run the message you provided, attack gets updated to 8 (as well as other params).

Pls let me know if it works for you too. Thx.

1 Like

thanks @martin for the quick fix. wil test it soon.

1 Like

Hi Martin,

I did some more testing. It looks I am back in the old situation where the data incoming is parsed.
Have’nt verified 100%
However the Eone gets struck after after just playing with some parameters.
Full on crash. The memory indicator doesn’t reveal anything.

So sadly the template cannot be used at all.
The crash is easy to reproduce.

So now I wonder did you test this on a Mirage running Soundprocess OS?

1 Like

does it simply crash after some time, if you play with any parameters, or only certain parameters cause the crash?

Also - if you slowly adjust values instead of quick turns of the encoders, does that keep it from crashing?

One thing to do (I know it makes it less immediate/usable) – set the timer period to 150 and everywhere else you change it, comment that line out.

The thought is that by slowing down the transmission of MIDI, you might be queueing up more data than can be stored in the E1 memory.

1 Like

This is regarding another template for another os for the Mirage.
The OS is called soundprocess os.
the sysex implementation supports normal parameter changes.
the lua code for this on is very minimal and there is no timer.

The crashes happen on changing any parameter. no matter if a Lua function is assigned or not.

The Template you are helping me with is for The Ensoniq MASOS (Mirage advanced Sampling OS).
It has a completely different sysex implementation.

Both OS’s are very useful to use together. Samples made with MASOS can be loaded into Soundporcess.

Cheers

Tim

1 Like

I still do not have Mirage around - hopefully next week. I tested the preset with sending the sysex messages manually. That seemed to work ok. I will take a look at soundprocess version of your script.

I did see some lua code in the original preset and garbage collection calls commented out. But I think it is irrelevant to the soundprocess. Anyways, I will take a look.

1 Like

Does the Mirage (running the Soundprocess OS) send back MIDI data when you make parameter changes via the Electra One?

I did some test:

  1. clone of the template, without LUA, but some calls still bound to some parameters.
  • result: Mirage freezes
  1. clone of the template, without LUA, or calls
  • result: Mirage freezes
  1. clone of the template, with LUA and no patch response
  • result Mirage freezes
  1. New template, 2 controls pasted in it
  • result: Mirage does not freeze

Yes the Mirage Soundprocess replies to any request with a status message:

Some examples are:

00 = ok,

01 = no computer control

02 = undefined error

Here is a parameter update and a ‘ok’ reply

1 Like

what happens if you temporarily disconnect the cable connecting Mirage OUT to Electra One IN ?

1 Like
  1. Another test:
    Copied all controls to a new template with the Lua code.
  • result: no crash
  1. Another test:
    Copied all controls to a new template with the Lua code. And the patch response:
  • result: crash
  1. Another test:
    Copied all controls to a new template with the Lua code. And the patch response:
    Midi in cable disconnected from the Eone.
  • result: no crash

I have witnessed a similar issue with the Masos template.
If you remember the section I commented out in the patchon.reponse.
Where you replied the code is ok.

   -- FIXME this does not work. Eone gets stuck when this section is enabled. 
   -- The idea id to catch the program parameter messages for the large value controls 
   -- and correct the values.
   -- so we perferably want to only catch the last message.
   -- queue, fetch last... clear the rest?
   -- 0E = wave parameter update message

   elseif (recvSize == 9) and (sysexBlock:peek(4) == 14) and ( progDataEnabled == 0 ) then

      local skipBytes = 5   
      sysexBlock:seek(skipBytes)   

      for i = 0, 3, 1 do
         deSyx[i] = sysexBlock:read()
      end

      if (deSyx[0] < 8) then
         print ("Lower wavesample number: " .. deSyx[0])
      elseif (deSyx[0] > 15) then
         print ("Upper wavesample number: " .. (deSyx[0] & 0x0F))
      else
         print ("error program bytes does not make sense byte value = " .. deSyx[0] )
      end

      print("The message we received is for Parameter: " .. deSyx[1])

      if ((deSyx[1] >= 60) and (deSyx[1] <=64)) or (deSyx[1] == 68) then
         value = makeSwapB(deSyx[2], deSyx[3])
      elseif (deSyx[1] == 37) then
         -- This is a program message not a wave #FIXME
         value = makeSwapB(deSyx[2], deSyx[3]) / 2
      else
         print("no special control processed")
      end

But when I enabled it there would be a full freeze as well.
Then I also discovered a bug. When you request the parameter status of [60] or [61] it would burst out the status for 7 .parameters.

It looks the Eone has issues with small incoming messages.
Does it overflow something in the parser?

Some other minor issue I found:
Trying to remove patch section for the device results in:
And a F0 and f7 are sended when you press the patch request button.

  "devices": [
    {
      "id": 1,
      "name": "Generic MIDI",
      "instrumentId": "generic-midi",
      "port": 1,
      "channel": 1,
      "patch": [
        {
          "request": [],
          "responses": []
        }
      ],
      "rate": "80"
    }
  ],

Where it should like this:

VS

  "devices": [
    {
      "id": 1,
      "name": "Generic MIDI",
      "port": 1,
      "channel": 1
    }
  ],

I do not quite understand this part.
If there is some problem with parameter status 60 or 61, for now just put in some debug code and do nothing else until you understand what is being received.

Something like

if (deSyx[1] == 60) or (deSyx[1] ==61)  then
   print ("message size was " .. recvSize)
   print ("deSyx[2] is " .. deSyx[2])
   print ("deSyx[3] is " .. deSyx[3])
end