drb Posted July 31, 2013 Share Posted July 31, 2013 (edited) I have created a script for the MIDI plugin Scripter that sets the MIDI channel for channel messages by Program Change messages. This may be of interest if: 1) You have a multi-timbral software instrument that does interpret MIDI channels 2) but does not interpret Program changes 3) and you want to change "voice" within one track. In my case this came up with the Aria version of the Garritan Personal Orchestra and a score that had one musician switching between flute and piccolo. This allowed me to easily keep one staff in the score without having to edit the MIDI channels of the track. Since dirrent MIDI channels are can be used by the Notation part of Logic for polyphonic parts and hiding key switches, this can make changing "voice" easier when global changes to the MIDI channel are not easy. Instructions are in the script. Note that the channel strip MIDI channel must be set to "All". /* Implement program change messages as changes in MIDI channel for Instruments that implement MIDI channel changes but not program changes. Program number becomes MIDI channel. Starts as 1. Program change message results in saving new channel number. Program change message not passed through. Other channel messages passed through with MIDI channel set to saved channel number Non channel message passed through unchanged. No configuration parameters. Assuming MIDI channel and program numbers start at 1, not 0 Assuming track MIDI channel set to ALL. */ var savedChannel = 1; // MIDI channel number to use function HandleMIDI(event) { if ( event instanceof ProgramChange ) { if ( 1 <= event.number && event.number <= 16 ) { // ignore if not a good MIDI channel savedChannel = event.number; // save program number as MIDI channel } } else if ( event instanceof NoteOn || // all other channel messages event instanceof NoteOff || event instanceof PolyPressure || event instanceof ControlChange || event instanceof ChannelPressure || event instanceof PitchBend ) { event.channel = savedChannel; // set to saved program number event.send(); // pass through event } else { event.send(); //send anything else through unchanged } } function reset() { savedChannel = 1; // back to default } Edited August 1, 2013 by drb Quote Link to comment Share on other sites More sharing options...
anp27 Posted August 1, 2013 Share Posted August 1, 2013 Very cool drb! Can't wait to try this! Quote Link to comment Share on other sites More sharing options...
Chris Rickwood Posted August 1, 2013 Share Posted August 1, 2013 Have you tested this with overlapping notes? I wrote a script similar to this but found if you switch channels in the middle of a note, you never send a MIDI Off event to the correct channel. Thus you'll get a hanging note. Quote Link to comment Share on other sites More sharing options...
drb Posted August 1, 2013 Author Share Posted August 1, 2013 anp27, thanks. cmrick, No, you caught me. The case I was using it for, simulating a musician changing instruments, doesn't bring this up. If you are interested, I think it could be done -- but the script would have to track note ons, then generate a note off itself for notes still going during a program change. This would not help with synthesizers that abruptly end release and effects that may go on after a note off when the "voice" changes. So, it still would not be perfect for the case of a program change during a note. Quote Link to comment Share on other sites More sharing options...
drb Posted August 1, 2013 Author Share Posted August 1, 2013 cmrick, After the last reply, thinking some more, I realized that since what is really happening is a channel change on a multitimbral instument, not a program change, my worries about release and effects may not be correct. This makes your point even better. If you wish, I can try making this change tomorrow (it's late on the east coast). Quote Link to comment Share on other sites More sharing options...
drb Posted August 1, 2013 Author Share Posted August 1, 2013 Here is a more complex version in an attempt to deal with unfinished business at a program channel change - that is, hanging notes. A note held over a program/channel change can still have odd results. If a new note of the same pitch is started and not finished before the note end of the previous note, the first note off stops the note prematurely. I also try to deal with the sustain and sostenuto controllers. Since some controllers are undefined in the MIDI spec and some are used in non-standard ways, I cannot anticipate all possibilities. For recorded sequence work, I think I will use the first version and be sure one instrument is done before trying to use another. /* ProgramNumberToMIDIChannel-1.1.js written by David R. Baker Version 1.1 2013 08 01 Implement program change messages as changes in MIDI channel for Instruments that implement MIDI channel changes but not program changes. Program number becomes MIDI channel. Starts as 1. Program change message results in turning outstanding notes/sustain/sostenuto off (new 1.1) and saving new channel number. Program change message not passed through. Other channel messages passed through with MIDI channel set to saved channel number Non channel message passed through unchanged. No configuration parameters. Assuming MIDI channel numbers start at 1, not 0 Assuming track MIDI channel set to ALL. */ var savedChannel = 1; // MIDI channel number to use var noteOnCnt = [ // 1 element for each note number/pitch 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ]; function HandleMIDI(event) { var off = new NoteOff; var cc = new ControlChange; //event.trace(); off.channel = savedChannel; off.velocity = 0; if ( event instanceof ProgramChange ) { if ( 1 <= event.number && event.number <= 16 ) { // ignore if not a good MIDI channel for (var i=0; i<128; i++) { // for each MIDI pitch for (var j=0; j<noteOnCnt[i]; j++) { // for each outstanding note on off.pitch = i; // send note off off.send(); //Trace("generated note off"); } noteOnCnt[i] = 0; } cc.channel = savedChannel; cc.value = 0; cc.number = 64; // turn off sustain cc.send(); //Trace("generated sustain off"); cc.number = 66; // turn off sostenuto cc.send(); //Trace("generated sostenuto off"); savedChannel = event.number; // save program number as MIDI channel } } else if ( event instanceof NoteOn ) { noteOnCnt[event.pitch] += 1; // increment number of note On's event.channel = savedChannel; // set to saved program number event.send(); // pass through event } else if ( event instanceof NoteOff ) { if ( noteOnCnt[event.pitch] > 0 ) { // odd case of note crossing channel change noteOnCnt[event.pitch] -= 1; // decrement number of note On's } event.channel = savedChannel; // set to saved program number event.send(); // pass through event } else if ( event instanceof PolyPressure || // all other channel messages event instanceof ControlChange || event instanceof ChannelPressure || event instanceof PitchBend ) { event.channel = savedChannel; // set to saved program number event.send(); // pass through event } else { event.send(); // pass anything else through unchanged } } function reset() { savedChannel = 1; // back to default for (var i=0; i<128; i++) { noteOnCnt[i] = 0; } } Quote Link to comment Share on other sites More sharing options...
Chris Rickwood Posted August 2, 2013 Share Posted August 2, 2013 For recorded sequence work, I think I will use the first version and be sure one instrument is done before trying to use another. Yeah, I haven't found a really elegant solution yet either. It's just something to be aware careful of I guess. Please Apple, just give us Cubase style Expression Maps! Quote Link to comment Share on other sites More sharing options...
anp27 Posted August 28, 2013 Share Posted August 28, 2013 Here is a more complex version in an attempt to deal with unfinished business at a program channel change - that is, hanging notes. Just tested this using GPO4 with the Woodwind quintet ensemble loaded. It works GREAT! I didn't test your newer code for the program change in between notes though. Thanks again! This is a good workaround to the lack of expression maps within Logic. Somewhat related.... would you have any ideas on how to get Logic's Smart Controls to see the ARIA Player by any chance? Would it involve some special script for this to work? I would love to be able to map ARIA's CCs to the Smart Controls. Quote Link to comment Share on other sites More sharing options...
drb Posted August 28, 2013 Author Share Posted August 28, 2013 anp27, Thanks again. Note - view this topic for a problem using the script on multiple tracks. http://www.logicprohelp.com/forum/viewtopic.php?f=42&t=98869 I hope this will be fixed. Meanwhile, I am having no problem using this script on a single track. On Smart Controls and Aria -- as far as I can tell Aria does not implement the automation parameters (as opposed to MIDI CC's) used by Smart Controls. If you switch the view for a plugin from Editor to controls on Logic instruments (or NI Kontakt for example) you see a bunch of parameters. On Aria, you see none. I am far from guru hood on this topic. So, maybe someone else can see a way that I cannot. Maybe an Environment window could do this. drb Quote Link to comment Share on other sites More sharing options...
anp27 Posted August 28, 2013 Share Posted August 28, 2013 anp27, Thanks again. Note - view this topic for a problem using the script on multiple tracks. http://www.logicprohelp.com/forum/viewtopic.php?f=42&t=98869 I hope this will be fixed. Meanwhile, I am having no problem using this script on a single track. On Smart Controls and Aria -- as far as I can tell Aria does not implement the automation parameters (as opposed to MIDI CC's) used by Smart Controls. If you switch the view for a plugin from Editor to controls on Logic instruments (or NI Kontakt for example) you see a bunch of parameters. On Aria, you see none. I am far from guru hood on this topic. So, maybe someone else can see a way that I cannot. Maybe an Environment window could do this. drb Just checked out that thread I'm sure Apple will fix it soon. As for the ARIA Player, I emailed Garritan and asked them about it, will have to wait for their reply. Do you have any hints on how the environment might be used in this situation? Quote Link to comment Share on other sites More sharing options...
drb Posted August 28, 2013 Author Share Posted August 28, 2013 anp27, On the environment instead of Smart Controls -- I am still learning Logic myself, so I would be figuring out how to make such an environment window from scratch. It appears that faders would do the job, but I have not actually done it. Please post when you hear from Garritan. drb Quote Link to comment Share on other sites More sharing options...
ski Posted August 28, 2013 Share Posted August 28, 2013 FWIW, doing this in the environment will prove a daunting task. And if you don't know the environment, it will take you years to figure out. At one time I was offering an environment macro called "SkiSwitcher" that solves all of these problems (it was donation-ware, but virtually no one donated so it's now off the market.) Anyway, the biggest issue here is not that the problems are unsolvable in scripts, but that you can't run more than one Script in LX without causing problems (thanks drb for pointing this out). Quote Link to comment Share on other sites More sharing options...
anp27 Posted August 28, 2013 Share Posted August 28, 2013 drb and ski, thank you both for your replies. I guess we will just have to wait for a fix then.. Quote Link to comment Share on other sites More sharing options...
anp27 Posted August 29, 2013 Share Posted August 29, 2013 anp27,Please post when you hear from Garritan. drb This is reply I received from Garritan: Unfortunately, the ARIA Player is not compatible with Logic's Smart Control. Since the ARIA player is a dynamic interface, the MIDI controls that are available with it will change from library to library and sometimes from sample to sample. The only way to change MIDI values is to use the UI in the ARIA player itself or to draw the MIDI data into the track itself. Please feel free to respond to this case if you have any further questions about this issue. Erin V. MakeMusic Customer Support Quote Link to comment Share on other sites More sharing options...
drb Posted August 29, 2013 Author Share Posted August 29, 2013 anp27, Thanks for the Garritan reply. Sort of what I guessed, though the explanation doesn't make sense to me. I think they just haven't implemented the automation stuff. Possibly because a major design and marketing point is that it is playable from a controller. drb Quote Link to comment Share on other sites More sharing options...
anp27 Posted August 29, 2013 Share Posted August 29, 2013 It works!! anp27, Thanks for the Garritan reply. Sort of what I guessed, though the explanation doesn't make sense to me. I think they just haven't implemented the automation stuff. Possibly because a major design and marketing point is that it is playable from a controller. drb I was actually expecting an answer like that from them. BUT! I did some poking around on the Web and did an experiment. I went to the Plogue site (which makes the sfz player) and downloaded the 'universal' sfz player that they have. I opened up the 'sforzando' plugin and GUESS WHAT?? The controls within the sforzando player ARE RECOGNIZED by Smart Controls! And I'm able to access all of my Garritan libraries as well! They happen to be fully compatible If you want to have access to the Smart Controls as well, I recommend you going to the Plogue site and grabbing the sfz player. Really happy right now Quote Link to comment Share on other sites More sharing options...
drb Posted August 29, 2013 Author Share Posted August 29, 2013 anp27, Good find! Thanks for sharing. drb 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.