Jump to content

Can I trigger patch change from Playback?


joachim_s

Recommended Posts

Hi!

 

I know that a regular way of trigger changes automatically in MainStage is from Logic. However, is it not possible to do some of the same things from Playback markers? I’d like to trigger a patch change from where an outro ends so that a playback in another patch starts.

 

Kindly,

Joachim

Link to comment
Share on other sites

what do you mean by playback markers? If you're wanting that one playback plugin to send patch changes...then no you can't. But I have setup mainstage to play a midi sequence in parallel with the audio playback..and then you can program that midi sequence to send patch changes at any point you desire. I actually shared a demo mainstage project on another thread here...have to find it now...
Link to comment
Share on other sites

Check out this example Mainstage Project:

 

PatchChanges.concert.zip

 

This is just a quirky little demo that plays an audio loop using the Playback plugin. At certain points of time that happen to be exactly on beats, ProgramChanges are being sent out by the Scripter script (shown below). This demo sends the Program Change to an IAC port, which then feeds back into Mainstage in order to visually watch the Mainstage patches change in response to the program change messages. In your own usage, you probably won't be doing that part, just sending the ProgramChange off to some external device.

 

in order to see this in action, you will need to create at least one IAC port if you don't have one created already, using Apple AudioMidi Setup. Once you have that, make sure the channel holding the Scripter plugin (which is in the set called "MySong"), is configured to send midi output to that IAC port. That's only in order to observe the loopback program changes.

 

iac.jpg.258f8c864d3d638fd41ca873b2370976.jpg

 

Then press play and watch the screen, you will hear a little audio loop playing and watch mainstage change patches exactly on beats, as configured in the script. You can speed up or slow down the tempo, won't matter, the patch changes will happen exactly on the beat because the audio has been beat mapped or whatever.

 

If you are trying to do something real, then you don't need the IAC stuff, just put the script on a channel that will be used to send out the program changes, and have it send to the device of your choice. If you want to be able to mess with tempo after the fact and have audio and midi remain in sync, then your audio needs to be setup as a legitimate apple loop file, which you can do ahead of time in Logic. If you don't plan to mess with tempo at all, then it doesn't really matter, but it may be more difficult to figure out exactly where on the midi timeline to send your PC, but with trial and error you can figure that out.

 

You have to edit the Script for where in time to send the ProgramChanges.

 

Here is the script:

 

var NeedsTimingInfo = true;

//========= EDIT THIS ARRAY ====================

var programChanges = [
   {beatPos:4.99, channel:1,  number:2}
  ,{beatPos:8.99, channel:1,  number:3}
  ,{beatPos:12.99, channel:1, number:1}
  ,{beatPos:16.99, channel:1, number:2}    
  ,{beatPos:20.99, channel:1, number:3}
  ,{beatPos:24.99, channel:1, number:1}
  // copy the above line for more Program changes
];


//========= DO NOT EDIT BELOW HERE =============

var idx = 0;
var pc = new ProgramChange;  //reuse in a loop

function ProcessMIDI() {
  /* Get current timing info */
  var info = GetTimingInfo();
 
  /* only do work if playing */
  if ( !info.playing ) {
      idx = 0;
      return;
  }
  
  if (idx < programChanges.length) {
  
     while ( idx < programChanges.length &&
             info.blockStartBeat <= programChanges[idx].beatPos && 
             info.blockEndBeat >= programChanges[idx].beatPos ) {
                  
        pc.number = programChanges[idx].number;    
        pc.beatPos = programChanges[idx].beatPos;
        pc.channel = programChanges[idx].channel;  
        pc.send();
        // pc.trace();
        idx++;
     }              
  }
  
}

// ignore incoming midi, might not need this, not sure right now
function HandleMIDI(event) {
}
Edited by Dewdman42
Link to comment
Share on other sites

I've bugged the bear about this a few times. There is not a way to currently send patch changes via audio markers.

 

It is a glaring omission.

 

Ok :/

 

Check out this example Mainstage Project:

 

PatchChanges.concert.zip

 

This is just a quirky little demo that plays an audio loop using the Playback plugin. At certain points of time that happen to be exactly on beats, ProgramChanges are being sent out by the Scripter script (shown below). This demo sends the Program Change to an IAC port, which then feeds back into Mainstage in order to visually watch the Mainstage patches change in response to the program change messages. In your own usage, you probably won't be doing that part, just sending the ProgramChange off to some external device.

 

