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: How to detect a "long tap" (0.5secs) on my BlueBoard?

edited July 2020 in Other

I'm starting to dive into MIDI scripting using Mozaic.

I have read the manual thoroughly, but I'm still a bit confused where to start with the following requirement, which is:

How to detect a "long tap" (0.5secs) on my BlueBoard? I think I need to look at the delta of the timestamp of incoming On/Off events. But where do I get this information from? And how/where do I store it, so I can check upon it when the Off event arrives?

My specific requirement is: I want to have 4 different "spaces" on my BlueBoard. Each space is associated to one of the BlueBoard's pads A, B, C, and D. By long-tapping on one of these pads, I activate the associated space, and now I have 4 functions available (that I can activate using a short tap) per space.

  • Space A: Clock & Record

    • A: Divide Clock
    • B: Multiply Clock
    • C: Record/Overdub
    • D: ???
  • Space B: Groups & Loops

    • A: Previous Group & select first loop
    • B: Next Group & select first loop
    • C: Toggle through loops
    • D: Play/Pause group
  • Space C: Instrument selection

    • A: Instrument only
    • B: Mic only
    • C: Both Instrument and Mic
    • D: Toggle through Instruments
  • Space D: ???

    • A: ???
    • B: ???
    • C: ???
    • D: ???

I could also add double clicks in spaces to have 4 more functions available.

Thank you.

PS: Is there a more appropriate place to ask questions like this? I know that the Audiobus forum is not a Mozaic support forum, but I can't find any other place (and I don't want to bother the official email support).

«1345

