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.

Request new Mozaic Scripts *HERE*

1636465666769»

Comments

  • edited December 2024

    @ztones said:
    I'm not sure what's going on but now its working. I did reboot about 10 mins ago for a different reason, wondering if that had something to do with it? This very same configuration was'nt working originally. Now it is. Please dont waste more of your time for now, thank you for trying, but lets see if this sticks before investing more of our time into it. Thanks guys!

    Circling back to this issue... Turns out I wasn't totally crazy and the problem didn't just "fix itself". I've been watching the behavior to see if I could spot a pattern but for now I'll just say it's random. I haven't changed a thing since the last postings about the tuner window showing and closing, but sometimes it closes the tuner window and sometimes it doesn't. I'll try to spot a pattern and when I figure it out, I'll certainly post back here in case somebody can benefit from the information.

  • Is there a way to write a script so that AUMs keyboard will always quantize to a scale of choice? Or to always tell the keys to run thru an app like scaler when you simply press the keyboard option on any open app?

    I know there are app like scaler that will quantize the keys, but in the middle of a live jam having to reroute to each instrument is not feasible.

    Would be cool if scales were added into aums keys but i don’t count on that ever happening

  • wimwim
    edited December 2024

    @reasOne said:
    Is there a way to write a script so that AUMs keyboard will always quantize to a scale of choice? Or to always tell the keys to run thru an app like scaler when you simply press the keyboard option on any open app?

    No. Mozaic can only act on midi that's routed through it. When you pull up the AUM keyboard by tapping the icon in an app window, the keyboard is automatically routed straight to the app.

    I know there are app like scaler that will quantize the keys, but in the middle of a live jam having to reroute to each instrument is not feasible.

    There are ways to make this a it more performance friendly.

    One is to use midi busses. Create one bus for each synth and make the routing from the bus to the synths. Route the AUM keyboard to the scale app. Route the scale app to all the busses. Disable all the busses but the one you want to play. When ready to switch, disable the old one and enable the new.

    Another is to use midi channels. You can route through a script such as MIDI Channel Router or others, to alter the outbound midi channel, then use channel filtering on the target apps.

    Of course, that doesn't bring the app window you want into the foreground. So the idea would probably need to be taken further to set up some buttons to send a midi command to parallel bind to change the routing and bring the app to the foreground.

  • Is it possible to create an awesome glide in Mozaic. Osc Audio made a great glide in sub808. If it’s possible to create a similar glide in Mozaic script. I can’t do Mozaic for the life of me.

  • @majorwizard047 said:
    Is it possible to create an awesome glide in Mozaic. Osc Audio made a great glide in sub808. If it’s possible to create a similar glide in Mozaic script. I can’t do Mozaic for the life of me.

    Glide is usually created in the synth itself via a setting that enables it for overlapping notes. It's not generally done over midi.

    One could use pitch bend with some knobs to control the rate, but it's problematic. Non MPE pitch bend is global, meaning it will affect all playing notes in the target synth. You also need some way to trigger the slide. If you use overlapping notes and there's more than one note overlapping, how do you know which note to slide to? The bend needs to be released in such a way that you don't hear it sliding back down. Mozaic can know when the note is turned off, but it has no way of knowing when the note has stopped sounding. If the target has a long decay, the release of the pitch bend will sound.

    Some of these issues would be a bit more manageable if the target synth is MPE enabled, or if it's purely Mono. But in those two cases I bet virtually every one has built-in glide.

    I could go on about all the potential issues, but I've already thought of enough to convince me I wouldn't like to try it.

    What target synth(s) did you have in mind.

  • @wim said:

    @majorwizard047 said:
    Is it possible to create an awesome glide in Mozaic. Osc Audio made a great glide in sub808. If it’s possible to create a similar glide in Mozaic script. I can’t do Mozaic for the life of me.

    Glide is usually created in the synth itself via a setting that enables it for overlapping notes. It's not generally done over midi.

    One could use pitch bend with some knobs to control the rate, but it's problematic. Non MPE pitch bend is global, meaning it will affect all playing notes in the target synth. You also need some way to trigger the slide. If you use overlapping notes and there's more than one note overlapping, how do you know which note to slide to? The bend needs to be released in such a way that you don't hear it sliding back down. Mozaic can know when the note is turned off, but it has no way of knowing when the note has stopped sounding. If the target has a long decay, the release of the pitch bend will sound.

    Some of these issues would be a bit more manageable if the target synth is MPE enabled, or if it's purely Mono. But in those two cases I bet virtually every one has built-in glide.

    I could go on about all the potential issues, but I've already thought of enough to convince me I wouldn't like to try it.

    What target synth(s) did you have in mind.

    I had assumed that glide was made with midi. I was using Dagger and wanted to glide with soundfonts too. Will be great to have for when you need it. Not every synth rompler has a glide. Do you know if ChatGPT or Ai can make Mozaic scripts?

  • wimwim
    edited January 21

    @majorwizard047 said:
    I had assumed that glide was made with midi. I was using Dagger and wanted to glide with soundfonts too. Will be great to have for when you need it. Not every synth rompler has a glide. Do you know if ChatGPT or Ai can make Mozaic scripts?

    Dagger has glide built in. Any other apps you have in mind? I can't think of any that don't have glide off the top of my head.

    I remember some attempts to get ChatGPT to write Mozaic code. I'm not sure if this was ChatGPT fail or success recently: https://forum.loopypro.com/discussion/comment/1378373/#Comment_1378373.

    You have a lot more questions to figure out before you try to write a program, ChatGPT or no. I listed a few. All of which and more would need to be considered. I'm not trying to be discouraging, I'm trying to help you set a direction that has a chance of being successful.

    On the other hand, sometimes the best way to flush out questions and issues is just to jump in. If I'm honest, a lot of my projects go that way. I think about it as hard as I'm able, but usually just dive in. Most people would tell us that's a bad way to go. It usually (eventually) works for me though.

  • Is there a script in existence which allows to set a timer in between messages that are being passed through?
    so for instance if you have a CC LFO, to be able to set the milliseconds in between every CC on the output?

  • wimwim
    edited January 25

    @Mo13 said:
    Is there a script in existence which allows to set a timer in between messages that are being passed through?
    so for instance if you have a CC LFO, to be able to set the milliseconds in between every CC on the output?

    Do you mean to only let through one message each period, ignoring the rest?
    I don’t see a script like that, but it would be simple to make if thats all that’s needed.

  • @wim said:

    @Mo13 said:
    Is there a script in existence which allows to set a timer in between messages that are being passed through?
    so for instance if you have a CC LFO, to be able to set the milliseconds in between every CC on the output?

    Do you mean to only let through one message each period, ignoring the rest?
    I don’t see a script like that, but it would be simple to make if thats all that’s needed.

    Not ignoring the rest but putting an interval in between every pass through message.

  • Thanks for the tip @Alfred but I don't think this is what I'm looking for as it doesn't seem to put a time distance in between sent out messages.

    Here is a line of code from @wim's "mega cc randomizer" which does exactly what I'm after, but then if it could be applied to process incoming messages:

    // default delay in ms between sending CC messages out
    cc_metering_ms = 50

  • @Mo13 said:

    @wim said:

    @Mo13 said:
    Is there a script in existence which allows to set a timer in between messages that are being passed through?
    so for instance if you have a CC LFO, to be able to set the milliseconds in between every CC on the output?

    Do you mean to only let through one message each period, ignoring the rest?
    I don’t see a script like that, but it would be simple to make if thats all that’s needed.

    Not ignoring the rest but putting an interval in between every pass through message.

    That would not work.

    If that LFO is sending a constant stream of messages, you can't just spread that out like that indefinitely.

    Let's say it's sending 100 messages per second (1 message even 10ms) and you tell it to spread them out to 50ms apart. You get and send the first message, then 10ms later the second message comes in. You want that message to fire 40ms later. So you save it, and trigger it 40ms later.But in the meantime, 4 more messages have come in.

    Each of those four messages has to be saved and delayed, but while each one is being delayed more messages are pouring in. You end up with a potentially infinite number of values that have to be saved and then played out over time. Mozaic has limited variable storage. Each variable can store only 1024 values. After that it gets tricky to manage storing lots of values.

    Think of an assembly line where parts come down the conveyer belt once per second. At one assembly point it takes 10 seconds to do an operation and put the part back on the belt. By the time the first part is done, there's 9 parts needing assembly. By the time the next part is done, there will be 18, by the time those 18 are done there will be something like 162, by the time those are done, something like 1,458 ... and so on.

    It could work for limited numbers of messages, but for something like a constant stream of LFO messages it'd be impractical.

  • edited January 27

    Hello all again! I’m trying to utilize the single/double/triple tap/hold script by @_ki but its a bit over my head (understatement of the year, but its only Jan, so its OK…. ;)). Where and how do I specify I want “THIS” to happen when I single / double / triple tap Pad 1 and Pad 2, etc. I’m sure it has to be in the @OnPadDown event, but I’m uncertain how. Right now the event looks like this:

    @OnPadDown
    pmPadDown[LastPad] = YES
    if pmPadExclude[LastPad]
    pPad = LastPad
    pNumTaps = 1
    pDown = YES
    Call @OnPad

    else
    Call @PMCheckStartTimer
    if not pmPadActive[LastPad]
    Inc pmPadsActiveCnt
    pmPadActive[LastPad] = YES
    endif
    inc pmPadTaps[LastPad]
    endif
    @End

    Do I change the LastPad to an actual pad number for each pad? What about the each tap? Or do I write it somwhere else entirely? Thanks!

    Here is the entire code:

    // ------ INSTRUCTIONS -----------------
    //     ( DO NOT INCLUDE )
    
    @Description
    ▫️◽️◻️⬜️ Pad & Shift Manager (Include) v3.1 ⬜️◻️◽️▫️
    
    Multi-pad or SHIFT single-/double-/triple-tap & hold interaction support script with user functions, intended to be easily included into your own scripts.
    
    Simply copy everything between 
      // =========================================
      //    PAD & SHIFT Manager 
      // ============== V 3.1 ====================
    
    and
      // ================ END ====================
      //    PAD & SHIFT Manager 
      // =========================================
    
    to the END of your own script. This garantees that you are still able to use own 
    OnPadDown/Up or OnShiftUp/Down interactions overriding the Pad & Shift Managers 
    functionality.
    
    
    In your @OnLoad need to call the Pad & Shift Managers initialization
    by adding 
      Call @PadAndShiftManagerInit
    
    If you want to, you can customize the behavior using *optional* variables 
    before calling the the initialization 
    
      pmAnalyseTime = 200         // Max delay for a single tap
      pmExcludePads = [7,15]       // Pads that will always do single taps
      pmExcludeCnt  = 2             // Number of pads with single taps
      pmManageTimer = YES        // NO when using own timer
      pmTickInterval = 50           // Timer interval
    
    A longer explanation of these optional parameters is found in the sample
    code part above the 'to be included scipt code'.
    
    There are also instructions on how to use only one of the pad and shift detection features or how to use an own timer event.
    
    Based on 
      Single Tap, Double Tap, and Tap-and-Hold by Bryan Appel
    
    
    
    HOW IT WORKS
      The pad manager delays all pad or shift-button reactions by a small time amout to be 
      able to analyse the interactions for single,double or triple taps and holds. 
      After the analyse time has passed and a pad has been tapped the OnPad user callback 
      event is called with pPad, pDown and pNumTaps parameter. 
      For shift taps, the OnShift user callback event is called with an pNumTaps parameter.
    
    It is possible to exclude specific pads or all pads or the shift button from the analysis. In this sample the last pads of each row react directly, calling OnPad without any analysis delay.
    
    If needed, the main timer can be managed by your own script.
    
    All user defined settings are done via variables in the OnLoad, no need to modify anything inside the Pad Manager Include snippet part of the source.
    @End
    
    
    
    @OnLoad
      ShowLayout 2
      LabelPads {P&S-M v3.1   Single-/double-/triple-tap and optionally hold PADs or SHIFT and watch Log output} 
    
      LabelKnobs { }
      LabelKnob 0,{ }
      LabelKnob 1,{ }
      LabelKnob 2,{ }
      LabelKnob 3,{HELP}
      for _knob = 0 to 3
        SetKnobValue _knob,0
      endfor
      showHelp = NO 
    
      // The following vars CAN be set before @PadAndShiftManagerInit
    
      // If they are not defined here, they will be automatically 
      // defined with their defaults in @InitPadManager
      //
      // In the most basic use-case, just Call @PadAndShiftManagerInit
      // in your OnLoad without setting any of them. 
    
    
      pmAnalyseTime = 300 
      // Length of double tap / tap-and-hold time window in msec. With 200ms one
      // is able to catch dbl-tap, with 250msec some triple-taps with hold and
      // 300msec seem to catch triple-tap without and with hold.
    
    
      pmManageTimer = YES
      // Set to NO if your script wants to controll the timer.
      // Your timer needs to run continously and with an update
      // interval faster than 50, otherwise the pad manager 
      // won't work. Also set pmTickInterval accordingly.
    
    
      pmTickInterval = 50
      // Update interval for the timer in msec.
    
    
      pmExcludePads = [7,15]
      pmExcludeCnt  = 2
      // List of pad ids and length of list to be excluded from
      // analysis. For these pads OnSingleTap will be called 
      // immediately in 'OnPadDown' without the analysis delay.
    
      Call @PadAndShiftManagerInit
    @End
    
    
    
    // USER EVENTS CALLED BY PAD & SHIFT MANAGER
    // -----------------------------------------
    
    @OnPad // params: pPad, pDown, pNumTaps
      if pDown
    
        if pNumTaps = 1
          Log {🟠 SINGLE-TAP & HOLD  on pad }, pPad
        elseif pNumTaps = 2
          Log {🟠 DOUBLE-TAP & HOLD  on pad }, pPad
        else
          Log {🟠 MULTI-},pNumTaps,{-TAP & HOLD on pad }, pPad      
        endif
    
      else
        if pNumTaps = 1
          Log {🟠 SINGLE-TAP         on pad }, pPad      
        elseif pNumTaps = 2
          Log {🟠 DOUBLE-TAP         on pad }, pPad      
        else
          Log {🟠 MULTI-},pNumTaps,{-TAP        on pad }, pPad      
        endif
    
      endif
    @Endgegner 
    
    @OnShift // param: pNumTaps
      if ShiftPressed
    
        if pNumTaps = 1
          Log {🔵 SINGLE-TAP & HOLD  on SHIFT}      
        elseif pNumTaps = 2
          Log {🔵 DOUBLE-TAP & HOLD  on SHIFT}        
        else    
          Log {🔵 MULTI-},pNumTaps,{-TAP & HOLD on SHIFT}
        endif
    
      else
    
        if pNumTaps = 1 
          Log {🔵 SINGLE-TAP         on SHIFT}      
        elseif pNumTaps = 2
          Log {🔵 DOUBLE-TAP         on SHIFT}  
        else    
          Log {🔵 MULTI-},pNumTaps,{-TAP        on SHIFT}
          endif
      endif
    @End
    
    // SPECIAL USES CASES
    // ------------------
    
      // If uncommented, your own shift event handler will be used.
      // You no longer need to define the OnShift special event in your script,
      // as it is no longer called.
      //
    //@OnShiftDown
    //  Log {My Shift Down}
    //@End
    
    
      // If uncommented, your own pad event handler will be used.
      // You no longer need to define the OnPad special event in your script, 
      // as it is not called anymore.
      //
    //@OnPadDown
    //  Log {My Pad Down }, LastPad
    //@End
    
    
      // When using an own timer, you need to call 
      //   @PadAndShiftManagerUpdate from within the timer event.
      // The timer needs to run continously with an update tick
      // faster than 50ms. Please set pmManageTimer = NO and 
      // pmTickInterval with your interval before calling
      //   @PadAndShiftManagerInit
      //
    //@SetupMyTimer
    //  SetTimerInterval 42
    //  pmTickInterval = 42
    //  pmManageTimer = NO
    //  StartTimer
    //@End
    //
    //@OnTimer
    //  Call @PadAndShiftManagerUpdate
    //  // Do whatever you intended to do with your timer
    //@End 
    
    @OnKnobChange
      if LastKnob = 3
        _val = GetKnobValue LastKnob
    
        // HELP knob handling with double-tap support
        if _val = 64
          showHelp = not showHelp
        else
          showHelp = (_val>64)
        endif
        ShowLayout 2 + 2*showHelp
        SetKnobValue 3, 127*showHelp
      endif    
    @End 
    
    
    
    // =========================================
    //          PAD & SHIFT Manager 
    // ============== V 3.1 ====================
    // -ki
    //
    // V3.1    13.07.2020  Simplified handling to two user callbacks
    // V3.0.1  19.01.2020  Changed formatting
    // V3.0    09.01.2020  Added SHIFT button and better instructions
    // V2.0.   01.06.2019  Release on PatchStorage
    
    @PadAndShiftManagerInit
    
      // Apply defaults, if the vars are not yet defined
    
      if Unassigned pmAnalyseTime
        pmAnalyseTime = 200 
      endif
      if Unassigned pmManageTimer
        pmManageTimer = YES
      endif
      if Unassigned pmTickInterval
        pmTickInterval = 50
      endif
      if Unassigned pmExcludePads
        pmExcludePads = []
      endif
      if Unassigned pmExcludeCnt
        pmExcludeCnt  = 0
      endif
    
      FillArray pmPadActive,  NO,16
      FillArray pmPadTicks,   0, 16
      FillArray pmPadTaps,    0, 16
      FillArray pmPadExclude, NO,16
      FillArray pmPadDown,    NO,16
      pmPadsActiveCnt = 0  
      pmShiftActive  = NO
      pmShiftTicks   = 0
      pmShiftTaps    = 0
    
      if pmExcludeCnt>0
        for _pad = 0 to pmExcludeCnt-1
          pmPadExclude[ pmExcludePads[_pad] ] = YES
        endfor
      endif
    
      pmAnalyseTicks = pmAnalyseTime / pmTickInterval
    
      pmTimerRunning = NO
      if pmManageTimer
        SetTimerInterval pmTickInterval
      endif
    
      Log {Pad & Shift Manager v3.1 started (},pmExcludeCnt,{ excluded pads, timer=}, pmTickInterval,{msec)}
    @End
    
    @PMCheckStopTimer
      if pmManageTimer and pmTimerRunning and pmPadsActiveCnt=0 and not pmShiftActive
        pmTimerRunning = NO
        StopTimer 
      endif
    @End
    
    @PMCheckStartTimer
      if pmManageTimer and not pmTimerRunning
        pmTimerRunning = YES
        StartTimer 
      endif
    @End
    
    @OnPadDown 
      pmPadDown[LastPad] = YES      
      if pmPadExclude[LastPad]
        pPad = LastPad 
        pNumTaps = 1
        pDown = YES
        Call @OnPad
    
      else
        Call @PMCheckStartTimer    
        if not pmPadActive[LastPad]
          Inc pmPadsActiveCnt
          pmPadActive[LastPad] = YES
        endif
        inc pmPadTaps[LastPad]
      endif
    @End 
    
    @OnPadUp 
      pmPadDown[LastPad] = NO  
    @End 
    
    @OnShiftDown
      pmShiftActive = YES
      inc pmShiftTaps
      Call @PMCheckStartTimer
    @End
    
    @OnTimer 
      if pmManageTimer
        Call @PadAndShiftManagerUpdate
      endif
    @End 
    
    @PadAndShiftManagerUpdate
      if not Unassigned pmShiftActive  
        for pPad = 0 to 15
          if pmPadActive[pPad]
            Inc pmPadTicks[pPad]
    
            if pmPadTicks[pPad] > pmAnalyseTicks
              pDown    = pmPadDown[pPad]
              pNumTaps = pmPadTaps[pPad]
              Call @OnPad
    
              // Reset pad
              pmPadActive[pPad] = NO
              pmPadTicks[pPad]  = 0
              pmPadTaps[pPad]   = 0
              pmPadExclude[pPad]= NO
              pmPadDown[pPad]   = NO
    
              Dec pmPadsActiveCnt
              Call @PMCheckStopTimer          
            endif
          endif
        endfor
    
        if pmShiftActive 
          Inc pmShiftTicks
          if pmShiftTicks > pmAnalyseTicks      
            pNumTaps = pmShiftTaps
            Call @OnShift       
    
            // Reset shift handling
            pmShiftActive = NO
            pmShiftTicks  = 0
            pmShiftTaps   = 0
    
            Call @PMCheckStopTimer
          endif
        endif
      endif
    @End
    
    // ================ END ====================
    //    PAD & SHIFT Manager 
    // =========================================
    
  • Hi. I think you do not want to change the script at all. According to the documentation, you need to implement the OnPad and OnShift event handlers, replacing the logging in the sample code with the actions you wish to implement.

  • @ztones and @uncledave
    Yes, you are right uncledave. The script is only a sample code on how to use the ‚script snippet‘ found between the lines

    // =========================================
    //          PAD & SHIFT Manager 
    // ============== V 3.1 ====================
    

    and

    // ================ END ====================
    //    PAD & SHIFT Manager 
    // =========================================
    

    As described in the source you need to Call @PadAndShiftManagerInit in the OnLoad function of your script and if needed, set set some of the pmXXX configuration variables before doing so.
    Then all you normall need to do is to add the two callback functions (ie user defined events) @OnPad and OnShift in which you need to react to the values set in their respective parameter variables.

    If your script really needs to implement the Mozaic events OnPadDown / OnPadUp / OnShiftDown / OnShiftUp or OnTimer, the script contains instructions on how to cope with this requirement - usually the functionallity of the two new events will be enough.

  • Ok I'll give that a go and see if I can set it up right... Thank you!

Sign In or Register to comment.