in order to see this in action, you will need to create at least one IAC port if you don't have one created already, using Apple AudioMidi Setup. Once you have that, make sure the channel holding the Scripter plugin (which is in the set called "MySong"), is configured to send midi output to that IAC port. That's only in order to observe the loopback program changes.

 

iac.jpg

 

Then press play and watch the screen, you will hear a little audio loop playing and watch mainstage change patches exactly on beats, as configured in the script. You can speed up or slow down the tempo, won't matter, the patch changes will happen exactly on the beat because the audio has been beat mapped or whatever.

 

If you are trying to do something real, then you don't need the IAC stuff, just put the script on a channel that will be used to send out the program changes, and have it send to the device of your choice. If you want to be able to mess with tempo after the fact and have audio and midi remain in sync, then your audio needs to be setup as a legitimate apple loop file, which you can do ahead of time in Logic. If you don't plan to mess with tempo at all, then it doesn't really matter, but it may be more difficult to figure out exactly where on the midi timeline to send your PC, but with trial and error you can figure that out.

 

You have to edit the Script for where in time to send the ProgramChanges.

 

Here is the script:

 

var NeedsTimingInfo = true;

//========= EDIT THIS ARRAY ====================

var programChanges = [
   {beatPos:4.99, channel:1,  number:2}
  ,{beatPos:8.99, channel:1,  number:3}
  ,{beatPos:12.99, channel:1, number:1}
  ,{beatPos:16.99, channel:1, number:2}    
  ,{beatPos:20.99, channel:1, number:3}
  ,{beatPos:24.99, channel:1, number:1}
  // copy the above line for more Program changes
];


//========= DO NOT EDIT BELOW HERE =============

var idx = 0;
var pc = new ProgramChange;  //reuse in a loop

function ProcessMIDI() {
  /* Get current timing info */
  var info = GetTimingInfo();
 
  /* only do work if playing */
  if ( !info.playing ) {
      idx = 0;
      return;
  }
  
  if (idx < programChanges.length) {
  
     while ( idx < programChanges.length &&
             info.blockStartBeat <= programChanges[idx].beatPos && 
             info.blockEndBeat >= programChanges[idx].beatPos ) {
                  
        pc.number = programChanges[idx].number;    
        pc.beatPos = programChanges[idx].beatPos;
        pc.channel = programChanges[idx].channel;  
        pc.send();
        // pc.trace();
        idx++;
     }              
  }
  
}

// ignore incoming midi, might not need this, not sure right now
function HandleMIDI(event) {
}

 

Thanks for all the help! I’ll try and figure it out. English isn’t my native tounge and some of the things you lay out for me are new, IAC for one and the programming. Thanks anyway!

Link to comment
Share on other sites

The IAC thing is only necessary for the demo. You can just use the script and tweak it for your purposes. I suggest google translate if English is an issue for technical details.

 

Unfortunately the audio markers can’t have program change attached to them. I doubt we will ever see that feature so your best bet is to use some kind of midi sequencer to playback your program changes. My script is essentially a very simple midi sequencer. But you could use the built in midi file player for this too although I’ve never used that. Plus you have to edit it in another program so my script is a bit more convenient for me, but if you use a midi file you can just use any midi sequencer to make it.

 

Then the audio and midi should both play but the question is how to make sure they are in sync. That’s a longer topic I don’t want to type from the iphone.

 

But anyway if In Logic you insert an actual program change event on a midi track that lines up exactly with your marker. Put all the program changes on one midi track lined up with the markers and make sure the tempo is fixed and unchanging, regardless of what the audio is doing. Then export that track as a midi file and load it into the main stage project to playback with the patch using the same tempo you had in logic. Use that instead of the script I shared earlier and it should work. You might encounter slight sync issues between the audio and midi due to the tempo in logic not being exactly the same as what you configure in main stage. If you are able to create an Apple loop caf file of your audio in logic, then you can force the audio in main stage to sync with the metronome.

 

Doing tempo changes in main stage is possible but extremely hard so I don’t reccomend it. If you have complicated material that changes tempo all over the place then just use logic instead of main stage. It is however possible to do some simple tempo changes in a song by using separate patches in main stage for different sections of a song. Each section having its own tempo. Plus getting the audio in sync with complicated tempo changes is non trivial. Single tempo is much easier. I posted on another thread a similar mainstage demo that sends out program changes and follows tempo changes while the caf Apple loop locks to the tempo changes. Check that out if you need to for tempo changes.

 

