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 StoreLoopy Pro is your all-in-one musical toolkit. Try it for free today.
<Very> basic Mozaic question
Hi, everyone. I’m getting my feet wet with Mozaic, and I have a question with this simple command.
When I run this, it works fine. Whatever note I press, Mozaic sends out a perfect 5th higher. Then the note stops.
@OnMidiNote
SendMIDIOut MIDIByte1, MIDIByte2 + 7, MIDIByte3
@End
However, instead of adding 7, I want to add a random value between 0 and 12:
@OnMidiNote
offset=Random 0, 12
SendMIDIOut MIDIByte1, MIDIByte2 + offset, MIDIByte3
@End
The problem is that the notes aren’t turning off.
Why does adding this variable value prevent a MIDI off message, and how do I fix it?
Thanks to any help you can offer.
Comments
There are 2 MIDI events for every note: On and Off.
Your start a the ON with a random Note value.
Then follow up with random OFF Note value that actually in most cases is NOT ON. There’s still one out there playing however.
A really simple alternative is to fix the note length by launching “Note On” and “Note Off + delay” together in your code.
The delay is just another value added to the SendMIDIOut parameters. I would use a pair similar to this:
SendMIDINoteOn MIDIChannel, Midibyte2 + offset, 100
SendMIDINoteOff MIDIChannel, MidiByte2 + offset, 0, 300
Another useful trick: a MIDI Note On command with the volume set to 0 is interpreted as a Note Off by almost all apps.
So, you can get away with this minimal code change:
Delay = 200
SendMIDIOut MIDIByte1, MIDIByte2 + offset, MIDIByte3
SendMIDIOut MIDIByte1, MIDIByte2 + offset, 0, Delay
Delay’s are in milliseconds with 1,000 = 1 second.
I've never used @OnMidiNote.
I would use @OnMidiNoteOn and @OnMidiNoteOff.
But the reason why it's not working, is that a new random number is being generated when it receives a NoteOff message.
So let's say you change that function to be @OnMidiNoteOn, and then you duplicate that function for @OnMidiNoteOff, but remove the "offset=Random 0, 12" statement from the @OnMidiNoteOff version. That's an improvement.
But now, if it receives two NoteOn messages before receiving a NoteOff, then it will still generate a new value for the "offset" variable, which means that only the most recent NoteOn will be paired with a NoteOff message.
So the solution would be to store each "offset" number in one array, and store the associated MIDIByte2 in another array, and put them both at the same location in the array.
The location variable could be called "Location" or "Index". After storing the offset and MidiByte2 in the two arrays, at the same "index", you'll want to change the index variable to a different number, so that the next NoteOn doesn't overwrite that data.
So you could use a third array to track which indexes are currently being used to store NoteOn messages, or when a NoteOff is received, you could change the value located in your MidiByte2 array to be -1, to indicate that no byte is being stored there.
(Side note: There are other ways to do this.
The most newbie-ish way might be to just write "inc index" or "index = index + 1" and then
if index = 100
index = 0
endif
But then, if 100 NoteOns and NoteOffs are played before a certain key is released, there will be a hanging note.)
Then, when a NoteOff is received, you want to use a "for loop" to cycle through the Byte2 array, and search for the Byte2 value of the NoteOff message. In the offset array, at the same location, that's where the associated "offset" message will be stored.
So that would look something like this.
@OnMidiNoteOff
OffByte2 = MidiByte2
for i = 0 to 127
if OnByte2Array[i] = OffByte2
SendMidiNoteOff MidiByte1, MidiByte2 + OffsetArray[i], MidiByte3
OnByte2Array[i] = -1
Exit
endif
endfor
@End
McD and Skyblazer, thanks very much for your fast replies and help! I appreciate it.
Everyone…mark your calendars…I hope to release a Mozaic script around August 2037.![:/ :/](https://forum.loopypro.com/resources/emoji/confused.png)
@dcollett I'd say that this is a perfect use case for the
NoteState
matrix:See section "6. Remembering note states" in the manual.
Grandbear, thanks very much for your input also. I really appreciate all of you helping. I may be able to speed up the release to 2036.