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.

One Finger Orchestra Mozaic Script

135

Comments

  • @McD said:

    @Jocphone said:
    Have you considered implimenting a Euclidean Rhythm generator?
    @McD replied:
    If the math is trivial I might do it.

    OK. The Math is NOT trivial.

    Actually I don't think the Maths is particularly involved but the JavaScript probably makes it look more complex than it is.

  • @Jocphone said:

    @McD said:

    @Jocphone said:
    Have you considered implimenting a Euclidean Rhythm generator?
    @McD replied:
    If the math is trivial I might do it.

    OK. The Math is NOT trivial.

    Actually I don't think the Maths is particularly involved but the JavaScript probably makes it look more complex than it is.

    You might be right that the Maths is fairly basic but converting that code to Mozaic will
    require a gifted programmer well versed in Javascript. This is the type of challenge that
    @_Ki knocks off in a couple hours.

  • @McD Maybe i'll have a look at the javascript code on the weekend - but i have to admit i already started two new Mozaic sideprojects while still not having published my initial side-project for the In-Order ARPs. I tend to daily discover new 'things don't work as intended/expected' cases while testing, forcing me to hold it back until its fixed.

    I envy your courage to go public with a beta with known bugs - these were fixed very fast either by yourself or even by community contributions. And now you already are in the 'what crazy thing can i add next phase'. :) Respect !

  • @McD said:
    v0.97 - I added 4 new "Skip Knobs" for the Chord Delays.

    This test drive is completely "Hands Off" using Riffer for MIDI input to the script.
    BPM = 20 and lots of "skips" to create seeming randomness.

    Wow, this script is huge. So many possible permutations. The rests work wonderfully.

  • @_ki said:
    @McD Maybe i'll have a look at the javascript code on the weekend - but i have to admit i already started two new Mozaic sideprojects while still not having published my initial side-project for the In-Order ARPs. I tend to daily discover new 'things don't work as intended/expected' cases while testing, forcing me to hold it back until its fixed.

    Keep on your main projects. We can re-visit the idea of Euclidean Rhythms later.

    I envy your courage to go public with a beta with known bugs - these were fixed very fast either by yourself or even by community contributions. And now you already are in the 'what crazy thing can i add next phase'. :) Respect !

    Thanks. I keep adding features and Mozaic keeps up. I'm going to re-arrange the order of the knobs... with Arp related knobs on top and the associated chord knob in the bottom.

  • @lukesleepwalker said:

    @McD said:
    v0.97 - I added 4 new "Skip Knobs" for the Chord Delays.

    Wow, this script is huge. So many possible permutations. The rests work wonderfully.

    They really opened up new territory. I haven't even started to build out the arp and chord tables and it's already got a lot of potential soundscapes just because of the rhythmic variety.

  • I was able to load Mozaic in NS2 and drive several Obsidian synths playing arp’s and chords using the internal keyboard of NS2. Now I need to try that on my phone and figure out how to record and export the resulting audio.

  • edited November 2019

    So, @McD, if you have randomly generated three pages of incomprehensible (to me) comments there must be something to this. I investigated. I buy Mozaic and then can download your work of wizardry? Excuse my ignorance... but then what do I do?? I think you have found your metier... forget that music making and arch commentary.... become the Moses in Mozaic!

  • @LinearLineman said:
    So, @McD, if you have randomly generated three pages of incomprehensible (to me) comments there must be something to this. I investigated. I buy Mozaic and then can download your work of wizardry? Excuse my ignorance... but then what do I do?? I think you have found your metier... forget that music making and arch commentary.... become the Moses in Mozaic!

    Don’t buy it! At least not until I figure out how to use it in Cubasis. Give me a couple days to check it out. I’m testing NS2 first. If you use AUM we can go now.

  • Just don’t ask me to make a video. That’s yet another application domain in some dark room down the dark hall of secrets.

  • @McD .... your wish is my command.

  • @LinearLineman said:
    @McD .... your wish is my command.

    I tried out Cubasis and the AUv3 apps are acting weird with the MIDI input.
    They seem to be playing in the wrong octaves to the point where the actual melodic content
    becomes trashed.

    I switched back to adding more features in the code.

    I can't recommend this Mosaic script for use in Cubasis until I figure out root causes for
    the behavior. NS2 acted more consistently and AUM is a dream.

    Would you consider using AUM? If you want to stick with Cubasis, wait a bit longer.

  • edited November 2019

    @McD i found a simpler method for generating Euclidean Rhythms and posted a simple patch here:

    https://patchstorage.com/joc-euclidean-rhythm/

    Mine only outputs a single midi note per beat but feel free to rip out the CalcNotes function if you think it would be useful.

  • @Jocphone said:
    @McD i found a simpler method for generating Euclidean Rhythms and posted a simple patch here:

    https://patchstorage.com/joc-euclidean-rhythm/

    Mine only outputs a single midi note per beat but feel free to rip out the CalcNotes function if you think it would be useful.

    That's great. Don't hold your breathe for me to get to this however.

    FYI: I was reading the manual and @Brambos writes this:

    Recursion
    If you enjoy living on the edge, you can even call a user event from within itself. This is called recursion, and it's incredibly risky because it's all too easy to create an infinite loop and hang your plugin. So you always have to make sure that there's a solid exit strategy built into a recursive script.
    However, in some exotic cases they can be really powerful. For example, the most common algorithm for calculating Euclidean divisions is based on recursive logic.

    I'll use your code to understand better what these rhythmic patterns are like.

    The v1.0 of the script i a massive re-organization of the knob layouts and it's really testing
    my abilities to maintain a functioning application. I find that creative use of the Logging facility is essential to develop these scripts and insure you don't have flawed logic.

    I've got the knobs layed out with Arp related parameters on the top line and the Chord related parameters on the lower line.

  • @McD said:

    @Jocphone said:
    @McD i found a simpler method for generating Euclidean Rhythms and posted a simple patch here:

    https://patchstorage.com/joc-euclidean-rhythm/

    Mine only outputs a single midi note per beat but feel free to rip out the CalcNotes function if you think it would be useful.

    That's great. Don't hold your breathe for me to get to this however.

    FYI: I was reading the manual and @Brambos writes this:

    Recursion
    If you enjoy living on the edge, you can even call a user event from within itself. This is called recursion, and it's incredibly risky because it's all too easy to create an infinite loop and hang your plugin. So you always have to make sure that there's a solid exit strategy built into a recursive script.
    However, in some exotic cases they can be really powerful. For example, the most common algorithm for calculating Euclidean divisions is based on recursive logic.

    I'll use your code to understand better what these rhythmic patterns are like.

    Hmm, my code isn't using recursion, just a simple loop. It is based on Bresenham's line drawing algorithm, which makes it sound impressive but really it is quite simple. Based on two variables num_notes and num_pulses it populates an array of size 16 with 1s and 0s. Also num_pulses is used to cut down the size of the array/sequence.

    The v1.0 of the script i a massive re-organization of the knob layouts and it's really testing
    my abilities to maintain a functioning application. I find that creative use of the Logging facility is essential to develop these scripts and insure you don't have flawed logic.

    I've got the knobs layed out with Arp related parameters on the top line and the Chord related parameters on the lower line.

    I think a good rule of thumb when learning to code is that you are writing it for other people to read. The fact that it tells a machine how to act is almost an afterthought.

  • @Jocphone said:

    @McD said:

    @Jocphone said:
    @McD i found a simpler method for generating Euclidean Rhythms and posted a simple patch here:

    https://patchstorage.com/joc-euclidean-rhythm/

    Mine only outputs a single midi note per beat but feel free to rip out the CalcNotes function if you think it would be useful.

    That's great. Don't hold your breathe for me to get to this however.

    FYI: I was reading the manual and @Brambos writes this:

    Recursion
    If you enjoy living on the edge, you can even call a user event from within itself. This is called recursion, and it's incredibly risky because it's all too easy to create an infinite loop and hang your plugin. So you always have to make sure that there's a solid exit strategy built into a recursive script.
    However, in some exotic cases they can be really powerful. For example, the most common algorithm for calculating Euclidean divisions is based on recursive logic.

    I'll use your code to understand better what these rhythmic patterns are like.

    Hmm, my code isn't using recursion, just a simple loop. It is based on Bresenham's line drawing algorithm, which makes it sound impressive but really it is quite simple. Based on two variables num_notes and num_pulses it populates an array of size 16 with 1s and 0s. Also num_pulses is used to cut down the size of the array/sequence.

    In my Rozeta Rhythm (and Ruismaker) sequencers I'm using Godfried Toussaint's original algorithm for calculating Euclidean patterns:

    http://cgm.cs.mcgill.ca/~godfried/publications/banff.pdf

    Page 3:

    But there are other ways to accomplish the same thing.

    :)

  • McDMcD
    edited November 2019

    @Jocphone said:
    I think a good rule of thumb when learning to code is that you are writing it for other people to read. The fact that it tells a machine how to act is almost an afterthought.

    At my stage of learning, I get excited by the sounds that are generated.

    My version 2.0 will be readable as I look at other well crafted scripts and apply what I learn
    about variable naming and commenting to my functioning 1.x version.

    I get frustrated with something aspects of the syntax and control:
    like the inability to generate any formatting out the output
    no facility for inputing text

    I wanted to display the 1's and 0's of a 16 element boolean array and it took a lot of
    code to log:

    ==== Arp Mask ====
    0010
    0001
    1011
    1101

    But seeing that in the logging window really helps dial-in a specific 16 pulse rhythm.
    I'm still wondering if there's a way to get it to display:

    0010 0001 1011 1101

    without having to create a massive if/elseif/endif ladder. 4 digits per line takes a lot of code
    without any concept of "strings" or something simple like an optional "no carriage return" on a Log statement.

  • @brambos said:

    @Jocphone said:

    @McD said:

    @Jocphone said:
    @McD i found a simpler method for generating Euclidean Rhythms and posted a simple patch here:

    https://patchstorage.com/joc-euclidean-rhythm/

    Mine only outputs a single midi note per beat but feel free to rip out the CalcNotes function if you think it would be useful.

    That's great. Don't hold your breathe for me to get to this however.

    FYI: I was reading the manual and @Brambos writes this:

    Recursion
    If you enjoy living on the edge, you can even call a user event from within itself. This is called recursion, and it's incredibly risky because it's all too easy to create an infinite loop and hang your plugin. So you always have to make sure that there's a solid exit strategy built into a recursive script.
    However, in some exotic cases they can be really powerful. For example, the most common algorithm for calculating Euclidean divisions is based on recursive logic.

    I'll use your code to understand better what these rhythmic patterns are like.

    Hmm, my code isn't using recursion, just a simple loop. It is based on Bresenham's line drawing algorithm, which makes it sound impressive but really it is quite simple. Based on two variables num_notes and num_pulses it populates an array of size 16 with 1s and 0s. Also num_pulses is used to cut down the size of the array/sequence.

    In my Rozeta Rhythm (and Ruismaker) sequencers I'm using Godfried Toussaint's original algorithm for calculating Euclidean patterns:

    http://cgm.cs.mcgill.ca/~godfried/publications/banff.pdf

    Page 3:

    But there are other ways to accomplish the same thing.

    :)

    Nice :smile:

    But at least half of the 'professional' programmers I work with shy away from recursion.

    Also the absense of scope in Mozaic would mean that the developer has to maintain their own stack of inputs and ouputs, or do you have another way?

  • @Jocphone said:

    @brambos said:

    @Jocphone said:

    @McD said:

    @Jocphone said:
    @McD i found a simpler method for generating Euclidean Rhythms and posted a simple patch here:

    https://patchstorage.com/joc-euclidean-rhythm/

    Mine only outputs a single midi note per beat but feel free to rip out the CalcNotes function if you think it would be useful.

    That's great. Don't hold your breathe for me to get to this however.

    FYI: I was reading the manual and @Brambos writes this:

    Recursion
    If you enjoy living on the edge, you can even call a user event from within itself. This is called recursion, and it's incredibly risky because it's all too easy to create an infinite loop and hang your plugin. So you always have to make sure that there's a solid exit strategy built into a recursive script.
    However, in some exotic cases they can be really powerful. For example, the most common algorithm for calculating Euclidean divisions is based on recursive logic.

    I'll use your code to understand better what these rhythmic patterns are like.

    Hmm, my code isn't using recursion, just a simple loop. It is based on Bresenham's line drawing algorithm, which makes it sound impressive but really it is quite simple. Based on two variables num_notes and num_pulses it populates an array of size 16 with 1s and 0s. Also num_pulses is used to cut down the size of the array/sequence.

    In my Rozeta Rhythm (and Ruismaker) sequencers I'm using Godfried Toussaint's original algorithm for calculating Euclidean patterns:

    http://cgm.cs.mcgill.ca/~godfried/publications/banff.pdf

    Page 3:

    But there are other ways to accomplish the same thing.

    :)

    Nice :smile:

    But at least half of the 'professional' programmers I work with shy away from recursion.

    Also the absense of scope in Mozaic would mean that the developer has to maintain their own stack of inputs and ouputs, or do you have another way?

    Yeah.. I second the notion of staying away from recursion. If it can be avoided, do so for your own sanity. ;)

  • @McD ... will wait. You got a good thread going. You are in your element!

  • @LinearLineman said:
    @McD ... will wait. You got a good thread going. You are in your element!

    Thanks for your patience. It Cubasis ran without any issues I'd encourage you to
    join as a knob tweaker. At some point I'll be asking you to send me some block chord
    MIDI recordings I can use for structures to encode into the Chord Table of my script.
    But first I need to make it stable and clean up the GUI. Then figure out what synths work well with it in Cubasis.

  • @McD said:

    @Jocphone said:
    I think a good rule of thumb when learning to code is that you are writing it for other people to read. The fact that it tells a machine how to act is almost an afterthought.

    At my stage of learning, I get excited by the sounds that are generated.

    My version 2.0 will be readable as I look at other well crafted scripts and apply what I learn
    about variable naming and commenting to my functioning 1.x version.

    I get frustrated with something aspects of the syntax and control:
    like the inability to generate any formatting out the output
    no facility for inputing text

    I wanted to display the 1's and 0's of a 16 element boolean array and it took a lot of
    code to log:

    ==== Arp Mask ====
    0010
    0001
    1011
    1101

    But seeing that in the logging window really helps dial-in a specific 16 pulse rhythm.
    I'm still wondering if there's a way to get it to display:

    0010 0001 1011 1101

    without having to create a massive if/elseif/endif ladder. 4 digits per line takes a lot of code
    without any concept of "strings" or something simple like an optional "no carriage return" on a Log statement.

    Best i could come up with:

    // input is bin_val
    @DisplayBinary
      pos = 1
      str = []
      for i = 0 to 15
        pos = Pow 2, i 
        bit = bin_val & pos
        if bit > 0
          str[i] = 1
        else
          str[i] = 0
        endif 
      endfor
      Log str[0], str[1], str[2], str[3], str[4], str[5], str[6], str[7], str[8], str[9], str[10], str[11], str[12], str[13], str[14], str[15]
    @End 
    

    The cursor control is hateful on iOS. You wouldn’t believe how long that line with all the str[] access took!

  • _ki_ki
    edited November 2019

    @Jocphone That's nearly what i would have come up with.

    Instead of using the Pow function (internally quite computing intensive) several times in the loop, i would set up a mask variable that get shifted in the loop. If the str array is filled with 0's with a fast FillArray, one only needs to add the 1's. I have also added spaces every 4 bits:

    @OnLoad
      arpMask = 0x8376
      Call @DisplayArpMask
    @End
    
    
    @DisplayArpMask // param arpMask
      _mask = 1
      FillArray _str,0,16
      for i = 0 to 15
        if arpMask & _mask
          _str[i] = 1
        endif
        _mask = _mask * 2
      endfor
      Log {ArpMask = },_str[0], _str[1], _str[2], _str[3],{ },_str[4], _str[5], _str[6],_str[7],{ },_str[8],_str[9], _str[10], _str[11], { },_str[12], _str[13],_str[14], _str[15]
    @End
    

    @McD Outputs ArpMask = 0110 1110 1100 0001 in the Log window

    (PS: edited variable name style to use _ as first letter for local variables which are only used inside a single event)

  • @Jocphone said:
    Log str[0], str[1], str[2], str[3], str[4], str[5], str[6], str[7], str[8], str[9], str[10], str[11], str[12], str[13], str[14], str[15]

    @_ki said:
    @Jocphone That's nearly what i would have come up with.

    Log str[0], str[1], str[2], str[3],{ },str[4], str[5], str[6],str[7],{ },str[8],str[9], str[10], str[11], { },str[12], str[13],str[14], str[15]

    Thanks guys! I was close to these excellent approaches.

    It just didn't occur to me to output "white space" by wrapping it in { }'s.

    My approach outputs all combinations from 0000 to 1111 as {0000} to {1111}.
    I'm still glad I found a solution to display my Logical Masks before reading the right answer.
    I will take away from this advice with a much better understanding of how to make better, readable and more efficient Mozaic scripts (or "tiles" since Mozaic's are made from small "tiles").

  • Hi @McD , I like your idea of combining an arpeggiator and a chordulator in your mcOrchestrator script! But before you go on implementing new functionallity, I hope you will investigate your code as it is now and make the script more 'robust' and reliable, because there are bugs and a maybe-bug:

    The bugs:

    • hanging notes (ouch!) when using longer notes as input with instruments with 'pad'-like sounds (longer then delay=200 in noteoff-messages?). @_ki mentioned this problem earlier and gave you hints to solve it... (for the time being maybe a AllNotesOff-message-trigger with the SHIFT-button?);
    • you don't use the SetKnobValue function at all, so reloading your script in Mozaic after saving in a host, resets the knobs on their default values and these values are not visible after executing the default LabelKnob functions...
    • you don't initialize your var 'init' with a (whatever) value after 'if Unassigned init' (in OnLoad), thus 'init' is never 'assigned'!

    The maybe-bug:
    There seems to be no relationship between the arpeggiator and the chordulator... I have to dial the Arp- and Chordknob to the same value and only then the result sounds 'consonant'; is this by design? And why start the Arp on OnMetroPulse instead of on OnMidiInput?

    Small tip:
    Your very long MyLabelPPQNKnob and MyLabelPulsesKnob-procedures could be much shorter! Like this:
    MyLabelPPQN
    LabelKnob PPQNKnob, {PPQN=}, PPQN // values 0 - 24
    End
    MyLabelPulsesKnob
    LabelKnob PulsesKnob, {Pulses=}, Pulses // values 0 - 24
    End

    Thank you.

  • @Harro said:
    Hi @McD

    Thanks. That is a great list of recommendations for improving the code quality. I know I dropped a buggy, poorly designed script on PatchStorage before it's a quality design and implementation. If you've heard my musical postings on the Forum you'll recognize my
    total lack of attention to "production values". I'm a hack and I know it.

    But making scripts do anything is fun and sharing them for comment is, in my opinion,
    the best way to learn from your mistakes. I have benefitted from the early efforts and I will now turn my attention to making what I have limping along perform better and with more predictable results.

    To me this biggest problem with Mosaic is the small community of users. The only solution is
    to attract more users (of all types) and encourage adoption of this amazingly powerful app.
    Writing scripts is challenging and the only way to get more beginner's to attempt it is to
    encourage their efforts to try. And continue to assist them in their learning process as @wim, @_ki, @alfred and you are doing for me.

  • McDMcD
    edited November 2019

    I have uploaded v1.beta of the script.

    All 22 knobs have functions now:
    Top Row impact the Arp functionality (Channel 1)
    Bottom Rom impacts the Chord Functionality (Channel 2)

    There’s still work needed on Knob Labeling but the Logging functionality displays the Arp and Chord Rhythm Masks. Populating these masks with the Euclidean Rhythm Masks seems easy with the example code provided. But I'll target the Labeling first and other
    quality improvements.

  • _ki_ki
    edited November 2019

    @McD Nice :) The wrong labels are a bit distracting, but if one opens up the Log view, one can see what each knob really changes.

    .

    An easy way to get rid of the multiple log output lines (or multiple computations) when turning a knob is to just compute the new value into a temporary variable and compare that to the old value. Only call the log output (or heavy computation) when something changed. This 'trick' only works for 'integer' knobs, as 'float' values tend to always differ in some bits. (To compare floats, you need to calculate the difference and check if that's smaller than a tiny epsilon - then there equal)

    Applied to your code i mean:

        ...
        elseif LastKnob = 15
          RhythmMask1 = GetKnobValue  15
          RhythmMask1 = Round (TranslateScale RhythmMask1, 0,127, 0, 15)
          // Log{RhythmMask1: }, RhythmMask1
          if RhythmMask1 % 2
             ChordRhythmArray[1] = 1
              ... 
          endif
    
          Call @MyLogChordRhythmMask  
    
        elseif LastKnob = 16
           ...
    

    changed into :

        elseif LastKnob = 15
          _val = GetKnobValue 15
          _tmp = Round (TranslateScale _val, 0,127, 0, 15)
          if RhythmMask1 <> _tmp       //  Only do computation and output if the value changed
            RhythmMask1 = _tmp
            // Log{RhythmMask1: }, RhythmMask1
            if RhythmMask1 % 2
               ChordRhythmArray[1] = 1
              ... 
            endif
    
            Call @MyLogChordRhythmMask  
          endif
    
        elseif LastKnob = 16
    
    
  • @_ki said:
    @McD Nice :) The wrong labels are a bit distracting, but if one opens up the Log view, one can see what each knob really changes.

    I agree. But I get good input by sharing incremental changes. This was a really big one for me.

    An easy way to get rid of the multiple log output lines (or multiple computations) when turning a knob is to just compute the new value into a temporary variable and compare that to the old value. Only call the log output (or heavy computation) when something changed. This 'trick' only works for 'integer' knobs, as 'float' values tend to always differ in some bits. (To compare floats, you need to calculate the difference and check if that's smaller than a tiny epsilon - then there equal)

    Applied to your code i mean:

        ...
        elseif LastKnob = 15
          RhythmMask1 = GetKnobValue  15
          RhythmMask1 = Round (TranslateScale RhythmMask1, 0,127, 0, 15)
          // Log{RhythmMask1: }, RhythmMask1
          if RhythmMask1 % 2
             ChordRhythmArray[1] = 1
              ... 
          endif
          
          Call @MyLogChordRhythmMask  
    
        elseif LastKnob = 16
           ...
    

    changed into :

        elseif LastKnob = 15
          _val = GetKnobValue 15
          _tmp = Round (TranslateScale _val, 0,127, 0, 15)
          if RhythmMask1 <> _tmp       //  Only do computation and output if the value changed
            RhythmMask1 = _tmp
            // Log{RhythmMask1: }, RhythmMask1
            if RhythmMask1 % 2
               ChordRhythmArray[1] = 1
              ... 
            endif
          
            Call @MyLogChordRhythmMask  
          endif
    
        elseif LastKnob = 16
    
    

    Nice. I've had some versions that broke the Logging function with excess output. At some point
    I'm going to study the MIDI streams out to really understand how everything works. The last version of
    the script kept changing the Preset selected in iSymphonic which I assumed would require a PC Command and I'm not sending any.

  • McDMcD
    edited November 2019

    Lots of knobs that are fun to play with... Version 1.2.

Sign In or Register to comment.