If you mess with all of this and come back with questions I can walk you through getting something working. Personally I think the easiest way is to forget about sync and just playback the audio and figure out the right beat position to place the program change in the script. Once you do it a couple times it’s not that hard. I can also give you another script to put into logic to figure out the exact beat position values you need for the script in each case.

Link to comment
Share on other sites

Tutorial #1 - No Beat Mapping

 

Scenario

You have a non-beatmapped audio that needs to play and you need Program Changes sent out a certain points of time you have marked in LogicPro with markers. The audio does not necessarily line up with the metronome in this example.

 

  1. In LogicPro, place markers where you intend for Program Changes to be sent out.
     
    markers1.jpg.e295f6cc392c555d1081eaa088dbc30e.jpg
    markers1-list.jpg.ba2dd1533888188de57fd5ab4ed02878.jpg
     
  2. Because the audio is not synced with the metronome, in this example, the markers may or may not line up on beat lines, but it doesn't matter. Place them wherever you want, but you should right click on each marker and lock it to the SMPTE time line so that it will always be at the correct point relative to the audio, regardless of what the tempo is set to.
     
    lock.jpg.5bdb22266144055b72c0a66e0cf31c3e.jpglockilst.jpg.2328bcdc0b8348bbc2d00473c881d912.jpg
     
  3. Create a software instrument track and create a region on it. Drag the length to be as long as the audio track.
     
     
  4. Position the playhead at each marker and create a program change event in the event list using the + button. Right click on each event to lock it to SMPTE, as you did for markers. Set the "val" parameter of each program change event to the outgoing PC number you want (note that in the event list, the "Number" parameter seems to be used for bank or something like that).
     
    lockedpslist.jpg.f1015a41aefb35febed394f2095bb4b6.jpg
     
  5. You will end up with a region that shows some PC messages in a region that line up with the markers.
     
    finalproj.jpg.5ea3bfa2844c68c6aca7cc3f352ae2ad.jpg
     
  6. Right click on the midi region and choose export midi file. Save the mid file somewhere convenient.
     
    export.jpg.5be0f89cb01d88a8ad666a2786faa918.jpg
     
  7. Take note of the tempo in Logic for this project (There should not be any tempo changes). You will need to set the same tempo over in mainstage.

 

 

At this point you have a midi file with program change messages that are exactly where you need them aligned with your non-beatmapped audio. In theory if you use exactly the same metronome tempo in mainstage and playback that sequence in Mainstage while the audio also plays back there, then the program changes should go out exactly at the right times. The problem is how to playback the midi file. I see three possible solutions

 

  1. Mainstage midi file playback feature. This is hit or miss, I found it too difficult to use. Playback happens if and only if you change to the patch from an other patch. You can't start it or stop it manually that I can figure out. I found this method very difficult to deal with, but it might work for you, so try it. Its built in though, so maybe worth a try. Instructions below
  2. Third party midifx plugin to play back midifiles. As of now I only know of one, Plogue Bidule, which I have tried and it works. Reaktor might work too. There might be others. This sequencer is attached to the play button in mainstage and will absolutely play in sync with the playback plugin. Instructions below...
  3. Scripter. You can use the free script I have provided, and will provide again below, which is like a little mini sequencer that only sends Program changes at exact points of time. It will absolutely play in sync with the playback plugin. Instructions below..

 

The next few posts will outline each of those options in Mainstage

Link to comment
Share on other sites

Mainstage Midifile Playback

 

