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
I think the round robin would work best simply with dials for each of the intervals. Perhaps that is what @winconway is getting at.
You can also add attachments to replies on patchstorage.com. This might be the best way to add the pdf file.
I'm looking forward to checking out the script. As someone else just learning as I go, I like seeing how different people approach things.
I just put my Mozaic app, called Frazer (described in a previous post) on patchstorage.com. The first comment there contains links to Dropbox for the documentation and the AUM project file. Helpful comments are appreciated!
I’m having trouble with AUM saving Mozaic GLOBALs in an AUM Project. I posted a week or so ago asking about it, and was assured that all Mozaic Variables were saved when you saved. But I just finished a test, and it didn’t happen as I expected.
Step by step:
1. Empty AUM PROJECT WITH A NEW INSTANCE OF Mozaic.
2. Ran this code:
GLOBAL71[5] 6
GLOBAL71[4] 5
GLOBAL71[3] 4
GLOBAL71[2] 3
GLOBAL71[1] 2
GLOBAL71[0] 1
Saved the AUM project as LoadReadTest and closed AUM.
Reopened AUM and opened the LoadReadTest project.
Ran this part of the code:
for idx = 0 to 5
log {GLOBAL71[}, idx, {] }, GLOBAL71[idx]
endfor
The Mozaic Log shows:
GLOBAL71[5] 0
GLOBAL71[4] 0
GLOBAL71[3] 0
GLOBAL71[2] 0
GLOBAL71[1] 0
GLOBAL71[0] 0
They’re empty and don’t appear to have been saved. Either my understanding of how this works is flawed, or there’s a problem.
@brambos ?
No, I actually answered that question. Globals are not saved, since they don't belong to any one instance of the plugin. It's conceptually impossible.
And that’s why I asked if there was a way to save GLOBALs, so the answer is no. The only way to communicate between two instances of Mozaic is with GLOBALs, right? I guess I could always copy the GLOBALs to internal variables before saving, then check if they were saved and restore them on reopening. My Frazer Mozaic “app” was loaded to patchstorage this morning. I’ll post my revision this afternoon.
Thanks for your quick reply. You’re amazingly attentive.
This MOZAIC app is pretty amazing, very cool to see so many people involved... creating.
@motmeister tried to download your script Frazier via chrome and I get this. Every other script downloads without a problem?
I tried other browsers aswell with built in download capabilities get the same page come up ?
Globals are primarily meant for communicating between instances. Is it essential for your script to be able to save global states in AUM sessions?
Well, what I’ve now added to my Frazer Project is a function to copy GLOBALs to internals before saving the AUM project, then giving the option of restoring the internals back to GLOBALs when reopening the AUM project, but I think it would be helpful. There are ways around it with code, which I’ve utilized.
There are two modules in Frazer. The main one does all the heavy lifting creating MIDI phrases. The second one, which is a player, needs access to these phrases to “play” them. The player doesn’t change them. I’m thinking of ways to use temporary GLOBALS that are just used for the communication. That could possibly work. Then I could change the more persistent variables to internals, and they’d always be saved when the AUM project was saved.
I highly recommend this. Remember that Globals are not a safe space for storage. Another script (or another instance of the same script) could be overwriting the same Globals at any moment.
@brambos on the topic of GLOBALs - is every global a Mozaic array (ie behaves exactly like normal variables) or are there any caveats?
I'm thinking of a "copy pattern between instances" feature for Flow - that would require globals to be full arrays and support the normal FillArray/CopyArray functions.
Ooooh. That would be a great addition for Flow.
@Peblin Yes, the FillArray/CopyArray functions work like normal on the global arrays.
Yeah - I need it myself when developing to be able to move patterns between versions
Now I only have to solve the problem that I'm running out of pads/buttons for adding new features!
Need to fit in CC automation as well somewhere...
Thanks @_ki!
@Peblin : Just found a glitch in Flow 1.0.1
=> [ONPADSINGLETAP_BUTTONS] Syntax Error: unknown or invalid argument "
️"
BTW: The 'box' character is only shown here in the AB forum post after copying the error-message, in Mozaic there's just the double-quotes and a line-break.
.
I could not really see an error in the OnPadSingleTap_Buttons function, the code look alright.
But when i removed the indentation in all lines following ' elseif pad = BTN_CLEAR_ALL' (and checked for trailing spaces) and re-added the spaces, the error was gone.
.
@Brambos It seems there is an offending 'invisible' char in there somewhere, could you check the script ?
Thanks, I managed to reproduce it. I'll check the code and see if some leftover unicode marker is lurking somewhere.
On a vaguely related note @brambos - I've have had several instances where Mozaic's parser breaks when editing the code, and rearranging the code or just clicking "Upload" again makes the code parse correctly. So, I think there might be some parser quirks to iron out.
@_ki (and others... hi @wim ) if you come up with improvements for Flow I'm more than happy to add collaborators and/or accept pull requests at https://github.com/peblin/flow-sequencer. I've got some CC automation cooking there as well but haven't come up with a nice way of "smoothing" CC values between recorded steps yet.
@Peblin Yay, cool that you are using github for collaborative Mozaic script development - thats another step into the right direction 👍🏻
As i see that you did a lot of commits, how is your workflow ?
I script and edit directly in Mozaic/AUM with a bluetooth keyboard and therefore all i can imagine is 'select all' and 'copy' in Mozaic and then somehow paste into an git-enabled editor on the iPad and commit to github.
My workflow is kind of "bi-directional", using handoff/universal clipboard in MacOS/iOS;
I use GitHub Desktop to simplify my git work. It's really handy and you see all your changes right away in the commit window.
I'm really satisfied with the workflow above - it makes it a lot less scary to do weird refactoring and break stuff when you know that all your stuff is versioned and safe.
EDIT: Forgot to say that I use CoffeScript syntax highlighting in VSCode, it handles most of the Mozaic language quite alright. Except of course the string {brackets}.
This doesn't sound safe, if any other script could overwrite the same globals during the copy process?
Dang, we are gonna need a mozaic YouTube channel soon!
Indeed, it's not safe. It's also based on an undocumented hack in the way Apple has implemented AUv3 in iOS. It's dirty in every single way
There's a reason I didn't want to incorporate it into Mozaic at first. I only added it after 'the community' asked me to do it anyway, in spite of all the drawbacks. So it's pretty much a "use at your own risk" affair.
@Peblin
Thanks for the in deep workflow description. Having a mac and universal clipboard feature makes things easier than with a windows pc. I just searched for IOS github clients and there some with integrated editors and syntax highlighting...
@bleep
Luckily there aren't
a) that many scripts using globals and
b) there are 100 arrays with 1000 entries each.
Therefore interference is quite unlikely (nowadays)
Nevertheless, to check for other scripts interfering my code for bi-directional script to script communication uses
This might seem overkill but it was quite easy to implement, allows to recognize interference by other scripts, shutdown own sending and output a log message. I prefer this idea than users just wondering why scripts combinations are not working
BTW My scripts with communication use global99[960-999] . If there are objections i'll move to another location.
@_ki sounds like a carefully implemented solution!
Still, it leaves open a blast from the past with "Syntax error: 999"
In theory yes.
In practice, I'd suspect that most scripts will use globals for communicating between instances on interaction - such as copying stuff between instances with a button. Feels like really bad practice if a script depends on globals being reliable and consistent over time.
I'm really impressed by the elegance of @_ki 's checksum solution but I personally think it's overkill and that GLOBALs shouldn't be used for any kind of "realtime"/continuous script communication. We have midi (soon SYSEX?) for that
It was a serious change in direction for the Frazer app, but lots of lessons learned. The old method stored its main data in GLOBALs and simply told the “player” scripts to go read them. The new way packages the data the players need and puts them in GLOBALs only long enough for the players to internalize them, then they delete the contents of those GLOBALs. At the time the data is passed to the players, they play the phrases immediately. I wasn’t sure whether the data transfer would be enough of a hit to affect the timing. I’m still testing, but I can’t hear any delay, thank goodness. My documentation will clearly spell out which GLOBALs I’ll be using so others will be aware. And if they interfere with someone else’s script, I can change them. There aren’t that many now.
@Peblin The scripts communicate about once a bar or when settings change (its ToggleChannelsOnBarDivisions and its WIP companion) - not a continuous stream with lots of traffic.
I could change that to sysex (when available in the store version) - but this would require two routings to be setup by the user. The current solution with globals just works, without any setup.
Another, acceptable way (for me anyway) is just to chain instances. Solo the first, record the second, press play. But you have to do your best to press stop before it loops or you get stacked notes.
This is also a good way to "bounce" patterns. Enable the patterns you want in the first instance, arm one on the second instance, and do as above.
If there was a single loop record option, it would make the above even easier.