Audiobus: Use your music apps together.

What is Audiobus?Audiobus is an award-winning music app for iPhone and iPad which lets you use your other music apps together. Chain effects on your favourite synth, run the output of apps or Audio Units into an app like GarageBand or Loopy, or select a different audio interface output for each app. Route MIDI between apps — drive a synth from a MIDI sequencer, or add an arpeggiator to your MIDI keyboard — or sync with your external MIDI gear. And control your entire setup from a MIDI controller.

Download on the App Store

Audiobus is the app that makes the rest of your setup better.

Request new Mozaic Scripts *HERE*

1414244464762

Comments

  • wimwim
    edited October 2021

    @slicetwo said:
    Where would it actually go in the code?...

    I would put it right after the knob movement:

    if knob = 0
    bank = Round (TranslateScale val, 0,127, 0,7)
    SendMIDIBankSelect chan,0,bank
    Call @RedrawBankKnob
    Call @ClearPads
    

    Note that the bank goes in the lsb parameter of SendMIDIBankSelect chan,msb,lsb. At least that's what worked in my Basic Midi Controls script.

    ... I tried making it to the knobs could do different letters beyond H. I based it off the code that's already in there, but it kept turning into musical notes (A, A#, etc.). I feel like I obviously missed something. Haha.

    You can't display any letters past G with this hack. GetNoteName only works on the 12 notes of an octave. Note 0, 12, 24, 36, 48, ... etc are all C.

    (Note: To get multiple line code to format correctly in forum posts, place three ` characters on a line by themselves before and after the code. )

  • _ki_ki
    edited October 2021

    @slicetwo said:
    I just saw this reply for some reason. Where would it actually go in the code? Also, I tried making it to the knobs could do different letters beyond H.

    The RedrawBankKnob user function creativly used the NoteName function to output the letters A-G in one go. Since this trick only works the letters A-G, the H was handled differently.

    If you need more letters, you have to extend the if-elseif-cascade like in this example for twelve banks (0-11):

    @RedrawBankKnob
      if bank = 7
        LabelKnob 0,{Bank H}
      elseif bank=8
        LabelKnob 0,{Bank I}
      elseif bank=9
        LabelKnob 0,{Bank J}
      elseif bank=10
        LabelKnob 0,{Bank K}
      elseif bank=11
        LabelKnob 0,{Bank L}
      else
        ABCDEFG = [9,11,0,2,4,5,7]    
        LabelKnob 0,{Bank }, (NoteName ABCDEFG[bank], NO)
      endif
    @End
    

    I was too lazy to write down a 16 bank version, but it should clear how to extend it

  • edited October 2021

    @wim and @_ki The two of you are magical. If you are ever in the Philadelphia area, hit me up and I'll buy ya a cheesesteak.

    @wim

    Is this what you're saying? How does it know to switch between bank 0 for A-H, and bank 1 for I-P?

    @OnKnobChange
    
      knob = LastKnob
      val = GetKnobValue LastKnob
    
    if knob = 0
    bank = Round (TranslateScale val, 0,127, 0,7)
    SendMIDIBankSelect 15,0,1
    Call @RedrawBankKnob
    Call @ClearPads
    
        elseif knob = 3
      ch = Round (TranslateScale val, 0,127, 0,15)
      LabelKnob 3, {Channel },ch+1
      endif
    
    @End
    
  • @slicetwo said:
    @wim and @_ki The two of you are magical. If you are ever in the Philadelphia area, hit me up and I'll buy ya a cheesesteak.

    @wim

    Is this what you're saying? How does it know to switch between bank 0 for A-H, and bank 1 for I-P?

    That's what I meant, but I see that I didn't look at your question well enough. I though you were just switching banks with knob 0. I'd need to look more closely and review older posts to understand what you're trying to do.

  • edited October 2021

    @wim said:

    @slicetwo said:
    @wim and @_ki The two of you are magical. If you are ever in the Philadelphia area, hit me up and I'll buy ya a cheesesteak.

    @wim

    Is this what you're saying? How does it know to switch between bank 0 for A-H, and bank 1 for I-P?

    That's what I meant, but I see that I didn't look at your question well enough. I though you were just switching banks with knob 0. I'd need to look more closely and review older posts to understand what you're trying to do.

    The Digitone and Digitakt only have 8 banks with 16 patterns each to choose from (so values 0-127), whereas the OT has 16 banks of 16 patterns, which means I need to go from bank 0 to bank 1 if I want to get to the 2nd set of 8 banks on the OT. I was told that it was "as simple" as having the controller send the bank change. So I guess I'd need another knob to change the bank, along with the pattern PC message.

    Maybe it would make sense to use the other 2 knobs for the bank and OT PC changes only, as I don't know how the Digi boxes would respond to PCs on other banks.

  • OK, I'm starting to hit a roadblock with arrays again.

    I have 3 banks (working as radio buttons) with 4 on/off toggles per bank.
    Can anyone post a quick "off the cuff" script to store and recall the states of the 4 toggles when switching between banks?
    Im not using pads, buttons, sliders, etc in the mozaic GUI for these banks.

    I also have 1 other dumb question which I think I know the answer to, but looking for a definitive answer. If I have the following:

    @onmidicc
        <some code>
        Call @Action
        <some more code>
        <some more code>
    @End
    
    @Action 
        <some code>
        <some more code>
    @End
    

    When the @onmidicc is running and it gets to the Call @Action, is the code from the @aaction inserted into the @OnmidiCC, or does it jump to the Call and not execute the remainder of the @OnMidiCC?

    I'm asking because a huge section of one of the things i'm working on is a lot of elseif calls (instead of nesting if statements):

    @OnMidiInput
        if midibyte2 = 21
            Call @Action1
        elseif midibyte2 = 22
            Call @Action2
        elseif midibyte2 = 23
            Call @Action3
    
        ....
        ....
        ....
    
        else midibyte2 = 29
            Call @Action9
    @End
    
  • @AlmostAnonymous said:
    OK, I'm starting to hit a roadblock with arrays again.

    I have 3 banks (working as radio buttons) with 4 on/off toggles per bank.
    Can anyone post a quick "off the cuff" script to store and recall the states of the 4 toggles when switching between banks?
    Im not using pads, buttons, sliders, etc in the mozaic GUI for these banks.

    I also have 1 other dumb question which I think I know the answer to, but looking for a definitive answer. If I have the following:

    @onmidicc
      <some code>
      Call @Action
      <some more code>
      <some more code>
    @End
    
    @Action   
      <some code>
      <some more code>
    @End
    

    When the @onmidicc is running and it gets to the Call @Action, is the code from the @aaction inserted into the @OnmidiCC, or does it jump to the Call and not execute the remainder of the @OnMidiCC?

    I'm asking because a huge section of one of the things i'm working on is a lot of elseif calls (instead of nesting if statements):

    @OnMidiInput
      if midibyte2 = 21
          Call @Action1
      elseif midibyte2 = 22
          Call @Action2
      elseif midibyte2 = 23
          Call @Action3
          
      ....
      ....
      ....
    
      else midibyte2 = 29
          Call @Action9
    @End
    

    When you use “call @action”, it is treated like any instruction. Mozaic executes the call to action and proceeds to the line of code after the call.

  • Thats what I figured, just wanted to be sure before i go down this rabbit hole further. Thank you.

    As far as the 1st part about the array's im having issues with. Is there anything at Patchstorage you (or anyone else wrote) that I can take a look at for storing and recalling multiple arrays based on incoming midi input?

  • Just an idea… I Stumbled across this and the idea of sampling small midi sequences and chopping then up into new sounds was extremely excitin. A way to mix up a short pattern. Somewhat similar to my previous idea, but different…This is probably a hard one to cook up, and a long shot in terms of a request, but I had to throw it out there… just chopping out a set amount of bars into a set amount of slices and being able to play them back in various orders would be cool.

    reMIDI 2 - MIDI Sampling Is Finally Here

    Introducing reMIDI 2, the follow up to reMIDI that allows you to take MIDI sampling to the next level with its new features. reMIDI 2 is a MIDI effect plugin that samples musical notes from MIDI files that allows you to quickly find, chop, key shift and time-stretch samples and map them to a controller.

    https://www.pluginboutique.com/products/5935

  • @Poppadocrock said:
    Just an idea… I Stumbled across this and the idea of sampling small midi sequences and chopping then up into new sounds was extremely excitin. A way to mix up a short pattern. Somewhat similar to my previous idea, but different…This is probably a hard one to cook up, and a long shot in terms of a request, but I had to throw it out there… just chopping out a set amount of bars into a set amount of slices and being able to play them back in various orders would be cool.

    reMIDI 2 - MIDI Sampling Is Finally Here

    Introducing reMIDI 2, the follow up to reMIDI that allows you to take MIDI sampling to the next level with its new features. reMIDI 2 is a MIDI effect plugin that samples musical notes from MIDI files that allows you to quickly find, chop, key shift and time-stretch samples and map them to a controller.

    https://www.pluginboutique.com/products/5935

    This one has been on my mind for a while. It's not the easiest concept to design a UI for, and it's not my top priority, but I'm open to the idea of working on it in the future. Unquantized MIDI playback already uses a lot of CPU in Mozaic, and a "MIDI slicer" is basically that, but with several playheads. So just be prepared for that. :) A regular app would be much better suited to this purpose.

  • edited October 2021

    @Poppadocrock said:
    Just an idea… I Stumbled across this and the idea of sampling small midi sequences and chopping then up into new sounds was extremely excitin. A way to mix up a short pattern. Somewhat similar to my previous idea, but different…This is probably a hard one to cook up, and a long shot in terms of a request, but I had to throw it out there… just chopping out a set amount of bars into a set amount of slices and being able to play them back in various orders would be cool.

    reMIDI 2 - MIDI Sampling Is Finally Here

    Introducing reMIDI 2, the follow up to reMIDI that allows you to take MIDI sampling to the next level with its new features. reMIDI 2 is a MIDI effect plugin that samples musical notes from MIDI files that allows you to quickly find, chop, key shift and time-stretch samples and map them to a controller.

    https://www.pluginboutique.com/products/5935

    If you don't mind the hardware route (and its a little on the pricey side), there's the Midiphy LoopA. I'm thinking of grabbing one for myself as i still prefer to compose on external sequencers.

    https://www.midiphy.com/en/loopa-v2/

  • @Skyblazer said:

    @Poppadocrock said:
    Just an idea… I Stumbled across this and the idea of sampling small midi sequences and chopping then up into new sounds was extremely excitin. A way to mix up a short pattern. Somewhat similar to my previous idea, but different…This is probably a hard one to cook up, and a long shot in terms of a request, but I had to throw it out there… just chopping out a set amount of bars into a set amount of slices and being able to play them back in various orders would be cool.

    reMIDI 2 - MIDI Sampling Is Finally Here

    Introducing reMIDI 2, the follow up to reMIDI that allows you to take MIDI sampling to the next level with its new features. reMIDI 2 is a MIDI effect plugin that samples musical notes from MIDI files that allows you to quickly find, chop, key shift and time-stretch samples and map them to a controller.

    https://www.pluginboutique.com/products/5935

    This one has been on my mind for a while. It's not the easiest concept to design a UI for, and it's not my top priority, but I'm open to the idea of working on it in the future. Unquantized MIDI playback already uses a lot of CPU in Mozaic, and a "MIDI slicer" is basically that, but with several playheads. So just be prepared for that. :) A regular app would be much better suited to this purpose.

    Yea that’s what I was thinking an individual app would probably be the way to go here.

  • @slicetwo said:

    @wim said:

    @slicetwo said:
    @wim and @_ki The two of you are magical. If you are ever in the Philadelphia area, hit me up and I'll buy ya a cheesesteak.

    @wim

    Is this what you're saying? How does it know to switch between bank 0 for A-H, and bank 1 for I-P?

    That's what I meant, but I see that I didn't look at your question well enough. I though you were just switching banks with knob 0. I'd need to look more closely and review older posts to understand what you're trying to do.

    The Digitone and Digitakt only have 8 banks with 16 patterns each to choose from (so values 0-127), whereas the OT has 16 banks of 16 patterns, which means I need to go from bank 0 to bank 1 if I want to get to the 2nd set of 8 banks on the OT. I was told that it was "as simple" as having the controller send the bank change. So I guess I'd need another knob to change the bank, along with the pattern PC message.

    Maybe it would make sense to use the other 2 knobs for the bank and OT PC changes only, as I don't know how the Digi boxes would respond to PCs on other banks.

    Sorry for the delay responding. I think I understand now. My confusion was over the dual use of "banks" as used in the script and "banks" as used referring to the two banks in the OT. If I understand correctly, you need to select bank 0 on the OT for your first 8 "banks" and bank 1 on the OT for the second 8 "banks".

    So, a simple place to put send the bank select is in the @OnKnobChange event when you're selecting the script bank. This was what I said before but I missed that you're only selecting from two banks the OT. So, I'm thinking this would work...

    ...
      if knob = 0
        bank = Round (TranslateScale val, 0,127, 0,15)
      
        if bank <= 7
          SendMIDIBankSelect ch,0,0
        else
          SendMIDIBankSelect ch,0,1
        endif
      
      Call @RedrawBankKnob
      Call @ClearPads
    ...
    

    Also, as @_ki illustrated, here's the full knob labeling code needed to get the letters beyond G.

    @RedrawBankKnob
      if bank = 7
        LabelKnob 0,{Bank H}
      elseif bank = 8
        LabelKnob 0,{Bank I}
      elseif bank = 9
        LabelKnob 0,{Bank J}
      elseif bank = 10
        LabelKnob 0,{Bank K}
      elseif bank = 11
        LabelKnob 0,{Bank L}
      elseif bank = 12
        LabelKnob 0,{Bank M}
      elseif bank = 13
        LabelKnob 0,{Bank N}
      elseif bank = 14
        LabelKnob 0,{Bank O}
      elseif bank = 15
        LabelKnob 0,{Bank P}
      else
        ABCDEFG = [9,11,0,2,4,5,7]
        LabelKnob 0,{Bank }, (NoteName ABCDEFG[bank], NO)
      endif
    @End 
    

    Here's the completely untested code as I think it should work ...

    @Description 
    TURN ON MIDI LINK
    (Modified with bank select 0, 1 for the Octatrack)
    This script lets you send PC messages 0-127 on any MIDI channel of your choice. Use the BANK knob to choose the bank, and the PATTERN pads to choose your pattern. Change the MIDI channel using the CHANNEL knob. Big ups to @wim and @_ki from the Audiobus forums for helping me make this work! Made specifically with the Elektron boxes in mind, but it could probably work for other gear.
    @End
    
    @OnLoad
      default_channel = 15
      default_bank = 0
      default_program = 0
      
      if Unassigned init 
        // Only do this stuff on a new load so that the 
        // State is the same in saved sessions
        
        init = YES
        
        ch = default_channel
        bank = default_bank
        program = default_program
        SetKnobValue 0, TranslateScale bank, 0,7, 0,127
        SetKnobValue 3, TranslateScale ch, 0,15, 0,127
        
        SetKnobValue 0,bank 
        Call @RedrawBankKnob
        
        Call @ClearPads
      endif
    
      LabelPad 0, {01}
      LabelPad 1, {02}
      LabelPad 2, {03}
      LabelPad 3, {04}
      LabelPad 4, {05}
      LabelPad 5, {06}
      LabelPad 6, {07}
      LabelPad 7, {08}
      LabelPad 8, {09}
      LabelPad 9, {10}
      LabelPad 10, {11}
      LabelPad 11, {12}
      LabelPad 12, {13}
      LabelPad 13, {14}
      LabelPad 14, {15}
      LabelPad 15, {16}
      
      Call @RedrawBankKnob
      LabelKnob 1, { }
      LabelKnob 2, { }
      LabelKnob 3, {Channel },ch+1
      
      LabelKnobs {Controls}
      LabelPads {Patterns}
      
      SetShortName {ElkPtrn}
      
      ShowLayout 2
    
    @End
    
    @OnKnobChange
    
      knob = LastKnob
      val = GetKnobValue LastKnob
      
      if knob = 0
        bank = Round (TranslateScale val, 0,127, 0,15)
      
        if bank <= 7
          SendMIDIBankSelect ch,0,0
        else
          SendMIDIBankSelect ch,0,1
        endif
      
      Call @RedrawBankKnob
      Call @ClearPads
      
      elseif knob = 3
        ch = Round (TranslateScale val, 0,127, 0,15)
        LabelKnob 3, {Channel },ch+1
      endif
      
    @End
      
    @OnPadDown
      program = LastPad
      
      Call @ClearPads
      Latchpad program, YES 
      SendMIDIProgramChange ch, (program + (bank*16))
    @End
    
    @ClearPads
      // Blank all pads
      for idx = 0 to 15
        LatchPad idx,NO 
      endfor
    @End
    
    @RedrawBankKnob
      if bank = 7
        LabelKnob 0,{Bank H}
      elseif bank = 8
        LabelKnob 0,{Bank I}
      elseif bank = 9
        LabelKnob 0,{Bank J}
      elseif bank = 10
        LabelKnob 0,{Bank K}
      elseif bank = 11
        LabelKnob 0,{Bank L}
      elseif bank = 12
        LabelKnob 0,{Bank M}
      elseif bank = 13
        LabelKnob 0,{Bank N}
      elseif bank = 14
        LabelKnob 0,{Bank O}
      elseif bank = 15
        LabelKnob 0,{Bank P}
      else
        ABCDEFG = [9,11,0,2,4,5,7]
        LabelKnob 0,{Bank }, (NoteName ABCDEFG[bank], NO)
      endif
    @End 
    
  • @AlmostAnonymous said:
    OK, I'm starting to hit a roadblock with arrays again.

    I have 3 banks (working as radio buttons) with 4 on/off toggles per bank.
    Can anyone post a quick "off the cuff" script to store and recall the states of the 4 toggles when switching between banks?
    Im not using pads, buttons, sliders, etc in the mozaic GUI for these banks.

    The basic idea is to have one array that holds your current four toggles, then to copy the contents of that array into another array for storage, and retrieve them into the current array when you need them.

    You can save a lot of code by packing all the sets of toggles in one array, so I wrote it this way. If it's too confusing to understand how to look up where the values are stored in the big array, you could store each bank in it's own array and then access them by if ... else if blocks statements. I hope that makes sense.

    @Description
    Demo of one way to save and retrieving three banks of four toggles.
    All the toggles are saved in a single array. We know how to find a toggle by multiplying the current bank by the number of toggles.
    The currently active toggles are in an array called activeToggles. We just save and retrieve the ones we need as we go.
    @End
    
    @OnLoad
      numBanks = 3
      numToggles = 4
      
      if Unassigned init
        init = TRUE
        // One array for storing all toggles.
        // numBanks * numToggles must not exceed 1024
        FillArray toggles, NO, numBanks*numToggles
        currentBank = 0
        Call @GetToggles
      endif
      
      Call @Demo
    @End
    
    @Demo
      // Demo - randomize toggles in bank 0 and bank 2
      currentBank = 0
      Call @RandomizeToggles
      Call @SaveToggles
      currentBank = 2
      Call @RandomizeToggles
      Call @SaveToggles
      
      // Demo - recall and log the stored banks.
      for currentBank = 0 to (numBanks - 1)
        Call @GetToggles
        Log {Bank }, currentBank, { [}, activeToggles[0], {, }, activeToggles[1], {, }, activeToggles[2], {, }, activeToggles[3], {]}
      endfor
    @End
    
    @RandomizeToggles
      // this is just to randomize the active toggles for demo purposes
    
      //Set currentBank before calling!
      for toggle = 0 to (numToggles - 1)
        activeToggles[toggle] = (Random 0,1)
      endfor
    @End
    
    @GetToggles
      // Set currentBank before calling!
      CopyArray toggles[currentBank * numToggles], activeToggles, numToggles
    @End
    
    @SaveToggles
      // Set currentBank before calling!
      CopyArray activeToggles, toggles[currentBank * NumToggles], numToggles
    @End
    
  • Thank you kind sir. Your code looks so pretty compared to mine.
    Literally embarrassed to post anything here or patchstorage.
    Probably could have written my lighting your way instead me sending a million predefined variable a la arduino coding

  • wimwim
    edited October 2021

    @AlmostAnonymous said:
    Thank you kind sir. Your code looks so pretty compared to mine.
    Literally embarrassed to post anything here or patchstorage.
    Probably could have written my lighting your way instead me sending a million predefined variable a la arduino coding

    Hey bro, any code that works consistently and that you understand is good code. 🤙🏼 Sometimes doing things just to produce elegant code backfires by making it harder to get your head around.

    I debated doing it the less elegant but easier to understand way, but the code would have been longer, and learning to pack and unpack arrays in this way is good to know.

    The concept is the same either way. Have an "active" array, then save those values to a "storage" array or arrays when you need to. Copy the storage array values to the active array when you need them.

    That way, you only need to write any code that works on or with a single active array at any one time.

  • Thank god for fast devices.
    They always seems to run my sloppy, unnessecarily long, inefficient code without a hitch.

  • @AlmostAnonymous said:
    Thank god for fast devices.
    They always seems to run my sloppy, unnessecarily long, inefficient code without a hitch.

    I started coding two years ago, with Mozaic, with help from the AudioBus forum, especially @wim and @_ki. I tried to learn coding three times before that, and my brain just couldn't do it. I wanted to share my perspective, in case you (or anyone) might find it useful.

    I've realized that "proper coding conventions" are sometimes more about CPU efficiency, and readability for programmers, than general readability, and it's good to know your options. For example...

    I often write code like:

    if var = 0
    elseif var = 1
    elseif var = 2
    elseif var = 3
    elseif var = 4
    endif

    because changing "elseif var = 4" to "else" makes it slightly less readable for me. It's like saying "1, 2, 3....and the number that comes after 3" when I read it.

    wim and _ki tend to use math whenever possible.
    Var = (Var + 1) modulo 8
    instead of:
    "if var = 7, var = 0, else var = var + 1."
    and I do use modulo for long/complex/CPU-heavy scripts.

    I don't prioritize educational accessibility over functionality. But I'm barely smart enough to code, and most people who excelled at high school math seemed to have a stable home life, and the ability to stay awake during class. They were from the wealthier side of town. So I don't want to exclude people.

    I use OnMidiNoteOn and OnMidiNoteOff, as taught by Bram Bos, in the Mozaic manual.

    And when I do use OnMidiInput, I don't use hexadecimal. I only use hex for byte packing, which I still barely understand.

    My cousin tried to graduate from Scratch to Python, and he gave up. He's in elementary school. So I'm keeping people like him in mind. "oh this? it's just an 8-base number system."

    Sometimes I do write code that is objectively worse than the alternative suggested by wim or _ki, and I try to remember...their minds are also sharp because they didn't just finish designing a UI, coming up with variable names, and writing the other functions. I'm always grateful for improvements to my code, and some of the first suggestions I received were things like, "use an array instead of 100 variables."

    Writing code is still a humbling, empowering, egoic journey for me, so I just let it be like that. I need to update my scripts on PatchStorage, but this is my current philosophy on writing code.

  • edited October 2021

    @wim said:

    @slicetwo said:

    @wim said:

    @slicetwo said:
    @wim and @_ki The two of you are magical. If you are ever in the Philadelphia area, hit me up and I'll buy ya a cheesesteak.

    @wim

    Is this what you're saying? How does it know to switch between bank 0 for A-H, and bank 1 for I-P?

    That's what I meant, but I see that I didn't look at your question well enough. I though you were just switching banks with knob 0. I'd need to look more closely and review older posts to understand what you're trying to do.

    The Digitone and Digitakt only have 8 banks with 16 patterns each to choose from (so values 0-127), whereas the OT has 16 banks of 16 patterns, which means I need to go from bank 0 to bank 1 if I want to get to the 2nd set of 8 banks on the OT. I was told that it was "as simple" as having the controller send the bank change. So I guess I'd need another knob to change the bank, along with the pattern PC message.

    Maybe it would make sense to use the other 2 knobs for the bank and OT PC changes only, as I don't know how the Digi boxes would respond to PCs on other banks.

    Sorry for the delay responding. I think I understand now. My confusion was over the dual use of "banks" as used in the script and "banks" as used referring to the two banks in the OT. If I understand correctly, you need to select bank 0 on the OT for your first 8 "banks" and bank 1 on the OT for the second 8 "banks".

    So, a simple place to put send the bank select is in the @OnKnobChange event when you're selecting the script bank. This was what I said before but I missed that you're only selecting from two banks the OT. So, I'm thinking this would work...

    ...
      if knob = 0
        bank = Round (TranslateScale val, 0,127, 0,15)
      
        if bank <= 7
          SendMIDIBankSelect ch,0,0
        else
          SendMIDIBankSelect ch,0,1
        endif
      
      Call @RedrawBankKnob
      Call @ClearPads
    ...
    

    Also, as @_ki illustrated, here's the full knob labeling code needed to get the letters beyond G.

    @RedrawBankKnob
      if bank = 7
        LabelKnob 0,{Bank H}
      elseif bank = 8
        LabelKnob 0,{Bank I}
      elseif bank = 9
        LabelKnob 0,{Bank J}
      elseif bank = 10
        LabelKnob 0,{Bank K}
      elseif bank = 11
        LabelKnob 0,{Bank L}
      elseif bank = 12
        LabelKnob 0,{Bank M}
      elseif bank = 13
        LabelKnob 0,{Bank N}
      elseif bank = 14
        LabelKnob 0,{Bank O}
      elseif bank = 15
        LabelKnob 0,{Bank P}
      else
        ABCDEFG = [9,11,0,2,4,5,7]
        LabelKnob 0,{Bank }, (NoteName ABCDEFG[bank], NO)
      endif
    @End 
    

    Here's the completely untested code as I think it should work ...

    @Description 
    TURN ON MIDI LINK
    (Modified with bank select 0, 1 for the Octatrack)
    This script lets you send PC messages 0-127 on any MIDI channel of your choice. Use the BANK knob to choose the bank, and the PATTERN pads to choose your pattern. Change the MIDI channel using the CHANNEL knob. Big ups to @wim and @_ki from the Audiobus forums for helping me make this work! Made specifically with the Elektron boxes in mind, but it could probably work for other gear.
    @End
    
    @OnLoad
      default_channel = 15
      default_bank = 0
      default_program = 0
      
      if Unassigned init 
        // Only do this stuff on a new load so that the 
        // State is the same in saved sessions
        
        init = YES
        
        ch = default_channel
        bank = default_bank
        program = default_program
        SetKnobValue 0, TranslateScale bank, 0,7, 0,127
        SetKnobValue 3, TranslateScale ch, 0,15, 0,127
        
        SetKnobValue 0,bank 
        Call @RedrawBankKnob
        
        Call @ClearPads
      endif
    
      LabelPad 0, {01}
      LabelPad 1, {02}
      LabelPad 2, {03}
      LabelPad 3, {04}
      LabelPad 4, {05}
      LabelPad 5, {06}
      LabelPad 6, {07}
      LabelPad 7, {08}
      LabelPad 8, {09}
      LabelPad 9, {10}
      LabelPad 10, {11}
      LabelPad 11, {12}
      LabelPad 12, {13}
      LabelPad 13, {14}
      LabelPad 14, {15}
      LabelPad 15, {16}
      
      Call @RedrawBankKnob
      LabelKnob 1, { }
      LabelKnob 2, { }
      LabelKnob 3, {Channel },ch+1
      
      LabelKnobs {Controls}
      LabelPads {Patterns}
      
      SetShortName {ElkPtrn}
      
      ShowLayout 2
    
    @End
    
    @OnKnobChange
    
      knob = LastKnob
      val = GetKnobValue LastKnob
      
      if knob = 0
        bank = Round (TranslateScale val, 0,127, 0,15)
      
        if bank <= 7
          SendMIDIBankSelect ch,0,0
        else
          SendMIDIBankSelect ch,0,1
        endif
      
      Call @RedrawBankKnob
      Call @ClearPads
      
      elseif knob = 3
        ch = Round (TranslateScale val, 0,127, 0,15)
        LabelKnob 3, {Channel },ch+1
      endif
      
    @End
      
    @OnPadDown
      program = LastPad
      
      Call @ClearPads
      Latchpad program, YES 
      SendMIDIProgramChange ch, (program + (bank*16))
    @End
    
    @ClearPads
      // Blank all pads
      for idx = 0 to 15
        LatchPad idx,NO 
      endfor
    @End
    
    @RedrawBankKnob
      if bank = 7
        LabelKnob 0,{Bank H}
      elseif bank = 8
        LabelKnob 0,{Bank I}
      elseif bank = 9
        LabelKnob 0,{Bank J}
      elseif bank = 10
        LabelKnob 0,{Bank K}
      elseif bank = 11
        LabelKnob 0,{Bank L}
      elseif bank = 12
        LabelKnob 0,{Bank M}
      elseif bank = 13
        LabelKnob 0,{Bank N}
      elseif bank = 14
        LabelKnob 0,{Bank O}
      elseif bank = 15
        LabelKnob 0,{Bank P}
      else
        ABCDEFG = [9,11,0,2,4,5,7]
        LabelKnob 0,{Bank }, (NoteName ABCDEFG[bank], NO)
      endif
    @End 
    

    I'll test this out tonight. Thank you. I loaded it up on my iPad and threw mfxMonitor into it. The only thing that looks weird is that on banks A-H, the PC messages are 000-127, but on I-P they're all just 127. Shouldn't I01 be 000 and P16 be 127?

    I tried changing the translate scale from 7 to 15 in SetKnobValue 0, TranslateScale bank, 0,7, 0,127

    Wouldn't 0-7 only affect be A-H? Either way, it didn't work. I do see the Bank changing when I turn the knob past H, which is good. Also, if bank = default_bank, then wouldn't anywhere that BANK shows up immediately go there regardless of the new bank selection code?

    Also, no worries on timing. You're doing me a solid and I'm 100% ok with waiting as long as I need to in order to steal your precious precious knowledge. :)

  • @RajahP pointed out a cool feature in a Desktop app called "Groove Lock"

    @RajahP said:
    Groove lock is at 9:13 into the video..

    I think we could have something like this arpeggiator made using Mozaic. The ideas are all MIDI event based.

    1 Hold hands on keyboard to define notes to arpeggiate on MIDI channel 1
    2. arpeggiate notes as some multiple of the BPM MIDI clock in
    3. GROOVE LOCK: "sync" notes to MIDI channel 2 input rather than using BPM

  • _ki_ki
    edited November 2021

    @McD

    I‘m still not shure, if i fully understood what happened in the video. Does the ARP advance (and play) whenever any of the drum notes is playing ? Or is there more to it ? (Id it only reacts to certain of the sounds)

    .

    So the script would get two midi inputs, one from the keyboard with the notes to be arped and a second midi stream from a drum sequencer that also plays the drum sounds that now additionally triggers the arp.

    .

    I had a peak into my In-Order-ARP but the logic in there is quite complicated and i would need to rip apart 80% of the code - i didn’t see how i could mock to do groove locking it in a simple way to test how the above idea would sound.

    I’m currently quite loaded with work (over-hours) so there is not much spare time - maybe another picks up the idea.

  • @_ki said:
    @McD

    I‘m still not shure, if i fully understood what happened in the video. Does the ARP advance (and play) whenever any of the drum notes is playing ? Or is there more to it ? (Id it only reacts to certain of the sounds)

    The "one" needs to stay coherent between the arp and the "rhythmic" driver, IMHO.
    So it could get tricky if a drum input had 9 notes and the arp was a 6 note pattern.
    So, the BPM should inform the correlation.

    Now some might just like the arp to just follow the rhythmic input and not have a clear alignment on the "one" beat.

    The simplest case to program would be that the arp emits notes aligned on "one" and
    after emptying its list of notes waits for a new "one" to output more notes.

    All these decisions are open to a developer to create a script and get feedback.
    There are probably scripts that exist that could be deployed to create a prototype for
    an "arp" or a sequence script that is driven by a rhythm "modulator". The scripts that
    @hynopad asked for that are driven by his MIDI drum pads are probably the right place to
    start.

    I’m currently quite loaded with work (over-hours) so there is not much spare time - maybe another picks up the idea.

    No rush... I don't think this would be that hard and someone will probably take a "swing" at it... (pun intended). Someone else will try and cable together some existing scripts and share the results with the input being something cool like a @LuisMartinez drumming app.

    This whole idea started because @LuisMartinez has implement sync'ing between his Indian drummer and the mid east drummer as a new feature. I'm expecting him to add this feature to more of his apps. A Mozaic script to add in some melodic materials to the mix would be
    a nice tool.

  • @McD said:

    @_ki said:
    @McD

    I‘m still not shure, if i fully understood what happened in the video. Does the ARP advance (and play) whenever any of the drum notes is playing ? Or is there more to it ? (Id it only reacts to certain of the sounds)

    The "one" needs to stay coherent between the arp and the "rhythmic" driver, IMHO.
    So it could get tricky if a drum input had 9 notes and the arp was a 6 note pattern.
    So, the BPM should inform the correlation.

    Now some might just like the arp to just follow the rhythmic input and not have a clear alignment on the "one" beat.

    The simplest case to program would be that the arp emits notes aligned on "one" and
    after emptying its list of notes waits for a new "one" to output more notes.

    All these decisions are open to a developer to create a script and get feedback.
    There are probably scripts that exist that could be deployed to create a prototype for
    an "arp" or a sequence script that is driven by a rhythm "modulator". The scripts that
    @hynopad asked for that are driven by his MIDI drum pads are probably the right place to
    start.

    I’m currently quite loaded with work (over-hours) so there is not much spare time - maybe another picks up the idea.

    No rush... I don't think this would be that hard and someone will probably take a "swing" at it... (pun intended). Someone else will try and cable together some existing scripts and share the results with the input being something cool like a @LuisMartinez drumming app.

    This whole idea started because @LuisMartinez has implement sync'ing between his Indian drummer and the mid east drummer as a new feature. I'm expecting him to add this feature to more of his apps. A Mozaic script to add in some melodic materials to the mix would be
    a nice tool.

    I think Photon AU does this, but I've never tried that feature myself so not entirely certain.

  • @McD said:
    I think we could have something like this arpeggiator made using Mozaic. The ideas are all MIDI event based.

    1 Hold hands on keyboard to define notes to arpeggiate on MIDI channel 1
    2. arpeggiate notes as some multiple of the BPM MIDI clock in
    3. GROOVE LOCK: "sync" notes to MIDI channel 2 input rather than using BPM

    I'm not sure I fully understand what's wanted, but the Groove Lock thing reminds in some ways of the 'Hypno-Sequence' Mozaic script Wim wrote for Hypnopad some time ago, where play of each note in a sequence (which could be an arp note progression) was "triggered" by the rhythm of a stick on a drum pad. https://patchstorage.com/hypno-sequence/

  • Does anybody know of Chord based midi mapper.

    The basic idea is two streams of midi 1) Contains chords 2) Contains midi note date. The midi note data is transposed in realtime to the closest note in the current chord data.

    Would save a huge amount of time when trying midi patterns against a harmony. The output midi could then be recorded in say Atom and then tweaked or just used directly.

    Its a bit like a scaler but the scale is defined by the incoming chord notes.

    Possible to do?

  • @plopseaw said:
    Possible to do?

    Yes.

    Mozaic is perfect for using a MIDI channel to trigger events and output new notes
    in the same rhythm that meet some criteria like a chord progression. The chord progression
    can be coded into the script or driven from another MIDI input channel as a chord played as
    long tones. There are apps that will output chords as whole notes but like an arranger keyboard the chord could be based on a "chord glossary":

    root and fifth = major chord on root
    root and 7th = 7th chord on root
    root and minor 3rd = minor chord
    etc

    or it can be literal notes to use on the output MIDI stream using the rhythms on the rhythm stream.

    A lot of decisions on the arpeggios would be coded by the developer and many approaches could be configuration by a knob.

    The app could be simple and basic or very eloborate with a lot of knobs for choices just like any desktop arrpegiator. The Omnisphere product shows a wealth of interesting ideas to
    implement.

  • @plopseaw said:
    Does anybody know of Chord based midi mapper.

    The basic idea is two streams of midi 1) Contains chords 2) Contains midi note date. The midi note data is transposed in realtime to the closest note in the current chord data.

    Would save a huge amount of time when trying midi patterns against a harmony. The output midi could then be recorded in say Atom and then tweaked or just used directly.

    Its a bit like a scaler but the scale is defined by the incoming chord notes.

    Possible to do?

    That sounds doable. Are you able to send the chords and the notes to be transposed on separate midi channels? That's the only way it can work.

    Stuck note prevention complicates this a little. Notes are actually two messages, a note-on at the start of the note and a note-off at the end of it. If the note-on has been quantized to one chord, then when the note-off comes there's a new chord, you have to make sure that you don't quantize that to the new chord or you get a note that never turns off. But that's manageable.

  • @plopseaw said:
    Does anybody know of Chord based midi mapper.

    The basic idea is two streams of midi 1) Contains chords 2) Contains midi note date. The midi note data is transposed in realtime to the closest note in the current chord data.

    Would save a huge amount of time when trying midi patterns against a harmony. The output midi could then be recorded in say Atom and then tweaked or just used directly.

    Its a bit like a scaler but the scale is defined by the incoming chord notes.

    Possible to do?

    Been there, done that. I called it SMARTARSE and described it as a Bum Note Corrector.
    It went a bit further than making notes conform to a played chord. It built scales based on the notes in the chord according to a selection of build rules and made the incoming notes conform to the built scale. It works really well for when your improvisatory skills are a bit sketchy.

  • @TheOriginalPaulB said:

    @plopseaw said:
    Does anybody know of Chord based midi mapper.

    The basic idea is two streams of midi 1) Contains chords 2) Contains midi note date. The midi note data is transposed in realtime to the closest note in the current chord data.

    Would save a huge amount of time when trying midi patterns against a harmony. The output midi could then be recorded in say Atom and then tweaked or just used directly.

    Its a bit like a scaler but the scale is defined by the incoming chord notes.

    Possible to do?

    Been there, done that. I called it SMARTARSE and described it as a Bum Note Corrector.
    It went a bit further than making notes conform to a played chord. It built scales based on the notes in the chord according to a selection of build rules and made the incoming notes conform to the built scale. It works really well for when your improvisatory skills are a bit sketchy.

    Good to know on two levels if it meets @plopseaw's needs. 1) I don't need to debug the little exploratory script I worked on for a bit, and 2) I don't need to try to think of the ultimate script name 'cause you already took the prize.

  • @wim said:

    @TheOriginalPaulB said:

    @plopseaw said:
    Does anybody know of Chord based midi mapper.

    The basic idea is two streams of midi 1) Contains chords 2) Contains midi note date. The midi note data is transposed in realtime to the closest note in the current chord data.

    Would save a huge amount of time when trying midi patterns against a harmony. The output midi could then be recorded in say Atom and then tweaked or just used directly.

    Its a bit like a scaler but the scale is defined by the incoming chord notes.

    Possible to do?

    Been there, done that. I called it SMARTARSE and described it as a Bum Note Corrector.
    It went a bit further than making notes conform to a played chord. It built scales based on the notes in the chord according to a selection of build rules and made the incoming notes conform to the built scale. It works really well for when your improvisatory skills are a bit sketchy.

    Good to know on two levels if it meets @plopseaw's needs. 1) I don't need to debug the little exploratory script I worked on for a bit, and 2) I don't need to try to think of the ultimate script name 'cause you already took the prize.

    Sorry. An arpeggiator is a pattern generator. Adding rhythmic sync'ing to the apppegiator is the ask here. Changing played notes to match a chords is a simpler use case.

    Think of "Riffer" for example that outputs notes in perfectly sync'ed alignment with Funk Drummer input on channel 1 and you get the "ask". Riffer tends to play on straight eighth with or without swing. Yawn.

Sign In or Register to comment.