This describe how to setup the Midifile playback of program changes using a previously prepared midi file in LogicPro as described above.

 

  1. Create an external instrument channel. This can be at the patch level, set level, but note that if its at the set level, for example, then the midi file will start playing as soon as you select a patch within that set, after you were previously in a patch outside the set. Once you're in the set, the file continues uninterrupted as you change patches within the set.
     
  2. Configure the output device and channel where you want the midifile containing the program change to be sent.
     
    extinst.jpg.f9ffb1ab06fd66607b1c185b2f458fcf.jpg
     
  3. The Patch or Set where the midifile channel is located needs to have the tempo set appropriately. Set it to the same value as it was in your LogicPro project.
     
    mainstagetempo.jpg.02df7ac71e59e6faebde06bfb7b88547.jpg
     
  4. I think its a good idea to block any incoming midi from coming through this channel strip, its being used only to send OUT program changes. I use a little script for this, but there might be a way to block that in mainstage, I'm not sure. Here's the script:
    extinstscript.jpg.fa1c938ed157c57feb248351d0769484.jpg
    function HandleMIDI(event) {
    // block all incoming midi here
    }
    


     

  5. Assign the midifile to the channel, select the channel and edit the midi output area.
     
    sendfile.jpg.3fd684d24d4e4bd53068de3805e47bb5.jpg
     
  6. Create a software instrument channel and host the playback plugin. Load your audio file and in this case make sure it is NOT being tempo adjusted in anyway, you want the audio to playback at its original speed. Make sure its also setup to play when the patch is loaded, rather then via the play button.
     
    syncoff.jpg.71d0a932cbb178890d49050035a82624.jpgstartchange.jpg.834df8378a38f2fc2e9cb7d4209ebe5c.jpg
     
  7. That's it, it should work. When you select that patch or set, you should hear playback of your audio and the midifile with program changes will send out.

Link to comment
Share on other sites

Third Party Sequencer Plugin in Mainstage - Plogue Bidule

 

This will describe how to setup playing a midifile in Mainstage using a third party plugin such as Plogue Bidule

 

  1. Create external instrument channel to handle this, see steps 1-4 in the above example.
     
     
  2. Place instance of Plogue Bidule midifx plugin in the midifx slot, below the midi blocking script:
     
    biduleinstance.jpg.d48f25435e39151061699c80ea6983c3.jpg
     
  3. Open PlogueBidule and create a setup with a midifile player using the following circuit.
     
    bidulecircuit.jpg.e5698f6d9c60287467c5b83f20785ead.jpg
     
  4. Open the midifile player object and configure it with the midifile, take note of some of the other options. Also note in the top right corner the "sync" parameter needs to be set also in order to sync to the host.
     
    biduleseq.jpg.033f13ad84f0e223c09f3362f32ae94a.jpg
     
  5. Setup the playback plugin as in the previous example. Note, however, that in this approach the playback can be configured to happen when loading the patch or by hitting the play button, your choice. Either way, the Plogue Bidule sequencer will play in sync with the audio.

Link to comment
Share on other sites

Scripter-based sequencer

 

This will explain how to use the free Scripter script to perform mainstage sequencing of program changes. Note, in this case, the previously saved midi file is not used, but the Logic Pro project is still useful.

 

  1. Create an external instrument channel as in the first example steps 1-3 (note the midi blocking script is not needed here)
     
     
  2. Create a channel for the playback plugin as described above for the audio.
     
     
  3. Place an instance of scripter into the midifx slot. Use the following script:
    extinstscript.jpg.ba72f9281a2d6d7d64c063175634fb41.jpg
    var NeedsTimingInfo = true;
    
    //========= EDIT THIS ARRAY ====================
    
    var programChanges = [
       {beatPos:4.99, channel:1,  number:2}
      ,{beatPos:8.99, channel:1,  number:3}
      // copy the above line for more Program changes
    ];
    
    
    //========= DO NOT EDIT BELOW HERE =============
    
    var idx = 0;
    var pc = new ProgramChange;  //reuse in a loop
    
    function ProcessMIDI() {
      /* Get current timing info */
      var info = GetTimingInfo();
     
      /* only do work if playing */
      if ( !info.playing ) {
          idx = 0;
          return;
      }
      
      if (idx < programChanges.length) {
      
         while ( idx < programChanges.length &&
                 info.blockStartBeat <= programChanges[idx].beatPos && 
                 info.blockEndBeat >= programChanges[idx].beatPos ) {
                      
            pc.number = programChanges[idx].number;    
            pc.beatPos = programChanges[idx].beatPos;
            pc.channel = programChanges[idx].channel;  
            pc.send();
            // pc.trace();
            idx++;
         }              
      }
      
    }
    
    // ignore incoming midi, might not need this, not sure right now
    function HandleMIDI(event) {
    }
    



     

  4. The script now needs to be edited. The following section of the script is where you can edit it, change these lines to have the program changes you want at the beat positions you want:
    //========= EDIT THIS ARRAY ====================
    var programChanges = [
       {beatPos:4.99, channel:1,  number:2}
      ,{beatPos:8.99, channel:1,  number:3}
      // copy the above line for more Program changes
    ];
    //========= DO NOT EDIT BELOW HERE =============
    


     
    In order to edit this section, you will need to edit the beatPos, channel and number values for each program change you want to send. You can add more program changes by copying the 2nd line as many times as you want. The beatPos represents the time in total beats from the start, without regard to bars; when the program change should be sent. Channel and Number are self explanatory.
     
    The beatPos is a fractional value in order to place in between or just before beats for example. In this example I have two program changes happening just before beats 5 and 9 of the sequence. You can use trial and error to figure out the beatPos values to use.
     
    Or....
     
    you can use a special logging script I made which you can insert into the midi track of the LogicPro project you used earlier. Then hit play and watch the script src window to see the exact beatPos values logged for you that line up with the program changes and markers you made earlier in LogicPro.
     
    Here is that script and some example output

    var NeedsTimingInfo = true;
    
    function HandleMIDI(event) {
       event.send();
       if (event instanceof ProgramChange) {
           Trace(event.beatPos + " : Program Change " + event.number);
       }
    }
    


    4.624444431749483 : Program Change 4
    6.499637178517878 : Program Change 5
    15.666303845246633 : Program Change 6
    

 

