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.

MIDI buffer - does this app exist?

What I am interested in is an app that would take in note input, store them in a buffer, and after some threshold or trigger, release all notes from buffer.

Easy use case: app waits for midi input. after any 4 notes reach the input, they are released from the buffer as a chord.

Or!

The notes build up in the buffer. When a CC LFO triggers the buffer to release, the notes then release in quick succession, ie. 1/32nd notes.

I've been playing around with the probability setting on Cality, setting it low, and playing with note streams from other MIDI Au sequencers. This would be another cool tool in the MIDI AU toolbox to pipe these note streams in to.

Is there anything currently that does this?

Maybe it could be coded in Bram Bos's coming app? But I bet a developer who wanted to run with this idea could come up with a great UI and implementation to allow for a number of different possibilities.

«1

Comments

  • I don’t recall any app like that. But it could be done with a StreamByter script. I bet if you asked over on the Audionic StreamByter forum, someone would code one, or point you to one if it already exists.

  • edited April 2019

    Yes, this should be fairly easy in Mozaic. I'm almost at a point where I can start requesting suggestions for demo presets, so I'll keep this one in mind.

  • @brambos said:
    Yes, this should be fairly easy in Mozaic. I'm almost at a point where I can start requesting suggestions for demo presets, so I'll keep this one in mind.

    woot!

  • edited April 2019

    @wim @brambos I think I will hold out for Mozaic. StreamByter looks too advanced for me, and i'd appreciate the visual interface as well.

  • wimwim
    edited April 2019

    @bcrichards said:
    @wim @brambos I think I will hold out for Mozaic. StreamByter looks to advanced for me!

    It can be advanced, or simple, depending on what you want to do. What you want to do is definitely advanced. However, I bet you’d get someone writing a script for you within a few days without any effort on your part if you asked.

    I’m totally looking forward to Mozaic too! Your idea would be a fun test/learning case that I’d probably try just for fun.

  • @bcrichards said:
    @wim @brambos I think I will hold out for Mozaic. StreamByter looks too advanced for me, and i'd appreciate the visual interface as well.

    Here's a quick proof of concept. :)

    And here's the script I used for it. I've got some bugs to iron out, but it shows how you could probably achieve what you describe with just a dozen of lines of script...

    @Onload
      var0 = 0 // we'll use this to count the notes we've buffered
    @End
    
    @OnMidiNoteOn
      // store incoming midi note and velocity...
      var1[var0] = MIDINote 
      var2[var0] = MIDIVelocity 
      Inc var0 // increase the counter...
    
      if var0 = 3
        for var99 = 0 to 3
           SendMIDINoteOn 0, var1[var99], var2[var99] 
           SendMIDINoteOff 0, var1[var99], 0, 500.0
        endfor 
        var0 = 0 // reset to beginning of buffer
      endif 
    @End 
    
  • @brambos Cool!
    Nothing better than a real life example :smiley:

  • Cool. And I’m assuming you could set the number of notes before trigger variable to a knob. And do all sorts of nice things like create a variable and control for the note off delay, insert a variable for wait time in ms between triggers, etc.. I can see I’m gonna have a blast with Mozaic.

  • @wim said:
    Cool. And I’m assuming you could set the number of notes before trigger variable to a knob. And do all sorts of nice things like create a variable and control for the note off delay, insert a variable for wait time in ms between triggers, etc.. I can see I’m gonna have a blast with Mozaic.

    Yes to all of those.

    I'm currently working on the programming manual. I'll upload as soon as I have a first draft to give an idea of the bandwidth of things you can do.

  • @rs2000 said:
    @brambos Cool!
    Nothing better than a real life example :smiley:

    One thing is better... being able to buy the product being demo'ed. Pre-sale must buy if it's discounted
    for Easter. I hope we're that close.

  • Nah. I wanna pay full ride for this one. I would not like to be tempted for a lower price.

  • @brambos thanks for taking the time to do this. Super cool! Excited to dig in.

  • edited April 2019

    @brambos said:

    @Onload
      var0 = 0 // we'll use this to count the notes we've buffered
    @End
    
    @OnMidiNoteOn
      // store incoming midi note and velocity...
      var1[var0] = MIDINote 
      var2[var0] = MIDIVelocity 
      Inc var0 // increase the counter...
    
      if var0 = 3
        for var99 = 0 to 3
           SendMIDINoteOn 0, var1[var99], var2[var99] 
           SendMIDINoteOff 0, var1[var99], 0, 500.0
        endfor 
        var0 = 0 // reset to beginning of buffer
      endif 
    @End
    

    Is that playing 4 times the stored notes for 500ms at every incoming 3rd note?

  • wimwim
    edited April 2019

    It looks to me like it’s triggering the three notes all at once for 500ms when the 4th note is received.

  • edited April 2019

    @MrBlaschke said:

    @brambos said:

    @Onload
      var0 = 0 // we'll use this to count the notes we've buffered
    @End
    
    @OnMidiNoteOn
      // store incoming midi note and velocity...
      var1[var0] = MIDINote 
      var2[var0] = MIDIVelocity 
      Inc var0 // increase the counter...
    
      if var0 = 3
        for var99 = 0 to 3
           SendMIDINoteOn 0, var1[var99], var2[var99] 
           SendMIDINoteOff 0, var1[var99], 0, 500.0
        endfor 
        var0 = 0 // reset to beginning of buffer
      endif 
    @End
    

    Is that playing 4 times 3 notes for 500ms at the incoming 3rd note?

    Yeah good catch.. that for loop should be 0 to 2 (I was initially recording 4 notes, and then changed it to 3). That's what you get for trying to be too quick :D

    It should be playing 3 notes for 500ms after the counter has reached 3 (meaning we've just recorded the third note into the buffer). Then if resets the counter to 0 and starts recording again.

  • It was just for my own confirmation of script „understandingness“ :smile:

  • Watched over that @brambos example the last minutes.
    I like the logical structure. I frequently used StreamByter but never got around that language.
    It is usable - no questions asked - but at least for me not „easily logical“ all the time - and i do code for my living for > 20 years. The Mozaic version looks fine to me.
    So, i am here to beta test it :smile:
    Happily trying to convert my StreamByter scripts to whatever you name your language.

  • @brambos does the script compile only on load or use jit approach like xcode playgrounds?

  • @midiSequencer said:
    @brambos does the script compile only on load or use jit approach like xcode playgrounds?

    It compiles on load.

  • @brambos said:
    And here's the script I used for it. I've got some bugs to iron out, but it shows how you could probably achieve what you describe with just a dozen of lines of script...

    @Onload
      var0 = 0 // we'll use this to count the notes we've buffered
    @End
    
    @OnMidiNoteOn
      // store incoming midi note and velocity...
      var1[var0] = MIDINote 
      var2[var0] = MIDIVelocity 
      Inc var0 // increase the counter...
    
      if var0 = 3
        for var99 = 0 to 3
           SendMIDINoteOn 0, var1[var99], var2[var99] 
           SendMIDINoteOff 0, var1[var99], 0, 500.0
        endfor 
        var0 = 0 // reset to beginning of buffer
      endif 
    @End
    

    Realizing I never got back to bothering you with my syntax questions!

    Here's two. :) Can variables be used in for loops and can variables use letters instead of numbers? As in this edit:

    @Onload
      var0 = 0 // we'll use this to count the notes we've buffered
      varLimit = 3;
    @End
    
    @OnMidiNoteOn
      // store incoming midi note and velocity...
      var1[var0] = MIDINote 
      var2[var0] = MIDIVelocity 
      Inc var0 // increase the counter...
    
      if var0 = varLimit
        for var99 = 0 to varLimit
           SendMIDINoteOn 0, var1[var99], var2[var99] 
           SendMIDINoteOff 0, var1[var99], 0, 500.0
        endfor 
        var0 = 0 // reset to beginning of buffer
      endif 
    @End
    

    Ok, and another. Is there something like a wait command? That SendMIDINoteOff has an extra argument (vs NoteOn) feels asymmetrical and antibramian. Is something like this possible?

    SendMIDINoteOn 0, var1[var99], var2[var99] 
    Wait 500.0
    // SendMIDINoteOff's fourth argument defaults to 0 if not passed. 
    SendMIDINoteOff 0, var1[var99], 0
    
  • edited April 2019

    @syrupcore said:

    @brambos said:
    And here's the script I used for it. I've got some bugs to iron out, but it shows how you could probably achieve what you describe with just a dozen of lines of script...

    @Onload
      var0 = 0 // we'll use this to count the notes we've buffered
    @End
    
    @OnMidiNoteOn
      // store incoming midi note and velocity...
      var1[var0] = MIDINote 
      var2[var0] = MIDIVelocity 
      Inc var0 // increase the counter...
    
      if var0 = 3
        for var99 = 0 to 3
           SendMIDINoteOn 0, var1[var99], var2[var99] 
           SendMIDINoteOff 0, var1[var99], 0, 500.0
        endfor 
        var0 = 0 // reset to beginning of buffer
      endif 
    @End
    

    Realizing I never got back to bothering you with my syntax questions!

    Here's two. :) Can variables be used in for loops and can variables use letters instead of numbers? As in this edit:

    @Onload
      var0 = 0 // we'll use this to count the notes we've buffered
      varLimit = 3;
    @End
    
    @OnMidiNoteOn
      // store incoming midi note and velocity...
      var1[var0] = MIDINote 
      var2[var0] = MIDIVelocity 
      Inc var0 // increase the counter...
    
      if var0 = varLimit
        for var99 = 0 to varLimit
           SendMIDINoteOn 0, var1[var99], var2[var99] 
           SendMIDINoteOff 0, var1[var99], 0, 500.0
        endfor 
        var0 = 0 // reset to beginning of buffer
      endif 
    @End
    

    Ok, and another. Is there something like a wait command? That SendMIDINoteOff has an extra argument (vs NoteOn) feels asymmetrical and antibramian. Is something like this possible?

    SendMIDINoteOn 0, var1[var99], var2[var99] 
    Wait 500.0
    // SendMIDINoteOff's fourth argument defaults to 0 if not passed. 
    SendMIDINoteOff 0, var1[var99], 0
    

    You can’t name your own variables. To speed up the interpreter (make it predictable to identify variables in a certain format) the naming of vars is numbered like this.

    But everything can be parametrized, including for-loops... you can do this:

    for var99 = 0 to var4

    Or this

    for var99 = 0 to (Random 1, 50)

    Re: waiting. Don’t think of it as waiting. It’s more like a to-do-list you can scribble midi instructions onto. Mozaic will make sure your messages are sent out in time while you’re doing other things. Any midi message can have an (optional) delay parameter added to itself (which is indeed zero if not specified), so there is no asymmetry.

    We can schedule midi events for tomorrow if we like. Wouldn’t want the audio-thread to wait until that happens, would we? ;)

    And don't worry about the exact syntax of all functions... the IDE has code-completion so it will remind you what parameters are needed.

  • edited April 2019

    For completeness and to address the OP's request, here is a StreamByter script that will work with the current App Store version. You can use slider 1 to set the length of the outgoing notes and slider 2 to set the number of notes in the buffer dynamically. The left block label shows how many notes are currently buffered as you play them in.

    # MIDI note buffer by audeonic
    IF LOAD
      # slider 1 - variable note length (100-5000ms)
      SET Q0 LENGTH $100 $5000
    
      # slider 2 - variable number of notes in buffer (2-8)
      SET Q1 NUMBER 2 8
    
      # slider 3 - delay between notes
      SET Q2 DELAY 0 $1000
    
      ASS Q0 = $500 $3 # 500ms, 3 notes default
      ASS L80 = 0 # internal index pointer, (note count * 3)
    END
    
    # handle note on event
    9X XX 00 = 8X
    IF MT == 90
      # buffer note on, increment and block
      ASS LL80 = M0 M1 M2
      MAT L80 = L80 + 3
    
      MAT I0 = L80 / 3 # number of notes buffered
      SET LB0 I0 +D # show number of notes held
      IF I0 == Q1
        # reached note count, send buffered notes with loop
        ASS I0 = 0
        ASS I4 = 0
        IF I0 < L80 +L
          # get note number & velocity indices into I1, I2
          MAT I1 = I0 + 1
          MAT I2 = I1 + 1
    
          # send note on
          SND LI0 LI1 LI2 +DI4
    
          # send note off
          MAT LI0 = LI0 - 10
          SND LI0 LI1 00 +DQ0
    
          # next note in buffer
          MAT I0 = I0 + 3
          MAT I4 = I4 + Q2
        END
    
        # reset buffer 
        ASS L80 = 0
        SET LB0 S—-
      END
    END
    
    # block all original note ons/offs
    NX = XX +B
    

    NB @syrupcore, 1.4 of StreamByter includes the ability to name your own variables and literals. Currently in beta for expected release next week - ping me if you would like TestFlight invite.

  • edited April 2019

    @audeonic said:
    For completeness and to address the OP's request, here is a StreamByter script that will work with the current App Store version. You can use slider 1 to set the length of the outgoing notes and slider 2 to set the number of notes in the buffer dynamically. The left block label shows how many notes are currently buffered as you play them in.

    Thanks Nic. But it seems that this is playing only the last Notenheft went into the buffer - even if your commented code says „send buffered notes with loop“.

  • edited April 2019

    Maybe I have misunderstood the original request. The notes you play do not play in a loop, they just get buffered until you play the final note at which point all 3 (or whatever slider 2 is set to) are played simultaneously. The 'loop' comment means that the code runs through the buffered notes with a programming loop.

  • @audeonic said:
    Maybe I have misunderstood the original request. The notes you play do not play in a loop, they just get buffered until you play the final note at which point all 3 (or whatever slider 2 is set to) are played simultaneously. The 'loop' comment means that the code runs through the buffered notes with a programming loop.

    Well, maybe i have then :smile:
    In that case all is well. Thanks.

  • edited April 2019

    script v script!! Love it.

    Both solutions fail to consider the 1/32 tempo playback option (ie strum) - just the easier option 1 (chord of notes)

    I see this useful for rhythmic playing - e.g. play any four notes at any time & 4th will then strum them back with a tempo division of the host tempo.

    Add to that AU Parameter exposure for automation...

    Happy to throw my hat in the ring here with an AU to do this?

  • @audeonic Thank you very much!!
    You never fail to deliver :smiley: :+1: :+1:

  • @midiSequencer said:
    script v script!! Love it.

    Both solutions fail to consider the 1/32 tempo playback option (ie strum) - just the easier option 1 (chord of notes)

    You got that right!

    StreamByter doesn't (currently) know about the host tempo, but I have tweaked the script above to add a 3rd slider with a variable called 'DELAY' which lets you set the inter-note delay in ms when the buffer is triggered. I suppose I could have made this BPM - I'll leave that one as an exercise.

    I see this useful for rhythmic playing - e.g. play any four notes at any time & 4th will then strum them back with a tempo division of the host tempo.

    Add to that AU Parameter exposure for automation...

    Happy to throw my hat in the ring here with an AU to do this?

    If you think it is worth making an AU for this, that's up to you. Seems like a fairly minor feature to code a whole AU around but maybe this could be just a germ of inspiration for your next one?

  • @audeonic Nic, opening up Streambyter to include transport info from the render buffer would greatly improve its usefulness imo.
    Every AU app I write has this to access, along with AU Parameters feed through the midi event buffer.
    I’m guessing Mosaic will have these too?
    might be worth considering if there is enough interest?

  • @rs2000 said:
    @audeonic Thank you very much!!
    You never fail to deliver :smiley: :+1: :+1:

    His MidiBus library still powers Quantum & MidiSequencer!!

Sign In or Register to comment.