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 hope I didn't belabor the point too much, but it's important to understand the differences between AUv3 parameter control and direct MIDI control in apps.
Right on! Happy to learn! Looking forward to testing your new script soon!
Once again, I am ever so thankful! This works amazingly well! I am able to switch script presets and the light stays on the previously chosen pad!!!! AWESOME!!! Thank you so much for getting this to work! Again!
Great! Do you have any questions about how it works? It's helpful to understand things as you go so that you can more easily make use of the concepts later on.
Yes I would love to know how it works! Right now I am thinking of the global variable as sort of a "RAM storage place" where even when other scripts open and close information is stored at this global level. Am I close?
Close, but it's not as extensive as that. The global variables are just simple pieces of data that are available to read and set from any instance. So, if Global0 is set to the number of the lit pad, then any script can see which number pad is lit.
Scripts don't know anything about each other's state, so the second part about the "open and close information" isn't accurate.
You could use a global variable to store information about which scripts are running, but you'd have to devise a way of using a Global variable to do that. Explaining ways to do that could get complex, so I won't try unless you have an actual problem to solve that requires knowing the state of other instances.
The explanation for the pad-lights example I just gave is pretty simple. Global0 is set to the number of the pad that is lit. Any script can check that variable to know which pad was last lit. Any script can update Global0 with the number of the last pad that it lit. Simple.
Except, care is needed. If any script can set a variable, and you don't know what that variable means then misunderstandings can occur. Let's say you use Global0 for that last pad number, but you load a script from someone else and you don't realize that they use Global0 for something else like "last note played". I think you can see how that would mess things up.
Hope I didn't make your head spin with all that. tldr; Avoid global variables if at all possible, but use them with care if they're needed.
Thank you for that excellent and detailed explanation! You're an excellent teacher!
I'm glad it helped. 👍🏼
New quest! I haven't been able to locate a solution. My expression pedal outputs a cc value curve that is a quick ramp up than flattens out. Is there a way to scale it so that it's more even?
@ztones, do you have Drambo?
The easiest way I can think of is to use Drambo’s graphic shaper to draw in a compensating curve, futzing around with it until it responds the way you like.
You could do it with Mozaic, but you have to be better at math than I am. Check out the TranslateCurve function first if you want to try.
@ztones, midi curve from the midi tools suite might work too. It’s iPad only. KQ Midi Modulate is an advanced app that should be able to handle this. It has a pretty steep learning curve though.
From what I can tell, those curve tools are velocity curve tools. I need CC values re-scaling, so as the values are coming in, they'd be individually rescaled to different values. I sent a message to Midi Tools so I'll confirm for sure....
I did a quick and dirty work around with Midi messenger (could have been done in mozaic too) where I created "stepped" ranges and subtracted varying amounts from the value. So the 0-60 was divided by 2, then, since I couldn't divide by 1.x, I had to subtract -40 from 60-100, -30 from 100-110, -20 from 110-120, -10 from 120-125 and zero from 15-127. Something similar, not exactly this...can't remember and not in front of it. It kinda works, much better and the changes are fast enough to not hear an audible volume skip, but it would be nice to have a better formula! LOL
Mozaic has both linear and non-linear rescaling functions you can use on any kinds of values.
Drambo with its Graphic Shaper module could handle the CC's.
You're right about the velocity curve tools. I shouldn't try to solve problems when my mother-in-law is yakking away in the background. 😂
I haven't looked too far in detail, but I'm pretty sure KQ Midi Modulate could deal with this.
Are those scales scales of values or musical scales? Can you show an example of what that code would look like? And most importantly what the math would look like? Thanks!
values. I mean scaling in mathematical terms. One function handles linear rescaling/remapping of values (TranslateScale) and the other TranslateCurve uses power curves. See the Mozaic manual for details.
I don't have Drambo but I just read that midiflow can do this... going to check it out as well as KQ.
I kinda got it working…but not reliably… in mozaic.
So the normal pedal CC’s are set to move knob 1 in the node’s midi control settings. Then I’m attempting to alter knob 1 sending the scaled CC's. The idea is to scale the knob's values from 0-100 to 0-60, and from 101-127 to 61-127. Sometimes it works, sometimes it doesn’t…it mostly doesn’t go below 61. Obviously the code is bad somewhere….but I tried!
`@OnKnobChange
v0 = GetKnobValue 0
scaled1 = TranslateScale v0, 0, 100, 0, 60
scaled2 = TranslateScale v0, 101, 127, 61, 127
if LastKnob = 0
if v0 = 0 to 100
SendMIDICC 2, 23, scaled1
else
v0 = 101-127
SendMIDICC 2, 23, scaled2
endif
endif
//Log (GetKnobValue LastKnob))
@End `
My recommendation is to first write pseudo code that captures what you want to do then turn that to code. See if this helps
You said:” The idea is to scale the knobs values from 0-100 to 0-60, and from 101-127 to 61-127. ”
Get a cc value and call it myvalue
If myvalue is 100 or less, scale that to a number in the range 0 to 60 and call it scaledvalue
Otherwise scale myvalue (which we know is 101-127) to a value from 61 to 127) and call it scaled value
Send scaledvalue
Your
if
condition syntax is wrong. Try changingif v0 = 0 to 100
toif v0 <= 100
to begin with, and take it from there. (Alternativelyif v0 >= 0 and v0 <= 100
if it's clearer for you.)Be sure to check the log whenever things aren't working as expected (or better yet always). That error would have been shown in the log.
Thanks @wim, cleaning up the existing code does work! It doesn’t quite like to go all the way to 127 (stops a lil shy) but it’s close enough. I think squeezing 61-127 into a small 11-127 is the reason….
`@OnKnobChange
v0 = GetKnobValue 0
scaled1 = TranslateScale v0, 0, 110, 0, 60
scaled2 = TranslateScale v0, 111, 127, 61, 127
if LastKnob = 0
if v0 <= 110
SendMIDICC 2, 23, scaled1
else
SendMIDICC 2, 23, scaled2
endif
endif
//Log (GetKnobValue LastKnob))
@End `
The not so great thing about this approach is that the knob is still displaying the original “bad” movement of the incoming CC’s, I will try @espiegel123 ’s recommendation of capturing the CC’s rather than knob movement, see which one I like better. Thanks guys!!!
You can use my logic with knob values, too. The main difference with your code is that you have one output variable and you only do one conversion per value. Your original code always converts two values.
I got it work beautifully with this:
>
ccin = MIDIByte3
scaled1 = TranslateScale ccin, 0, 110, 0, 60
scaled2 = TranslateScale ccin, 111, 127, 61, 127
if (MIDIChannel = 0) and (MIDIByte2 = 23) and (MIDIByte3 <= 110)
sendMIDICC 2, 23, scaled1
else
sendMIDICC 2, 23, scaled2 + 6
endif
!
However, how do I specify the “ccin” to be the MDIBytes3 for this particular CC ONLY, not any CC? Right now it’s effecting other CC values as well. Tried to specify only on ch1 and CC23 but now it’s only jumping between 0 and 64.
This does not work:
ccin = (MIDIByte1 = 0) and (MIDIByte2 = 23) and (MIDIByte3 <= 0)
MIDIByte1 is more than the channel number. It’s contains the MIDI command, which for a CC is 0xB0 added to the channel. Mozaic has convenience variables to check these separately. So, assuming your code above is in the
@OnMidiInput
event, theif
statement should be:I see! Of course! Makes sense! I was in the @onMIDICC section. Assuming there I wouldn't need the MIDICommand = 0xB0 part, will the Midi channel = 0 work there or do I have to move everything to the @OnMidiInput event?
@ztones : the way your if is set up> @ztones said:
If it is onmidicc, there is no need to test the midibyte1 or midicommand. You know it is a cc. You only need to test the channel and cc number
The problem with your if statement is that the else is activated for any incoming value not captured by the if — whether it is the right cc number or channel.
I’d suggest restructuring your whole block. Something like this pseudo code
IF ccNumber is 23 and midiChannel is 0
else
outValue = conversion for high values
end conversion section
sendmidicc 0, 23, outValue
ELSE (not cc 23 on channel 0)
Sendmidicc midiChannel, midibyte2,midibyte3
END handling cc23
Thank you both! Here is what I came up with that seems to work. Do you see any potential unintended consequences I may have missed?
@ztones Do you want other midi messages, such as other CC's, notes, etc, to be blocked by the plugin or to be passed through? Right now, if that's all of your code, everything else will be blocked.
@ztones - just a suggestion:
When you post multiple line code on the forum, the single back-tick in front and behind the code isn't enough to keep the forum from messing with the format.
To post in a code format box you can either either
The second option indents what you have highlighted by 4 spaces, resulting in the same thing as the three back-tick method. I prefer the three back-tick method, but both will work.
Thank you for that clarification! I was pressing the code shortcut before typing or pasting my code. I was not understanding that I had to highlight it and then choose that formatting. I'll do that next time!
As far as letting other messages through, I guess I I'll need to put SendMIDIthru.