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.

Moziac latch pad Help

Hello there,
I am not sure if this is the right place for this post but I was hoping to get some assistance with what I think is a pretty basic idea to achieve, but I am struggling with actually achieving it in the day or so since downloading the app

I would like to have a latchable pad that is triggered by a single SendMIDINoteOn , SendMIDICC, and/or sustain pedal (say from a bluetooth midi controller) that sends separate messages for latching and unlatching

My end goal is to use a single button to trigger “schedule loop 1” upon latching and “schedule stop” upon unlatching in the Helium AUv3 MIDI sequencer.

Any help would be appreciated

Adam

Comments

  • wimwim
    edited July 2021

    Well, latching or unlatching a pad doesn't send any midi messages, but you can do both actions separately in the code. Here's a basic example:

    @Description
    Demo - upon receiving a trigger midi message, toggle between sending two different messages. Latch and unlatch a pad to indicate which message was sent last. In the example below, note-on MIDI note 36, on MIDI Channel 1 alternates between CC 20 value 127 and CC 20 value 0.
    @End
    
    @OnLoad
      // Define the three bytes of the incoming midi message
      trigger = [0x90, 36, 127]
    
      // Define the pad that will be latched / unlatched
      pad = 0
    
      // Define the messages sent on latching and un-latching
      latchmsg = [0xB0, 20, 127]
      unlatchmsg = [0xB0, 20, 0]
    
      // Things to initialize only on a new load.
      if Unassigned init
        init = YES
        LatchPad 0,NO 
      endif
    
    @End
    
    @OnMidiInput
      if (MIDIByte1 = trigger[0]) and (MIDIByte2 = trigger[1]) and (MIDIByte3 = trigger[2])
    
        LatchPad pad, NOT(PadState pad)
        if PadState pad = YES
          SendMIDIOut latchmsg[0],latchmsg[1],latchmsg[2]
        else
          SendMIDIOut unlatchmsg[0],unlatchmsg[1],unlatchmsg[2]
        endif
    
      else
        // SendMIDIThru
      endif
    
    @End
    
  • @wim I knew that you would probably have a useful answer, but I decided to try writing some code before refreshing the page, because when I started learning to code, I would have loved to see multiple variations of every function. And I've been getting back into writing Mozaic recently. So partially for my own practice, partially for you @GrizzlyATOM, I first wrote the main function, how I would have written it in my first month (Switch1), and then how I'd probably write it today (Switch2)...unless it was part of a larger project, then it would look more similar to wim's.

    Another little design philosophy difference, I think it was @_ki who converted me to the practice of reformatting code before I share it, to remove the line breaks. The formatting of my version would have intimidated me more on day 1, but now, I prefer to read it this way, and then dissect it by constantly adding and removing my own line breaks, just to shift things around my visual field. So I don't see this as claustrophobic anymore. When the concepts become slightly more advanced, I have to read it line by line, and the line breaks trip me up.

    @OnLoad
      if Unassigned Latched 
        Latched = False
      endif
    @End
    ////////////////
    @Switch1
      if Latched = FALSE
        LatchPad 0, TRUE
        Latched = TRUE
        Call @SendOutput_On
      elseif Latched = TRUE
        LatchPad 0, FALSE
        Latched = FALSE
        Call @SendOutput_Off
      endif
    @End
    ////////////////
    @Switch2
      Latched = NOT Latched
      if Latched = FALSE
        LatchPad 0, FALSE
        Call @SendOutput_Off
      else
        LatchPad 0, TRUE
        Call @SendOutput_On
      endif
    @End
    ////////////////
    @OnPadDown
      if LastPad = 0
        Call @Switch2
      endif
    @End
    ////////////////
    @OnMidiNoteOn
      if MIDIByte2 = 60
        Call @Switch2
      endif
    @End
    ////////////////
    @SendOutput_On
      // SendMIDINoteOn, SendMIDICC, etc.
    @End
    ////////////////
    @SendOutput_Off
      // SendMIDINoteOn, SendMIDICC, etc.
    @End
    
  • Just a short remark: The Mozaic function PadState <num> returns the latchstate of a pad, so you don‘t have to store it in an own variable like Latched in your script.

    If i use that function in an Ifexpression, i perfer to add brackets to make the functions parameter more visible/readable like in
    If (PadState 1)
    which is the same as
    If (PadState 1) = TRUE
    instead of
    If PadState 1
    which in my eyes looks like a comparison operator is missing :)

  • edited July 2021

    @_ki Thanks, I forgot about PadState. I'll use that from now on. I think it was added in an update?

    I'll probably keep typing = TRUE, because I want my code to be as accessible as possible. I tried and gave up on learning to code at least three times, and now when I solve a difficult problem, I still wake up the next day with what almost feels like a hangover, or the brain equivalent of muscle soreness the day after a workout. I wonder if it's harder to code when you're only fluent in English, as I am.

  • edited July 2021

    @wim said:
    Well, latching or unlatching a pad doesn't send any midi messages, but you can do both actions separately in the code. Here's a basic example:

    @Description
    Demo - upon receiving a trigger midi message, toggle between sending two different messages. Latch and unlatch a pad to indicate which message was sent last. In the example below, note-on MIDI note 36, on MIDI Channel 1 alternates between CC 20 value 127 and CC 20 value 0.
    @End
    
    @OnLoad
      // Define the three bytes of the incoming midi message
      trigger = [0x90, 36, 127]
      
      // Define the pad that will be latched / unlatched
      pad = 0
      
      // Define the messages sent on latching and un-latching
      latchmsg = [0xB0, 20, 127]
      unlatchmsg = [0xB0, 20, 0]
      
      // Things to initialize only on a new load.
      if Unassigned init
        init = YES
        LatchPad 0,NO 
      endif
      
    @End
    
    @OnMidiInput
      if (MIDIByte1 = trigger[0]) and (MIDIByte2 = trigger[1]) and (MIDIByte3 = trigger[2])
      
        LatchPad pad, NOT(PadState pad)
        if PadState pad = YES
          SendMIDIOut latchmsg[0],latchmsg[1],latchmsg[2]
        else
          SendMIDIOut unlatchmsg[0],unlatchmsg[1],unlatchmsg[2]
        endif
        
      else
        // SendMIDIThru
      endif
      
    @End
    

    Beautiful, this is exactly the kind of thing I was looking for!
    Upon first upload I am unable to get it working but I am sure it is user error on my part,
    Questions:

    1. Is the squared off pad pictured above the one that will latch as an indicator?
    2. Is C1 the correct trigger note?
    3. Can I have different notes as outputs? (or cc’s for that matter?)
    4. How would the code have to change to use a sustain pedal as the trigger (from my Akai LPK25 Wireless)

    I attempted to hodgepodge together the code from the 3rd image from the user guide PDF in an attempt to more easily mirror the A and B Banks of my Akai LPD8 wireless controller. Could you help me incorporate the ideas (color scheme) from my hodgepodge into your code? It would be fantastic if the latched/unlatched pads displayed respective customizable labels.

    I appreciate your speedy response and am excited to implement this into my live set up, I can post video if you’d like lol
    Adam

  • wimwim
    edited July 2021

    @GrizzlyATOM said:

    @wim said:
    Well, latching or unlatching a pad doesn't send any midi messages, but you can do both actions separately in the code. Here's a basic example:

    Upon first upload I am unable to get it working but I am sure it is user error on my part,
    Questions:
    1. Is the squared off pad pictured above the one that will latch as an indicator?

    Yes

    1. Is C1 the correct trigger note?

    No. C2 is note 36 in AUM. Octave naming varies in hardware and from app to app.
    Also, the demo code specifies velocity 127 as the trigger. If you're really trying to do this with notes from the AUM keyboard, you probably don't want to check that value because it's not easy to get a velocity 127 from the AUM keyboard. To make it so that any note-on from the specified note will trigger, change the if clause ...

    if (MIDIByte1 = trigger[0]) and (MIDIByte2 = trigger[1])
    
    1. Can I have different notes as outputs? (or cc’s for that matter?)

    Yes. Check the section in the Mozaic manual that describes MIDI Messages to understand MIDI messages better. It's very well written. You just need to change the three bytes in the latchmsg and unlatchmsg arrays. The first number is the message type and channel. Examples:

    • 0x90 is Note-On message type on channel 1. 0x91 is Note-On message on channel 2.
    • 0x80 is Note-Off message on channel 1
    • 0xB0 is a CC message on channel 1, 0xB1 is CC message on channel 2

    The second number is the note or the CC number.
    The third number is the note velocity or the CC value

    1. How would the code have to change to use a sustain pedal as the trigger (from my Akai LPK25 Wireless)

    Sustain is almost always cc 64. Values 64 and above turn it on, and Values 63 or below turn it off. So ...

    // Set trigger to sustain pedal
    // Assuming MIDI Channel 1
    trigger = [0xB0, 64, 64]
    

    You'll also need to change the if statement to check for any value greater than or equal to the CC value from the pedal.

      if (MIDIByte1 = trigger[0]) and (MIDIByte2 = trigger[1]) and (MIDIByte3 >= trigger[2])
    

    I attempted to hodgepodge together the code from the 3rd image from the user guide PDF in an attempt to more easily mirror the A and B Banks of my Akai LPD8 wireless controller. Could you help me incorporate the ideas (color scheme) from my hodgepodge into your code? It would be fantastic if the latched/unlatched pads displayed respective customizable labels.

    I'm a little confused. Is this a different application that is using screen taps rather than messages from the LPD8? Or, are you wanting the LPD8 to send messages to toggle the pads? I think you'll need to choose one or the other. I don't see from the LPD manual that it can receive messages to turn the pad lights on and off. So, if you toggled a pad on using the controller, then toggled it off by touching the screen, the controller and the app would be out of sync.

    It's possible that the LPD will respond to incoming midi to turn the lights on and off, but that would make for a more complicated app and routing scheme in AUM.

    If you want to trigger from the LPD8, then it'll also be necessary to know the exact messages coming from the LPD8 for each pad per bank. The controller is customizable, so I can't assume what is coming from it.

  • edited August 2021
    1. Is C1 the correct trigger note?

    No. C2 is note 36 in AUM. Octave naming varies in hardware and from app to app.
    Also, the demo code specifies velocity 127 as the trigger. If you're really trying to do this with notes from the AUM keyboard, you probably don't want to check that value because it's not easy to get a velocity 127 from the AUM keyboard. To make it so that any note-on from the specified note will trigger, change the if clause ...

    if (MIDIByte1 = trigger[0]) and (MIDIByte2 = trigger[1])
    

    I am experimenting with cutting AUM out and just running everything through AudioBus 3, so all the screen shots have AB3 as the host.
    Does AB3 have the same octave naming conventions as AUM?

    1. Can I have different notes as outputs? (or cc’s for that matter?)

    Yes. Check the section in the Mozaic manual that describes MIDI Messages to understand MIDI messages better. It's very well written. You just need to change the three bytes in the latchmsg and unlatchmsg arrays. The first number is the message type and channel. Examples:

    • 0x90 is Note-On message type on channel 1. 0x91 is Note-On message on channel 2.
    • 0x80 is Note-Off message on channel 1
    • 0xB0 is a CC message on channel 1, 0xB1 is CC message on channel 2

    The second number is the note or the CC number.
    The third number is the note velocity or the CC value

    1. How would the code have to change to use a sustain pedal as the trigger (from my Akai LPK25 Wireless)

    Sustain is almost always cc 64. Values 64 and above turn it on, and Values 63 or below turn it off. So ...

    // Set trigger to sustain pedal
    // Assuming MIDI Channel 1
    trigger = [0xB0, 64, 64]
    

    You'll also need to change the if statement to check for any value greater than or equal to the CC value from the pedal.
    ```
    if (MIDIByte1 = trigger[0]) and (MIDIByte2 = trigger[1]) and (MIDIByte3 >= trigger[2])

    Thank you, this is very helpful. I am pretty new to MIDI protocol.

    ```

    I attempted to hodgepodge together the code from the 3rd image from the user guide PDF in an attempt to more easily mirror the A and B Banks of my Akai LPD8 wireless controller. Could you help me incorporate the ideas (color scheme) from my hodgepodge into your code? It would be fantastic if the latched/unlatched pads displayed respective customizable labels.

    I'm a little confused. Is this a different application that is using screen taps rather than messages from the LPD8? Or, are you wanting the LPD8 to send messages to toggle the pads? I think you'll need to choose one or the other.

    I am wanting to use the pads on the LPD8 to trigger the on screen toggling through Mozaic, with AudioBus as the host,
    but I would also like to be able to use the sustain pedal from my LPK25 to trigger the onscreen toggling of a single pad
    I don’t actually need to use screen taps on the respective toggling pads, though it would be cool to be able to do so for moments when my midi controllers aren’t handy.

    I don't see from the LPD manual that it can receive messages to turn the pad lights on and off. So, if you toggled a pad on using the controller, then toggled it off by touching the screen, the controller and the app would be out of sync.

    It's possible that the LPD will respond to incoming midi to turn the lights on and off, but that would make for a more complicated app and routing scheme in AUM.

    If you want to trigger from the LPD8, then it'll also be necessary to know the exact messages coming from the LPD8 for each pad per bank. The controller is customizable, so I can't assume what is coming from it.

    I don’t actually want the lights on the LPD8 to latch along with the on screen latching, too much battery usage anyhow lol, I just need a single momentary pad to trigger the onscreen toggle pad that sends out two different cc’s (one to assign to the “schedule loop” parameter and one to assign to “schedule stop”.)
    The separate specific cc’s sent out by Mozaic which will actually trigger the scheduling can be anything, as I can use MIDI-learn to assign them


    This is my current standard set up for the LPD8
    I mainly want to us the cc’s from the 8 pads of the A Bank, but I’m interested in being able to use the B bank pads as well.
    I’d like to have it all in one instance, so in order to use the sustain pedal as a single trigger I imagine I would have to cut out one of the B bank pads to free up room for the sustain triggered toggle pad on Moziac

    I’m only interested in being able to use notes as triggers as a learning exercise.
    The notes assigned to the LPD8 are to control drum pads in an instance of BeatHawk, so I would like to leave those unused. That way I can switch from controlling drums to scheduling midi-loop starting /stopping easily, by holding the two buttons to change the controller to send cc’s instead of the notes that it sends on start up. Below is a screen shot of my current test AudioBus setup

    I plan to get an iRig Blueboard soon, and would like to be able to use it in a similar fashion, to make it easier to control the scheduling of instances of the Helium midi loops that are controlling BeatHawk drums and BASSalicious synth bass while I play the ukulele and sing

    Thank you again for your time and expertise

  • wimwim
    edited August 2021

    @GrizzlyATOM said:
    Does AB3 have the same octave naming conventions as AUM?

    No, Note 36 is C1 in Audiobus.

    I am wanting to use the pads on the LPD8 to trigger the on screen toggling through Mozaic, with AudioBus as the host,
    but I would also like to be able to use the sustain pedal from my LPK25 to trigger the onscreen toggling of a single pad
    I don’t actually need to use screen taps on the respective toggling pads, though it would be cool to be able to do so for moments when my midi controllers aren’t handy.
    I don’t actually want the lights on the LPD8 to latch along with the on screen latching, too much battery usage anyhow lol, I just need a single momentary pad to trigger the onscreen toggle pad that sends out two different cc’s (one to assign to the “schedule loop” parameter and one to assign to “schedule stop”.)

    OK then triggering from both the LPD and the screen will be fine.

    The separate specific cc’s sent out by Mozaic which will actually trigger the scheduling can be anything, as I can use MIDI-learn to assign them

    Sure that's not a problem as you can configure them to whatever you want via the latchmsg and unlatchmsg array variables.

    I’d like to have it all in one instance, so in order to use the sustain pedal as a single trigger I imagine I would have to cut out one of the B bank pads to free up room for the sustain triggered toggle pad on Moziac

    There can be other options, such as using colors rather than latching.

    I’m only interested in being able to use notes as triggers as a learning exercise.
    The notes assigned to the LPD8 are to control drum pads in an instance of BeatHawk, so I would like to leave those unused. That way I can switch from controlling drums to scheduling midi-loop starting /stopping easily, by holding the two buttons to change the controller to send cc’s instead of the notes that it sends on start up. Below is a screen shot of my current test AudioBus setup

    I plan to get an iRig Blueboard soon, and would like to be able to use it in a similar fashion, to make it easier to control the scheduling of instances of the Helium midi loops that are controlling BeatHawk drums and BASSalicious synth bass while I play the ukulele and sing

    Thank you again for your time and expertise

    I would be happy to work on this, but I'm going to be traveling over the next week, so I'm not too likely to have time until I return. On the other hand, I might get some unexpected downtime. I can't say for sure.

    I'd say if anyone else feels like taking this on that would be great - otherwise, I'll be happy to pick it up when my time frees up a bit.

  • I would be happy to work on this, but I'm going to be traveling over the next week, so I'm not too likely to have time until I return. On the other hand, I might get some unexpected downtime. I can't say for sure.

    I'd say if anyone else feels like taking this on that would be great - otherwise, I'll be happy to pick it up when my time frees up a bit.

    You are both a gentleman and a scholar @wim
    I completely understand and any help at all is appreciated
    I am making my way through the Moziac pdf. I skipped to the chapter on MIDI messages (Understanding MIDI input) to get a better understanding of the very basics.

    I am also very interested in learning to use the host’s time clock as a variable (<-yes?) to alter the function of a button.
    So a button that would send a cc that normally just cues up a bass line could instead send out:

    • 2 different cc’s if pressed between times A and B, possibly cueing up an additional loop
    • or send out a different cc than normal between times A and B to cue up an alternative loop

    Thanks for your generous donation of your time and knowledge so far. The possibilities are so interesting

  • @Skyblazer said:
    @wim I knew that you would probably have a useful answer, but I decided to try writing some code before refreshing the page, because when I started learning to code, I would have loved to see multiple variations of every function. And I've been getting back into writing Mozaic recently. So partially for my own practice, partially for you @GrizzlyATOM, I first wrote the main function, how I would have written it in my first month (Switch1), and then how I'd probably write it today (Switch2)...unless it was part of a larger project, then it would look more similar to wim's.

    Another little design philosophy difference, I think it was @_ki who converted me to the practice of reformatting code before I share it, to remove the line breaks. The formatting of my version would have intimidated me more on day 1, but now, I prefer to read it this way, and then dissect it by constantly adding and removing my own line breaks, just to shift things around my visual field. So I don't see this as claustrophobic anymore. When the concepts become slightly more advanced, I have to read it line by line, and the line breaks trip me up.

    @OnLoad
      if Unassigned Latched 
        Latched = False
      endif
    @End
    ////////////////
    @Switch1
      if Latched = FALSE
        LatchPad 0, TRUE
        Latched = TRUE
        Call @SendOutput_On
      elseif Latched = TRUE
        LatchPad 0, FALSE
        Latched = FALSE
        Call @SendOutput_Off
      endif
    @End
    ////////////////
    @Switch2
      Latched = NOT Latched
      if Latched = FALSE
        LatchPad 0, FALSE
        Call @SendOutput_Off
      else
        LatchPad 0, TRUE
        Call @SendOutput_On
      endif
    @End
    ////////////////
    @OnPadDown
      if LastPad = 0
        Call @Switch2
      endif
    @End
    ////////////////
    @OnMidiNoteOn
      if MIDIByte2 = 60
        Call @Switch2
      endif
    @End
    ////////////////
    @SendOutput_On
      // SendMIDINoteOn, SendMIDICC, etc.
    @End
    ////////////////
    @SendOutput_Off
      // SendMIDINoteOn, SendMIDICC, etc.
    @End
    

    Thank you @Skyblazer, I will definitely be looking through this to try to better understand what’s actually going on here

  • edited August 2021

    You're welcome @GrizzlyATOM, hope it helps, looking forward to seeing what you build. The PDF should give you what you need to understand it, but I tried to rewrite it to be simpler.

    And my code isn't working! :D @_ki, I guess I'm not understanding PadState. Switch is being called, but it's going to "else", yet when I use Log, it says PadState 0 = 0.

    (Edit: Added parentheses around the PadState call, as ki suggested)

    ////////////////
    // When you tap the top left pad, the switch is activated or deactivated. 
    @OnPadDown
      if LastPad = 0
        Call @Switch
      endif
    @End
    
    ////////////////
    // When Mozaic receives MIDI Note 60, aka C3 or C4, it will also activate or deactivate the switch.  
    @OnMidiNoteOn
      if MIDIByte2 = 60
        Call @Switch
      endif
    @End
    
    ////////////////
    // If the pad is off, turn it on, and vice versa. 
    // Do this in the Mozaic backend, on the user interface, and also send out different CC values, for on and off. 
    @Switch
      if (PadState 0) = 0
        LatchPad 0, TRUE
        SendMIDICC 0, 5, 100
        // The ON message is: Channel 0, CC Num 5, CC Val 100. 
      else
        LatchPad 0, FALSE
        SendMIDICC 0, 5, 1
        // The OFF message is: Channel 0, CC Num 5, CC Val 1.  
      endif
    @End
    
  • _ki_ki
    edited August 2021

    Just add the brackets like i initially suggested:

    if (PadState 0) = 0

    It seems the = has higher precedence than the function call - so without any brackets it computes something like if PadState (0 = 0) which is recalling and checking the latch state of pad 1 as (0=0) is TRUE, which equals 1.

    Therefore the brackets are not only better to read but mandatory around function calls with parameters.

  • Thanks! Added the brackets. (I think I vaguely remember you saying that not everyone calls them parentheses?)

  • You are right, the non-curly and non-square ones are called parentheses. Perhaps i used the term bracket because i had a british english teacher, but i think i derived it from ‚curly brackets‘ without curls :)

  • edited August 2021

    Ok, here is what I have so far, I think I figured out the basics of what’s going on.
    Thank you for all of your help @Skyblazer, @wim, and @_ki!
    Seriously, having two versions to compare really helped @Skyblazer.
    I got it to work with 3 buttons, so I should be able to replicate what I did for the other 13 buttons

    Tell me what you think? Any input is appreciated.


    @OnLoad ShowLayout 2 call @lpd8wireless if Unassigned Latched Latched = False endif @End // Format colors of pads to match green A & red B banks of lpd8wireless @lpd8wireless for i = 0 to 3 c = 3 ColorPad i, c endfor for i = 4 to 7 c = 7 ColorPad i, c endfor for i = 8 to 11 c = 3 ColorPad i, c endfor for i = 12 to 16 c = 7 ColorPad i, c endfor @End //////////////// // When you tap the first 3 pads a switch is activated or deactivated. @OnPadDown if LastPad = 0 Call @ASwitch endif if LastPad = 1 Call @BSwitch endif if LastPad = 2 Call @CSwitch endif @End @OnMidiCC //////////////// // When Mozaic receives MIDI CC 21, 127 it will also activate or deactivate the first switch. if (MIDIByte2 = 21) and (MIDIByte3 = 127) Call @ASwitch endif //////////////// // When Mozaic receives MIDI CC 22, 127 it will also activate or deactivate the second switch. if (MIDIByte2 = 22) and (MIDIByte3 = 127) Call @BSwitch endif //////////////// // When Mozaic receives MIDI CC 23, 127 it will also activate or deactivate the third switch. if (MIDIByte2 = 23) and (MIDIByte3 = 127) Call @CSwitch endif @End First Switch //////////////// @ASwitch1 if Latched = FALSE LatchPad 0, TRUE Latched = TRUE Call @SendOutput_On elseif Latched = TRUE LatchPad 0, FALSE Latched = FALSE Call @SendOutput_Off endif @End //////////////// @ASwitch2 Latched = NOT Latched if Latched = FALSE LatchPad 0, FALSE Call @SendOutput_Off else LatchPad 0, TRUE Call @SendOutput_On endif @End //////////////// // If the pad is off, turn it on, and vice versa. // Do this in the Mozaic backend, on the user interface, and also send out different CC values, for schedual and stop. @ASwitch if (PadState 0) = 0 LatchPad 0, TRUE SendMIDICC 0, 5, 100 // The ON message is: Channel 0, CC Num 5, CC Val 100. else LatchPad 0, FALSE SendMIDICC 0, 6, 100 // The OFF message is: Channel 0, CC Num 6, CC Val 100. endif @End Second Switch //////////////// @BSwitch1 if Latched = FALSE LatchPad 1, TRUE Latched = TRUE Call @SendOutput_On elseif Latched = TRUE LatchPad 1, FALSE Latched = FALSE Call @SendOutput_Off endif @End //////////////// @BSwitch2 Latched = NOT Latched if Latched = FALSE LatchPad 1, FALSE Call @SendOutput_Off else LatchPad 1, TRUE Call @SendOutput_On endif @End //////////////// // If the pad is off, turn it on, and vice versa. // Do this in the Mozaic backend, on the user interface, and also send out different CC values, for schedual and stop. @BSwitch if (PadState 1) = 0 LatchPad 1, TRUE SendMIDICC 0, 8, 100 // The ON message is: Channel 0, CC Num 8, CC Val 100. else LatchPad 1, FALSE SendMIDICC 0, 9, 100 // The OFF message is: Channel 0, CC Num 9, CC Val 100. endif @End Third Switch //////////////// @CSwitch1 if Latched = FALSE LatchPad 2, TRUE Latched = TRUE Call @SendOutput_On elseif Latched = TRUE LatchPad 2, FALSE Latched = FALSE Call @SendOutput_Off endif @End //////////////// @CSwitch2 Latched = NOT Latched if Latched = FALSE LatchPad 2, FALSE Call @SendOutput_Off else LatchPad 2, TRUE Call @SendOutput_On endif @End //////////////// // If the pad is off, turn it on, and vice versa. // Do this in the Mozaic backend, on the user interface, and also send out different CC values, for schedual and stop. @CSwitch if (PadState 2) = 0 LatchPad 2, TRUE SendMIDICC 0, 10, 100 // The ON message is: Channel 0, CC Num 10, CC Val 100. else LatchPad 2, FALSE SendMIDICC 0, 11, 100 // The OFF message is: Channel 0, CC Num 11, CC Val 100. endif @End
  • Hi @GrizzlyATOM - good job taking that on! Sorry, I've no time to review right now, but just a quick comment - If you edit your post to place three backticks on a line by themselves before and after the code, it'll format better on the forum. It's sometimes hard to locate the back tick with some locale settings, but you can copy/paste this: ```

  • _ki_ki
    edited August 2021

    Hi @GrizzlyATOM , after looking through the script i noticed that Switch1 and Switch2 are not called, these can be removed.

    .

    You can now either continue adding similar code for the remaining pads - or start to simplify and unify the code:

    All your cases in @OnMidiCC and also the code inside each @ASwitch Just differs in the CCs used - so these can be compacted into a single function taking a parameter that specifies which of the pads it should work on in combination with constant arrays containing the input CC and output CCs for each of the 16 pads.

    .

    In the below code i use the variable pPad as paramater to the new general @LatchSwitch function.

    • In @OnPadDown this variable is set to the LastPad value specifiying which pad was pressed.
    • In @OnMidiCC it is used as loop variable testing the current midi input for the 16 possible input CCs and then calling @LatchSwitch for that pPad.

    .

    Here the full code for all 16 pads, you only need to add the constants for the remaining 13 pads, currently only the first 3 work. Hopefully i didn‘t make bigger mistakes - didn‘t test yet :)

    @OnLoad
      ShowLayout 2
      // Per pad constants, 16 values in each array
      PAD_COLOR     = [3,3,3,3,7,7,7,7,3,3,3,3,7,7,7,7]
      OUT_ON_CC     = [5,8,10]
      OUT_OFF_CC    = [6,9,11]
      INP_TOGGLE_CC = [21,22,23]
      // Format colors of pads to match green A & red B banks of lpd8wireless
      for i = 0 to 15
        ColorPad i, PAD_COLOR[i]
      endfor
      // UI Setup of labels, knobs and icon-title
      SetShortName {CC-Tog}
      LabelPads {GrizzlyATOMs CC-Toggles}
      LabelKnobs { }
      for i = 0 to 3
        LabelKnobs i, { }
        SetKnobValue i,0
      endfor
    @End
    // When you tap any pad,the corresponding switch is activated or deactivated. 
    @OnPadDown
      pPad = LastPad 
      Call @LatchSwitch
    @End
    ////////////////
    // When Mozaic receives an input MIDI CC of 127 it will also activate 
    // or deactivate the corresponding switch.
    @OnMidiCC
      for pPad = 0 to 15
        if (MIDIByte2 = INP_TOGGLE_CC[pPad]) and (MIDIByte3 = 127)
          Call @LatchSwitch
        endif
      endfor
    @End
    ////////////////
    // If the pad is off, turn it on, and vice versa. Do this in the Mozaic backend, 
    // on the user interface, and also send out different CC values, for schedule and stop. 
    @LatchSwitch // parameter: pPad
      if (PadState pPad) = 0
        LatchPad pPad, TRUE
        SendMIDICC 0, OUT_ON_CC[pPad], 100
        // The ON message is: Channel 0, CC Num depends on pPad, CC Val 100. 
      else
        LatchPad pPad, FALSE
        SendMIDICC 0, OUT_OFF_CC[pPad], 100
        // The OFF message is: Channel 0, CC Num depends on pPad, CC Val 100. 
      endif
    @End
    

    I additionally simplified the code for pad colorization and added UI initialization for the main labels, unused knobs and Mozaic icon.

  • @_ki awesome! Thank you so much, everything seems to work great

    Is there any way to play with the size of the pad labels?

  • _ki_ki
    edited August 2021

    From the screenshot i see there was a typo in the UI initialization part of th knobs inside @OnLoad - sorry, i really should have tested it at least once :)

    Inside the loop use LabelKnob i, { } , just remove the extra „s“ at the end of the command. This fixes the ‚visual bug‘ that there are still numbers used as knob labels and also removes the ‚3‘ above the knobs.

    .

    Is there any way to play with the size of the pad labels?

    You can‘t change the pad label size.

    The only sneaky way to cheat this limitation is to use Unicode characters, which come in a bit fatter variant in the Mathematical Alphanumeric Symbols page (1D400-1D7FF).

    There are several drawback‘s

    • One can’t type them with a keyboard, but has to copy them one by one into Mozaic. This is quite cumbersome.
    • If more than around 70 unicode chars are used in a single Mozaic line, Moazic can throw an error: Mozaic has a line length limit of about 200 chars or so. Each of the unicode chars is internally represented by 2 to 4 chars - so using many of them may reach the line length limit...
    • Some of the charsets are missing letters on IOS (like the Double Line set misses capital CHNPQRZ ... one has to find and use words without these letters)
  • edited August 2021

    Thank you @_ki !
    Now I just have to figure out why AudioBus won’t recognize the cc’s Moziac is sending out for the MIDI learn to control the loops in Helium 😅

    One little step at a time lol…

    EDIT: I guess it’s back to AUM as everything easily works correctly through AUM. Thanks for all your help

    EDIT 2: never mind yay! I figured out how to connect Moziac to AB3’s MIDI learn. I think I’ll stick with AB3 alone after all.

  • @_ki is there a way to control and rotate the on screen knobs with a knob on my midi-controller?

  • @GrizzlyATOM said:
    @_ki is there a way to control and rotate the on screen knobs with a knob on my midi-controller?

    Listen for the related MIDI events and then use SetKnobValue to set the knob to the corresponding value.

  • wimwim
    edited August 2021

    @GrizzlyATOM - you can also map to the Knob 0 ... Knob 21 AUv3 parameters. This doesn't require any coding, but is less portable because you have to map the parameters in each host / session.

  • edited August 2021

    @espiegel123 said:

    @GrizzlyATOM said:
    @_ki is there a way to control and rotate the on screen knobs with a knob on my midi-controller?

    Listen for the related MIDI events and then use SetKnobValue to set the knob to the corresponding value.

    Ok cool, thank you @espiegel123, What is code for grabbing that corresponding value to type into the “value” field?

    I was also wondering if there was a simple way to exclude certain pads from the latch coding?

  • @GrizzlyATOM said:

    @espiegel123 said:

    @GrizzlyATOM said:
    @_ki is there a way to control and rotate the on screen knobs with a knob on my midi-controller?

    Listen for the related MIDI events and then use SetKnobValue to set the knob to the corresponding value.

    Ok cool, thank you @espiegel123 I think I know how to do that

    I was also wondering if there was a simple way to exclude certain pads from the latch coding?

    One way to accomplish this would be to add an 'if' statement (a conditional) in LatchSwitch (or alternately anywhere LatchSwitch is called) so that it only calls LatchSwitch if LastPad is in a certain range of pad numbers.

    for example, along the lines of

    if (LastPad>=0) and (LastPad<=11)
    call @Latchswitch....
    endif

    The least amount of coding would put the test in LatchSwitch -- but the logic is less elegant.

  • @espiegel123 What is code for grabbing that corresponding value from my midi controller to type into the “value” field of Setknobvalue?

  • edited August 2021

    @GrizzlyATOM said:
    @espiegel123 What is code for grabbing that corresponding value from my midi controller to type into the “value” field of Setknobvalue?

    When a MIDI CC value is received, the value is in Midibyte3

  • here's some very basic code. There are more elegant ways to do it but this example is meant for simplicity and clarity.

    @OnLoad
      // define a MIDI cc for each knob we want to control
      cc0 = 20
      cc1 = 21
    @End
    
    @OnMidiCC
      if MIDIByte2 = cc0
        SetKnobValue 0,MIDIByte3 
        LabelKnob 0,MIDIByte3
      elseif MIDIByte2 = cc1
        SetKnobValue 1,MIDIByte3
        LabelKnob 1,MIDIByte3
      else
        SendMIDIThru 
      endif
    @End
    
    @OnMidiInput
      // we already handled MIDI CC's so don't send those here but 
      // do send everything else
      if MIDIChannel <> 0xB0
        SendMIDIThru 
      endif
    @End
    
  • edited August 2021

    Ok @espiegel123 ,
    I don’t know how elegant this is, but everything seems to be in working order


    @OnLoad ShowLayout 2 // Per pad constants, 16 values in each array PAD_COLOR = [3,3,3,3,7,7,7,7,3,3,3,3,7,7,7,7] OUT_ON_CC = [1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31] OUT_OFF_CC = [2,4,6,7,10,12,14,16,18,20,22,23,26,28,30,31] INP_TOGGLE_CC = [21,22,23,24,29,30,31,32,17,18,19,20,25,26,27,64] // Format colors of pads to match green A & red B banks of lpd8wireless for i = 0 to 15 ColorPad i, PAD_COLOR[i] endfor LabelPad 0, {BASS} LabelPad 1, {BASS} LabelPad 2, { } LabelPad 3, {Schedule Stop} LabelPad 7, {MUTE UKE} LabelPad 8, {DRUMS} LabelPad 9, { } LabelPad 10, { } LabelPad 11, {Show Plugin} LabelPad 15, {PLAY} // UI Setup of labels, knobs and icon-title SetShortName {Grizzly} LabelPads {GrizzlyATOMs CC-Toggles} LabelKnobs {Volumes} for i = 0 to 3 LabelKnob 0,{Uke} LabelKnob 1, {Delay} LabelKnob 2, {Drums} LabelKnob 3, {Bass} SetKnobValue i,0 endfor @End // When you tap any pad,the corresponding switch is activated or deactivated. @OnPadDown pPad = LastPad if (LastPad<=2) or (LastPad = 4) or (LastPad = 5) or (LastPad = 6) or (LastPad = 7) or (LastPad = 8) or (LastPad = 9) or (LastPad = 10) or (LastPad>=12) Call @LatchSwitch elseif (lastpad = 3) SendMIDICC 0, 7, 127 elseif (lastpad = 11) SendMIDICC 0, 23, 127 endif @End //////////////// // When Mozaic receives an input MIDI CC of 127 it will also activate // or deactivate the corresponding switch. @OnMidiCC for pPad = 0 to 2 if (MIDIByte2 = INP_TOGGLE_CC[pPad]) and (MIDIByte3 = 127) Call @LatchSwitch endif endfor for pPad = 3 to 3 if (MIDIByte2 = INP_TOGGLE_CC[pPad]) and (MIDIByte3 = 127) SendMIDICC 0, 7, 127 FlashPad 3 endif endfor for pPad = 4 to 10 if (MIDIByte2 = INP_TOGGLE_CC[pPad]) and (MIDIByte3 = 127) Call @LatchSwitch endif endfor for pPad = 11 to 11 if (MIDIByte2 = INP_TOGGLE_CC[pPad]) and (MIDIByte3 = 127) SendMIDICC 0, 23, 127 FlashPad 11 endif endfor for pPad = 12 to 15 if (MIDIByte2 = INP_TOGGLE_CC[pPad]) and (MIDIByte3 = 127) Call @LatchSwitch endif endfor @End //////////////// // If the pad is off, turn it on, and vice versa. Do this in the Mozaic backend, // on the user interface, and also send out different CC values, for schedule and stop. @LatchSwitch // parameter: pPad if (PadState pPad) = 0 LatchPad pPad, TRUE SendMIDICC 0, OUT_ON_CC[pPad], 100 // The ON message is: Channel 0, CC Num depends on pPad, CC Val 100. else LatchPad pPad, FALSE SendMIDICC 0, OUT_OFF_CC[pPad], 100 // The OFF message is: Channel 0, CC Num depends on pPad, CC Val 100. endif @End @OnKnobChange if LastKnob = 0 setting = GetKnobValue 0 SendMIDICC 4, 9, setting // send out CC#9 on channel 5 endif if LastKnob = 1 setting = GetKnobValue 1 SendMIDICC 4, 10, setting // send out CC#10 on channel 5 endif if LastKnob = 2 setting = GetKnobValue 2 SendMIDICC 4, 13, setting // send out CC#13 on channel 5 endif if LastKnob = 3 setting = GetKnobValue 3 SendMIDICC 4, 14, setting // send out CC#14 on channel 5 endif @End @OnMidiInput if (MIDIByte1 = 0xB4) and (MIDIByte2 = 9) SetKnobValue 0, MIDIByte3 SendMIDICC 4, 9, MIDIByte3 endif if (MIDIByte1 = 0xB4) and (MIDIByte2 = 10) SetKnobValue 1, MIDIByte3 SendMIDICC 4, 10, MIDIByte3 endif if (MIDIByte1 = 0xB4) and (MIDIByte2 = 13) SetKnobValue 2, MIDIByte3 SendMIDICC 4, 13, MIDIByte3 endif if (MIDIByte1 = 0xB4) and (MIDIByte2 = 14) SetKnobValue 3, MIDIByte3 SendMIDICC 4, 14, MIDIByte3 endif @End
  • @GrizzlyATOM The code looks ok.

    In @OnPadDown you can simplify the long

    if (LastPad<=2) or (LastPad = 4) or (LastPad = 5) or (LastPad = 6) or (LastPad = 7) or (LastPad = 8) or (LastPad = 9) or (LastPad = 10) or (LastPad>=12) 
    

    by ‚inverting‘ the expression - there are just two exceptions: Pad 3 and 11. So just test if the number differs from 3 AND differs from 11:

    if (LastPad<>3) and (LastPad<>11)
    

    .

    Another solution is to exchange the order of options tesed and use an else branch - this gets rid of any extra tests:

    if (LastPad = 3)
      ...
    elseif (LastPad = 11)
      ..
    else
      // Code to run if not 3 or 11  
    endif
    
Sign In or Register to comment.