Set that up and playback of the program changes should happen exactly in sync with the audio as in the other examples.

Edited by Dewdman42
Link to comment
Share on other sites

Whew that is a lot to grok, but there are 3 possible ways to get program changes sent out more or less in sync with the audio. I don't particularly like the built in midi file approach, its kind of unpredictable for me, but the other two approachs both work. If you can handle a little bit of script editing you can do it for free. If not, then you can buy a third party sequencer such as Plogue Bidule and get it done that way with the midi file.

 

This took a while to write, so I'm off for now, but in the future I might also present some ideas about how things can be easier if your audio is beatmapped or sliced. If you have audio material that is pretty close to match a tempo, then you can beatmap it and force it to conform to Mainstage's metronome. When you do that it becomes monumentally easier to figure out the beatPos values I mentioned earlier since they are probably just sitting right on beat lines. Anyway, I leave that to you to figure out, for now, try some of the above and let me know if you have any questions.

Link to comment
Share on other sites

Whew that is a lot to grok, but there are 3 possible ways to get program changes sent out more or less in sync with the audio. I don't particularly like the built in midi file approach, its kind of unpredictable for me, but the other two approachs both work. If you can handle a little bit of script editing you can do it for free. If not, then you can buy a third party sequencer such as Plogue Bidule and get it done that way with the midi file.

 

This took a while to write, so I'm off for now, but in the future I might also present some ideas about how things can be easier if your audio is beatmapped or sliced. If you have audio material that is pretty close to match a tempo, then you can beatmap it and force it to conform to Mainstage's metronome. When you do that it becomes monumentally easier to figure out the beatPos values I mentioned earlier since they are probably just sitting right on beat lines. Anyway, I leave that to you to figure out, for now, try some of the above and let me know if you have any questions.

 

Thanks so much for the extensive help! I’m sick right now which is why I’m not answering. I’ll get back to you when I’ve regained my strength.

Link to comment
Share on other sites

  • 2 months later...

Dewdman42,

 

I just need you to know that you are so awesome. Thanks for taking the time to both write the script and share it.

 

I have done every method of automating MainStage up until scripting, and all of them had pros and cons. I knew scripting would end up being the solution, but my programming chops just aren't there yet. (I'm doing the first few lessons on Java with Codeacademy right now).

 

This saves me so much time and effort, so thank you very much.

Link to comment
Share on other sites

Happy to help. FYI this is “javascript” and not “Java”. The two are very very different and it’s very strange the author of JavaScript chose to use the word Java, I can’t remember why, but if you’re going to try to learn it, you want “javascript”.

 

I also want to say that javascript is capable of some wild and crazy things which go way beyond what is really useful in Logic Pro scripter. You can get a LOT of effective midi scripting done in logic and main stage with some pretty basic and simple JavaScript, learnable in an afternoon. What takes a little more time is coming to understand the midi handling specifics of the Scripter plugin.

Link to comment
Share on other sites

Happy to help. FYI this is “javascript” and not “Java”. The two are very very different and it’s very strange the author of JavaScript chose to use the word Java, I can’t remember why, but if you’re going to try to learn it, you want “javascript”.

 

