joachim_s Posted March 6, 2018 Share Posted March 6, 2018 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 Quote Link to comment Share on other sites More sharing options...
jwhitesides Posted March 7, 2018 Share Posted March 7, 2018 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. Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted March 7, 2018 Share Posted March 7, 2018 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... Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted March 7, 2018 Share Posted March 7, 2018 (edited) 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. 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 June 30, 2018 by Dewdman42 Quote Link to comment Share on other sites More sharing options...
joachim_s Posted March 8, 2018 Author Share Posted March 8, 2018 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! Quote Link to comment Share on other sites More sharing options...
joachim_s Posted March 8, 2018 Author Share Posted March 8, 2018 what do you mean by playback markers? By Playback markers I mean the marker info that come along with a audio file containing marker information from Logic. Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted March 8, 2018 Share Posted March 8, 2018 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. Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted March 10, 2018 Share Posted March 10, 2018 Alright I have some time this morning to make a little tutorial. Actually I may do several different ones in several different post with slight variations... Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted March 10, 2018 Share Posted March 10, 2018 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. In LogicPro, place markers where you intend for Program Changes to be sent out. 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. Create a software instrument track and create a region on it. Drag the length to be as long as the audio track. 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). You will end up with a region that shows some PC messages in a region that line up with the markers. Right click on the midi region and choose export midi file. Save the mid file somewhere convenient. 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 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 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... 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 Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted March 10, 2018 Share Posted March 10, 2018 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. 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. Configure the output device and channel where you want the midifile containing the program change to be sent. 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. 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: function HandleMIDI(event) { // block all incoming midi here } Assign the midifile to the channel, select the channel and edit the midi output area. 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. 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. Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted March 10, 2018 Share Posted March 10, 2018 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 Create external instrument channel to handle this, see steps 1-4 in the above example. Place instance of Plogue Bidule midifx plugin in the midifx slot, below the midi blocking script: Open PlogueBidule and create a setup with a midifile player using the following circuit. 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. 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. Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted March 10, 2018 Share Posted March 10, 2018 (edited) 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. Create an external instrument channel as in the first example steps 1-3 (note the midi blocking script is not needed here) Create a channel for the playback plugin as described above for the audio. Place an instance of scripter into the midifx slot. Use the following script: 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) { } 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 June 8, 2018 by Dewdman42 Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted March 10, 2018 Share Posted March 10, 2018 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. Quote Link to comment Share on other sites More sharing options...
joachim_s Posted March 11, 2018 Author Share Posted March 11, 2018 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. Quote Link to comment Share on other sites More sharing options...
DolmensDude Posted March 12, 2018 Share Posted March 12, 2018 well done. respect. Quote Link to comment Share on other sites More sharing options...
SRF_Audio Posted June 4, 2018 Share Posted June 4, 2018 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. Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted June 4, 2018 Share Posted June 4, 2018 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. Quote Link to comment Share on other sites More sharing options...
SRF_Audio Posted June 5, 2018 Share Posted June 5, 2018 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? Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted June 5, 2018 Share Posted June 5, 2018 you did the math right. Can you send me the MainStage concert file to look at Quote Link to comment Share on other sites More sharing options...
SRF_Audio Posted June 5, 2018 Share Posted June 5, 2018 Ah geez...never mind. Math in public. I forgot to subtract 3 beats to get the previous downbeat. *sheepish grin* It works great man. Thank you so much. This is just incredible. Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted June 5, 2018 Share Posted June 5, 2018 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. Quote Link to comment Share on other sites More sharing options...
SRF_Audio Posted June 7, 2018 Share Posted June 7, 2018 Dewdman42, Ok, I actually do need a bit of help with the script that prints beat position to the console. I've cut and pasted the script, and it's on a MIDI track with PC's, but no output to the console. Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted June 7, 2018 Share Posted June 7, 2018 Should work. Did you hit the run script button? Quote Link to comment Share on other sites More sharing options...
SRF_Audio Posted June 8, 2018 Share Posted June 8, 2018 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. Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted June 8, 2018 Share Posted June 8, 2018 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. Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted June 8, 2018 Share Posted June 8, 2018 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. Quote Link to comment Share on other sites More sharing options...
SRF_Audio Posted June 30, 2018 Share Posted June 30, 2018 Hey Dewdman42, just wanted to follow up to say thanks. I gave you a big shout out in my recent tutorial on this topic: And also, good call on needing an instrument. That solved it! Quote Link to comment Share on other sites More sharing options...
itayburg Posted September 21, 2018 Share Posted September 21, 2018 Amazing!! One Question - How do I choose the Bank? Thx Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted September 21, 2018 Share Posted September 21, 2018 Check out this article: https://www.sweetwater.com/sweetcare/articles/6-what-msb-lsb-refer-for-changing-banks-andprograms/ So basically you need to send a CC00 and CC32 message right in front of the actual program change message. Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted September 21, 2018 Share Posted September 21, 2018 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) { } 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.