Loopy Pro: Create music, your way.

What is Loopy Pro?Loopy Pro is a powerful, flexible, and intuitive live looper, sampler, clip launcher and DAW for iPhone and iPad. At its core, it allows you to record and layer sounds in real-time to create complex musical arrangements. But it doesn’t stop there—Loopy Pro offers advanced tools to customize your workflow, build dynamic performance setups, and create a seamless connection between instruments, effects, and external gear.

Use it for live looping, sequencing, arranging, mixing, and much more. Whether you're a live performer, a producer, or just experimenting with sound, Loopy Pro helps you take control of your creative process.

Download on the App Store

Loopy Pro is your all-in-one musical toolkit. Try it for free today.

MOZAIC - Create your own AU MIDI plugins - OUT NOW!

16566687071106

Comments

  • @horsetrainer said:

    Can the TRIGGER PAD be used to hold each note for as long as the Pad is held down (like a keyboard key).?

    Sure. For the sake of simplicity, let's set up the pads to be consecutive midi notes staring with note number 60.

    Here is the pseudo-code. (By the way, I am almost always write in pseudo-code first and then just translate that into the actual programming language).

    When a pad down event is detected:   send a midi note on event 
    
    When a pad up event is detected: send a midi note off event
    

    I can see that we need to know what note to send and what velocity to use. So, I add to my pseudo-code to capture that info:

    When the script first starts, set it up by:
    * assigning a note to be used for each pad using consecutive notes starting with C3 (note number: 60) for the first pad (pad 0)
    * use 90 as the velocity.
    
    When a pad down event is detected:   send a midi note on event 
    
    When a pad up event is detected: send a midi note off event
    

    Now, I'll write the pseudo-code for setting up the note assignments for the pads:

    firstNote = 60
    for padNumber 0 through 7, set padNote to (firstNote + padNumber)
    

    Here is the pseudo-code for triggering the pads:

    When  pad is held down, send MIDI note on (firstNote+padNumber) with velocity 90
    
    When a pad is released, sendMIDI note off (firstNote+padNumber)
    

    Most of that pseudo-code translates straightforwardly into Mozaic script statements that you can probably figure out from looking at the list of Mozaic commands.

    Hopefully that was helpful.

    In my opinion, being able to describe things in pseudo-code -- first as general vague directions and then refined into more specific directions is really helpful. The hardest part of programming is making the transition from thinking in general terms to thinking in terms of little steps.

  • @McD said:

    @horsetrainer said:
    In my mind, what you've said translates to this....

    Mozaic has two main parts. A hidden event handling engine running in the background, that linearly handles events fed into it by a code interpreter that reads code programed by the user.

    Close but not quite accurate. There's the Script which is fed events from a single lane MIDI road.

    The script triggers FUNCTIONS based upon the MIDI event type:

    • Notes
    • CC's
    • MIDI Clock
    • etc. ( added this incase I forget some other MIDI type... like SysEx)

    That Mozaic script can store information in variables, like:

    • save note details (memorize) in a list (useful for making loopers, playing chords, detecting incoming chords)
    • save CC values to use as parameters (like Channel, Volume, LFO settings).

    "memorize" is a nice analogy for the timeline in the core engine. It's a long running memo/list of events to sent out with timestamps on them: a "to do later" list.

    The script can also forward MIDI outputs the the BACKEND runtime wizard that accepts commands and manages the future timeline.

    I'll use the Echo example again:

    1. Note comes in on the MIDI road
    2. Mozaic passes the NOTE ON details to the OnMidi code function
    3. The user script decides everything that follows and the OnMIDI commands all run in 0.0000001th of a second

    Almost all details other than these are up to the script writer. Mozaic can accept slow MIDI streams from the MIDI road in and request thousands of MIDI events be sent in the future. What is sent and at what time is all coded in the FUNCTIONS commends. One event in and 1 to 100,000 events out.

    All the other questions have to do with using Variables and Commands to create interesting MIDI FX solutions.

    The things that can't be done usually have to do with someone asking for an event out in response to
    something changing in the future. That won't fit on the 3-step loop of execution. Programmers call this type of Loop a REPL (read-eval-print loop)

    1. read from the MIDI highway in
    2. evaluate (that backend is really evaluating the commands in our functions)
    3. print (either send out an immediate event or make a notation on the timeline list to do it later)
    4. loop (go back to #1 for a new event) "No! Not the dreaded Go To Statement"

    My description does mention an explicit Go To but it does help understand the real time flow of
    the engine.

    Does that help any further...
    Studying any single script misses something essential... you can build some amazingly complex MIDI Functions and each one is a unique script with it's own internal logic.

    Yes, all the descriptions about how Mozaic handles Events, Commands, and Functions are very helpful.

    It allows me to better understand the rules Mozaic uses to parse the code, rather than "guess" how any particular event or command will be interpreted by the Mozaic "engine".

  • @wim said:
    You’re pretty good at articulating what you want, so maybe you should noodle on it until what you want it to do fully gels, then float it over on the script request thread. Most likely someone will pick it up.

    I'll give it try. :)

  • @espiegel123 said:

    @horsetrainer said:

    Can the TRIGGER PAD be used to hold each note for as long as the Pad is held down (like a keyboard key).?

    Sure. For the sake of simplicity, let's set up the pads to be consecutive midi notes staring with note number 60.

    Here is the pseudo-code. (By the way, I am almost always write in pseudo-code first and then just translate that into the actual programming language).

    When a pad down event is detected: send a midi note on event

    When a pad up event is detected: send a midi note off event

    I can see that we need to know what note to send and what velocity to use. So, I add to my pseudo-code to capture that info:

    When the script first starts, set it up by:
    * assigning a note to be used for each pad using consecutive notes starting with C3 (note number: 60) for the first pad (pad 0)
    * use 90 as the velocity.
    
    When a pad down event is detected:   send a midi note on event 
    
    When a pad up event is detected: send a midi note off event
    

    Now, I'll write the pseudo-code for setting up the note assignments for the pads:

    firstNote = 60
    for padNumber 0 through 7, set padNote to (firstNote + padNumber)
    

    Here is the pseudo-code for triggering the pads:

    When  pad is held down, send MIDI note on (firstNote+padNumber) with velocity 90
    
    When a pad is released, sendMIDI note off (firstNote+padNumber)
    

    Most of that pseudo-code translates straightforwardly into Mozaic script statements that you can probably figure out from looking at the list of Mozaic commands.

    Hopefully that was helpful.

    In my opinion, being able to describe things in pseudo-code -- first as general vague directions and then refined into more specific directions is really helpful. The hardest part of programming is making the transition from thinking in general terms to thinking in terms of little steps.

    Thanks, that is helpful. :)

    I'll try writing out the note recording / pad tap playback script in pseudo-code and see if I can fill out all the necessary elements.

    I'll have to put some deep thought into how Arrays function, and how to get Midi notes in and out of an Array.

  • @horsetrainer said:
    I'll have to put some deep thought into how Arrays function, and how to get Midi notes in and out of an Array.

    Let's consider the case where you want to store incoming notes and additional details into somearray(s).
    Set up 3 arrays and an index variable:

    Channels[0] // you may just be dealing with a single channel and can skip building this array
    Notes[0] = 0
    Velocities[0] = 0
    TimeStamp = ?? // you would have to add commands to read the Mozaic clock and insert it here
    index = 0
    advance = 0

    I MIDI Note ON comes in:

    1. save the channel in Channels[index]
    2. save the notes value in Notes[index]
    3. save the velocity in Velocities[index]
    4. increment the index to be ready to store the next triplet of data

    Do this for every Note in and you will have a list of Note event data of length index.

    When you want to play back those notes in order use:
    Channels[advance]
    Notes[advance]
    Velocities[advance]
    and increment advance to be ready to recall the next note data triplet

    This way of making and using lists of things with a pointer to the Head where data is written
    and the tail where data is read in called a FIFO (First In - First Out) Data Structure.
    What I've added is the idea of a multidimensional Array which Mozaic does not explicitly
    provide. But 3 aligned arrays would have 3 Dimensions. But a real Multi-dimensional array
    would allow for Nested Loops to advance across dimension pulling out the values related to some
    index.

    I hope this gives you some insight into how to read and write from arrays and apply this to
    typical kinds of Midi problems.

    Aligned arrays can also hold values related to Knobs, Pads, Chord Structures, Rhythms, etc.
    A basic C_Major_Chord could be stored as follows:

    C_Major_Chord = [60, 64, 67]

    and sent out in 3 MidiOut events which will be sent sequentially space out by 0.0000001 seconds
    or effectively at the same time to out ears.

  • edited February 2020

    @McD said:

    @horsetrainer said:
    I'll have to put some deep thought into how Arrays function, and how to get Midi notes in and out of an Array.

    Let's consider the case where you want to store incoming notes and additional details into somearray(s).
    Set up 3 arrays and an index variable:

    Channels[0] // you may just be dealing with a single channel and can skip building this array
    Notes[0] = 0
    Velocities[0] = 0
    TimeStamp = ?? // you would have to add commands to read the Mozaic clock and insert it here
    index = 0
    advance = 0

    I MIDI Note ON comes in:

    1. save the channel in Channels[index]
    2. save the notes value in Notes[index]
    3. save the velocity in Velocities[index]
    4. increment the index to be ready to store the next triplet of data

    Do this for every Note in and you will have a list of Note event data of length index.

    When you want to play back those notes in order use:
    Channels[advance]
    Notes[advance]
    Velocities[advance]
    and increment advance to be ready to recall the next note data triplet

    This way of making and using lists of things with a pointer to the Head where data is written
    and the tail where data is read in called a FIFO (First In - First Out) Data Structure.
    What I've added is the idea of a multidimensional Array which Mozaic does not explicitly
    provide. But 3 aligned arrays would have 3 Dimensions. But a real Multi-dimensional array
    would allow for Nested Loops to advance across dimension pulling out the values related to some
    index.

    I hope this gives you some insight into how to read and write from arrays and apply this to
    typical kinds of Midi problems.

    Aligned arrays can also hold values related to Knobs, Pads, Chord Structures, Rhythms, etc.
    A basic C_Major_Chord could be stored as follows:

    C_Major_Chord = [60, 64, 67]

    and sent out in 3 MidiOut events which will be sent sequentially space out by 0.0000001 seconds
    or effectively at the same time to out ears.

    Thanks @McD , this is exactly the stuff that I have the toughest time with.

    But,
    When I put this into Mozaic. I only get single C4, and not chord.

    @OnMidiInput
    
    C_Major_Chord = [60, 64, 67]
    SendMIDINoteOn 0, C_Major_Chord, 100
    
    @End 
    

    I don't understand how.... C_Major_Chord = [60, 64, 67] .... works?
    Are you saying 3 values can be assigned to a single variable, and the somehow recalled as individual variables?

  • @horsetrainer : ARRAYS! (apologies for some bad formatting below)

    Ok. I see a frequent comment from potential scripters without programming backgrounds about arrays. Arrays (and other data structures) can seem daunting -- but let me see if I can help them seem less confusing and abstract.

    An array is just a virtual shelf with a number (called an index) that let's you specify where on the shelf you want to put something or take something. You can put anything on the shelf for later retrieval. The major "trick" is that you need decide how you want to organize the shelf.

    Let's look at the pads to notes script, we were talking about up-thread. Let's have a shelf (array) where we store the note numbers for the pads to play. We will store the note a pad plays (the MIDI note number) on the shelf at a location that has the same number as the pad. Here is the pseudo-code for putting things on the array shelf (initializing the array). We will start by putting consecutive note numbers starting at 60 on the shelf. We'll look later at how to put arbitrary notes you play on the shelf.

    PSEUDO-CODE
    when the program loads do these things:
    set firstNote to 60
    for padNumber from 0 to 7, put (firstNote + padNumber) onto shelf padNote at location padnumber
    when a pad is touched:
    send out the midi note whose number is stored at location padNumber from the padNote shelf

    So, an array name is just the shelf name. And we tell Mozaic where on the shelf to store something or look for something by putting the location in brackets. So, our padNote shelf is the padNote array. Programmers start counting at 0. So, the first location on the padNote shelf is padNote[0]. We stick something on the padNote shelf like this:

    padNote[theLocationNumber] = someNumber

    we retrieve something from the shelf like this:

    someNumber = padNote[theLocationNumber]

    Here is the Mozaic code for the pseudo-code above:

    @onLoad
      firstNote = 60 //this is the note sent by the first pad. feel free to change it
      //put notes on the padNote shelf
     for padNumber = 0 to 7
        padNote[padNumber] = firstNote + padNumber
     endfor
    
    @End
    

    That's it. The note numbers are now safely stored. Now, if you don't want to limit the pads to consecutive notes starting at firstNote. You can do something like this.

    PSEUDOCODE
    if a pad is held down and the shift key is down and a midi note comes in, store that note on the padNote shelf.

    Now, I need to refine the pseudo-code to be structured a little differently since I know that Mozaic listens for events to happen and runs code (event handlers) when those events happen.

    REFINED PSEUDOCODE:
    when a midi note comes in, if a pad is being held down, store the midi note on the padNote shelf at the pad's number

    when a pad is held down, make note of the fact that I am listening for a note to store on the padNote shelf
    
    when a pad is released, forget that I was listening for a note to store on the padNote shelf
    

    MOZAIC

    @onLoad
        //in addition to all the other onLoad stuff, we need some variables to 
        listeningForNote = NO   
    @end
    
    @onMidiNoteOn
      if listeningForNote
       padNote[padNumber] = MIDINote
      endif
    
    @End
    
    @onPadDown
      listeningForNote = YES
      padNumber = lastPad
    
    @End
    
    @OnPadUp
      listeningForNote = NO
    @End
    

    This is very bare bones. It assumes, for instance, that only when pad will be pressed at a time. But, hopefully that helps demystify things a bit.

  • When I put this into Mozaic. I only get single C4, and not chord.

    @OnMidiInput
    
    C_Major_Chord = [60, 64, 67]
    SendMIDINoteOn 0, C_Major_Chord, 100
    
    @End 
    

    C_Major_Chord is a variable that holds multiple values, yep! An array is a variable that can hold multiple values. Think of it like a chest of drawers..."C_Major_Chord" is the entire chest of drawers, and each drawer can hold one value. You open each drawer in the chest with a number. So C_Major_Chord[0] is 60, C_Major_Chord[1] is 64, etc.

    You'll need to sequentially step through every element of the C_Major_Chord array (i.e. open each drawer of the chest) in order to hear the entire chord, otherwise Mozaic thinks you just want the first element of the array, which in your case is 60/C4.

    I've been doing this with for loops like so:

     C_Major_Chord = [60, 64, 67]
    
     for i = 0 to 2
        SendMIDINoteOn 0, C_Major_Chord[i], 100 
     endfor
    

    This might seem counterintuitive but it's not Mozaic's fault - MIDI is a serial protocol so a chord is always a quick succession of single note events.

  • Oops sorry! I guess @espiegel123 already answered while I was typing!

  • @horsetrainer Imagine each variable name beeing a cupbard wih 1024 drawer each. The index number given in square brackets points out which of the drawer of the cupboard to open to retrieve a number or in which drawer to put a number if user left of the assignment’s equal sign.

    If you omit the index, Mozaic will use the draw with index 0. So my_var = 100 is the same as `my_var[0] = 100, both store the value 100 in the drawer 0 of the cupboard named ‚my_var‘.

    The same applies to value retrieval.

    The line C_Major_Chord = [60, 64, 67]uses another Moazic language feature: Array Assignment. It allows to specify values for successive indexes.
    Mozaic also allows to offset the desination, the line test[3]=[10,15,20] would set test[3] to 10, test[4] to 15 and test[5] to 20.

    This concepts of storing multiple values inside the same varibale is called Array. They are very helpful, because you can also use another variable or even calculation as index. Quite often the variable used for indexing into an array is also named something with ‚index‘ to help understanding its purpose.

    .

    In your example, you didn‘t use the array brackets, so you indexed the value at index 0.

    @OnMidiInput
      C_Major_Chord = [60, 64, 67]
      For i = 0 to 2
        SendMIDINoteOn 0, C_Major_Chord[i], 100
      Endfor
    @End 
    

    But beware, your code now sends out 3 fixed notes for any incomming midi message - for each keyboard press and also for the release of the keyboard, tons of notes for pitchbend or modwheel etc :)

  • @espiegel123 , @unicity , @_ki

    Thanks guys,
    Now it’s finally starting to make sense.

    Now I understand that all Mozaic variables have the potential to become arrays.
    I can enter multiple values into an array by putting the values between brackets.
    To play a chord with code, I have to send out each note individually using a method such as a loop, that can use a variable to index each value out of an array, one step at a time.

    This below was a major help...

    @OnMidiInput
    C_Major_Chord = [60, 64, 67]
    For i = 0 to 2
    SendMIDINoteOn 0, C_Major_Chord[i], 100
    End-for
    @End 
    
  • @horsetrainer said:
    @espiegel123 , @unicity , @_ki

    Thanks guys,
    Now it’s finally starting to make sense.

    Now I understand that all Mozaic variables have the potential to become arrays.
    I can enter multiple values into an array by putting the values between brackets.
    To play a chord with code, I have to send out each note individually using a method such as a loop, that can use a variable to index each value out of an array, one step at a time.

    This below was a major help...

    @OnMidiInput
    C_Major_Chord = [60, 64, 67]
    For i = 0 to 2
    SendMIDINoteOn 0, C_Major_Chord[i], 100
    End-for
    @End
    

    Btw, it isn't just that Mozaic variables CAN become arrays -- all Mozaic variables ARE arrays. Mozaic simply lets you access the first slot of an array without providing its index. So, you don't need to know that it is an array.

  • Real programmers will be upset from I would start by exposing 1 new concept at this time.
    Show how you must send/play a chord:

    @OnMidiInput
    C_Major_Chord = [60, 64, 67]
    SendMIDINoteOn 0, C_Major_Chord[0], 100
    SendMIDINoteOn 0, C_Major_Chord[1], 100
    SendMIDINoteOn 0, C_Major_Chord[2], 100
    @End

    // even more basic

    SendMIDINoteOn 0, 60, 100
    SendMIDINoteOn 0, 64, 100
    SendMIDINoteOn 0, 67, 100

    Now a real programmer like @_Ki sees an opportunity to wrap the 3 send in a Loop that runs
    three times and advances the C_Major_Chord index:

    For i = 0 to 2
    SendMIDINoteOn 0, C_Major_Chord[i], 100
    End-for

    Now all three Notes will be dispatched with a 0.0000001 second delay between notes. On our scale of hearing they are simultaneous making a "chord". Midi only transmits 1 event at a time on the MIDI Highway.

    Real programmer's like to save extra typing but when you're learning don't be afraid to just create
    with the Commands you understand at your stage of development.

    My first StreamByter script was over 100 lines and @_Ki understood the idea and re-coded it in about 12 lines. They sounded exactly the same but my 2nd version started with his elegant solution and what he
    did taught me more StreamByter Commands that I hadn't discovered yet. That started a series of updates that @_Ki made that basically coded a lot of my music theory ideas about MIDI FX.

    When I took those ideas to Mozaic I used a similar approach and later looked at some of @Wim's code related to Chords and saw whole different approach using the Mozaic Scales Functions.

  • wimwim
    edited February 2020

    @McD said:
    When I took those ideas to Mozaic I used a similar approach and later looked at some of @Wim's code related to Chords and saw whole different approach using the Mozaic Scales Functions.

    I was thinking of bringing up the way I found to "calculate" standard chords from a single root note, but this discussion is about Mozaic programming concepts more than those specifics. There's a post many pages back about it that I can dig up if needed, but it seems like it would be a distraction from the main flow of thought at this point.

  • If this play a C Chord on middle C...

    C_Major_Chord = [60, 64, 67]
    SendMIDINoteOn 0, C_Major_Chord[0], 100
    SendMIDINoteOn 0, C_Major_Chord[1], 100
    SendMIDINoteOn 0, C_Major_Chord[2], 100

    What do you think this does?

    Strum_Rate = 100

    C_Major_Chord = [60, 64, 67]
    SendMIDINoteOn 0, C_Major_Chord[0], 100
    SendMIDINoteOn 0, C_Major_Chord[1], 100, Strum_Rate
    SendMIDINoteOn 0, C_Major_Chord[2], 100, Strum_Rate * 2

    It all goes out in 0.000001 milliseconds so what will Mozaic's execution engine do with these 3 commands in "real time"?

    HINT: The manual state a simple explanation:
    SendMIDINoteOn and SendMIDINoteOff take 3 mandatory parameters, and an optional 4th one:

    1. channel number
    2. note number
    3. velocity value
    4. and an optional delay parameter; the time in milliseconds before the message is sent out

    That's one way to ask for something to happen in the future.
    There are more of course but one idea at a time.

  • McDMcD
    edited February 2020

    @wim said:
    I was thinking of bringing up the way I found to "calculate" standard chords from a single root note.

    I'd definitely read it if you care to write it up. When I saw what you did I thought "Wow. I wish I had just used this to make my One Finger app." The One Finger app sounds good but the code is beyond confusing in a lot of ways. Still, I code for own use as a rule to solve puzzles and problems. Usually to save money or drudgery. I never really save much time since it takes a lot to get something useful done.

    It's useful to invent your own solutions but also good to see how it could be more elegant, extensible, and re-editable. The Bram Father gave us scales... we should use them. One chord routine will work across all those scales... a lot smarter than (60, 64, 67).

  • @McD said:

    @wim said:
    I was thinking of bringing up the way I found to "calculate" standard chords from a single root note.

    I'd definitely read it if you care to write it up. When I saw what you did I thought "Wow. I wish I had just used this to make my One Finger app." The One Finger app sounds good but the code is beyond confusing in a lot of ways. Still, I code for own use as a rule to solve puzzles and problems. Usually to save money or drudgery. I never really save much time since it takes a lot to get something useful done.

    It's useful to invent your own solutions but also good to see how it could be more elegant, extensible, and re-editable. The Bram Father gave us scales... we should use them. One chord routine will work across all those scales... a lot smarter than (60, 64, 67).

    I already did write it up, and I'm pretty sure you read and commented on it. I'll see if I can track it down and PM you the link. :D

  • @wim said:

    @McD said:

    @wim said:
    I was thinking of bringing up the way I found to "calculate" standard chords from a single root note.

    I'd definitely read it if you care to write it up. When I saw what you did I thought "Wow. I wish I had just used this to make my One Finger app." The One Finger app sounds good but the code is beyond confusing in a lot of ways. Still, I code for own use as a rule to solve puzzles and problems. Usually to save money or drudgery. I never really save much time since it takes a lot to get something useful done.

    It's useful to invent your own solutions but also good to see how it could be more elegant, extensible, and re-editable. The Bram Father gave us scales... we should use them. One chord routine will work across all those scales... a lot smarter than (60, 64, 67).

    I already did write it up, and I'm pretty sure you read and commented on it. I'll see if I can track it down and PM you the link. :D

    I couldn’t find it, but have now added it as a brief tip on the wiki page: https://wiki.audiob.us/mozaic_tips_and_tricks#calculate_standard_chords_from_a_root_note.

    Now, if I can only remember that I did that for the next time it comes up...

  • @McD , @espiegel123 , @unicity , @_ki , @wim

    Thanks to your help, I FINALLY made a script that actually works! :)

    @Description
    This script allows you to record three notes for a chord by pressing three keyboard keys.
    Then you can play the chord by pressing the Pad labeled "PLAY".
    Pressing the pad labeled "RESET" will erase the recorded notes, and ready the script for entering a new chord.
    @end
    
    // Set the pad Layout, Initialize the variables, Add Labels to the pads.
    
    @OnLoad
    ShowLayout 2
    LabelPad 0 , {RESET} 
    LabelPad 1 , {PLAY}
    counter = 0
    FillArray chordnote, 0, 10
    @End 
    
    @OnPadDown
    
    // Reset the Array when the Reset Pad is pressed.
    
    if LastPad = 0
    counter = 0
    FillArray chordnote, 0, 10
    endif 
    
    // Play the chord when the Play Pad is pressed.
    
    if LastPad = 1
    
    SendMIDINoteOn 0, chordnote[0], 100
    SendMIDINoteOn 0, chordnote[1], 100
    SendMIDINoteOn 0, chordnote[2], 100
    
    SendMIDINoteOff 0, chordnote[0], 100, 500 
    SendMIDINoteOff 0, chordnote[1], 100, 500
    SendMIDINoteOff 0, chordnote[2], 100, 500
    
    endif 
    @End 
    
    // Record three notes for the chord by pressing keyboard keys.
    
    @OnMidiNoteOn
    
    if counter = 0
    chordnote[0] = MIDIByte2 
    endif 
    
    if counter = 1
    chordnote[1] = MIDIByte2
    endif
    
    if counter = 2
    chordnote[2] = MIDIByte2
    endif
    
    Inc counter
    @End 
    
  • wimwim
    edited February 2020

    Nice work @horsetrainer!

    Just one tiny suggestion. You might want to fill the array with -1 rather than 0 since 0 is a valid midi note and will be played back when you hit the play pad if you haven’t recorded a note in each position. Then you can further enhance the script by checking that the chordnote array variable isn’t equal to -1 before playing a note on the off chance that a synth would be buggered up if an invalid note is sent to it.

    You can also avoid the three if statements in the @OnMIDINoteOn event by replacing them with with a single chordnote[counter] = MIDIByte2. Of course, the main thing is to keep the code understandable to you, not to anyone else, so feel free to ignore these thoughts.

    @OnMIDINoteOn
      if counter > 3
         counter = 0
      else
        chordnote[counter] = MIDIByte2
        Inc counter
      endif
    @End
    
  • @wim said:
    Nice work @horsetrainer!

    Just one tiny suggestion. You might want to fill the array with -1 rather than 0 since 0 is a valid midi note and will be played back when you hit the play pad if you haven’t recorded a note in each position. Then you can further enhance the script by checking that the chordnote array variable isn’t equal to -1 before playing a note on the off chance that a synth would be buggered up if an invalid note is sent to it.

    You can also avoid the three if statements in the @OnMIDINoteOn event by replacing them with with a single chordnote[counter] = MIDIByte2. Of course, the main thing is to keep the code understandable to you, not to anyone else, so feel free to ignore these thoughts.

    @OnMIDINoteOn
      if counter > 3
         counter = 0
      else
        chordnote[counter] = MIDIByte2
        Inc counter
      endif
    @End
    

    No, those are really good thoughts.
    Now that I have a base to work off of, I can understand the code you wrote above.

    I also now get what that -1 is all about.

    Thanks Wim.

  • @horsetrainer said:
    @McD , @espiegel123 , @unicity , @_ki , @wim

    Thanks to your help, I FINALLY made a script that actually works! :)

    It feels great when it does what you wanted, doesn't it. I suspect you have greatness in you for
    turning ideas into working scripts. Mastering code does take a lot of effort and study but
    hacking out ideas is really just a matter of persistence.

    If you're brave you can ask the pro's to provide advice where optimizations might be possible.
    Sometimes they will generate a quick sample that shows how they might approach the same
    effective solution. I do think tackling these problems alone help the learning stick and become a part of your neural pathways.

    You can watch someone ride and pick up some tips but you really must get on the horse to get better.

  • McDMcD
    edited February 2020

    Another teaching example of a Mozaic script segment:

    If this plays a C Chord on middle C...

    C_Major_Chord = [60, 64, 67]
    SendMIDINoteOn 0, C_Major_Chord[0], 100
    SendMIDINoteOn 0, C_Major_Chord[1], 100
    SendMIDINoteOn 0, C_Major_Chord[2], 100

    What do you think this does?

    transpose = 2
    Strum_Rate = 100

    C_Major_Chord = [60, 64, 67]
    SendMIDINoteOn 0, C_Major_Chord[0] + transpose, 100
    SendMIDINoteOn 0, C_Major_Chord[1] + transpose , 100, Strum_Rate
    SendMIDINoteOn 0, C_Major_Chord[2] + transpose, 100, Strum_Rate * 2

    Imagine set a value of transpose and Strum_Rate with a Knob control.
    They can be set anywhere in the script and when the Knob is turned the chords will
    be transposed and strummed at the new settings.

    The Knob changes will be in an OnKnob event block while the SendMidiNoteOn is somewhere else.

    I hope that help explain how you can adjust knobs linked to a variable and the script produces
    altered output as you roll the knobs.

    There are also some Global Variables that share their values across Mozaic runtime instances.
    Change a Knob in one script and outputs change across 2 or more different Mozaic scripts.

    You can tie Knobs to all kinds of typical App parameters like Transpose, Scale, PPQN, etc.

  • edited February 2020

    Mozaic app is freezing in standalone and AUv3 mode, when I try to 'Select all' text on the code page.

    I was wanting to export the Chordial code into Sublime Text 3 to review the code with @ki 's syntax, but the app freezes and I need to exit via home button.

    Any advice? cheers

  • @SpookyZoo said:
    Mozaic app is freezing in standalone and AUv3 mode, when I try to 'Select all' text on the code page.

    I was wanting to export the Chordial code into Sublime Text 3 to review the code with @ki 's syntax, but the app freezes and I need to exit via home button.

    Any advice? cheers

    Tried with different scripts and even the Chordial. Not reproducible. Works as expected.
    Try the windows solution. reboot :smile:

  • edited February 2020

    @MrBlaschke said:

    @SpookyZoo said:
    Mozaic app is freezing in standalone and AUv3 mode, when I try to 'Select all' text on the code page.

    I was wanting to export the Chordial code into Sublime Text 3 to review the code with @ki 's syntax, but the app freezes and I need to exit via home button.

    Any advice? cheers

    Tried with different scripts and even the Chordial. Not reproducible. Works as expected.
    Try the windows solution. reboot :smile:

    Hmm. Yes, I've just reset iPad with long press of home and off buttons. Same issue. Once I have selected all the text, app freezes.

    I'm on iOS 12.4.1

    iPad Pro 12.9 (2nd gen)

    Any easy ways of getting code exported from the app?

  • @SpookyZoo said:
    Mozaic app is freezing in standalone and AUv3 mode, when I try to 'Select all' text on the code page.

    I was wanting to export the Chordial code into Sublime Text 3 to review the code with @ki 's syntax, but the app freezes and I need to exit via home button.

    Any advice? cheers

    What hardware and OS version?

    As MrB suggests, try rebooting.

  • @espiegel123 said:

    @SpookyZoo said:
    Mozaic app is freezing in standalone and AUv3 mode, when I try to 'Select all' text on the code page.

    I was wanting to export the Chordial code into Sublime Text 3 to review the code with @ki 's syntax, but the app freezes and I need to exit via home button.

    Any advice? cheers

    What hardware and OS version?

    As MrB suggests, try rebooting.

    Yeah, no joy. :(

    We posted at same time btw.

    Would be great to have dedicated 'copy all' and 'export' buttons in the code section. @brambos :)

  • You can't see it, but once all text is selected I'm trying to copy. App freezes, no response.

  • @SpookyZoo said:

    @MrBlaschke said:

    @SpookyZoo said:
    Mozaic app is freezing in standalone and AUv3 mode, when I try to 'Select all' text on the code page.

    I was wanting to export the Chordial code into Sublime Text 3 to review the code with @ki 's syntax, but the app freezes and I need to exit via home button.

    Any advice? cheers

    Tried with different scripts and even the Chordial. Not reproducible. Works as expected.
    Try the windows solution. reboot :smile:

    Hmm. Yes, I've just reset iPad with long press of home and off buttons. Same issue. Once I have selected all the text, app freezes.

    I'm on iOS 12.4.1

    iPad Pro 12.9 (2nd gen)

    Any easy ways of getting code exported from the app?

    Is this happening with all scripts or only Chordial?

    Even though, you rebooted, see if powering down (I.e. saying "yes" to a power off prompt) and powering back up works. I have occasionally had that solve issues that the other types of reset didn't.

Sign In or Register to comment.