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.

Learn to Program the Mozaic Workshop to create MIDI FX and Controllers *you could learn something*

245678

Comments

  • I do find it cool that @_Ki can write code for hardware that he doesn't own. Total Pro.

    New stuff I found:

    Call @InitSysexMessage

    You can write you own Events like @FeedPidgeon and then call them from outside Event Blocks. Why would you want to do that? To save writing the same commands over and over in every other block that might want to use those commands.

    @FeedPidgeon
       Log {Hey. Feed the carrion pigeon. Yum. Pick up some buns.}
    @End
    

    What did you spot? Pro's can play too.

  • _ki_ki
    edited January 2020

    Or if your code get longer, you use the user events to structure your code into smaler blocks. Its a lot easier to then read and grasp the higher level functions, since these then also get smaler. I often do this, since one can't see that many lines of code in the internal editor. I try to 'split away codeparts' if an event gets longer than about 30 lines.

  • New stuff answer #2:

    controler[00] = [0x30, 0x01, 0x02, 0x09, 0x0B, 0x0C, 0x0D, 0x0E]

    I know. Pro's forget to turn on the spell check (just kidding, @_ki). He has a custom code checker in play.

    Every variable in Mozaic is really a File Cabinet with 1,024 Folders inside number from
    0 to 1023. The first folder in the "controler" File Cabinet is called up as "controler[00]".
    controler[0] would work too but @_ki likes to line stuff up. Tidy.

    // List of controler ids
    controler[00] = [0x30, 0x01, 0x02, 0x09, 0x0B, 0x0C, 0x0D, 0x0E] // knobs 1-8
    controler[08] = [0x33, 0x03, 0x04, 0x0A, 0x05, 0x06, 0x07, 0x08] // knobs 9-16
    controler[16] = [0x32, 0x35] // Shift knob1 and shift knob 9
    

    So, one the right side of the = are number to place in folders 0 to 8. You can access any of them with the right Folder Number in the code later.

    The numbers in this example are on Hexadecimal. Hexidecimal was invented for computers with 8 fingers each hand for a total of 16 fingers. Since we stop at finger number 9 (which is really 10 but it's that 0 is really ONE thing again).

    We count to 9 and roll over the odometer to a 1 in the Ten's and a Zero in the Ones.
    Computers need labels for fingers 10-15 for use to convert their thinking.
    We use:
    10 is A
    11 is B
    12 is C
    13 is D
    14 is E
    15 is F

    You can write some cool works with Hexa decimal and Programmers do this all the time in the code:

    0xBADCAFE4ABBAFAD which just broke my calculator.

    So, @_Ki is making his code more readable for the computer. Probably because the manual for the Akai also uses Hex values and it makes his code easier to understand.

    OK. That's a damn good answer but I'll keep the game open until Dinner, PST.

  • edited January 2020

    I'm hitting limits to Mozaic. It doesn't appear to support multidimensional arrays, for one, nor shorthand like "+=". The latter is easy to workaround, but the former limits how much information you can store in the note state table.

    Regardless, this is a ridiculously ambitious and amazing project.

    This is the code I was working on for the McD challenge, but it ends up with stuck notes since you can't nest arrays. There might be some clever way to do some bit manipulations to store the note state as a single integer but I don't see any tools for reversing that operation.

    @OnLoad
        ResetNoteStates
    
        // initialize layout to window and 4 knob layout
        ShowLayout 4
    
        // initialize the first knob to be the MIDI channel transform
        channel = 1
        LabelKnob 0, {MIDI CH }, channel
        SetKnobValue 0, channel
    
        // initialize the second knob to be the MIDI note transpose
        transpose = 0
        LabelKnob 1, {Trans }, transpose
    
        voices = 1
        LabelKnob 2, {Voices }, voices
        SetKnobValue 2, voices
    
        voiceOffset = 0
        LabelKnob 3, {VOffset }, voiceOffset
        SetKnobValue 3, voiceOffset
    @End
    
    @Description
        This is a cheesy and fragile MIDI manipulator script.
    
        There are four knobs that will break your MIDI input in "interesting" ways.
        * MIDI CH will modify your MIDI input to send on the adjusted channel.  This is stupidly fragile and if you monkey with this while a note is playing you're going to end up with stuck notes and have a bad day.  I only did this because it was a part of the problem statement.
        * Transpose will alter the pitch of your note in the set number of semitones.  This is for those of you that are scared of the black keys.
        * Voices is a half-assed chord builder that will stack voices based on the number of V[oice]Offset semitones.  Enjoy your diminished and augmented chords.  I was too lazy to write a real chord builder.
        * VOffset is the Voice Offset to use in coordination with Voices as describe above.
    @End
    
    @OnKnobChange
        if LastKnob = 0
            rawValue0 = GetKnobValue 0
            channel = Round( TranslateScale rawValue0, 0, 127, 1, 16)
            LabelKnob 0, {MIDI CH }, channel
            Log {MIDI Channel: }, channel
        elseif LastKnob = 1
            rawValue1 = GetKnobValue 1
            transpose = Round( TranslateScale rawValue1, 0, 127, -24, 24)
            LabelKnob 1, {Trans }, transpose
            Log {Transposition: }, transpose
        elseif LastKnob = 2
            rawValue2 = GetKnobValue 2
            voices = Round( TranslateScale rawValue2, 0, 127, 1, 8)
            LabelKnob 2, {Voices }, voices
            Log {Voices: }, voices
        elseif LastKnob = 3
            rawValue3 = GetKnobValue 3
            voiceOffset = Round( TranslateScale rawValue3, 0, 127, 1, 24)
            LabelKnob 3, {VOffset }, voiceOffset
        endif
    @End
    
    @OnMidiNoteOn
        // here we create an array with the various control parameters and store it in the note state table for the current note.
        noteOnInfo = [transpose, voices, voiceOffset]
        Log {Storing note state: }, noteOnInfo
        SetNoteState channel, MIDINote, noteOnInfo
        notePitch = MIDINote + transpose
    
        for i = 0 to voices
            SendMIDINoteOn channel, notePitch, MIDIVelocity
            notePitch = notePitch + voiceOffset
        endfor
    @End
    
    @OnMidiNoteOff
        // grab the previously stored control parameters for the transmitted note from the note state table.
        noteOffInfo = GetNoteState channel, MIDINote
        noteTranspose = noteOffInfo[0]
        noteVoices = noteOffInfo[1]
        noteVoiceOffset = noteOffInfo[2]
        notePitch = MIDINote + noteTranspose
    
        for i = 0 to noteVoices
            SendMIDINoteOff channel, notePitch, MIDIVelocity
            notePitch = notePitch + noteVoiceOffset
        endfor
    @End
    
  • The user events are probably what I was looking for as far as custom functions. But I guess you can't pass parameters to them short of using global variables?

  • @Liquidmantis said:
    I'm hitting limits to Mozaic. It doesn't appear to support multidimensional arrays, for one, nor shorthand like "+=". The latter is easy to workaround, but the former limits how much information you can store in the note state table.

    Yes. @Brambos is extremely careful with passing out RAM. 2-dimensional arrays would be
    lovely but I'm sure he has concerns about Blocks with such complex looping code (potentially buggy loops) that is makes Mozaic appear to have significant timing bugs when
    it's just coders creating excess calculation loops. He's given us a tool that's stable but sometimes challenging to design in. It's not the apple CPU that gets swamped it's his
    interpreter and it's working well. It's a one man operation and he just announced a new app
    while supporting a new programming tool for non-programmers.

    Here's a way to think about complex data structures you can scale and still control:
    Notes[00] = [1,2,3,4...]
    Channel[00] = [1,2,3,4..]
    Velocities[00] = [1,2 3,4...]
    TimingOffset[00] = [150, 216,85,,,,]
    LFO[00]

    You will have to type more than a 2-dimensional array but it will insure you can't
    bury the interpreter with excess work in a given time slot for the GLOBAL Mozaic
    interpreter.

    Then you can recall a list of parameters using a single index.
    Notes[Index]
    Channel[Index]
    Velocities[Index]
    ...

    You can think of these parallel structures as a List of Notes like a buffer (First In First Out)
    and wrap around at some special value or fixed at 1024. Exceed 1024 and have a 2nd set, then 3rd until you hit the practical limit.

    @Liquidmantis said:
    The user events are probably what I was looking for as far as custom functions. But I guess you can't pass parameters to them short of using global variables?

    Not Globals really. A variable has a single state and can be used in any block. So set some
    parameters and call the Function which uses these most recently set values.

    There are GLOBALS that use the AUv3 shared memory to pass data between Mozaic run-time instances.

    You re very advanced and can get Pro assistance to make the leap o this thread where the
    real programmers help each other and get input from @Brambos on language issues.

    https://forum.audiob.us/discussion/32930/mozaic-create-your-own-au-midi-plugins-out-now#latest

    @_Ki figured out a way to pack/unpack 2 bytes into every NoteState File Cabinet Array.

    Post your code there for some excellent advice from the guys that have build the most robust PatchStorage Scripts.

  • There are no multi-dimensional arrays in Mozaic, but you can ‚fold‘ these into a single dimension if you have a fixed row length:


    rowLength = 16 x = 2 y = 5 value = 42 // write the value to position x,y : twoDimStorage[ x + rowLength*y] = value // retrieve value from 5,3 x = 5 y = 3 value = twoDimStorage[ x + rowLength*y ]

    Mozaics array length is limited to 1024, so 32x32 just fits - but 128x16 (often needed in midi programming) doesn‘t.

    There is a single two dimensional array in Mozaic that fits this dimensions, the note state array. It uses special access functions to store and retrieve values. There is only one array of this kind, but sometimes you Need to store multiple values. In such a case, its possible to fold these values into a single value using the example code on the wiki. (Thats what @McD mentioned).
    .

    @McD, the indentations of my code-example were lost during copying - making it a bit hard to read

  • @_ki said:
    @McD, the indentations of my code-example were lost during copying - making it a bit hard to read

    Sorry. I have fixed it.

  • I just updated the mozaic tips and tricks wiki page with the topics "two and multi dimensional array access" and how to "store two positive values in a single variable" .

  • McDMcD
    edited January 2020

    ki said:
    I just updated the mozaic tips and tricks wiki page with the topics _"two and multi dimensional array access"
    and how to "store two positive values in a single variable" .

    Nice. There's some excellent computer science at work in these tips.

    Also some wonderful code suitable for typing to reach 10 words per minute in 2020.
    Set goals for yourself. My goal is to reach 2021 without having a stroke.

    STUDENTS: @_Ki's code and tips will stimulate questions, I'm sure, so please ask any questions for have about his Tips and coding style.

  • I'm loving this thread.
    But unrelenting painful dental infection is making it hard to focus and concentrate on code.
    Hope to be able to join in soon.

  • @horsetrainer said:
    I'm loving this thread.

    Thanks for the feedback. One never knows when typing on the web without feedback.

    But unrelenting painful dental infection is making it hard to focus and concentrate on code.

    Sorry to hear about your dental pain... It's the time of year when I decide if I should
    pay for insurance coverage to lower my costs over the next year. I dropped it last year and
    made it without urgent care needed but it's only a matter of time at my age before I need
    expensive repairs. Another form of painful distractions... health care.

    Hope to be able to join in soon.

    No hurry. MIDI will still be here to abuse for many more years.

    Do you really Train Horses? If you lead them to water...

  • @McD said:

    @horsetrainer said:
    I'm loving this thread.

    Thanks for the feedback. One never knows when typing on the web without feedback.

    But unrelenting painful dental infection is making it hard to focus and concentrate on code.

    Sorry to hear about your dental pain... It's the time of year when I decide if I should
    pay for insurance coverage to lower my costs over the next year. I dropped it last year and
    made it without urgent care needed but it's only a matter of time at my age before I need
    expensive repairs. Another form of painful distractions... health care.

    Hope to be able to join in soon.

    No hurry. MIDI will still be here to abuse for many more years.

    Do you really Train Horses? If you lead them to water...

    Yup. I was a pro rider/trainer of sport horses for 25 years (can longer ride due to injury).
    Some farms use automatic waterers where the horse has to push down an aluminum paddle in the drinking bowl with their nose to activate a valve that fills the bowl with drinking water (called a Bar-Bar-A waterer). When you first install this type of waterer. You do indeed have to lead the horses to the waterer, and train them how to use it. Fortunately most horses are smart, so you only have to teach one or two horses, and the others will learn two use the waterer from the others.

  • So you lead a horse to water and make him teach others to drink?

    This feels strangely parallel to this thread...

  • edited January 2020

    ki said:
    I just updated the mozaic tips and tricks wiki page with the topics _"two and multi dimensional array access"
    and how to "store two positive values in a single variable" .

    This is really awesome stuff. I knew there had to be some clever structure but I wasn’t clever enough. I thought of concatenating values with a delimiter, but without some string slicing functions it wouldn’t be reversible.

    So the Note State array is two dimensional? That’s what I was attempting to use but it wasn’t working for me. I guess I need to dig back into it.

  • @horsetrainer said:
    Yup. I was a pro rider/trainer of sport horses for 25 years (can longer ride due to injury).

    Polo ponies? (I hope that's not insulting). What types of sports?

    you only have to teach one or two horses, and the others will learn two use the waterer from the others.

    Give a horse a drink and he is sated, teach a horse to drink from a Bar-Bar a and...

  • edited January 2020

    @McD said:

    @horsetrainer said:
    Yup. I was a pro rider/trainer of sport horses for 25 years (can longer ride due to injury).

    Polo ponies? (I hope that's not insulting). What types of sports?

    you only have to teach one or two horses, and the others will learn two use the waterer from the others.

    Give a horse a drink and he is sated, teach a horse to drink from a Bar-Bar a and...

    // Answer to McD's question

    General Riding Horses, Show Jumpers, Three Day Eventers, Dressage Horses, a Discipline called "Hunters", and a few of the Western disciplines.

    Mostly I like teaching regular average people to ride regular average horses in regular average Barns.

    No Polo or Racing Horses.

    @ End

  • Very good code donation. I'd suggest one extra line be added:

    @MyAnswer

    to start the code block and // to avoid having the first words interpreted as Variables and log
    a dozen errors on Loading.

    Just use // in front of each line of free text.

    Optionally, you could wrap your Answer text as a Description Block:

    @Description
    .
    .
    .
    @End 
    

    Thats the only Block where free text is allowed.

    I bet you have a million stories from your career teaching people and horses.
    Horses are amazing and people on horses are a magical experience.

    I found myself on a horse with little training and it jumped a log
    and raced at top speed back to the barn. I was lucky to have good balance to help me survive to tell the tale.

  • edited January 2020

    I have an idea for a Mozaic program. I'll describe on this thread because I'd like to hear some general coding theory about how it might be accomplished (if it's even possible).

    The script would work as a Midi Control Change Recorder.

    ( Is there a synth that has this feature built-in? )

    The idea is to be able to have a patch loaded in a synth, then play a note while manually adjusting Frequency, or Resonance, or Pulse Width, or any CC parameter that can be controlled by a controller (like Mozaic) .

    Then be able to "record" your manual adjustment with the Mozaic script. Once it's recorded, every time you press any key to play any note, Mozaic detects a @OnMIDINote Event, and Mozaic sends the synth the recorded manual CC adjustment and the synth applies it to the patch in real time.

    This is different from having an LFO modulate a CC parameter, because if you looked at a graphed curve produced by your manual adjustment, it could look like any shape, because it's manually input.

    The problem I see creating a Mozaic script to do this, is it could not control a single synth polyphonically. But this could be overcome by loading (say) Three or Four AU instances of the same synth (but each instance having it's own Midi Channel). Then tell Mozaic on each new@OnMIDINote Event, to send each new Midi note you play, out to sequential Midi Channels (The same way the Oberheim SEM created polyphony by using multiple sound modules.)

    To me the mind boggling programing issue, would be how to make Array code blocks that could use the output from manually changed knobs in a Mozaic layout, and record the Data in a way that could be recalled.

    It seem to me the Mozaic output would be very step-like and not smooth.

    But what I wonder is if there is some type of math equation that could take a graph of plotted points, and interpolate it so the synth receives a smooth control change instead of a series of abrupt control change steps.

    I'd like to think that with a program like this, you might be able to "record" multiple control changes for various synth parameters, and get consistent groups of complex control changes that would sound really cool.

    With a program like this, you could run two Mozaic instances each controlling it's own "synth group".

    Then imagine the possibilities for creatively "blending" the combined output from two different "synth groups" each having it's own unique control changes, timed in particular ways to create infinite numbers of unique blending techniques.

  • @horsetrainer said:
    I have an idea for a Mozaic program. I'll describe on this thread because I'd like to hear some general coding theory about how it might be accomplished (if it's even possible).

    Lot's of challenges in your idea for me. I would like to share your request with @_Ki, @Wim and the pot tier programmers that converse on anther thread for a feasibility assessment.

    I'm considering taking the tutorial towards a simple program that is followed by a dozen lessons that continue to add features by adding knobs, additional data structures, etc.

    We might start with a hardware knob tied to a CC for a well known synth. For example and
    as we add script features we add more hardware and software controllers. So, both communities of control cases are involved.

    After the first code version v1.0 Id ask for a poll on 2 or more options for the next version feature change and we'd add code for that feature and discuss the way a change is considered and implemented without breaking v1.0 for the users as v2.0 is created.

    It shows how to start with a single idea and use 10-20 iterations to get t something like you
    have requested. Break it down to working blocks of code and add them taking users from a basic tool to a fully fleshed out application like you have requested.

    Hang in there.

  • wimwim
    edited January 2020

    @horsetrainer, I’m working on a midi recording and playback script that addresses the recording and playback of any midi data to an approximate 1ms timing. The technique used to store the events and timing could be adapted for what you want to do. However, keep in mind that the data has to pass through Mozaic to be captured or played back. That means you either need to control the synth from outside it, or the app has to output midi when controls are moved. Most don’t.

    At some point I’ll detail how I’m doing this recording and retrieval, but not quite yet as I’m still in the testing stages. It will be a topic more advanced than seems appropriate for this thread.

    There’s another thread @McD set up already for script ideas. That would be a better place to pursue your idea probably.

  • @horsetrainer: @wim writes exceptionally complex scripts. They are very challenging to
    comprehend because he uses sophisticated techniques and gets excellent results. I use his code to see examples of Knob programming and using the scales routines.

    If you want to write this script your self, we have a lot of functionality to teach you or you need to hit the manual like a fiend and start small and grow the code. There are many here to advise and help debug as you advance.

    For general teaching incentives your app is a bit too niche for my plans.

    I think I want to make a 16-step sequencer and keep adding GUI controls. It can never be a
    piano roll GUI but it can be surprisingly complex and useful for live jamming. And as you predict running many copies in parallel would simulate a Fugue session. But I'm going to
    have readers vote on the next feature so we could end up with a totally different outcome
    and make something beyond my or your vision.

    FYI: There's a thread to literally request Mozaic scripts. No promises someone will write to for you but good programmers live for interesting problems to solve.

  • @McD
    I just wanted to hear your thoughts about the plausibility of the idea.

    Please do keep this thread simple and work upward. I agree that is the best way to learn.
    Step by step, slowly adding new concepts.
    Working upward from a foundation of understanding the fundamental basics.

    @wim
    That's cool that you're working on a recorder!
    It means that what I'm thinking about may be plausible.

    The way I was imagining it working was to use Mozaic's own "controller layout" to send the CC's to the synth.
    It could be one instance of Mozaic used for sending CC's to the synth, and another to do the recording.
    Or one script handling controlling the synth, and recording what it sends out, simultaneously.

    I'll move the idea over to the script idea thread.

  • @McD said: FYI: "U" misspelled a word. Why do you folks say Al-you-minium? Do you always phoneticize the vowels. God save the Cue-You-Ee-Ee-En? It sounds phoney to Yanks. We continue to bastardize the language... LOL. S'up.

    nope. Americans misspell it.
    Aluminum is only known in the US. the rest of the world knows it as Aluminium. ;)
    (latain aluminis) ;)

  • @Max23 said:
    nope. Americans misspell it.

    I think we optimized it for extra productivity. We want our Princess back too. We will even take Harry in to get Meghan. She too good for the Royals. No common touch. We are a nation of commoners by design.

    Aluminum is only known in the US. the rest of the world knows it as Aluminium. ;)

    Not sure about this. I have a box of it in my kitchen and it's aluminum.

    (latain aluminis) ;)

    So, you be like Boarding school educated or what? Be best. I be state college certified
    twice over. We use common sense and value ignorance as a valid rationale for saving time
    over little details that don't give us more money.

    Meanwhile Venice drowns... Australia burns... and Greta gets bullied by our Dear Leader.
    I'm sorry for my new grand baby. She will not have the same advantages I had for a decent and peaceful life.

  • edited January 2020

    BTW. Cue-You-Ee-Ee-En is very creative misspelling. ^^
    took me a while to get it :D

    btw. the German short form for aluminium
    is Alu, a little tripple click could have told u that

  • @Max23 said:
    BTW. Cue-You-Ee-Ee-En is very creative misspelling. ^^
    took me a while to get it :D

    btw. the German short form for aluminium
    is Alu, a little tripple click could have told u that

    Wow. My whole brain just went nucular.
    Everything seems to be a one big lie or a twisty maze of little lies. Zyzzx. Plugh.
    One big Colossal Cave Adventure.
    Fake reality... go figure. Sorry, go maths.

  • edited January 2020

    No, math doesn't go because I always went to the gentlemens room smoking. ^^
    I payed much more attention to my language classes; ;)
    so you can imagine I find the new speak of the man with the orange hair quite revealing.

  • @Max23 said:
    so you can imagine I find the new speak of the man with the orange hair quite revealing.

    I feel like I'm stuck in a new Vonnegut Novel...Catch 2020.

    On the edge of a Mad Max prequel.

    I did not have the discipline for languages. It required actual work. Everything else I could
    just attend lectures and survive or even thrive. But French killed me. Conjugations? Please lady. Invent sentences? Just teach me to order fast food and ask for the location of the Loo.
    No. I am so screwed. Pulled out a C.

  • edited January 2020

    @McD

    there are lots of unfriendly big birds over my head and they do dont take bonbons where they are going. ;)
    greetings from Germany.

Sign In or Register to comment.