Jump to content

Composer Tools Pro Recall Script


bpford

Recommended Posts

Hi y'all,

I'm trying to replace a transform object in the environment that's used to recall patches in Composer Tools Pro on my iPad for articulation switching. It's a simple transform object that listens for CC 119( coming from CTPro on the iPad), and converts it to a user specified program change number and channel number. The transformer than filters all other information out and sends the program change and channel out to a specified Lemur port via another midi instrument in the environment. The program change number and channel number is the unique ID that Composer Tools Pro uses to identify which patch to recall.

 

If my explanation is confusing, here's a youtube example of the setup:

 

 

So, I know next to nothing about java scripting, but I can't use environment objects because of my workflow. I've moved away from using one huge template pre setup with these environment objects, and instead populate each project with channel strip presets and track stack patches as I go. The problem is those saved channel strips and patches don't bring along their attached environment objects though. But if I had a script that did the same thing, it would always travel with the instrument preset...e.g. Spitfire Violin 1 or whatever.

 

But I've failed to get anywhere cobbling together code from various examples. Here's what I've got so far.

/*Script that transforms control change 119 into a program change 
with user definable channel number and program change number and filter all other midi events
*/


var PluginParameters = [

{
	name:"Channel", 
	type:"valueStrings",
	defaultValue:1,
	minValue:1, 
	maxValue:16,
  numberOfSteps:15
},
										
{
	name:"Program #", 
	type:"valueStrings",
	defaultValue:0,
	minValue:0, 
	maxValue:127,
	numberOfSteps:127
},
];

function HandleMIDI(recall) 
{
if(recall instanceof ControlChange && recall.number == 119)
{
	var p = new ProgramChange;			//generates program change message and saves as "p"
	var prog = GetParameter("Program #")		//retrieves program number from user input and saves to "prog"
	var chan = GetParameter("Channel")		//retrieves channel number from user input and saves to "chan"
	p.channel = chan				//sets program change to "prog"
	p.number = prog					//sets program change channel to "chan"
	recall.trace();					//filters out all other midi messages
	p.send();					//sends out only channel and program change # 
}
}

 

Did I mention I don't know what I'm doing? Anybody got helpful hints? So far, the script is just spitting out what I send it...CC 119.

 

It would also be GREAT if I could specify what port to send out the program change to, but as far as I can tell, that's not a capability? That would also help me to avoid having to cable each instrument to the instrument object that's pointing to the Lemur output port.

Link to comment
Share on other sites

yes! That worked! Thanks!

 

So I know that my script works, but how do I get it to work with a regular software instrument?

 

Connecting a cable from a software instrument channel to a midi instrument with its output set to the correct port in the environment should perform the same function, no?

Link to comment
Share on other sites

Unfortunately, midi generated inside a channel object cannot currently be cabled out of it in the environment. Please submit a feature request to Apple on this, as have I and many others.

 

The only work around if you want to use Scripter to drive other things in the environment, is to use the External instrument plugin that Eric mentioned and send the midi to an IAC port. Once it goes to the IAC port, then it will be coming back into Logic as if its a new midi coming in, and you can route it anywhere you want in the environment from there, by default it will go to the sequencer.

Edited by Dewdman42
Link to comment
Share on other sites

Well you can get the midi back around through IAC, that will work... I'm not sure yet whether you'd be able to create a nice easy patch you can reload, but maybe. I didn't quite understand the complete midi flow, where does the midi come from that is feeding your script? and where do you need to get it to after going through your script?
Link to comment
Share on other sites

Here's the way it works using the transformer object in the environment.

 

All of my software instrument tracks are cabled to their own individual transform objects. The condition for all these individual transform objects is that they need to see CC 119. And they all perform the same operation but with different user inputted values. So, when CC 119 is met, you fix a program change to a user specified channel and program change number. My violin 1 track is cabled to a transform object that will spit out Channel 1, Program Change 0 for instance, and my violin 2 is cabled to a transform object that will spit out Channel 1, Program Change 1.

 

All of these transform objects are then a cabled to an instrument whose port is set to the virtual Lemur Daemon Output 0, which is the virtual input port on the iPad.

 

