Six-trak panel is in BETA

Home Forums General Programming Six-trak panel is in BETA

Viewing 19 posts - 1 through 19 (of 19 total)
  • Author
    Posts
  • #117324
    EnzoF04
    Participant
    • Topics: 17
    • Replies: 96
    • Total: 113
    • ★★

    Dear members, hopefully has anyone a Sequential Circuits Six-trak; a almost fully functioning panel is available for this beautiful synthesizer.

    First things first: I wish to thank Dnaldoog, Goodweather, Human Fly and the creator of the first version of the panel, Muve.

    Now almost everything works fine and updates to the values in the panel of the synthesizer.
    The only thing that doesn’t work for now is the receiving of the three value parameter for filter keyboard tracking; this is sent over 2 bytes. If both are switched off key tracking is off, if one is 1 key tracking is half and if the other one is 1, key tracking is full. As Dnaldoog helped me with code for assigning data from the sysex into a table, I don’t really can get it in my head how I can do the assigning of the data to the slider.

    Second thing, pretty important to me: When assigning the received data from the synthesizer to the modifiers on the panel, the parameters are send back to the synth again. I have the setValue (value, false, false, false) but somehow it manages to send it anyways.

    How can I check if the midi sending / receiving is enabled on the synth? I’ve thought of that by creating a function called in the midiReceived panel part but when the synth is not sending, then nothing is received by the panel so nothing is processed, like switching a message “no communication” or such a signal.

    Next things I’m thinking of is a random program (patch) knob and a way to use stack mode, six voices with six different programs (patches).

    Any suggestions are welcome, critics and comments are valuable to me and when you encounter a bug; let me know! My code is pretty Fred Flintstonian and I know how to compact and build more modular code.

    See attached!

    Attachments:
    You must be logged in to view attached files.
    #117327
    Tedjuh
    Participant
    • Topics: 3
    • Replies: 25
    • Total: 28

    To check if the midi sending/ receiving is enabled, you could send a system id request. If the synth sends an id back, the sending/ receiving should be on. If it doesn’t it’s turned off. Should be doable with an easy if then else statement.

    #117328
    Tedjuh
    Participant
    • Topics: 3
    • Replies: 25
    • Total: 28

    Double post, I know.. but I noticed messages disappear when edited too much.

    For sending/ receiving. See page 7 of the midi implementation. “Enable all Midi Send/ Receives.
    Send: F0 01 7E F7

    This forces all send/ receives to be enabled, including wheels, program changes and parameter changes. Should be harmless to send it anyway at panel loaded. Right?

    For the key tracking? Can this be done with an else/ if statement in the midireceived?

    if byte(A) == 0 and byte(B) == 0 then
    set slider to off
    elseif byte(A) == 1 and byte(B) == 0 then
    set slider to half
    elseif byte(A) is 0 and byte(B) is 1 then
    set slider to full.

    #117329
    EnzoF04
    Participant
    • Topics: 17
    • Replies: 96
    • Total: 113
    • ★★

    Thanks Tedjuh, That would be a nice work around. Can explore the SCI-id sending receiving. Would love to, from the user interface psychology stand point, to implement a midi on/of. This will give me the future possibility to implement different midi modes, so I can assign a single voice to program (patch) and other modes.

    The work around with the triple position parameter is a nice concept, thanks! The bigger challenge is to get the data analyzed from a table. It’s declared as:

    modulators{
    parameter01 - value 02
    parameter02 - value 01
    parameter03 - value 00
    parameter04 - value 63
    }

    I have to evaluate the values of parameter02 and parameter03. Thinking about questioning this gives me a rough idea of how to do it. Will try it when there is time!

    Thanks for now, Tedjuh!

    #117330
    Tedjuh
    Participant
    • Topics: 3
    • Replies: 25
    • Total: 28

    modulators{[1]=value,[2]=value, and so on}

    if modulators[2] == 0 then
    Do something..

    Hope this gives you a headstart..

    #117331
    EnzoF04
    Participant
    • Topics: 17
    • Replies: 96
    • Total: 113
    • ★★

    Will try it tonight! Keep you posted!

    Thanks, Tedjuh!

    #117337
    goodweathergoodweather
    Participant
    • Topics: 41
    • Replies: 443
    • Total: 484
    • ★★

    Hi, I looked a bit at your panel…

    Suggestion:
    Call your modulators without putting mod in front.
    Create a method called AssignModulators(). Add that line in PanelLoaded().
    In the AssignModulators(), declare all your modulator variables.
    Like

    modVcoTri = panel:getModulatorByName("VcoTri")
    modVcoFinFreq = panel:getModulatorByName("VcoFinFreq")
    ...

    Don’t put local in front of those.
    Then when needed you can use the mods in any method and you will directly know the name of the variable.
    In that way you will not have to do it in each method. The way you coded it now makes the system assigning the variable each time the method is run. Even if it works fine, this is not good.

    About data being sent back to the synth when received, this is just the way the panel works 😉
    MidiMessageReceived is getting the data and asking the modulator to change
    You assigned a method to the property “Called when modulator value changes” so it is executed and in that one you asked to send the message to the synth.

    First advice: rename your methods to something like VcoTri_Onchange() so you can directly identify which method is doing what (some are used OnClick, some OnChange…). Unfrotunately there is no rename and you must recreate them, copy/paste the code, rename the function.

    Now to solve you main problem you need to find a way to know you got a message from the synth (don’t send back) or to know you turned the button on the panel (send to synth).
    Method1: in the beginning of MidiMessageReceived, set a variable bFromSynth= true. Then in each method, test if not bFromSynth then send and reset bFromSynth=false at the end.
    Method2: in each method you can test the source of the change. This is the last parameter and it is automatically set. You want to send when a change is done from the panel so, use:
    if source==4 then send

    #117338
    EnzoF04
    Participant
    • Topics: 17
    • Replies: 96
    • Total: 113
    • ★★

    Very useful, Goodweather! I know my coding is Fred Flintstonian and I have to improve but doing it this way I get accustomed to declaration of data and variables and altering those. Last week I made a method myself with three variables and that worked. Have to learn how to give a processed variable back to the code that was executing the method. But I’m getting a bit more of a grip. Lua is fun to code. I will start the improvements to achieve a more stable panel.

    Thanks for the advice, it’s much appreciated!

    #117353
    dnaldoogdnaldoog
    Participant
    • Topics: 1
    • Replies: 236
    • Total: 237
    • ★★

    Goodweather is right and testing that code I posted, that filters an incoming 37 Byte message, it can be sped up using this advice.

    For example in an “Called when the panel has finished loading” initialise function, put

    
    modVcfKeyTrkA=panel:getModulatorByName("modVcfKeyTrkA")
    modVcfKeyTrkB=panel:getModulatorByName("modVcfKeyTrkB")
    modVcfKeyTrk=panel:getModulatorByName("modVcfKeyTrk")
    modVcaEnvRels=panel:getModulatorByName("modVcaEnvRels")
    modLfoPls=panel:getModulatorByName("modLfoPls")
    modVcoFinFreq=panel:getModulatorByName("modVcoFinFreq")
    modVcfCutoff=panel:getModulatorByName("modVcfCutoff")
    modVcfTriAmnt=panel:getModulatorByName("modVcfTriAmnt")
    modVcfEnvInvrt=panel:getModulatorByName("modVcfEnvInvrt")
    modVcoSaw=panel:getModulatorByName("modVcoSaw")
    modVcoEnvAtck=panel:getModulatorByName("modVcoEnvAtck")
    modVcfEnvRels=panel:getModulatorByName("modVcfEnvRels")
    modVcfEnvDecy=panel:getModulatorByName("modVcfEnvDecy")
    modVcaEnvDecy=panel:getModulatorByName("modVcaEnvDecy")
    modVcfResonnc=panel:getModulatorByName("modVcfResonnc")
    modVcfEnvAtck=panel:getModulatorByName("modVcfEnvAtck")
    modVcoEnvInvrt=panel:getModulatorByName("modVcoEnvInvrt")
    modVcoEnvRels=panel:getModulatorByName("modVcoEnvRels")
    modNoiseMixer=panel:getModulatorByName("modNoiseMixer")
    modVcoEnvAmnt=panel:getModulatorByName("modVcoEnvAmnt")
    modUnison=panel:getModulatorByName("modUnison")
    modGlideRate=panel:getModulatorByName("modGlideRate")
    modVoiceVolum=panel:getModulatorByName("modVoiceVolum")
    modPulseWidth=panel:getModulatorByName("modPulseWidth")
    modVcfEnvAmnt=panel:getModulatorByName("modVcfEnvAmnt")
    modLfoVcf=panel:getModulatorByName("modLfoVcf")
    modVcoEnvSust=panel:getModulatorByName("modVcoEnvSust")
    modLfoOsc=panel:getModulatorByName("modLfoOsc")
    modVcaEnvSust=panel:getModulatorByName("modVcaEnvSust")
    modVcoPls=panel:getModulatorByName("modVcoPls")
    modVcoTri=panel:getModulatorByName("modVcoTri")
    modLfoShp=panel:getModulatorByName("modLfoShp")
    modVcoCrsFreq=panel:getModulatorByName("modVcoCrsFreq")
    modVcaEnvAtck=panel:getModulatorByName("modVcaEnvAtck")
    modLfoAmount=panel:getModulatorByName("modLfoAmount")
    modVcfEnvSust=panel:getModulatorByName("modVcfEnvSust")
    modLfoFreq=panel:getModulatorByName("modLfoFreq")
    modVcoEnvDecy=panel:getModulatorByName("modVcoEnvDecy")
    

    Now in any function you can call

    modVcoEnvDecy:getModulatorValue()
    or
    modVcoEnvDecy:getComponent():setValue(x,true)

    instead of :

    panel:getModulatorByName("modVcoEnvDecy"):getModulatorValue()
    panel:getModulatorByName("modVcoEnvDecy"):getComponent():setValue(n,true)

    then when looping through a table of modulators use _G[] to access modVcoEnvDecy in the global environment if you also want to get the properties of the modulator itself:

    
    t={
    modVcfEnvSust={somevalue=4},
    modLfoFreq={somevalue=44},
    modVcoEnvDecy={somevalue=127},
    }
    
    for k in pairs (t) do
    local x = _G[k]:getModulatorValue()* t[k].somevalue
    end
    

    #117354
    goodweathergoodweather
    Participant
    • Topics: 41
    • Replies: 443
    • Total: 484
    • ★★

    Exactly!
    And to make things even nicer, I have a separate AssignModulators() method where I’m putting all those assignments and only that.
    I also separate them by group with comments like
    — OSCILLATORS
    — FILTERS
    — ENVELOPES

    Easier to debug later on if you are missing one
    (and a general coding tip is USE COMMENTS!!!)

    Then in PanelLoaded() you just need one line
    AssignModulators()

    #117355
    Tedjuh
    Participant
    • Topics: 3
    • Replies: 25
    • Total: 28

    How/ why is it faster to pre-define the modulators in a “panel finished loading” script? I read somewhere it had to do with lookup time for a certain modulator. I get that. But how much faster is it? Are we talking miliseconds? Is it more CPU friendly? What are the benefits?

    Because if that’s the case I have to go over 50 lua scripts to do that. Not that much of a problem, the panel (a librarian/ editor for the Roland SH-201) is almost done. Well, to be released as beta after 6 months in the making. Learning lua, juce and Ctrlr at the same time.

    But.. as I’m tempted to make another panel (for Roland Gaia SH-01) it gives me the chance to do it the proper way from the start.

    #117357
    goodweathergoodweather
    Participant
    • Topics: 41
    • Replies: 443
    • Total: 484
    • ★★

    Yep, this is the reason and it was explained by Atom that getModulatorByName() is doing a lookup in a table to search for the modulator. So better to do that only once.
    NOW, practically, as Lua is very fast you will not notice any difference.
    BUT as you want to learn and code properly, it is good to follow the advice of our master 😉

    Just keep your existing panel as-is.
    You made it, you are happy with it, you made mistakes, you learned…
    Same for all of us!
    Your next panel will be better and the next one even better 🙂 🙂

    #117360
    dnaldoogdnaldoog
    Participant
    • Topics: 1
    • Replies: 236
    • Total: 237
    • ★★

    Hi Tedjuh,

    Here is the original post about that:

    change midiMessageType of a modulator in LUA

    #117361
    Tedjuh
    Participant
    • Topics: 3
    • Replies: 25
    • Total: 28

    Thx. Ok, clear. More memory usage but faster lookup. I have a lot of modulators (1500+) so might be interesting to give it a go.

    #117362
    goodweathergoodweather
    Participant
    • Topics: 41
    • Replies: 443
    • Total: 484
    • ★★

    Of course, you should only declare the modulators that you are using in your code for some actions, not all of them 😉

    #117363
    Tedjuh
    Participant
    • Topics: 3
    • Replies: 25
    • Total: 28

    Unfortunately they are all being used. To be honest, I noticed a small delay (3 to 5 seconds) between the sysex and the modulators all being updated. This might explain why. I’m curious if it makes a difference. Couldn’t hurt to try it out.

    #117365
    dnaldoogdnaldoog
    Participant
    • Topics: 1
    • Replies: 236
    • Total: 237
    • ★★

    Tedjuh,

    Here’s a function that might help you do that!

    
    function cacheModNames()
      n = panel:getNumModulators()
      --Assign each modulator to a variable with same name
      --so we can just call myModulatorsName:getComponent():getValue()
      console("\n\n")
      local _t={}
      for i=0,n-1 do
        mod = panel:getModulatorByIndex(i)
        local Name= L(mod:getName())
        local subName=string.gsub(Name, "-", "_")
        table.insert(_t,subName)
      end
      table.sort(_t)
      for i,v in ipairs(_t) do
        console(String(string.format("%s=panel:getModulatorByName(\"%s\") --[%d]",v,v,i)))
      end
      console("\n\n")
    end --function
    
    #117387
    Tedjuh
    Participant
    • Topics: 3
    • Replies: 25
    • Total: 28

    Thank you DNalDoog, that code should save me a lot of time. I’ll get back on it..

    #117471
    EnzoF04
    Participant
    • Topics: 17
    • Replies: 96
    • Total: 113
    • ★★

    Here is a new BETA for the Six-trak, please be hard on me. I have to learn a lot still.

    Big shout to @Dnaldoog, he’s been helping me A LOT! Thanks! And the forum members also!

    See attached. It should be an improvement.

    Attachments:
    You must be logged in to view attached files.
Viewing 19 posts - 1 through 19 (of 19 total)
  • You must be logged in to reply to this topic.
There is currently 0 users and 34 guests online
No users are currently active
Forum Statistics
Threads: 2,308, Posts: 16,186, Members: 59,525
Most users ever online was 12 on January 22, 2019 3:47 pm
Do NOT follow this link or you will be banned from the site!