I also want to say that javascript is capable of some wild and crazy things which go way beyond what is really useful in Logic Pro scripter. You can get a LOT of effective midi scripting done in logic and main stage with some pretty basic and simple JavaScript, learnable in an afternoon. What takes a little more time is coming to understand the midi handling specifics of the Scripter plugin.

 

 

@Dewdman42 Gotcha.

 

Actually, quick question if you've got some time. I'm using your script, and I successfully got PC's triggering patch changes, but the beat position timing doesn't seem to correspond correctly. Maybe I'm not doing my beat position math correctly?

 

For example, I'm trying to have a patch change at beat 1 of Bar 8. So I did the math (4*8=32, +1 for the downbeat)...but when I hit play, the patch change occurs at Bar 25 Beat 4. Any ideas?

284910315_ScreenShot2018-06-05at9_01_50PM.thumb.png.8187476ffb4bd2a62f5152951ffa7cc5.png

Link to comment
Share on other sites

Glad its helping. If I get time later I'll make a version where you can set the program changes and beat positions in the UI rather then editing the script, but it probably works fine editing the script and its a simpler script this way. I also want to contemplate whether it would make sense to use automation to set the program change values...then perhaps they could be configured directly in MainStage somehow and the automation would drive them...but I have to ponder that.
Link to comment
Share on other sites

Should work. Did you hit the run script button?

 

I've been reading through the Effects manual, and your code looks correct...I don't know why it's not working.

 

BUT, I did find a pretty useful workaround for future reference.

 

In the Scripter Presets under Factory->Tutorial Scripts->9- NeedsTimingInfo and GetTimingInfo you can essentially get the same information...it just won't be filtered by PC's.

 

It will display the beat position value from where ever you hit play, so you can quickly go through your hit points and log the beat position.

1551039583_ScreenShot2018-06-08at11_26_04AM.thumb.png.e791018bdce35df53112460c4af53628.png

Link to comment
Share on other sites

Gettiminginfo will give you the start and end points of the process block. I’m not sure how big the process block is during handlemidi. Anyway glad to see you’re digging into the scripter manual to explore! I am bugged that the original simple script isn’t working for you though. Worked here.
Link to comment
Share on other sites

ok I think I know why that script didn't work for you. You need to have some kind of actual software instrument enabled on that channel, otherwise the midi for the channel doesn't get processed. This is just a LogicPro thing. No instrument, then Scripter doesn't do anything. So put an instrument there and then it should work.
Link to comment
Share on other sites

  • 3 weeks later...
  • 2 months later...

Here's a new version of the script that includes ability to send MSB/LSB bank messages:

 

var NeedsTimingInfo = true;

//========= EDIT THIS ARRAY ====================

var programChanges = [
   {beatPos:1.99, channel:1, msb:0, lsb:3, number:2}
  ,{beatPos:4.99, channel:1, number:3}
  // copy the above line for more Program changes
];


//========= DO NOT EDIT BELOW HERE =============

var idx = 0;
var pc = new ProgramChange;  //reuse in a loop
var cc = new ControlChange;

function ProcessMIDI() {
  /* Get current timing info */
  var info = GetTimingInfo();
 
  /* only do work if playing */
  if ( !info.playing ) {
      idx = 0;
      return;
  }
  
  if (idx < programChanges.length) {
  
     while ( idx < programChanges.length &&
             info.blockStartBeat <= programChanges[idx].beatPos && 
             info.blockEndBeat >= programChanges[idx].beatPos ) {
        
        if(programChanges[idx].msb != undefined) {         
            cc.channel = programChanges[idx].channel;
            cc.beatPos = programChanges[idx].beatPos;
            cc.number = 0;
            cc.value = programChanges[idx].msb;
            cc.send();
            //cc.trace();
        }
        
        if(programChanges[idx].lsb != undefined) {                    
            cc.channel = programChanges[idx].channel;
            cc.beatPos = programChanges[idx].beatPos;
            cc.number = 32;
            cc.value = programChanges[idx].lsb;
            cc.send();
            //cc.trace();
        }

        if(programChanges[idx].number != undefined) {
            pc.number = programChanges[idx].number;    
            pc.beatPos = programChanges[idx].beatPos;
            pc.channel = programChanges[idx].channel;  
            pc.send();
            //pc.trace();
        }
        
        idx++;
     }              
  }
  
}

// ignore incoming midi, might not need this, not sure right now
function HandleMIDI(event) {
}
  • Love 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...