Audiobus: Use your music apps together.

What is Audiobus?Audiobus is an award-winning music app for iPhone and iPad which lets you use your other music apps together. Chain effects on your favourite synth, run the output of apps or Audio Units into an app like GarageBand or Loopy, or select a different audio interface output for each app. Route MIDI between apps — drive a synth from a MIDI sequencer, or add an arpeggiator to your MIDI keyboard — or sync with your external MIDI gear. And control your entire setup from a MIDI controller.

Download on the App Store

Audiobus is the app that makes the rest of your setup better.

MOZAIC Help Line

13468915

Comments

  • @wim said:
    Another option would be to use a multi velocity layer sampler for the drum sounds, then load slightly detuned samples at different velocity layers. Digistix 2, Drambo, and AudioLayer come to mind.

    Not a very good option though since you also want to use velocity for ... velocity variations.

    In short ... detune through midi isn't too practical, but is technically possible in a limited sense.

    okay, thanks! I was just wondering about these functions. I bought the R8M because of this feel function (but sold it later). And from the MC505 I remember the kick drum became more alive with a little bit random detuning.

    I will dive into it later, I let it sink in for a while.

  • For the random detune, a solution would be to use a drum synth with a tune knob (and other knobs like decay, drive) that can be midi mapped. For example Ruismaker.

    From Mozaic or an other midi CC generator app there is a random midi cc stream for this knob and other knobs, just a slightly different value. So this mimics a real analogue kick drum, every hit is kind of unique instead of a static waveform.

    Other method would be sending ghost notes from a sequencer (with velocity 0) into Mozaic, and Mozaic transforms this in a random value for the tune knob and other parameters.

    Could this be a solution, instead of changing the pitch of the note?

  • @espiegel123 said:
    @pejman : let's take a look at TranslateScale. It translates from one number range to another one. The first pair of numbers should be range of numbers of the input. The second pair of numbers is the range of the output.

    When translating from a color value to a knob's range, you are translating from the range 0 thru 7 to the range 0 thru 127.

    I have done translat in two different places, Which one do you mean?
    Col or colo

    @onpaddown
    col = Round TranslateScale ( GetKnobValue 1 ) , 0, 127, nc, nc

    @onknobchange
    colo = Round TranslateScale ( GetKnobValue 1 ) , 0, 127, 0, 7

    Do you mean ,that i do this ?

    col = Round TranslateScale ( GetKnobValue 1 ) , 0, 7, 0, 127
    Or
    col = Round TranslateScale ( GetKnobValue 1 ) , 0, 127, 0, 7

    And

    colo = Round TranslateScale ( GetKnobValue 1 ) , 0, 7, 0, 127

    I have done these things before but did not get the right result.

  • @raabje said:
    For the random detune, a solution would be to use a drum synth with a tune knob (and other knobs like decay, drive) that can be midi mapped. For example Ruismaker.

    From Mozaic or an other midi CC generator app there is a random midi cc stream for this knob and other knobs, just a slightly different value. So this mimics a real analogue kick drum, every hit is kind of unique instead of a static waveform.

    yes, that would work.

    Other method would be sending ghost notes from a sequencer (with velocity 0) into Mozaic, and Mozaic transforms this in a random value for the tune knob and other parameters.

    That won't work because a Note ON with velocity 0 is the same as a Note-Off. In fact Mozaic converts it to a Note-Off to help disambiguate that. But you could send with a low velocity such as 1 or something.

    Could this be a solution, instead of changing the pitch of the note?

    Those are good ideas and could work well.

  • @pejman said:

    @espiegel123 said:
    @pejman : let's take a look at TranslateScale. It translates from one number range to another one. The first pair of numbers should be range of numbers of the input. The second pair of numbers is the range of the output.

    When translating from a color value to a knob's range, you are translating from the range 0 thru 7 to the range 0 thru 127.

    I have done translat in two different places, Which one do you mean?
    Col or colo

    @onpaddown
    col = Round TranslateScale ( GetKnobValue 1 ) , 0, 127, nc, nc

    @onknobchange
    colo = Round TranslateScale ( GetKnobValue 1 ) , 0, 127, 0, 7

    Do you mean ,that i do this ?

    col = Round TranslateScale ( GetKnobValue 1 ) , 0, 7, 0, 127
    Or
    col = Round TranslateScale ( GetKnobValue 1 ) , 0, 127, 0, 7

    And

    colo = Round TranslateScale ( GetKnobValue 1 ) , 0, 7, 0, 127

    I have done these things before but did not get the right result.

    Please re-read my earlier message (quoted below). You have overlooked the last paragraph which is important. The translatescale is not the only important error.

    —— my earlier message

    @pejman : let's take a look at TranslateScale. It translates from one number range to another one. The first pair of numbers should be range of numbers of the input. The second pair of numbers is the range of the output.

    When translating from a color value to a knob's range, you are translating from the range 0 thru 7 to the range 0 thru 127.

    In onPadDown, you should be setting the knob's value based on the note color array. Please take a look onPadDown and go through carefully, line-by-line and see if you can spot the problem. Besides a translatescale problem, there is another problem.

    HINT: the value you set knob 1 to should have its origin in the note color array.

    —- added Hint: go through onPadDown one line at a time. I recommend reading out loud and explaining to yourself what each line does to contribute to the tasks you are trying to achieve.

    If you can’t find the problem, I’ll give another hint. I think it is important that you be able to find this error.

  • edited May 2023

    @wim said:

    @raabje said:
    Could this be a solution, instead of changing the pitch of the note?

    Those are good ideas and could work well.

    I did look at patch storage and there are some scripts that could be a starting point. But I took the easy way out, in LK sequencer I drew some CC value lines and send them to the kick drum in Ruismaker on channel 1 for tune, decay, personality. Now the knobs are moving between a small range when this clip plays. This is pseudo-random because off the unknown interaction between these changing values. But the next loop it is the same again.

    But from a puristic point of view a random CC generator between an small range would be better. I keep this for later to explore.

    edit: just tried out Rozetta LFO, and that is exactly what I want, sample and hold setting. Interesting, with multiple instances running I can control more drum sounds, or more parameters.

  • @espiegel123 said:

    @pejman said:

    @espiegel123 said:
    @pejman : let's take a look at TranslateScale. It translates from one number range to another one. The first pair of numbers should be range of numbers of the input. The second pair of numbers is the range of the output.

    When translating from a color value to a knob's range, you are translating from the range 0 thru 7 to the range 0 thru 127.

    I have done translat in two different places, Which one do you mean?
    Col or colo

    @onpaddown
    col = Round TranslateScale ( GetKnobValue 1 ) , 0, 127, nc, nc

    @onknobchange
    colo = Round TranslateScale ( GetKnobValue 1 ) , 0, 127, 0, 7

    Do you mean ,that i do this ?

    col = Round TranslateScale ( GetKnobValue 1 ) , 0, 7, 0, 127
    Or
    col = Round TranslateScale ( GetKnobValue 1 ) , 0, 127, 0, 7

    And

    colo = Round TranslateScale ( GetKnobValue 1 ) , 0, 7, 0, 127

    I have done these things before but did not get the right result.

    Please re-read my earlier message (quoted below). You have overlooked the last paragraph which is important. The translatescale is not the only important error.

    —— my earlier message

    @pejman : let's take a look at TranslateScale. It translates from one number range to another one. The first pair of numbers should be range of numbers of the input. The second pair of numbers is the range of the output.

    When translating from a color value to a knob's range, you are translating from the range 0 thru 7 to the range 0 thru 127.

    In onPadDown, you should be setting the knob's value based on the note color array. Please take a look onPadDown and go through carefully, line-by-line and see if you can spot the problem. Besides a translatescale problem, there is another problem.

    HINT: the value you set knob 1 to should have its origin in the note color array.

    —- added Hint: go through onPadDown one line at a time. I recommend reading out loud and explaining to yourself what each line does to contribute to the tasks you are trying to achieve.

    If you can’t find the problem, I’ll give another hint. I think it is important that you be able to find this error.

    I can’t find the problem

  • @pejman: After thinking about it some more, I'd like to try something that might be more fruitful than my hinting at the issues. You have identified a problem where tapping a pad results in the wrong value being displayed by a knob. So, the problem might be in onPadDown or related to what happens when the knobs are changed.

    Rather than my directing your attention too much, let's get started by having you refine your script a little and explaining it and identifying the parts of your script potentially related to the problem. Fwiw, this is a process I go through myself.

    Btw, when I run the version you posted, the knobs both display "error" when I turn them even when a pad has been pressed. I believe you may have fixed that. Maybe you posted an updated script, but I am not finding it.

    TO DO:

    • make sure that "error" is only displayed if a knob is turned before any pad has been pressed. if a pad has been pressed one or more times, "error" should not be displayed.
      when you fix the problem, I advise that you set up your "if-clause" so that when the error condition is triggered nothing happens in onknobchange other than setting the error labels. The way you have it now, your script processes the knob change even when it is an error condition

    • in the script, add a comment before each line of code in your onPadDown and onKnobChange handlers explaining what the line of code is supposed to be doing. There are a few places where I am particularly interested to know what is intended to happen.

    • screenshot both the onpaddown and onknobchange handlers and use the markup tools in Photos to circle or highlight all lines of code that are potentially related to the value of note color or the display of the note color.
    • post the script and marked up screenshots and include a detailed english description of what is supposed to happen in onPadDown and onKnobChange. we will use that to see if the description matches the code.

    When you are adding comments in the script, perhaps you will identify something where you aren't sure what it does or if it is the right way to do what is intended. If that happens, post a question here...or troubleshoot a little on your own to see of there is a different or better way to accomplish the intended task.

    Some things you might want to do before or while adding comments to the script:

    • look at the for loop in onKnobChange. what is its purpose?
    • look at onknobchange and refine it so that when a knob changes, you only do things relevant to the changed knob. Right now, for example, you assign both noten and colorn no matter what knob was changed.
    • look at each handler and see if there are variable assignments that you make but don't use and remove them or comment them out. For example, in onknobchange, you have nn=noteNum[lastPad] but you don't use nn there. There are others where the same is true.
  • @espiegel, make sure that "error" is only displayed if a knob is turned before any pad has been pressed. if a pad has been pressed one or more times, "error" should not be displayed.
    when you fix the problem, I advise that you set up your "if-clause" so that when the error condition is triggered nothing happens in onknobchange other than setting the error labels. The way you have it now, your script processes the knob change even when it is an error condition.

    @Pejman : This is happening right now and I don't see anything wrong with it

    @espiegel : look at the for loop in onKnobChange. what is its purpose?

    @pejman : So that notes and colors are set in all 7 pads.

    @espiegel : look at onknobchange and refine it so that when a knob changes, you only do things relevant to the changed knob. Right now, for example, you assign both noten and colorn no matter what knob was changed.

    @pejman : I don't see any problem in this part because every knob is doing its job properly. Unless you meant something else, which I didn't understand and still don't know exactly what you meant.

    @espiegel: look at each handler and see if there are variable assignments that you make but don't use and remove them or comment them out. For example, in onknobchange, you have nn=noteNum[lastPad] but you don't use nn there. There are others where the same is true.

    @pejman : If I delete this line, for the first time when I hit the pads, the setknob number 0 will not be set correctly and the label will not be executed. Please do it yourself to see what I mean.
    I just removed [LastPad] in front of them and that solved the other problem I didn't explain to you before.

    nn = notenum //[LastPad]
    nc = notecolors // [LastPad]

    The fact that you told me to explain each line is very complicated and annoying for me because in many cases I can't express my meaning as it is and I have to write you perhaps very long lines, after which the possibility that you You don't understand what I mean, it's really beyond my patience.

    You gave me an exercise that I tried my best to do correctly. The result of what I gave you is the result of my best effort. Please, if there is a problem, fix it yourself and send it to me in a script. I get exactly the same result that you want to achieve after all the questions and answers.

    Maybe when you solved the script for me, I will understand that you meant something else. And I completely misunderstood what you meant.

    Because in these questions and answers, sometimes you or I may misunderstand each other's meaning. And this issue will lead to longer posts and questions and answers, and this will take a lot of your time and mine..
    I have no problem with teaching and learning.

    My suggestion is that you give me exercises, of course, not heavy and complicated (because our goal was step by step) and in the direction that I need them in my script, and I will solve it for you and send it to you. Check it and solve it for me if there are any mistakes. After solving it by you, I will realize my mistakes and faults, and if there is any question or ambiguity about it for me, I will ask you. This method can be much more efficient for me and by saving time and writing long.

    Please let's go ahead with this method, I assure you that I will learn the material well with this method as well.

  • edited May 2023

    Maybe if you and I were together and instead of typing and writing for a long time and replying to each other at very different times, we could talk much faster and understand each other's meaning faster and reach a conclusion faster, of course with a method. which you have now undertaken, and this method was no longer troublesome.

    Because I still have many problems and questions about my script, if we want to proceed with this method, it may take months and years.

  • @pejman : maybe I am not the right person to help you. I disagree that writing the code for you would be the best method. My opinion is that your back and forth with @wim indicated that there are some fundamentals that you need to learn. I was hoping to help you with that.

    You wrote: "My suggestion is that you give me exercises, of course, not heavy and complicated " I thought this exercise would not be heavy and complicated.

    You wrote: "You gave me an exercise that I tried my best to do correctly. The result of what I gave you is the result of my best effort. Please, if there is a problem, fix it yourself and send it to me in a script. I get exactly the same result that you want to achieve after all the questions and answers."

    It isn't that simple. Sometimes the issue is not that there is some line or couple of lines that need to be changed. Sometimes, it is important to understand the thought process behind an attemtped solution. The issue might not be this line or that line of code but how to think about the problem at hand. Understanding someone's intention/thought process can be a valuable part of finding a path to help them.

    Anyway, if you find this method irritating, I am sorry. Perhaps, someone else is better suited to helping you.

  • edited May 2023

    Hi @espiegel

    Before I answer the details of the post that you sent me in private, let's clarify one thing first.

    Do you mean something like that from the script you gave me as an exercise? :

    1, When the script is first loaded , before any pads have been touched, if we turn a knob , error message should be generated under knobs.

    Of course, this happens in the script that I have sent you.

    2, If I touch a pad, for first time, the information about that pad, which includes the note number and the color of the pad, should be shown in knobs 0 and 1.

    This is also done correctly in the script

    3, After that, if I move knob number 0, the note number created by the knob should be created in the last pad I touched, but not in all 7 pads simultaneously.

    Also, knob number one, which is related to color, should do exactly the same thing,

    If you mean something like what I wrote in topic number 3, then I must say that I had misunderstood your meaning before،

    This is not happening in my script now because of my misunderstanding of your request.

    My impression was that by turning the knob number 0 or 1 note is created and the color created through them should be created simultaneously in all 7 pads. That's why I had used copyArray and you asked me what you used it for.

    4, And again about step number 3 : After touching a pad, if I turn the knob number 0 or 1, the error message should not be created under them again , And this time, the information related to note number or color number should be created under knob 0 and 1. Along with the knobs being set ( setknob ) in the right note number and the right color number.

    This is not happening in my script now because of my misunderstanding of your request.

    And in addition to the problem that existed before, which was related to the color number of each pad, which is not displayed well in knob number one.

    Do you mean something like that from the script you gave me as an exercise?

  • edited May 2023

    @pejman : can you post your script? My comments were based on the script you posted. It sounds like you made changes and addressed some issues we talked about.

  • @espiegel123 said:
    @pejman : can you post your script? My comments were based on the script you posted. It sounds like you made changes and addressed some issues we talked about.

    ```

    @Description

    Now, let's get into some changes where you'll be using knobs to change those arrays.

    Here is the next stage. Add this functionality to your script.

    in the loading section, put the array setups inside an if-block so that they only get initialized the first time the script loads
    in the load section assign 0 to a variable called padUsedFlag.
    label knob 0 "note #"
    label knob 1 "color"
    setup the note knob so that
    What I'd like you to do is add this functionality:

    when a pad is touched, set padUsedFlag to 1.
    if knob 0 or 1 is turned and padUsedFlag is 0, change the knobs area label to "Error"
    when a pad is touched change the knobs area label to "Pad n" where n is the pad number
    when a pad is touched, set knob 0's value to the note number associated with the pad and set the knob's label to that number
    when a pad is touched, set knob 1's value to the color associated with the pad. HINT: you should use TranslateScale to map from the color number range to the knob's range (0 to 127)
    when knob 0 is changed, round the value, check to see if it is different from the previous value. if it is different, play the midi note AND store the knob's value back into the noteNum array
    when knob 1 is changed, translate the value back to the color range, if the value is different from the old value, color the pad with the new value and store the new value back into the array

    @End

    @OnLoad

    ShowLayout 2 // these are the 8 notenumbers for Ruismaker drums

    if Unassigned init
    init = 1
    notenum = [49, 51, 54, 56, 58, 61, 63, 66]
    notecolors = [2,1,6,0,5,7,4,3]

    endif

    padUsedFlag = 0

    LabelKnob 0, {note #}
    LabelKnob 1, {color}

    p = LastPad
    for p = 0 to 7

    ColorPad p, notecolors[p]
    LabelPad p, notenum[p]

    endfor
    @End

    @OnPadDown

    nn = notenum[LastPad]
    nc = notecolors[LastPad]
    vel = LastPadVelocity

    if LastPad < 8
    //padUsedFlag = 1

    SendMIDINoteOn 0, nn, vel
    SendMIDINoteOff 0, nn, 0, 100

    SetKnobValue 0, nn
    LabelKnob 0, {note #} , nn

    col = Round TranslateScale ( GetKnobValue 1 ) , 0, 127, nc, nc

    SetKnobValue 1,col //*18.28
    LabelKnob 1, {color } ,col

    endif

    @End



    @OnKnobChange

    noten = Round GetKnobValue 0
    colorn = Round GetKnobValue 1

    nn = notenum //[LastPad]
    nc = notecolors // [LastPad]

    colo = Round TranslateScale colorn , 0, 127, 0, 7

    for p = 0 to 7

    if LastKnob = 0
    CopyArray noten, notenum,8
    SendMIDINoteOn 0, noten, 5
    SendMIDINoteOff 0, noten, 0, 100
    LabelPad p, noten

    elseif LastKnob = 1
    CopyArray colorn, notecolors,8
    ColorPad p, colo

    endif
    endfor


    if padUsedFlag = 0
    LabelKnob 0, {error}
    LabelKnob 1, {error}
    endif

    @End


    ```



  • edited June 2023

    ```

    @espiegel123 said:
    @pejman: Nice work!

    Now, let's get into some changes where you'll be using knobs to change those arrays.

    Here is the next stage. Add this functionality to your script.

    • in the loading section, put the array setups inside an if-block so that they only get initialized the first time the script loads
    • in the load section assign 0 to a variable called padUsedFlag.
    • label knob 0 "note #"
    • label knob 1 "color"
    • setup the note knob so that

    What I'd like you to do is add this functionality:

    • when a pad is touched, set padUsedFlag to 1.
    • if knob 0 or 1 is turned and padUsedFlag is 0, change the knobs area label to "Error"
    • when a pad is touched change the knobs area label to "Pad n" where n is the pad number
    • when a pad is touched, set knob 0's value to the note number associated with the pad and set the knob's label to that number
    • when a pad is touched, set knob 1's value to the color associated with the pad. HINT: you should use TranslateScale to map from the color number range to the knob's range (0 to 127)
    • when knob 0 is changed, round the value, check to see if it is different from the previous value. if it is different, play the midi note AND store the knob's value back into the noteNum array
    • when knob 1 is changed, translate the value back to the color range, if the value is different from the old value, color the pad with the new value and store the new value back into the array

    @pejman said:
    Hi @espiegel

    Before I answer the details of the post that you sent me in private, let's clarify one thing first.

    Do you mean something like that from the script you gave me as an exercise? :

    1, When the script is first loaded , before any pads have been touched, if we turn a knob , error message should be generated under knobs.

    Of course, this happens in the script that I have sent you.

    2, If I touch a pad, for first time, the information about that pad, which includes the note number and the color of the pad, should be shown in knobs 0 and 1.

    This is also done correctly in the script

    3, After that, if I move knob number 0, the note number created by the knob should be created in the last pad I touched, but not in all 7 pads simultaneously.

    Also, knob number one, which is related to color, should do exactly the same thing,

    If you mean something like what I wrote in topic number 3, then I must say that I had misunderstood your meaning before،

    This is not happening in my script now because of my misunderstanding of your request.

    My impression was that by turning the knob number 0 or 1 note is created and the color created through them should be created simultaneously in all 7 pads. That's why I had used copyArray and you asked me what you used it for.

    4, And again about step number 3 : After touching a pad, if I turn the knob number 0 or 1, the error message should not be created under them again , And this time, the information related to note number or color number should be created under knob 0 and 1. Along with the knobs being set ( setknob ) in the right note number and the right color number.

    This is not happening in my script now because of my misunderstanding of your request.

    And in addition to the problem that existed before, which was related to the color number of each pad, which is not displayed well in knob number one.

    Do you mean something like that from the script you gave me as an exercise?

  • @espiegel , Modified script

    ```

    @Description

    Now, let's get into some changes where you'll be using knobs to change those arrays.

    Here is the next stage. Add this functionality to your script.

    in the loading section, put the array setups inside an if-block so that they only get initialized the first time the script loads
    in the load section assign 0 to a variable called padUsedFlag.
    label knob 0 "note #"
    label knob 1 "color"
    setup the note knob so that
    What I'd like you to do is add this functionality:

    when a pad is touched, set padUsedFlag to 1.
    if knob 0 or 1 is turned and padUsedFlag is 0, change the knobs area label to "Error"
    when a pad is touched change the knobs area label to "Pad n" where n is the pad number
    when a pad is touched, set knob 0's value to the note number associated with the pad and set the knob's label to that number
    when a pad is touched, set knob 1's value to the color associated with the pad. HINT: you should use TranslateScale to map from the color number range to the knob's range (0 to 127)
    when knob 0 is changed, round the value, check to see if it is different from the previous value. if it is different, play the midi note AND store the knob's value back into the noteNum array
    when knob 1 is changed, translate the value back to the color range, if the value is different from the old value, color the pad with the new value and store the new value back into the array

    @End

    @OnLoad

    ShowLayout 2 // these are the 8 notenumbers for Ruismaker drums

    if Unassigned init
    init = 1
    notenum = [49, 51, 54, 56, 58, 61, 63, 66]
    notecolors = [2,1,6,0,5,7,4,3]

    endif

    padUsedFlag = 0

    LabelKnob 0, {note #}
    LabelKnob 1, {color}

    p = LastPad
    for p = 0 to 7

    ColorPad p, notecolors[p]
    LabelPad p, notenum[p]

    endfor
    @End

    @OnPadDown

    nn = notenum[LastPad]
    nc = notecolors[LastPad]
    vel = LastPadVelocity

    if LastPad < 8
    padUsedFlag = 1

    SendMIDINoteOn 0, nn, vel
    SendMIDINoteOff 0, nn, 0, 100

    SetKnobValue 0, nn
    LabelKnob 0, {note #} , nn

    col = Round TranslateScale nc, 0, 7, 0, 127

    SetKnobValue 1,col
    LabelKnob 1, {color } ,nc

    endif

    @End


    @OnKnobChange

    noten = Round GetKnobValue 0
    colorn = Round GetKnobValue 1

    colo = Round TranslateScale colorn , 0, 127, 0, 7


    if LastKnob = 0 and padUsedFlag = 0
    LabelKnob 0, {error}

    elseif LastKnob = 0
    CopyArray noten,notenum[LastPad],1
    SendMIDINoteOn 0, noten, 50
    SendMIDINoteOff 0, noten, 0, 100
    LabelKnob 0, {note #}, noten
    LabelPad LastPad, noten

    endif

    if LastKnob = 1 and padUsedFlag = 0
    LabelKnob 1, {error}

    elseif LastKnob = 1
    CopyArray colo, notecolors[LastPad],1
    ColorPad LastPad, colo
    LabelKnob 1, {color} , colo

    endif

    @End

    ```




  • @pejman : good job. Before moving on to the next set of features to add (if you are interested in continuing), I think it is worth taking a look at a few things. The script works, but there are some things that I think are worth taking a look at in order to refine your thinking/scripting.

    When programming, sometimes we end up with things that are in our scripts that don't do anything. It is generally a good idea to identify them and remove them (or better comment them out so that if it turns out you really do need them, you can comment them back in. The other thing that it is worth doing is structuring your script so that instructions aren't performed unnecessarily. This is often a case of moving things into an if-block.

    Please take a look at each of these.

    • in OnLoad, you have a line p = LastPad. What does this contribute? Note that when your program loads LastPad is meaningless. It only means something after a pad has been tapped.
    • in onPadDown, the first three lines are executed every time a pad is tapped. Since we only handle pads 0 thru 7 and only set up the arrays with slots 0 thru 7, you might want to put them inside the if-clause. Otherwise, when pad 8 is tapped, you are going to be reading from an array slot that was never defined. Mozaic is forgiving and won't give an error. But it is generally a good idea to not read from an array slot that you haven't initialized.
    • in onKnobChange. I'd recommend taking a look at a few things. Everything works here, but I think it would be useful to make a few changes.

    ONKNOBCHANGE notes:
    ITEM 1
    For this exercise, we are considering handling knobs before a pad has been touched an error. your program does that, but you can structure it so that the only thing that happens when you turn a knob is to display an error message.

    I'd recommend structuring this part of the script something like this:

    @onKnobChange
    
    if thereIsAnError
       displayErrorMessageInKnobLabels
    else //handleTheKnobs
       if lastKnob = 0
          handleKnob0 stuff
       elseif lastKnob = 1
          handleKnob1 stuff
       endif // lastKnob =
    endif //there is an error
    
    @End
    
    

    ITEM 2
    CopyArray works, but I'd recommend that since you are just assiging one value that you do a standard assignment to the array slot in question. For example, noteColors[LastPad] = colo

    ITEM 3
    The first three lines of code are processed any time any knob is turned. I'd recommend that you put them where the knob in question is handled. For example, "noten = Round GetKnobValue 0 " belongs in the block where LastKnob = 0

    ITEM 4
    There is one part of the assignment that wasn't done -- and that's ok and worth coming back to after you have made the changes that I mentioned. "when knob 0 is changed, round the value, check to see if it is different from the previous value. if it is different, play the midi note AND store the knob's value back into the noteNum array." While this doesn't make a big deal in this particular script -- it is an important thing to know how to implement as sometimes sending out a stream of unnececessary MIDI messages can overwhelm the receiving hardware or software.

  • @espiegel123 said:
    @pejman : good job. Before moving on to the next set of features to add (if you are interested in continuing), I think it is worth taking a look at a few things. The script works, but there are some things that I think are worth taking a look at in order to refine your thinking/scripting.

    Yes, I am willing to continue on the path, of course, if you please and add more exercises, After I realized what exactly you want from me, the topic became interesting and exciting for me. This script was very interesting to me

    The things you mentioned below were very interesting to me and very informative. Thank you for explaining them to me in a simple way and terms.

    When programming, sometimes we end up with things that are in our scripts that don't do anything. It is generally a good idea to identify them and remove them (or better comment them out so that if it turns out you really do need them, you can comment them back in. The other thing that it is worth doing is structuring your script so that instructions aren't performed unnecessarily. This is often a case of moving things into an if-block.

    , ok , I try to behave like this

    Please take a look at each of these.

    • in OnLoad, you have a line p = LastPad. What does this contribute? Note that when your program loads LastPad is meaningless. It only means something after a pad has been tapped.

    Yes, unfortunately, I thought I should specify what p is, when there was no need to do so here at all.

    • in onPadDown, the first three lines are executed every time a pad is tapped. Since we only handle pads 0 thru 7 and only set up the arrays with slots 0 thru 7, you might want to put them inside the if-clause. Otherwise, when pad 8 is tapped, you are going to be reading from an array slot that was never defined. Mozaic is forgiving and won't give an error. But it is generally a good idea to not read from an array slot that you haven't initialized.

    I edited this thread like this, is that correct? :

    if LastPad < 8

    nn = notenum[LastPad]
    nc = notecolors[LastPad]
    vel = LastPadVelocity

    • in onKnobChange. I'd recommend taking a look at a few things. Everything works here, but I think it would be useful to make a few changes.

    ONKNOBCHANGE notes:
    ITEM 1
    For this exercise, we are considering handling knobs before a pad has been touched an error. your program does that, but you can structure it so that the only thing that happens when you turn a knob is to display an error message.

    I'd recommend structuring this part of the script something like this:

    @onKnobChange
    
    if thereIsAnError
       displayErrorMessageInKnobLabels
    else //handleTheKnobs
       if lastKnob = 0
          handleKnob0 stuff
       elseif lastKnob = 1
          handleKnob1 stuff
       endif // lastKnob =
    endif //there is an error
    
    @End
    
    

    I modified it like this in @OnPadDown, is it correct ? :

    @OnPadDown

    if LastPad > 7
    padUsedFlag = 0
    LabelKnob 0, {error}
    LabelKnob 1, {error}
    endif

    ITEM 2
    CopyArray works, but I'd recommend that since you are just assiging one value that you do a standard assignment to the array slot in question. For example, noteColors[LastPad] = colo

    I thought you wanted to teach me different ways to use CopyArray, because we used it before in our previous exercises ( brambos example )

    ITEM 3
    The first three lines of code are processed any time any knob is turned. I'd recommend that you put them where the knob in question is handled. For example, "noten = Round GetKnobValue 0 " belongs in the block where LastKnob = 0

    I corrected it

    ITEM 4
    There is one part of the assignment that wasn't done -- and that's ok and worth coming back to after you have made the changes that I mentioned. "when knob 0 is changed, round the value, check to see if it is different from the previous value. if it is different, play the midi note AND store the knob's value back into the noteNum array." While this doesn't make a big deal in this particular script -- it is an important thing to know how to implement as sometimes sending out a stream of unnececessary MIDI messages can overwhelm the receiving hardware or software.

    Is that what you mean?

    x = Round GetKnobValue 0

    if LastKnob = 0 and padUsedFlag = 0
    LabelKnob 0, {error}

    elseif LastKnob = 0 and x <> nn
    //CopyArray noten,notenum[LastPad],1
    noten = Round GetKnobValue 0
    notenum[LastPad] = noten
    SendMIDINoteOn 0, noten, 50
    SendMIDINoteOff 0, noten, 0, 100
    LabelKnob 0, {note #}, noten
    LabelPad LastPad, noten

    In this script ( // = modifiers )


    @OnLoad ShowLayout 2 // these are the 8 notenumbers for Ruismaker drums if Unassigned init init = 1 notenum = [49, 51, 54, 56, 58, 61, 63, 66] notecolors = [2,1,6,0,5,7,4,3] endif padUsedFlag = 0 LabelKnob 0, {note #} LabelKnob 1, {color} //p = LastPad for p = 0 to 7 ColorPad p, notecolors[p] LabelPad p, notenum[p] endfor @End @OnPadDown if LastPad > 7 padUsedFlag = 0 LabelKnob 0, {error} LabelKnob 1, {error} endif if LastPad < 8 nn = notenum[LastPad] nc = notecolors[LastPad] vel = LastPadVelocity padUsedFlag = 1 SendMIDINoteOn 0, nn, vel SendMIDINoteOff 0, nn, 0, 100 SetKnobValue 0, nn LabelKnob 0, {note #} , nn col = Round TranslateScale nc, 0, 7, 0, 127 SetKnobValue 1,col LabelKnob 1, {color } ,nc endif @End @OnKnobChange //noten = Round GetKnobValue 0 //colorn = Round GetKnobValue 1 x = Round GetKnobValue 0 //colo = Round TranslateScale colorn , 0, 127, 0, 7 if LastKnob = 0 and padUsedFlag = 0 LabelKnob 0, {error} elseif LastKnob = 0 and x <> nn //CopyArray noten,notenum[LastPad],1 noten = Round GetKnobValue 0 notenum[LastPad] = noten SendMIDINoteOn 0, noten, 50 SendMIDINoteOff 0, noten, 0, 100 LabelKnob 0, {note #}, noten LabelPad LastPad, noten endif if LastKnob = 1 and padUsedFlag = 0 LabelKnob 1, {error} elseif LastKnob = 1 //CopyArray colo, notecolors[LastPad],1 colorn = Round GetKnobValue 1 colo = Round TranslateScale colorn , 0, 127, 0, 7 notecolors[LastPad] = colo ColorPad LastPad, colo LabelKnob 1, {color} , colo endif @End
  • @pejman :smile:
    Looks good. Let's refine some of your IF blocks. The code you have works and can be improved here by using some 'else' statements.

    ITEM 1 - onPadDown IF CLAUSE refinements

    In onPadDown, it is currently structured like this:

    if lastPad > 7
         do some stuff
    endif
    
    if lastPad < 8
        do different stuff
    endif
    

    Since we know that lastPad is going to be in one group or the other, we don't have to test twice. It doesn't really matter here BUT ELSE clauses are often very valuable.

    Since we know that a pad will be in one group but not both, use an ELSE so that we only test once. So, try something like

    if lastPad < 8
    handle the top row of pads
    else
    handle the bottom row of pads
    endif

    You could apply this thinking to the knobChange handler but maybe let's just catch that later. But you can try it out if you are up for the practice.

    FEATURE TO ADD:
    Before we add a new layer of functionality/complexity, add the following feature that we talked about before:

    when the note number knob is turned, check to see if the new (rounded) knob value is different from the previous knob value and do something only if the rounded knob value (the note number) is different from the previous note sent.

    To see why this is hand AND to confirm that your code is working, add this line to your knobchange handler. add it after noten = Round

    log {Note Sent: }, noten

    Tap a pad and turn the knob fast. You will see a lot of duplicate notes. Your job is to add the code necessary so that you don't send consecutive duplicates. This should be handled in the part of the IF statement that handles knob 0. Eventually, we will add a handler for the duplicate detection, but for now, focus on figuring out how to do it.

  • edited June 2023

    @espiegel123 said:
    @pejman :smile:
    Looks good. Let's refine some of your IF blocks. The code you have works and can be improved here by using some 'else' statements.

    ITEM 1 - onPadDown IF CLAUSE refinements

    Since we know that lastPad is going to be in one group or the other, we don't have to test twice. It doesn't really matter here BUT ELSE clauses are often very valuable.

    Since we know that a pad will be in one group but not both, use an ELSE so that we only test once. So, try something like

    if lastPad < 8
    handle the top row of pads
    else
    handle the bottom row of pads
    endif

    @pejman , The topic was very informative, I corrected it

    You could apply this thinking to the knobChange handler but maybe let's just catch that later. But you can try it out if you are up for the practice.

    @pejman , I tried but failed to use ( elseif ) instead of ( if ) in onknobchange.

    FEATURE TO ADD:
    Tap a pad and turn the knob fast. You will see a lot of duplicate notes. Your job is to add the code necessary so that you don't send consecutive duplicates. This should be handled in the part of the IF statement that handles knob 0. Eventually, we will add a handler for the duplicate detection, but for now, focus on figuring out how to do it.

    @pejman , It was a very interesting topic, even for me there was a question why the notes are repeated, but I thought this was a normal topic for this script. And I know that this problem is through the decimal numbers obtained from the output values of KNOB.
    Anyway, I solved the issue like this.( X <> noten )

    elseif LastKnob = 0 and x <> nn and x <> noten

    BUT ,

    Problem 1: when I added this option, ( x <> nn ) , a new problem arose to fix the previous problem ITEM 4 : (not executing the note in the pad by turning the KNOB) that you probably did not notice either.

    1, upload script
    2, turns knob color
    Result: Running note number 64 in a row when we are turning Knob color
    For solving, i put ( nn = notenum[LastPad] ) In @onload

    Problem 2 : when I added this option, ( x <> noten ) , A new problem arose as before.

    1, upload script
    2, turns knob color
    Result: Running note number 64 but this time, Once , when we are turning Knob color
    For solving, i put ( noten = Round GetKnobValue 0 ) In @onload

    ```

    @OnLoad

    ShowLayout 2 // these are the 8 notenumbers for Ruismaker drums

    if Unassigned init
    init = 1
    notenum = [49, 51, 54, 56, 58, 61, 63, 66]
    notecolors = [2,1,6,0,5,7,4,3]

    endif

    nn = notenum[LastPad]
    noten = Round GetKnobValue 0
    padUsedFlag = 0

    LabelKnob 0, {note #}
    LabelKnob 1, {color}

    //p = LastPad
    for p = 0 to 7

    ColorPad p, notecolors[p]
    LabelPad p, notenum[p]

    endfor
    @End

    @OnPadDown

    if LastPad > 7
    padUsedFlag = 0
    LabelKnob 0, {error}
    LabelKnob 1, {error}

    elseif LastPad < 8

    nn = notenum[LastPad]
    nc = notecolors[LastPad]
    vel = LastPadVelocity

    padUsedFlag = 1

    SendMIDINoteOn 0, nn, vel
    SendMIDINoteOff 0, nn, 0, 100

    SetKnobValue 0, nn
    LabelKnob 0, {note #} , nn

    col = Round TranslateScale nc, 0, 7, 0, 127

    SetKnobValue 1,col
    LabelKnob 1, {color } ,nc

    endif

    @End


    @OnKnobChange

    //noten = Round GetKnobValue 0
    //colorn = Round GetKnobValue 1
    x = Round GetKnobValue 0

    //colo = Round TranslateScale colorn , 0, 127, 0, 7


    if LastKnob = 0 and padUsedFlag = 0
    LabelKnob 0, {error}

    elseif LastKnob = 0 and x <> nn and x <> noten
    //CopyArray noten,notenum[LastPad],1
    noten = Round GetKnobValue 0
    log {Note Sent: }, noten
    notenum[LastPad] = noten
    SendMIDINoteOn 0, noten, 127
    SendMIDINoteOff 0, noten, 0, 100
    LabelKnob 0, {note #}, noten
    LabelPad LastPad, noten
    endif


    if LastKnob = 1 and padUsedFlag = 0
    LabelKnob 1, {error}

    elseif LastKnob = 1
    //CopyArray colo, notecolors[LastPad],1
    colorn = Round GetKnobValue 1
    colo = Round TranslateScale colorn , 0, 127, 0, 7
    notecolors[LastPad] = colo
    ColorPad LastPad, colo
    LabelKnob 1, {color} , colo

    endif

    @End

    ```

  • @pejman : I think before we proceed, we should spend a little time working on the issues you mentioned. We want to make sure before proceeding that each concept/technique is well understood. So, I think you should rollback the changes you made for duplicate note elimination and let's master your understanding of the IF-clause in onKnobChange first.

    What you had works, but I'd like you to have the master of if/elseif/endif before proceeding since it is such an essential part of programming.

    For the edits, I am suggesting, please go back to the the version of the script from yesterday. (https://forum.audiob.us/discussion/comment/1214581/#Comment_1214581)

    The OnPadDown change you made for IF/ELSE works. So make that change.

    For the onknobchange use yesterday's version as the basis for change and not the newest version.

    What I'd like you to do is make the structure look like this:

    @onKnobChange
    
    if thereIsAnError
       displayErrorMessageInKnobLabels
    else //handleTheKnobs
       if lastKnob = 0
          handleKnob0 stuff
       elseif lastKnob = 1
          handleKnob1 stuff
       endif // lastKnob =
    endif //there is an error
    
    @End
    

    "there is an error" in this case means padUsedFlag = 0

    If you have trouble, post your best attempt and let's discuss. I think it is best for you to figure it out and discuss the problems rather than have me just post a solution.

    I strongly recommend that right out a summary in "pseudo-code" so that you have a strong idea of what you are trying to implement before you trying to implement it. I can't emphasize enough how valuable this technique is before you have command of programming.

    My version would be:

    When a knob changes:

    • check that a pad has ever been tapped (check padUsedFlag)
    • if no pad has ever been tapped, set the knob labels to "error" and do nothing else
    • otherwise, if knob 0 was changed, handle it
    • othersise, if knob 1 was changed handle it

    The result will be something like I posted a few lines up. There won't be any lines of script in the onKnobChange not in one of these IF clauses.

    Once this is nailed down, we will look at the duplication elimination.

    One important note: one of the changes you proposed was to add a getKnobValue to onLoad and add a reference to LastPad.

    I want to mention again that LastPad is not meaningful when you load your script. There is no need to use getKnobValue (which generally isn't something you will use until after a knob has been turned) in onLoad. It is something for you to keep in mind generally -- that you generally want to avoid referring to user interaction variables until there has been a meaningful user interaction. So, LastPad shouldn't be referenced until a pad has been pressed. You shouldn't generally need to get a knob's value, unless it has been turned.

  • edited June 2023

    @espiegel, I thought the labelknobs should show the error individually if we turn each knob separately.

    Therefore, I had put each of the knobs in separate ( ifs ) related to the error, And this seemed logical.

    But it seems that you want that if I move a knob, the label of both knobs will show an error simultaneously in state ( if paduseflage = 0 ).

    Anyway,

    Do you mean one of the two examples below? Both work without problems.

    With 2 if


    @OnKnobChange //noten = Round GetKnobValue 0 //colorn = Round GetKnobValue 1 x = Round GetKnobValue 0 if padUsedFlag = 0 LabelKnob 0, {error} LabelKnob 1, {error} else padUsedFlag = 1 if LastKnob = 0 and x <> nn noten = Round GetKnobValue 0 notenum[LastPad] = noten SendMIDINoteOn 0, noten, 127 SendMIDINoteOff 0, noten, 0, 100 LabelKnob 0, {note #}, noten LabelPad LastPad, noten elseif LastKnob = 1 colorn = Round GetKnobValue 1 colo = Round TranslateScale colorn , 0, 127, 0, 7 notecolors[LastPad] = colo ColorPad LastPad, colo LabelKnob 1, {color} , colo endif endif @End

    With 1 if


    @OnKnobChange x = Round GetKnobValue 0 //noten = Round GetKnobValue 0 //colorn = Round GetKnobValue 1 if padUsedFlag = 0 LabelKnob 0, {error} LabelKnob 1, {error} elseif LastKnob = 0 and x <> nn noten = Round GetKnobValue 0 notenum[LastPad] = noten SendMIDINoteOn 0, noten, 127 SendMIDINoteOff 0, noten, 0, 100 LabelKnob 0, {note #}, noten LabelPad LastPad, noten elseif LastKnob = 1 colorn = Round GetKnobValue 1 colo = Round TranslateScale colorn , 0, 127, 0, 7 notecolors[LastPad] = colo ColorPad LastPad, colo LabelKnob 1, {color} , colo endif @End

    Full patch

    ```

    @OnLoad

    ShowLayout 2 // these are the 8 notenumbers for Ruismaker drums

    if Unassigned init
    init = 1
    notenum = [49, 51, 54, 56, 58, 61, 63, 66]
    notecolors = [2,1,6,0,5,7,4,3]

    endif

    padUsedFlag = 0

    LabelKnob 0, {note #}
    LabelKnob 1, {color}

    //p = LastPad
    for p = 0 to 7

    ColorPad p, notecolors[p]
    LabelPad p, notenum[p]

    endfor
    @End

    @OnPadDown

    if LastPad > 7
    padUsedFlag = 0
    LabelKnob 0, {error}
    LabelKnob 1, {error}
    endif

    if LastPad < 8

    nn = notenum[LastPad]
    nc = notecolors[LastPad]
    vel = LastPadVelocity

    padUsedFlag = 1

    SendMIDINoteOn 0, nn, vel
    SendMIDINoteOff 0, nn, 0, 100

    SetKnobValue 0, nn
    LabelKnob 0, {note #} , nn

    col = Round TranslateScale nc, 0, 7, 0, 127

    SetKnobValue 1,col
    LabelKnob 1, {color } ,nc

    endif

    @End


    @OnKnobChange

    //noten = Round GetKnobValue 0
    //colorn = Round GetKnobValue 1
    x = Round GetKnobValue 0

    //colo = Round TranslateScale colorn , 0, 127, 0, 7


    if padUsedFlag = 0
    LabelKnob 0, {error}
    LabelKnob 1, {error}

         else
    
          padUsedFlag = 1
    
     If LastKnob = 0 and x <> nn
        //CopyArray noten,notenum[LastPad],1
         noten = Round GetKnobValue 0 
         notenum[LastPad] = noten
         SendMIDINoteOn 0, noten, 50 
         SendMIDINoteOff 0, noten, 0, 100
         LabelKnob 0, {note #}, noten
         LabelPad LastPad, noten
    
    
    elseif LastKnob = 1
     //CopyArray colo, notecolors[LastPad],1
     colorn = Round GetKnobValue 1
     colo = Round TranslateScale colorn , 0, 127, 0, 7
     notecolors[LastPad] = colo
     ColorPad LastPad, colo
     LabelKnob 1, {color} , colo
    
    endif
    

    endif

    @End

  • @pejman: the onknobchange version that was one if statement with two elseifs is what I had in mind.

    • It looks like you changed onPadDown again and removed the if/else structure. I suggest using the else structure from the previous version.
    • For the duplicate detection, you do not need to read the knob value outside of the if clause. So, remove the x =.... and the reference to it in the if clause. Let's talk through the duplicate detection before implementing a solution.
    • All the knobvalue "getting" should happen within the part of the if clause that handles the knob in question. It is a good habit to get into. While it doesn't make a big difference here, when you are working with many knobs, the code will often be more efficient and easier to follow if you stick to this principle.

    You have a good start on the duplicate detection. I am going to suggest that since tapping a pad sends a note, the solution take that note into consideration. Anytime the note knob is turned, there has already been a note sent. There are a few ways to tackle this. One solution involves using the same variable for the not to send in both padDown and knobChange.

  • @espiegel123 said:

    • It looks like you changed onPadDown again and removed the if/else structure. I suggest using the else structure from the previous version.

    I worked the version you referred me to, probably you posted the wrong link

    espiegel wrote: For the edits, I am suggesting, please go back to the the version of the script from yesterday. (https://forum.audiob.us/discussion/comment/1214581/#Comment_1214581)

  • @pejman said:

    @espiegel123 said:

    • It looks like you changed onPadDown again and removed the if/else structure. I suggest using the else structure from the previous version.

    I worked the version you referred me to, probably you posted the wrong link

    espiegel wrote: For the edits, I am suggesting, please go back to the the version of the script from yesterday. (https://forum.audiob.us/discussion/comment/1214581/#Comment_1214581)

    I don’t understand. The full script you just posted has two independent IF clauses in the padDown handler. In the previous edit , on padDown had an if/else structure

  • Ok , So you are talking about this link, not the one you sent by mistake.

    https://forum.audiob.us/discussion/comment/1214771/#Comment_1214771

    Ok , I will make the corrections and send.

  • @pejman, Can you please explain more about this paragraph you wrote

    espiegel wrote: You have a good start on the duplicate detection. I am going to suggest that since tapping a pad sends a note, the solution take that note into consideration. Anytime the note knob is turned, there has already been a note sent. There are a few ways to tackle this. One solution involves using the same variable for the not to send in both padDown and knobChange.


    @OnLoad ShowLayout 2 // these are the 8 notenumbers for Ruismaker drums if Unassigned init init = 1 notenum = [49, 51, 54, 56, 58, 61, 63, 66] notecolors = [2,1,6,0,5,7,4,3] endif nn = notenum[LastPad] noten = Round GetKnobValue 0 padUsedFlag = 0 LabelKnob 0, {note #} LabelKnob 1, {color} for p = 0 to 7 ColorPad p, notecolors[p] LabelPad p, notenum[p] endfor @End @OnPadDown if LastPad > 7 padUsedFlag = 0 LabelKnob 0, {error} LabelKnob 1, {error} elseif LastPad < 8 nn = notenum[LastPad] nc = notecolors[LastPad] vel = LastPadVelocity padUsedFlag = 1 SendMIDINoteOn 0, nn, vel SendMIDINoteOff 0, nn, 0, 100 SetKnobValue 0, nn LabelKnob 0, {note #} , nn col = Round TranslateScale nc, 0, 7, 0, 127 SetKnobValue 1,col LabelKnob 1, {color } ,nc endif @End @OnKnobChange //nn = notenum[LastPad] //noten = Round GetKnobValue 0 if padUsedFlag = 0 LabelKnob 0, {error} LabelKnob 1, {error} elseif padUsedFlag = 1 x = Round GetKnobValue 0 if LastKnob = 0 and x <> nn and x <> noten noten = Round GetKnobValue 0 notenum[LastPad] = noten SendMIDINoteOn 0, noten, 127 SendMIDINoteOff 0, noten, 0, 100 LabelKnob 0, {note #}, noten LabelPad LastPad, noten elseif LastKnob = 1 colorn = Round GetKnobValue 1 colo = Round TranslateScale colorn , 0, 127, 0, 7 notecolors[LastPad] = colo ColorPad LastPad, colo LabelKnob 1, {color} , colo endif endif @End


  • @pejman : go ahead and remove “ and x <> nn and x <> noten”

    And let’s talk through the situation before adding code to handle the duplicates.

    Also, remove the “ elseif padUsedFlag = 1” clause that you added. Perhaps, I wasn’t clear what you called the 1-if version of knobchange was the version I suggested you used.

    Since padUsedFlag can only be 0 or 1, there is no need to test it. We already know that it is not 0.

    Let’s get your base version with no duplicate detection squared away before tackling that little change.

  • edited June 2023

    @espiegel wrote: Also, remove the “ elseif padUsedFlag = 1” clause that you added. Perhaps, I wasn’t clear what you called the 1-if version of knobchange was the version I suggested you used.

    Since padUsedFlag can only be 0 or 1, there is no need to test it. We already know that it is not 0.

    @pejman , I know there was no need for this, but I had to create else padusesflag = 1 as you requested to put x = Round GetKnobValue 0 inside if Lastknob = …

    @espiegel:


    @OnLoad ShowLayout 2 // these are the 8 notenumbers for Ruismaker drums if Unassigned init init = 1 notenum = [49, 51, 54, 56, 58, 61, 63, 66] notecolors = [2,1,6,0,5,7,4,3] endif nn = notenum[LastPad] noten = Round GetKnobValue 0 padUsedFlag = 0 LabelKnob 0, {note #} LabelKnob 1, {color} for p = 0 to 7 ColorPad p, notecolors[p] LabelPad p, notenum[p] endfor @End @OnPadDown if LastPad > 7 padUsedFlag = 0 LabelKnob 0, {error} LabelKnob 1, {error} elseif LastPad < 8 nn = notenum[LastPad] nc = notecolors[LastPad] vel = LastPadVelocity padUsedFlag = 1 SendMIDINoteOn 0, nn, vel SendMIDINoteOff 0, nn, 0, 100 SetKnobValue 0, nn LabelKnob 0, {note #} , nn col = Round TranslateScale nc, 0, 7, 0, 127 SetKnobValue 1,col LabelKnob 1, {color } ,nc endif @End @OnKnobChange //nn = notenum[LastPad] //noten = Round GetKnobValue 0 if padUsedFlag = 0 LabelKnob 0, {error} LabelKnob 1, {error} if LastKnob = 0 noten = Round GetKnobValue 0 notenum[LastPad] = noten SendMIDINoteOn 0, noten, 127 SendMIDINoteOff 0, noten, 0, 100 LabelKnob 0, {note #}, noten LabelPad LastPad, noten elseif LastKnob = 1 colorn = Round GetKnobValue 1 colo = Round TranslateScale colorn , 0, 127, 0, 7 notecolors[LastPad] = colo ColorPad LastPad, colo LabelKnob 1, {color} , colo endif endif @End
  • @pejman : as discussed earlier: the onload section should not read from LastPad or use GetKnobValue. LastPad doesn’t have a meaningful value during onLoad. In this script , the knob values aren’t meaningful either.

    I want to make sure you understand why as this has been mentioned before. Please ask if you have any questions about why.

    Please make that change.

    To prepare for solving the duplicates issue, write a description or short outline describing the problem and a strategy for solving it. But don’t implement anything in your script. This doesn’t need to be long and involved. A few sentences or bullet points will probably be sufficient.

    Until you have mastered the fundamentals, it is enormously helpful to work out the problem and how to solve it before writing any code.

    People often like to jump into writing code before they have really grasped the problem and solution and often end up taking longer to get a working solution than if they had solved the problem first this way.

Sign In or Register to comment.