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.

StreamByter Orchestra in C Major with Oboe, Cello Soloists

2»

Comments

  • Hey SB geniuses: what's the lightest weight way to script "play all notes one octave higher"?

  • @lukesleepwalker said:
    Hey SB geniuses: what's the lightest weight way to script "play all notes one octave higher"?

    The SB Geniuses take Monday's off to write code. So, you'll get my newbie answer using 3 statements.

    IF M0 < A0               
      MAT M1 = M1 + C
    END
    

    WHAT"s Going On?

    You need to think in Hexadecimal like Computers do.

    1,2,3,4,5,6,7,8,9,A,B,C,D,E,F 
    

    Think of A = 10 and use your fingers
    and sing that song to reach F=15

    GUESS WHAT's 16 in Hex... 10. Think of on odometer that
    runs from 0-F. The next number after 000F is 0010.

    Note Off Messages start with 80 and Note On's 90
    Both are less than A0.

    IF M0 < A0
    

    A leading "M" means it's the Message Byte passing by
    M0 is the message type On, OFF, CC, PC, SYSEX, Pitch Bend,...

    MAT starts a MATH addition. You want to change the NOTE value up 1 octave. The MIDI NOTE is in M1 (the byte after the message type). So add 12 half-steps to the original NOTE.

    MAT M1 = M1 + C 
    

    What is 12 in Hex? Fingers + Alphabet song for the numbers past 9. 12 is more than 9 so 9,A,B,C. It's C see? So add plus 'C' to every NOTE.

    and END the IF section

    END
    
  • 👍🏻 Should work. I don‘t think it can be done in less than 3 statements

  • Works well and thanks for generously explaining the method behind the madness!

  • @lukesleepwalker said:
    Works well and thanks for generously explaining the method behind the madness!

    You can change the C value to any number and transpose.
    The numbers can also be subtracted to transpose down.

    The third Message Byte called M3 is the Notes Velocity and they can be tweaked up or down too.

    You can learn something new everyday to offset the 5 things you will forget.

  • I'm completely stumped on another StreamByter project. I know I'm doing something stupid but I can't figure out what... my goal is to send a PC with a note on. So, I press A2 and it sends PC10, as an example.

  • I thought you solved this one based upon the SB Forum on Jan 15.

    Post your code and I have $20 that says @_Ki solves it fast.

    I'll look at it but I'm still learning. I usually mess up some HEX value by
    using Decimal because my mind can only think in powers of 10.
    If we taught kids the 16 times table and had 16 fingers this would be easy.

    I think Nic should allow decimal values to sell more product. The computer chip thinks in HEX so he's focused on not adding any code to slow down the
    MIDI processing.

    Just indicate what numbers your intending so we can compare your HEX conversions.

  • @McD said:
    I thought you solved this one based upon the SB Forum on Jan 15.

    Post your code and I have $20 that says @_Ki solves it fast.

    I'll look at it but I'm still learning. I usually mess up some HEX value by
    using Decimal because my mind can only think in powers of 10.
    If we taught kids the 16 times table and had 16 fingers this would be easy.

    I think Nic should allow decimal values to sell more product. The computer chip thinks in HEX so he's focused on not adding any code to slow down the
    MIDI processing.

    Just indicate what numbers your intending so we can compare your HEX conversions.

    Yep, I solved it for sending a CC to generate the PC (works great). But I'm trying to send a note now and it's not behaving! And now that you mention that thread, I really should be asking this question on the SB forum so that the thread remains all in one place. I keep forgetting where I post these threads... First world internet problems and all.

  • @lukesleepwalker said:

    @McD said:
    I thought you solved this one based upon the SB Forum on Jan 15.

    Post your code and I have $20 that says @_Ki solves it fast.

    I'll look at it but I'm still learning. I usually mess up some HEX value by
    using Decimal because my mind can only think in powers of 10.
    If we taught kids the 16 times table and had 16 fingers this would be easy.

    I think Nic should allow decimal values to sell more product. The computer chip thinks in HEX so he's focused on not adding any code to slow down the
    MIDI processing.

    Just indicate what numbers your intending so we can compare your HEX conversions.

    Yep, I solved it for sending a CC to generate the PC (works great). But I'm trying to send a note now and it's not behaving! And now that you mention that thread, I really should be asking this question on the SB forum so that the thread remains all in one place. I keep forgetting where I post these threads... First world internet problems and all.

    Good idea. Nic or Ki will see it there. I need to develop the habit of reading their. It's just so slow compared to this forum. It only has a new message every few days. Yawn.

  • @McD said:

    @lukesleepwalker said:

    @McD said:
    I thought you solved this one based upon the SB Forum on Jan 15.

    Post your code and I have $20 that says @_Ki solves it fast.

    I'll look at it but I'm still learning. I usually mess up some HEX value by
    using Decimal because my mind can only think in powers of 10.
    If we taught kids the 16 times table and had 16 fingers this would be easy.

    I think Nic should allow decimal values to sell more product. The computer chip thinks in HEX so he's focused on not adding any code to slow down the
    MIDI processing.

    Just indicate what numbers your intending so we can compare your HEX conversions.

    Yep, I solved it for sending a CC to generate the PC (works great). But I'm trying to send a note now and it's not behaving! And now that you mention that thread, I really should be asking this question on the SB forum so that the thread remains all in one place. I keep forgetting where I post these threads... First world internet problems and all.

    Good idea. Nic or Ki will see it there. I need to develop the habit of reading their. It's just so slow compared to this forum. It only has a new message every few days. Yawn.

    Indeed, would be great to see it pick up a bit but I always enjoy my occasional visit there. So many cool ideas...

  • _ki_ki
    edited January 2019

    Just had a peek at the source at the audeonic forum. I don‘t quite get why you defined the vars K0 - K2 since these never change and the IFs could be hard coded with their values making the code more readable :)

    Also learned that an IF can test two arrays against each other the IF M0 == K0 K1 in fact tests if M0 == K0 and M1 == K1. Nice trick i didn“t know about.
    .

    This code catches a C3 note on channel 0 and then send out a PC0

    9X XX 00 = 8X #    // Convert NoteOn with zero velocity to NoteOff
    
    IF M0 == 90 3C #   if ( inputCmd = noteOnCmd noteNrInHex ) {
      SND C0 00 #          send PC 0
    END #              }
    
    XX = XX +B #       // block all incomming midi events, only send our cmds
    

    Since the octave definition is different between apps, it could be on C2 or C4

  • @_ki said:
    Just had a peek at the source at the audeonic forum. I don‘t quite get why you defined the vars K0 - K2 since these never change and the IFs could be hard coded with their values making the code more readable :)

    Also learned that an IF can test two arrays against each other the IF M0 == K0 K1 in fact tests if M0 == K0 and M1 == K1. Nice trick i didn“t know about.
    .

    This code catches a C3 note on channel 0 and then send out a PC0

    9X XX 00 = 8X #    // Convert NoteOn with zero velocity to NoteOff
    
    IF M0 == 90 3C #   if ( inputCmd = noteOnCmd noteNrInHex ) {
      SND C0 00 #          send PC 0
    END #              }
    
    XX = XX +B #       // block all incomming midi events, only send our cmds
    

    Since the octave definition is different between apps, it could be on C2 or C4

    cool. I took that $20 bet and will use the money to buys some more Apps.
    4Pockets FX are on the top. Doug's videos tell me what to buy. I am a sheep.

  • edited February 2019

    @_ki Thanks for the help above. You are correct that hard coding the note values is a better way to go. I've got another puzzle I'm working on (posted to Audeonic forum too):

    I want to create conditional states between two controllers. On one controller I want to “filter” notes I play on the second controller by playing the notes F2, G2, A2, B2. Every time I press A2 on the first controller, I then press C1 on the second controller and it is changed to C5. Every time I press G2, I want C1 to be played as D5. Every time I press B2, I want C1 to be changed to E5. And I press F2, C1 becomes F5.

    For the same four filter notes I want D1 to be transformed as such:
    press A2 — D1 becomes C6
    press G2 — D1 becomes D6
    press B2 — D1 becomes E6
    press F2 — D1 becomes F6

    I can get this working with a conditional with a single controller but the hard part is having the conditional apply across two controllers (I have other scripts set up for each of the controllers that I need to preserve).

  • @lukesleepwalker said:
    I can get this working with a conditional with a single controller but the hard part is having the conditional apply across two controllers (I have other scripts set up for each of the controllers that I need to preserve).

    @_Ki - is this a problem that Global Variables could solve: creating a global variable for the state of the conditional? Then changing it once applies to all the Scripts running that see the change variable and act accordingly?

  • _ki_ki
    edited February 2019

    Regarding globals: Do you want to handle several conditionals with just one script, or each of them in a seperate script but depending on a common condition ?

    Sorry, i first have a lot of questions before suggesting anything :)

    • are the control notes and „play“ notes comming in on the same midi channel ?
    • do you want to supress the ‚control‘ notes ?
    • is the applied offset the same for all play notes ? (prob not as b2 transforms C1 => E5 but also D1 => E6 - someach ‚play’ note has a different ‚out‘ note ?
    • Are there many ‚play‘ notes (up to maybe all except the control notes) or is the number of ‚play’ notes limited ?
    • Will there be just the four filter notes or more in the future ?

    Probabbly Nic already wrote a solution (or directing to it), i better should have a look at Audeonic forum before asking that much :)

    .... okay... had a peek, it seems as if sou just want that 4 filter notes and two ‚play‘ notes in a script without too many bling-bling-extra features.

    I would store the two offsets that need to be applied for the play notes into vars and if the two play notes arrive apply the offset. If a filter note arrives, change the two offsets with a single assign and block the note.

    All in all 2 IF/END for the play notes and 4 IF for the filter notes.

    The IFs are probably inside a IF noteOn or NoteOff cmd block (there is a special for for this like MT ?) as at least the play modification needs also be applied to the NoteOff. Thd filters should ideally only react to NoteOn, but also reacting to NoteOff does not form a problem as long as thee filter notes do not overlapp or are directly adjoining in time (and therefore NoteOff/NoteOn of another filter might be mixed up by the host during midi-note-deliver to StreamByter)

  • Answers interspersed. Thanks for engaging.

    @_ki said:
    Regarding globals: Do you want to handle several conditionals with just one script, or each of them in a seperate script but depending on a common condition ?

    Sorry, i first have a lot of questions before suggesting anything :)

    • are the control notes and „play“ notes comming in on the same midi channel ?

    Yes, channel 10.

    • do you want to supress the ‚control‘ notes ?

    No, want them to play too.

    • is the applied offset the same for all play notes ? (prob not as b2 transforms C1 => E5 but also D1 => E6 - someach ‚play’ note has a different ‚out‘ note ?

    The notes are triggering samples so if it's easier, I could aim for a common offset, say C1 to C5. But the filters would have to be four octaves plus one, plus two, etc and D1 would have to offset five octaves to "avoid" the C5 filtered notes.

    • Are there many ‚play‘ notes (up to maybe all except the control notes) or is the number of ‚play’ notes limited ?

    The play notes are limited to the eight I mentioned.

    • Will there be just the four filter notes or more in the future ?

    Just the four filter notes for now.

    Probabbly Nic already wrote a solution (or directing to it), i better should have a look at Audeonic forum before asking that much :)

    .... okay... had a peek, it seems as if sou just want that 4 filter notes and two ‚play‘ notes in a script without too many bling-bling-extra features.

    I would store the two offsets that need to be applied for the play notes into vars and if the two play notes arrive apply the offset. If a filter note arrives, change the two offsets with a single assign and block the note.

    All in all 2 IF/END for the play notes and 4 IF for the filter notes.

    The IFs are probably inside a IF noteOn or NoteOff cmd block (there is a special for for this like MT ?) as at least the play modification needs also be applied to the NoteOff. Thd filters should ideally only react to NoteOn, but also reacting to NoteOff does not form a problem as long as thee filter notes do not overlapp or are directly adjoining in time (and therefore NoteOff/NoteOn of another filter might be mixed up by the host during midi-note-deliver to StreamByter)

    This last paragraph contains the complexity that is over my head. I can figure out how to achieve one state but the second, third, and forth state are hard because they require complex on/off scenarios.

  • edited February 2019

    Guys, if you want some more info or ideas on the subject, there's somebody who's spent ages on connecting music theory with generative algorithms.
    Read a great resource here:
    https://patents.google.com/patent/US20070074620A1/en
    We won't be allowed to sell it, but we're free to experiment with the idea :smiley:

  • TL;DR StreamByter could be a tool everyone wants to have in their toolbox. If reading makes you upset that's what follows with more advocacy and details.

    But... StreamByter is a different beast. It's a lot like a programmable MIDI FX Black Box.
    It must be fed MIDI events and the program reacts to those events. I suppose the most general event could be a start signal for the type of algorithmic thinking that is referred to in this patent. But the StreamByter programmer has severe limits and @_Ki has mastered more of what can and can't be done that any other user that participates here.

    He's looking for input to help him know what kinds of tools people want but sometimes they request Applications that are best developed as standalone or AUv3 Apps using Objective-C or Swift and "Platforms" like AudioKit to save having to build it from scratch.

    What is possible with StreamByter has barely been investigated and I think we'll see some really great Scripts this year that will make it a must have AUv3 MIDI FX purchase.
    It' really good at coding scale, arpeggio and chord applications for example. Rhythm apps seem a lot better served by the Apps market but many of the useful tools in something like the Rozeta Suite could be coded in StreamByter but ideally similar but unique scripts would be better. Take @brambos suite of MIDI FX ideas as a starting point for a black box that would follow Cells, Baseline, Particles, etc and use those events to generate chords to augment the baselines or arpeggiate chords driven by a Cells pattern. A popular script could just as well become the kernel of an idea for @brambos to code up another Tool is his suite.

    The biggest barrier to StreamByter coding is the close to the metal nature of the language and the accepted syntax. There's currently no "Else" to match the IF and any old school programmer will know that just means a lot of extra IF's to perform the code that makes sense for a False result from an IF. There's not syntax checking behavior in the StreamByter editing window so you miss some small detail and it adds "ERR" to the line where the problem exists. In other words it's like a torture device for a real programmer.

    To even understand the manual you must have some programming experience to get the vocabulary being used to describe what statements are allowed.

    But a small group of real programming hobbyists will emerge and make things that can be shared. Ideally StreamByter add a feature to browse a Global Library of scripts and let user load one and see what it does when driven by Rozetta Bassline or Physicles (which is free due to some Spanish regulations about outside income for government employees).

    A lot of the ideas implemented in Arranger Workstations from Korg, Yamaha, Casio could probably be implemented in StreamByter code with enough effort.

    1 Note - major chord in that note
    2 Notes - minor chord on the lower note
    3 Notes - 7th Chord
    4 Note - diminished

    As an example. And StreamByter can be fed from another streambyter script so Bassline can send note and those in C2-B3 generate single notes with that Root and the next script produces a Major Chord. Notes from C3-C4 cause a Minor Chord etc. This maps the octave input to the chord type and lets the user program the whole chain of FX using Rozeta Bassline. Repeated notes and rests in Bassline can make rhythm patterns of chords played.

    There is an infinite number of possibilities. We just need to reward the efforts of the hobbyists and push for more accessible tools to open up this form of generative music.

    There's similar inspiration borrowing from TC-Data or using TC-Data as the input device for the SB Scripts in AB3, AUM or Cubasis rather than the standard controllers.

    We're just on the cusp of having user programmable tools for music "Application/FX" creations. After the initial $8 investment a wealth of new scripts will be useable overtime.
    More users will get the attention of the hobbyists that like to see people use their work and give feedback or just say "Thanks". It's amazing how many programmers write code to stay sharp and solve puzzles and they would love to get the occasional pat on the back for making something that works well and delights a creative person to make something that programmer probably can't because they don't think about music they way a creative musician might.

    We all have a support role to play: sound designers, programmers, scripters, reviewers and on down the line across the disciplines of the IOS Arts.

  • edited February 2019

    Programming MidiFire/StreamByter reminds me of coding in Lemur.
    The two main reasons why I would start a somewhat larger project in Lemur are hands-on control and the built-in sequencing features. You can do all MIDI processing in Lemur, using a somewhat less cryptic language than the above, but being able to change parameters of your algorithm on the fly makes it a lot more fun and playful experience, plus you can create your own algorithmic sequencers/arpeggiators/event generators.
    With these functions you have direct access to the internal timing clock in Lemur:
    clock_getbeats(target)
    clock_getbpm(target)
    clock_isrunning(target)
    clock_pause(target)
    clock_reset(target)
    clock_setbpm(target, bpm)
    clock_setoffset(target, ms)
    clock_start(start)
    clock_stop(target)

    What's more: This system works anywhere, and if you need it in your AUv3 pipe, you'd re-route Lemur using Victor Porof's new MIDI Tools.

  • I took a look at Lemur and was put off by a couple things:

    1. price (I have this $10 rule to keep me from throwing too much money at my iPad)
    2. lack of significant updates since announcement (is it growing a user base)
    3. focus on being a GUI generator when I need that screen real estate for other things

    Also people make UI's with Lemur... do they share the work? There was a complaint about not storing SysEx bigger than some small number and it never was addressed.
    "Too hard." You want hard? Make something work as an AUv3 MIDI Plug-in.

    Anyway. I could be convinced to reconsider Lemur but only when I have a month when there are no great $10 apps and after I get NS2.

  • @rs2000 said:
    Programming MidiFire/StreamByter reminds me of coding in Lemur.
    The two main reasons why I would start a somewhat larger project in Lemur are hands-on control and the built-in sequencing features. You can do all MIDI processing in Lemur, using a somewhat less cryptic language than the above, but being able to change parameters of your algorithm on the fly makes it a lot more fun and playful experience, plus you can create your own algorithmic sequencers/arpeggiators/event generators.
    With these functions you have direct access to the internal timing clock in Lemur:
    clock_getbeats(target)
    clock_getbpm(target)
    clock_isrunning(target)
    clock_pause(target)
    clock_reset(target)
    clock_setbpm(target, bpm)
    clock_setoffset(target, ms)
    clock_start(start)
    clock_stop(target)

    Interesting. I haven't looked at Lemur in a long time. Setting it up was always a bit painful. But I'd be interested in exploring ways to make 'programming' things like this a bit less like arcane magic and lower-threshold.

  • @McD nails it in his description of the strengths and weaknesses of SB. The documentation is written by someone who already knows too much to explain it to an outsider. I'm not a programmer but I've written a bit of JavaScript, for instance. The SB manual does not give me the info I need to grope my way through the first trees of the forest.

    What we need is a modular conditional MIDI AUfx tool that makes the if/thens easy enough for a non programmer to grok. @brambos or @blueveek might get there one day?

  • @brambos said:

    @rs2000 said:
    Programming MidiFire/StreamByter reminds me of coding in Lemur.
    The two main reasons why I would start a somewhat larger project in Lemur are hands-on control and the built-in sequencing features. You can do all MIDI processing in Lemur, using a somewhat less cryptic language than the above, but being able to change parameters of your algorithm on the fly makes it a lot more fun and playful experience, plus you can create your own algorithmic sequencers/arpeggiators/event generators.
    With these functions you have direct access to the internal timing clock in Lemur:
    clock_getbeats(target)
    clock_getbpm(target)
    clock_isrunning(target)
    clock_pause(target)
    clock_reset(target)
    clock_setbpm(target, bpm)
    clock_setoffset(target, ms)
    clock_start(start)
    clock_stop(target)

    Interesting. I haven't looked at Lemur in a long time. Setting it up was always a bit painful. But I'd be interested in exploring ways to make 'programming' things like this a bit less like arcane magic and lower-threshold.

    I agree. That's why I come back to Lemur only when I have enough time.
    Please have a look at http://lemur.boards.net.
    This friendly guy has posted a config file for the free "Visual Studio Code" editor that can help a bit by listing commands while typing, including valuable examples.
    He has also started to provide an alternative to the now dead svg2jzml site that allows for importing custom SVG shapes in a Lemur template.

  • I was just tinkering with Cells and Scaler and I think Cells could benefit from a Manual play mode. That is, I could advance through the cells by manually playing a note on my controller. Unless I'm missing something, @brambos and this is already possible?

  • Anyone think a walking bassline is possible using a variation on this script? It's really just an elongated strum--but getting the feel right would be the tough part, right? I just gave it a go and got kinda close but it FELT mechanical.

  • @lukesleepwalker The feel or groove of a walking baseline is hard to programm. Its a not only combination of rythmic variation of the beat division (1/16, 1/8 dotted, 1/4 tripletts) but also one needs to apply swing to bring the bassline to life...

    Maybe one could split the problem into a note/bassline generating script which is fed by a rythm generating script (or other midi tool)

Sign In or Register to comment.