Comments

  • There’s definitely some serious experts on here who probably have better ways to do this but I’ve done something similar using the following techniques...

    For the “long tap” you can use the SystemTime call with something like:

    @OnMidiNoteOn
      Longtap = SystemTime
    @End
    
    @OnMidiNoteOff
      If SystemTime - Longtap >= 500 //for 0.5 sec
         Space = midinote //sets the Space based on the note from  BlueBoard Pad
      Else
        SendMIDIThru
      Endif
    @End
    

    You could then add an if/then statement checking for the current value of “Space” to determine what to send for the pad triggered like:

    If MidiNote = (BlueBoard Pad 1)
       If Space = 1
         SendCommand for DivideClock
      Elseif Space = 2
       SendCommand for PreviousGroup and Selet First Loop
     Etc......
    Elseif MidiNote = BlueBoard Pad 2
     If Space = 1
      SendCommand for HalfClock
    Etc....
    
    

    Alternatively you could use separate channels for the separate “Spaces” with something like:

    @OnMidiNoteOn
      Longtap = SystemTime
    @End
    
    @OnMidiNoteOff
      If SystemTime - Longtap >= 500 //for 0.5 sec
         Space = MidiNote - (whatever value is needed here to bring the number down to a Channel number between 0-15)
     Else
      SendMidiThruOnCh Space
     Endif
    @End
    

    Hopefully that’s clear...?

    In these examples you’d be mapping NoteOff events to do your dirty work, but of course you could just have Mozaic send whatever type of event you wanted in the place where I put SendMIDIThruOnCh Space for example.

    I haven’t tried using this to do double click stuff as I think it’s a bit more complicated but I assume could use the same logic with SystemTime checks.

  • This works nicely, thank you. Didn't know about SystemTime.

    I'm still wondering what's a good way to send different MIDI signals from BlueBoard's A/B/C/D pads depending on the currently active space.

    I tried several approaches:

    1) A two-dimensional array:

    MidiOuts[0] = [0, 1, 2, 3] // Pad A
    MidiOuts[1] = [4, 5, 6, 7] // Pad B
    MidiOuts[2] = [8, 9, 10, 11]  // Pad C
    MidiOuts[3] = [12, 13, 14, 15] // Pad D
    

    But either there are no two-dimensional arrays (or they are not created like this), or I just wasn't able to get the correct values (e.g. using MidiOuts[ActiveSpace][PressedPad]).

    2) Instead of a two dimensional array, I tried 4 standard arrays:

    MidiOutsA = [0, 1, 2, 3] // Pad A
    MidiOutsB = [4, 5, 6, 7] // Pad B
    MidiOutsC = [8, 9, 10, 11]  // Pad C
    MidiOutsD = [12, 13, 14, 15] // Pad D
    

    I could create a wordy if/elseif/... now, checking for each array whether it's the appropriate one:

    if Space = 0 // Space A
      if MidiNote = 60 // Pad A
        SendMidiThruOnCh MidiOutsA[0]
      elseif MidiNote = 62 // Pad B
        SendMidiThruOnCh MidiOutsA[1]
      elseif MidiNote = 64 // Pad C
        SendMidiThruOnCh MidiOutsA[2]
      elseif MidiNote = 65 // Pad D
        SendMidiThruOnCh MidiOutsA[3]
      end
    elseif Space = 1 // Space B
      if MidiNote = 60 // Pad A
        SendMidiThruOnCh MidiOutsA[0]
      elseif MidiNote = 62 // Pad B
        SendMidiThruOnCh MidiOutsA[1]
      elseif MidiNote = 64 // Pad C
        SendMidiThruOnCh MidiOutsA[2]
      elseif MidiNote = 65 // Pad D
        SendMidiThruOnCh MidiOutsA[3]
      end
    elseif Space = 2 // Space C
      if MidiNote = 60 // Pad A
        SendMidiThruOnCh MidiOutsA[0]
      elseif MidiNote = 62 // Pad B
        SendMidiThruOnCh MidiOutsA[1]
      elseif MidiNote = 64 // Pad C
        SendMidiThruOnCh MidiOutsA[2]
      elseif MidiNote = 65 // Pad D
        SendMidiThruOnCh MidiOutsA[3]
      end
    elseif Space = 1 // Space D
      if MidiNote = 60 // Pad A
        SendMidiThruOnCh MidiOutsA[0]
      elseif MidiNote = 62 // Pad B
        SendMidiThruOnCh MidiOutsA[1]
      elseif MidiNote = 64 // Pad C
        SendMidiThruOnCh MidiOutsA[2]
      elseif MidiNote = 65 // Pad D
        SendMidiThruOnCh MidiOutsA[3]
      end
    end
    

    But this is very repetitive and ugly, but I failed yet to refactor it to be more elegant. Coming from a very powerful programming language like Ruby, I feel pretty limited here... But probably I just don't think yet in the right structures offered by Mozaic.

    Any suggestions are very welcome. :heart:

  • McDMcD
    edited July 2020

    I'll jump in on the Array topic. There are only one-dimensional arrays that hold up to 1024 values. The index used with any array name just indicates the starting point.

    MidiOuts[0] = [0, 1, 2, 3] // Pad A
    MidiOuts[1] = [4, 5, 6, 7] // Pad B
    MidiOuts[2] = [8, 9, 10, 11] // Pad C
    MidiOuts[3] = [12, 13, 14, 15] // Pad D

    Could be:

    MidiOuts[0] = [0, 1, 2, 3] // Pad A
    MidiOuts[4] = [4, 5, 6, 7] // Pad B
    MidiOuts[8] = [8, 9, 10, 11] // Pad C
    MidiOuts[12] = [12, 13, 14, 15] // Pad D

    But it's often best to create multiple arrays that can all benefit from the same index later:

    index = 0
    MidiChannel[index] = MIDIChannel
    MidiNote[index] = MIDIByte1
    MidiVelocity[index] = MIDIByte2
    MIDITimeStamp[index] = SystemTime

    This can provide one of there benefits of a 2-dimensional array with a common indexing relationship between the data.

  • This is a good idea. I will experiment with it.

    Another question: can I assign strings (text) to variables? Something like inputMode = "Xyz" and then check upon it like if inputMode = "Abc"? It seems I can't get it to work...

  • wimwim
    edited July 2020

    @josh83 said:
    Another question: can I assign strings (text) to variables? Something like inputMode = "Xyz" and then check upon it like if inputMode = "Abc"? It seems I can't get it to work...

    Nope. Numbers only.

    But, you can assign a constant value to a variable (@OnLoad is a good place to do this), then refer to the constant later on in the code. For instance.

    @OnLoad
      abc = 1
    @End
    
    @OnMidiInput
      if inputMode = abc
        // Do something
      endif
    @End
    

    I do this a lot to make coding easier and more clear.

  • That's very useful. Thank you.

    It's quite a unique experience to try to "unlearn" all those powerful features from "real" programming languages and dive back into such a primitive language like Mozaic. :neutral: Hell, I miss variable scopes, functions/methods, and all this stuff! :tongue: But I'm very grateful that there's Mozaic, and I'm eager to use it to its limits! :smiley:

  • wimwim
    edited July 2020

    @josh83 said:
    That's very useful. Thank you.

    It's quite a unique experience to try to "unlearn" all those powerful features from "real" programming languages and dive back into such a primitive language like Mozaic. :neutral: Hell, I miss variable scopes, functions/methods, and all this stuff! :tongue: But I'm very grateful that there's Mozaic, and I'm eager to use it to its limits! :smiley:

    I wouldn’t call it primitive. I’d call it intentionally limited in scope to reduce the learning curve for non programmers. ;) (and to keep the footprint light)

  • Different words, but essentially (to me) the same. Primitive doesn't mean "bad" in this situation. :smile:

  • Heh, heh, heh B) As someone staggered by the learning curve to integrate Swift, Objective-C and C++ to make even a basic iOS AUv3, I’ve come to love the relative scope of Mozaic. 😂

  • edited July 2020

    I'm pretty sure that you would have staggered even more with a limited programming language like Mozaic. An AUv3 plugin is much more complex than handling some MIDI signals, and thus a limited language would not be very helpful but would make things even more confusing. :smiley:

  • Dear @wim, I finally found the time to work a little on my script. It nicely sends now custom MIDI notes depending on the "space" selected. But sadly, Group the Loop seems not to accept it. Can you please take a look at it here, maybe you'll spot the critical code?

    https://forum.grouptheloop.com/index.php?p=/discussion/322/assigning-custom-midi-notes-from-my-blueboard-altered-through-aum-and-mozaic-doesnt-work/p1?new=1

    Thanks a lot! :smile:

  • _ki_ki
    edited July 2020

    @josh83 Just had a brief look at the Mozaic script listing.

    At the end of SendNoteFromCurrentSpace you use MidiByte1 twice in your midi-sending command. Since this event is called during the MidiNoteOff, thats two MidiNote-Off commands send.

    I assume you want to send a note-on and a note-off, so you could use something like

      SendMidiNoteOn MIDIChannel, noteToSend, 100
      SendMidiNoteOff MIDIChannel, noteToSend, 0, 50
    

    The last parameter 50 for the SendMidiNoteOff applies a delay, so that NoteOn and NoteOff are not send at the same timeframe, which could lead to problems for the receiver.

  • Thanks for giving advice, @_ki! I added the delay, but it doesn't help. :neutral:

    I have created a short video recording, demonstrating the issue:

  • Interesting fact: when I try to assign the modified MIDI signals inside AUM, it doesn't work either. In this case though, the received signal looks like it is indeed applied to a function, but when pressing the respective pad on the BlueBoard, the function is not executed.

    And again: when I switch the MIDI input from Mozaic to "plain ol'" BlueBoard, it works fine. So something with the MIDI that is sent from Mozaic definitely isn't correct yet.

  • _ki_ki
    edited July 2020

    Do you have a Midi Monitor to validate the output of the Mozaic script is what you expected ?

    if not, you can use this short monitor script in another instance:

    @OnMidiNoteOn
      Log SystemTime, { NoteOn  c},MIDIChannel,{ n},MIDINote,{ v},MIDIVelocity 
    @End 
    
    @OnMidiNoteOff
      Log SystemTime, { NoteOff c},MIDIChannel,{ n},MIDINote,{ v},MIDIVelocity 
      Log
    @End  
    

    and assign its input to the output of the blueboard-mozaic-script.
    I expect the other script to send a NoteOn and then sometwhat later a NoteOff (If you applied the changes i mentioned in the posting above)

  • Since i don‘t have a blue-board, i did a short script in Mozaic that uses the pads to send the 4 blue-board notes.

    Sending this to your script (with the SendMidiNoteOn/SendMidiNoteOff modification i suggested above) and the output of your script to the mini monitor script i get the following output:

    The 4 spaces are activated by longer pressing the pads and then shot-press sends out 4 different note configurations 0-3 for space 0, 4-7 for space 1, 8-11 for space 3 and lastly 12-15 for space 3. The systemtime output in the mini monitor confirms, that the send notes are active for about 50 msec.

    As i don‘t own Group-The-Loop, i can‘t test any further - but in general, your script and the long-press detection and scene switching seems to work :)

  • edited July 2020

    Thanks for your effort to check my script.

    It is strange: when running the script with Mozaic open, it seems to work perfectly: every key press does exactly what I expect it to do (at least the Log messages of my script indicate this). But when I close the Mozaic script and check what MIDI signals are received by other applications (be it Group The Loop, or AUM, or your little Logger-Script), some of the MIDI signals seem to be received, others are not.

    As you don't have Group the Loop, can you please check out whether you are able to assign some of AUM's controls (e.g. "Play") to one of the MIDI generated by my script? This didn't work for me, too.

  • @josh83 said:
    Thanks for your effort to check my script.

    It is strange: when running the script with Mozaic open, it seems to work perfectly: every key press does exactly what I expect it to do (at least the Log messages of my script indicate this). But when I close the Mozaic script and check what MIDI signals are received by other applications (be it Group The Loop, or AUM, or your little Logger-Script), some of the MIDI signals seem to be received, others are not.

    As you don't have Group the Loop, can you please check out whether you are able to assign some of AUM's controls (e.g. "Play") to one of the MIDI generated by my script? This didn't work for me, too.

    Hey, sorry for being out of the loop today. I knew I didn't have enough time to look at it fully during the day, so I stayed away until I did have time. I'll take a peek now.

    I remember having to go through some hoops due to how BlueBoard handles presses when I wrote my Blueboard MIDI Ramper scripts. Maybe I can clear the cobwebs off of some that code. I'll let you know what I find.

  • wimwim
    edited July 2020

    @josh83 - With @_ki 's fix for the Note-On / Note-Off, it's working fine for me with GTL. The only difference is I used a 10ms delay rather than 50ms for the note-off. Tested on iPad Air 2 and iPhone 7s, both on iOS 13.5.1.

    (Note: I'm doing my tests with the BB on the table, pressing the switches by hand so I can feel the clicks. That might be a good idea if you haven't been doing that - just to be sure it's not simply missed presses.)

  • BTW, nice idea with the long-presses to set different scopes for the buttons.

  • @wim said:
    @josh83 - With @_ki 's fix for the Note-On / Note-Off, it's working fine for me with GTL. The only difference is I used a 10ms delay rather than 50ms for the note-off. Tested on iPad Air 2 and iPhone 7s, both on iOS 13.5.1.

    Thanks for investigating this, but doesn't change anything for me. Pretty annoying. :frowning:

  • wimwim
    edited July 2020

    It has to be something about your setup. Mozaic doesn’t act differently when not in the foreground or with different apps.

    You’re in Bluetooth Midi mode for sure? Not using the iRig app?

    Rebooted phone?

    No other midi devices active?

    You’re sure you pressed Upload after fixing the code?

    Sorry for asking the obvious, but sometimes throwing things out like that sparks other thoughts.

  • @josh83 I can confirm that your script is able to toggle AUMs channel mutes/solos. I assigned notes 0 + 1 to toggles mutes of ch1/2 and notes 4/5 to toggles their solo button. Worked like a charm.

    .

    Here the updated version of your script that i used in all the tests
    With the SendMidiNoteOn/Off change using 50ms delay like @wim and and an added icon-name to better distinguish the 3 Mozaics instances for the different part of my test

    @OnLoad
      SetShortName {Joshua} 
    
      Log {Joshua wants to be a pop band}
      // BlueBoard (BB) pads
      bbA_in = 60
      bbB_in = 62
      bbC_in = 64
      bbD_in = 65
    
      // BlueBoard pad states
      bbDown = 100
      bbUp   = 0
    
      spaceA = 0
      spaceB = 1
      spaceC = 2
      spaceD = 3
    
      activeSpace = spaceA
    
      longTapTime = 200 // Milli seconds
    @End
    
    @OnMidiNoteOn
      DownStartTime = SystemTime
    @End
    
    @OnMidiNoteOff
      If SystemTime - DownStartTime <= longTapTime
        Call @ShortTap
      Else
        Call @LongTap
      Endif
    @End
    
    @ShortTap
      // Log {Short Tap: }, MidiNote
    
      Call @SendNoteFromCurrentSpace
    @End
    
    @LongTap
      // Log {Long Tap: }, MidiNote
    
      Call @ActivateSpace
    @End
    
    @ActivateSpace
      if MidiNote = bbA_in
        activeSpace = spaceA
      elseif MidiNote = bbB_in
        activeSpace = spaceB
      elseif MidiNote = bbC_in
        activeSpace = spaceC
      elseif MidiNote = bbD_in
        activeSpace = spaceD
      else
        Log {ERROR - Unexpected MidiNote: }, MidiNote
      endif
    
      Log {Activated space: }, activeSpace
    @End
    
    @SendNoteFromCurrentSpace
      baseNote = -1
      noteToSend = -1
    
      if activeSpace = spaceA
        baseNote = 0
      elseif activeSpace = spaceB
        baseNote = 4
      elseif activeSpace = spaceC
        baseNote = 8
      elseif activeSpace = spaceD
        baseNote = 12
      endif
    
      if MidiNote = bbA_in
        noteToSend = baseNote + 0
      elseif MidiNote = bbB_in
        noteToSend = baseNote + 1
      elseif MidiNote = bbC_in
        noteToSend = baseNote + 2
      elseif MidiNote = bbD_in
        noteToSend = baseNote + 3
      endif
    
      SendMidiNoteOn MIDIChannel, noteToSend, 100
      SendMidiNoteOff MIDIChannel, noteToSend, 0, 50
      Log {Sent Midi: }, noteToSend
    @End
    
  • I found the problem!

    I used:

      SendMidiOut MIDIByte1, noteToSend, 100
      SendMidiOut MIDIByte1, noteToSend, 0, 100
    

    @_ki used:

      SendMidiNoteOn MIDIChannel, noteToSend, 100
      SendMidiNoteOff MIDIChannel, noteToSend, 0, 100
    

    Obviously not the same thing. But what exactly is the difference?

    Boah guys, I'm so relieved that things are slowly getting into place... Soon I will be doing my first looping sessions at home, yeah! Thanks so much for your support. :heart:

  • _ki_ki
    edited July 2020

    I tried to explain the problem in my initial post:

    The MidiByte1 contains command and channel (in upper and lower nibble) and that code passage was called during the OnMidiNoteOff event - so for both SendMidiOut lines it will send out a NoteOff command.

  • @_ki said:
    I tried to explain the problem in my initial post:

    The MidiByte1 contains command and channel (in upper and lower nibble) and that code passage was called during the OnMidiNoteOff event - so for both SendMidiOut lines it will send out a NoteOff command.

    Damn, while I spotted that you added a delay of 50ms, I wasn't aware that you used another method than I did. :astonished:

    Thanks a lot for explaining it up there already, @_ki!

  • By the way, is it possible to somehow "talk" to the BlueBoard and tell it to lighten some of the pads? I know that when connecting through the BlueBoard app, the pads glow when pressing them. Is there a way to manipulate this behaviour through Mozaic/MIDI?

  • Or maybe asked differently: although I see most of the stuff that I manipulate through MIDI directly in the GUI of Group the Loop, some of the stuff I don't get any feedback, like switching between my custom spaces in BlueBoard. It would be great to get some kind of visual feedback though. Maybe there is a way to send messages through the iOS notifications center? It would clog it up for sure, but it could be a pragmatic way to transport messages from Mozaic to my screen regardless of the app that is currently in the foreground...

  • _ki_ki
    edited July 2020

    At first i thought one could just toggle the colors of Mozaics according to activeSpace - but from your description i understand that you normally don‘t see Mozaics UI because GroupTheLoop is in the foreground. Moazic can‘t send notifications, only midi output.

    I also looked up the iRig Blueboard manual, but there are no sysex or whatever commands to light up the blueboards pads.

    To further follow your notification idea, i checked that pythonista is able to send such notifications - but unfortunately it can‘t read midi. To get midi into pythonista, one would need MidiFire that offers a module to encapsulate incomming midi into UDP packets to localhost, that could be picked up by pythonista to then fire a notification.

    Having two more apps running in the background and doing a kind of a round-trip for the data until its shown as notification seems a bit of overkill. And i don‘t know if pythonista is able to run in background mode. I also don‘t own midifire to really try the midi to UDP connection.

Sign In or Register to comment.