So, now I scroll to my Violin 1 patch in Logic. I press the "recall" button on the iPad app, which sounds out a CC 119 message. The selected track in Logic sees that, performs the transform operation and then sends back out the channel number and program change unique to it to the iPad app. When the iPad sees that info, it switches to the corresponding patch with all of its unique articulation switches, sliders, etc.

 

It makes it easier to keep track of hundreds of different instruments and their own unique keyswitches as well as any other custom controllers you'd like to build into the iPad patch.

Link to comment
Share on other sites

Right so simply:

 

Lemur sends CC119 to Logic and depending on what track is selected in Logic, Logic sends midi back to Lemur which tells it what patch to switch to.

 

This would also be a lot easier, if, whenever you select an instrument track in Logic it automatically sends out a custom midi message containing the channel number and program change number.

Link to comment
Share on other sites

I watched the video above and understand it a little better now, thanks for explaining it. What I didn't understand is that you're needing to send program change back to Lemur to dynamically switch its display depending on which track is selected.

 

if Lemur sends CC119 to LPX, then the currently selected track will receive that midi and if you have midifx script, then it will be processed, and then you can use External Instrument plugin to get it back out to Lemur. That would be fine except you are wanting to also have a software inst hosted on that same channel. So how can you go about having both your hosted instrument as well as the ext inst plugin in order to send the midi back to Lemur. Yes?

 

I don't think this is possible either.

Link to comment
Share on other sites

