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.
Comments
What a brilliant script @McD looking forward to giving this a spin.
hot damn, I really love this!
This morning we had a discussion about killing hanging notes. I want to state that I am against the killing of notes. When they are hanging it is because off a fault of the controller, the notes are not to blame.
Since some hosts do not like to get their midi buffer filled with thousands of delayed midi commands I created this script to release all the notes that I accidentally hung, without any killing.
While programming with Mozaic this is a handy tool to keep in your midi effects chain.
https://patchstorage.com/abolisher/
@Alfred catch and release? It does seem more humane, though recent studies indicate that hung notes do feel pain.
@mojozart Yes I feel their pain. Allways franticly searching when I hear one being hung...
I thought this better and more humane then building a mouse trap.
Nice work. It's fun and instructive to read the script too. I just noticed you have a whole series of MIDI Scripts with Branding in the naming.
@McD I just published a note state tracking code example script showing how to implement note state tracking to enable functions acting on active notes only - the demo code 'mutes' all active notes.
You could use method or even parts of the sample code in your chorder script to send NoteOffs when a knob change for chord layout would result in hanging notes.
.
In my processing scripts (like Midi Filter and Transpose or CopyCat) i use a different strategy - i use the NoteStateArray to store the generated output note (using a combined single value v= ch*256 + note) and channel / input note in the OnMidiNoteOn. And when OnMidiNoteOff is triggered, i lookup the output and output a NoteOff using the stored note and channel. This will always turn off the correct note, regardless of what processing setting were changed between NoteOn and NoteOff.
Nice! I was thinking about doing the channel multiplier for the same purpose. One could pack other things in there with other multipliers as well.
@wim In the CopyCat script i pack three values into a single NoteStateArray entry - there is even documentatiom about this technique in the scripts source :
Thanks @_ki! Saved me some brain cells once again.
Do you think this encoding could be extended to hold up 8 values (64-bit integers)?
mask8 = maskmaskmaskmaskmaskmaskmask*mask
No hurry. I can write some tests and figure it where the limit is.
@McD , @wim Two additional things i forgot to mention and just added to my above code sample:
The stored values need to be positive and between 0 and mask. And the EMPTY constant also needs to be in that range.
Otherwise the proposed simple packing operation
storedVal = valC * mask2 + valB * mask + valA
will not work..
Regarding packing 8 values:
I know that Mozaic internally uses only a single datatype for the values - a floating point value. The largest integer that can be stored therefore depends on the number of mantissa bits used. In a 32 bit float, there are usually 23 bits for the mantissa. And in a 64 bit float there are 52 mantissa bits.
So you probably can't store integer values with 64 bits as the internal number format needs some bits for the exponent and sign bits (see wikipedia )
It’s a bit more complicated even. For integer-variables it uses 32 bits integers internally. But it can lose that precision when:
A. You change its variable type (e.g. when using it in a floating point context)
B. When a variable is loaded from a saved state
So you could in practice use 32 bits of packed data (and even perform bitwise operations on them), but it’s not guaranteed to work under every circumstance.
@brambos Thanks for the clarification, i'll keep that in mind when i use packed values.
Hey I just wrote two scripts for use in Loopy which accomplish the same thing in different ways and am wondering which would be considered ‘better’ or more efficient, and of course if there’s more efficient ways to write either of these scripts, or something different altogether for the idea. Both work as I’m intending so I’m wondering what other more experienced programmers would do in this case, and also figure it could be a good example for other beginners.
The intention is to ‘remember’ a set number of pads/notes played and then recall those with the push of a single pad/note. This again is for live use in Loopy to mute/unmute any number of tracks with the push of a single button, currently not supported as a midi binding option in Loopy, though fairly sure it will be with the next Loopy edition...but I can’t wait... 😉
I actually ran this by the forum back in June or July to see how I was doing when just starting to try things out and actually @wim you said you were too tired at the moment to look at it but would check it out later (no problem at all of course, I got too busy with other things to continue with Mozaic anyways until now)...That first script used NoteStates to remember the notes played, but was quite messy and now while in the process of reviewing it before posting again I came up with another idea for how to do it with arrays instead of NoteState saving (also wanted to try to get a handle on arrays and a use for it in the first place), which I thought would be more efficient. But then realized NoteState saving was totally superfluous in the first script and could just be done with variables, BUT that pointed me to using note states instead of arrays in the SECOND script to prevent a possible accidental double memorizing and sending of the same notes within an array... Learning is fun. 😛
ANYWAYS, so now I have two which I’m unsure about which is better! Here’s the first using simple variables:
AND here’s the second version with NoteStates, feels prettier to me but still wonder if it’s better in the end...
Any comments/input is super helpful as I’m learning! Thanks_
@ManWhoWouldBeStrings The best way to learn this stuff is study as many different scripts as you can find to get a sense of style and learn neat tricks.
It looks like you are testing to much. Start with testing if it is the right channel. Then inside that block test if it is the right note. Also if you first test if the channel is not your channel, then right away you can sendMidiThru.
I would make a separate handler for the toggling so you only have to change your code in one place.
@ManWhoWouldBeStrings The first version can be shorted to less than half length just by using arrays:
.
To enhance your script , you should setup a visually clutter free GUI just showing the name, also
set the icon name by extending your @OnLoad :
You could also make a pad recall the current set. By moving the recall code into a
user event which then is called from both the sendtrigger detection and in @OnPadDown.
@ManWhoWouldBeStrings I Just looked through your second source - you are basically using only one dimension of the 2D note state array.
So you can replace all
SetNoteState 0,a,b
withstate[a] = b
and allGetNoteState 0,a
withstate[a]
to start using the correct array type..
My above script ent one step further and did not need to step through a note range to find the right one, but defined the correct value in a trigger[] array - therefore it always only needs to step through these 12 entries.
I'm uploaded the "McOrchestrator" Mozaic Script building on the work @_Ki and I did with the "One Finger Orchestra" concepts.
By default it outputs Arpeggio's on Channel 0 and Voiced Chords on Channel 1. There are knobs for a lot of tweaking parameters.
I made a quick demo in AUM using:
Ravenscroft 275 for Arpeggios
Noise Strings for chords
AudioKit D1 Digital Synth chords
FX from:
Visual Mixer
Eventide Black Hole
TB Reverb
https://patchstorage.com/mcorchestrator/
Just use "One Finger" at a time to play it (single notes are best). It can generate a lot of notes quickly. The Arps are "Sample and Hold" and the Chords will follow the Note Off's of the input.
Chords also have a Delay option from fast strum to one note per second or so. They can complete with the Arp output in good and really bad ways.
Hi @McD is see where you are hanging the notes in the arp section.
Give them a release ticket right away. Another noteOn with velocity 0 and delay 200 will do.
Thanks. I'll do that. I'm having fun making up new chord/arp combinations/sequences.
Next update is getting some noticeable performance upgrades and a system that will try to rescue you from accidental infinite loops.
Is there any example code for making infinite loops?
I'm glad you're updating the app. I hope we can help find more users of the tool to reward your investment in the product.
I went to the coffee shop and it works! So I put some SendMIDIOut statements in the Loop and the whole room started dancing. When I got home... it stopped working.
When good boffin humor goes bad.
I added the extra SendMIDIOn with 0 velocity and (200 + Delay). Delay is a variable which allows the users to dial-in more note length to taste.
I probably need to have a delay for chords and another for arp's since they control the "strum" simulation as well in chord play and the ambient slow roll out of notes and a control for Arp "release". I upload the patched script as v0.8.
I need to give the Chord Maps useful names. Right now they echo the Scales of "The-Chordulator" since @wim's code showed me a solid way to add labeling for knobs and I didn't have ready names for the various chord maps.
That's where the fun lies for me... generating chord maps. It's composing really. I had a "rest" feature and will probably add it back to
avoid quantized brain syndrome.
It don't men a thing if it ain't got that fascination' rhythm.
Oh yeah. I should dial in "Scha-wing" with another knob. I'm going to end up with 22 knobs with knob 22 being used to load a new knobset or maybe not.
I've waiting to hear something that someone else makes with this script to see what that feels like.
Hey thanks @_ki and @Alfred for the suggestions and code for my little attempts at scripts. SUPER helpful for my understanding of things. I understand better now how to use arrays in interesting ways and the difference with the note state array system. Much appreciated.
However there’s something going on with the script you wrote @_ki which I can’t figure out, which is that it is always sending 0x14 (the note stored in the trigger[0] array) on ‘memory recall’...
Also,
@_ki said:
The reason I did it the way I did before was to only send the notes that had been stored, rather than sending 12 notes every time whether or not they had stored values or simply 0. I tried it again using your array system like this...
What do you think?
@_ki said:
I left any GUI stuff out as I don’t actually use the (super cool) GUI system with Mozaic as I keep Loopy open on screen all the time and manage everything else with an external controller (with my setup I find things start to go off the rails if I switch between IAA apps too much live). However I was just thinking...in your opinion would it be a good idea to JUST use one of the Pads like you suggested, midi-bound to a command (the same sendtrigger) in AUM, and so just use the OnPadDown - Call@RecallTracks instead of testing for the note itself? One less thing to test for?
I have a few more general questions (rather than concerning the stuff above in my last post) regarding what is a more efficient way to setup a few simple scripts running in AUM for controlling Loopy in interesting ways.
Is it better to:
embed each of the fairly simple codes I’ve got going into one longer script
OR
load multiple instances of Mozaic with the separate scripts
And with multiple instances of Mozaic, is it better to:
Load them all in a chain in one AUM channel
OR
Give them each seperate channels
?