Right, because a software instrument (that's hosting kontakt or an instance of VEPro), doesn't behave in the same way as an external instrument plugin?

 

The output (triangle thingy) that you cable from in the environment on a software instrument track is actually BEFORE the midi script in the midi signal flow I suppose?

Link to comment
Share on other sites

Mainly because of the following to limitations in Logic

 

  1. Midi that is generated inside a channel object cannot be cabled out in the enviornment.
  2. There is a workaround of using the External Instrument plugin to get the generated midi out to IAC, but....
  3. There is only one instrument plugin slot in a channel object in order to host an instrument. which means if you are hosting kontakt there, you can't host the external instrument plugin.

 

The triangle in the environment must be before the plugins do all their stuff, so its basically just a midi THRU on the channel object, any midi generated inside the channel object by plugins is sandboxed there and not sent out. But strangely, other kinds of stuff like moving the fader and what not is sent...

 

I will try to think today a bit about how this might be accomplished, but I think probably you are going to be forced to just make a template with environment objects in it. You might at least be able to do something smart with the template so that you don't have to know ahead of time how many tracks or what instruments will be loaded in, etc, but I will have to think about it a bit.

Link to comment
Share on other sites

ok, here is a work around that might get you there, but you will have to buy 3rd party software. Plogue Bidule. Plogue Bidule has an object inside it for sending midi directly to a midi device.

 

So basically you can setup a mixer channel with your instrument like this, note Scripter is first midiFX, plogue bidule is second midifx (it will be used to send to lemur), then kontakt is in the instrument slot:

 

channel.jpg.4d3b2affbcf320f828735d083aa9c3d3.jpg

 

Then you configure plogue bidule to fork off the midi to a midi device like this. Note: I am using an IAC port because I don't have an actual lemur to send to. So just pretend that my picture is showing it cabled directly to the lemur midi device INPUT.

 

plogue.jpg.b32a7858cdbe13f6bba21e85f6b6e073.jpg

 

Note that its critical that you use plogue to cable to the midi INPUT of the lemur midi device. Lemur must not forward those midi notes thru to its own midi output, because if so then it will be sent back into LPX again and create a midi feedback loop, not good. Be careful not to send to IAC, for example, because that will definately loop back around into LPX.

Link to comment
Share on other sites

Hey Dewdman,

 

Thanks for turning me onto Bidule. I got it stuck in my head after I discovered it's capabilities, that it would be better if I could do this process with just one midi plugin (bidule), instead of 2 (bidule, my script). So this is what I built in Bidule and it seems to work like it should.

 

I haven't bought the full version of Bidule yet, so I'm not 100% positive it would work within Logic, but I can't see why it wouldn't.

418048435_BiduleRecallTrigger.thumb.png.f87d9cd3ebb047def6dbb2cb706f287e.png

Link to comment
Share on other sites

Very interesting way to avoid Scripter and it goes to show that Bidule in general is capable of doing some interesting midi transforms. Myself I find it easier to read and understand Javascript, but this is cool and since it gives you some sliders and stuff might be easier to tweak for each channel as you go... I can't think of any reason it wouldn't work in logic either.
Link to comment
Share on other sites

  • 2 years later...
  • 5 weeks later...
  • 7 months later...
Hey Dewdman,

 

Thanks for turning me onto Bidule. I got it stuck in my head after I discovered it's capabilities, that it would be better if I could do this process with just one midi plugin (bidule), instead of 2 (bidule, my script). So this is what I built in Bidule and it seems to work like it should.

 

I haven't bought the full version of Bidule yet, so I'm not 100% positive it would work within Logic, but I can't see why it wouldn't.

 

Ah, of course! I had a thread about CTP recall and Logic going last year and we couldn't really find a method since Scripter does not allow MIDI out per port. But Bidule yes! I have been using Bidule (bought a license circa 2010 i think) on and off for a decade and forgot that it can be used as a plugin. I will try your method, thanks for posting the screenshot. How is it working out?

Link to comment
Share on other sites

I got this to work successfully using the script posted in the OP, and using Bidule in the second insert MIDI fx slot, simply passing the filtered cc119 on to the lemur port. Very cool! I am interested in seeing how you did the entire conversion in Bidule though, effectively removing Scripter from the equation... I'm unfortunately not quite crafty enough in Bidule to figure that out yet. How do you create the Recall Trigger module and various input values for the PC and MIDI channel building blocks? I was hoping I could use the MIDI Kinetics plugin within bidule plugin, which you can, but the MIDI Kinetics plug doesn't have a "MIDI out"... I guess because it functions on an Instrument track within Cubase / Pro Tools / DP, etc, where the MIDI out routing is set by the track. Perhaps MIDI kinetics can make a new plugin that will work inside of Bidule for Logic to simplify this for all. Thanks for any input!
Link to comment
Share on other sites

I was able to get this to work across multiple tracks by using a virtual MIDI port within the bidule plugin and then using Bidule standalone to pass the MIDI from the virtual ports to the lemur port. It seems there is probably a slicker way to do this using MIDI Kinetics own recall plugin, but I haven't figured that out yet.
Link to comment
Share on other sites

Very interesting way to avoid Scripter and it goes to show that Bidule in general is capable of doing some interesting midi transforms. Myself I find it easier to read and understand Javascript, but this is cool and since it gives you some sliders and stuff might be easier to tweak for each channel as you go... I can't think of any reason it wouldn't work in logic either.

 

@dewdman42 - of course I had only been testing this with the iPad controller and not whether it was actually passing MIDI data/ notes through to the track. That initial script that the OP posted seems to keep MIDI data from moving through the track in Logic when it is enabled. How would you modify the script to make sure all MIDI gets passed along to the track / instrument? i can use bidule to keep the program change/channel going through to Lemur only. Thanks!

Link to comment
Share on other sites

try this:

 

/*Script that transforms control change 119 into a program change 
with user definable channel number and program change number and filter all other midi events
*/
var PluginParameters = [
{       name: "Channel",
       type: "valueStrings",
       defaultValue: 1,
       minValue: 1,
       maxValue: 16,
       numberOfSteps: 15},
{       name: "Program #",
       type: "valueStrings",
       defaultValue: 0,
       minValue: 0,
       maxValue: 127,
       numberOfSteps: 127
}];

function HandleMIDI(recall) {
   if (recall instanceof ControlChange && recall.number == 119) {
       var p = new ProgramChange; //generates program change message and saves as "p"
       var prog = GetParameter("Program #") //retrieves program number from user input and saves to "prog"
       var chan = GetParameter("Channel") //retrieves channel number from user input and saves to "chan"
       p.channel = chan //sets program change to "prog"
       p.number = prog //sets program change channel to "chan"
       recall.trace(); //filters out all other midi messages
       p.send(); //sends out only channel and program change # 
   } 
   else {
       recall.send();
   }
}
Edited by Dewdman42
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...