Jump to content

Trigger A Really Long Fade In?


paulnajar

Recommended Posts

Hi Folks,

 

I’ve been scratching my head trying to figure a way to trigger a really long fade in - like 90 - 180 seconds from zero to 100% volume where all I have to do is play a note/s and keep holding it.

 

The message could be MIDI or it could be an audio plugin. Closest I’ve come is using MainStage’s MIDI modulator plugin mapping a 32 bar triangle wave (for a linear response) to expression which is mapped to volume in the patch I need to control. I also set the patch tempo to something slow like 90 BPM or lower which extends the rise time the slower the tempo.

 

There are two problems with this approach. One is the LFO won’t retrigger at the bottom of it’s cycle (so that the volume rises from zero) and the other issue is once the top of the triangle shape is reached it starts to descend again as an LFO should but of course I don’t want that.

 

I am simply looking for a long fade in triggered by me playing a keyboard. Maybe there’s an AU plugin one of you know about or another solution?

 

Kind regards

Link to comment
Share on other sites

Here's a couple examples, you can make different variations.

 

example 1: Hit play and CC7 starts at 0 and starts ramping up over a time period of 360 beats

var fullLevel = 127;
var totalBeats = 360;

var cc = new ControlChange;
cc.channel = 1;
cc.number = 7;
cc.value = 0;

var NeedsTimingInfo = true;

function ProcessMIDI() {
   var ctx = GetTimingInfo();
   var level = Math.round((ctx.blockStartBeat/totalBeats) * fullLevel);
   if (level != cc.value) {
      cc.value = level;
      cc.trace();
      cc.send();
   }
}

 

Here's a more elaborate example that doesn't start the timer until you hit the first key:

 

var fullLevel = 127;
var totalBeats = 360;

var cc = new ControlChange;
cc.channel = 1;
cc.number = 7;
cc.value = 0;

var NeedsTimingInfo = true;
var startBeat = 0;

function ProcessMIDI() {
   var ctx = GetTimingInfo();
   if(ctx.playing && startBeat > 0) {

       var level = Math.round(((ctx.blockStartBeat-startBeat)/totalBeats) * fullLevel);
       if (level != cc.value) {
          cc.value = level;
          cc.trace();
          cc.send();
       }
   }
}


function HandleMIDI(event) {

   // if this is first note press, then start the timer
   if (event instanceof NoteOn && startBeat==0) {
      startBeat = event.beatPos;
      cc.value = 0;
      cc.trace();
      cc.send();
   }
   event.send();
}

function Reset() {
   startBeat = 0;
}

 

You could choose to use automation instead of CC also, there are other variations. Anyway, that's a start...good luck

Link to comment
Share on other sites

I really appreciate your reply and I must confess that I’m long overdue to teach myself how to script a bit. It still seems like such gibberish to me but with your generous examples I will definitely dive in.

 

I’ll report back once I’ve had time to have a play....

 

Thanks again

Link to comment
Share on other sites

So I've just tried your second script example and the scripter returns this message.

 

Any thoughts?

 

Thanks again for your help.

 

***Creating a new MIDI engine with script***

 

Evaluating MIDI-processing script...

Script evaluated successfully!

Exception calling HandleMIDI() function:

[JS Exception] TypeError: event.send is not a function. (In 'event.send()', 'event.send' is undefined) line:35

[ControlChange channel:1 number:7 [Volume] value:0]

>

Edited by paulnajar
Link to comment
Share on other sites

Sorry, I was a bit quick to post.

 

I've worked it out now. I had to put in a note passthrough command and I also had to start MainStage's playback to make it work.

 

But now that it's all working this script is causing massive CPU spiking! Any of the other factory scripts are fine but this one. I'm wondering why. This is on a quad core i7 Mac Mini with 2 SSD's and 16GB ram.

 

Any thoughts?

Link to comment
Share on other sites

Further to my last post I've discovered that any script that uses clock information in MainStage causes the same CPU overload;-(

 

I've tested on 2 different powerful macs. The same script in Logic has no problems. This is a MianStage bug for sure. I've already reported to Apple.

 

What a bummer. I had it working and everything:-(

Link to comment
Share on other sites

I wasn't getting any cpu spiking...so not sure what was going on with you... Its possible there is something about your MainStage setup or some kind of midi loopback is happening there....

 

Anyway, here is a new version that doesn't use GetTimingInfo at all. Another side benefit is that you don't need MainStage to be PLAYING... just hit a key and it will start the timer..

 

var fullLevel = 127;
var totalSeconds = 20;

var cc = new ControlChange;
cc.channel = 1;
cc.number = 7;
cc.value = 0;

var start = 0;
var totalMS = totalSeconds*1000;

function HandleMIDI(event) {

   // if this is first note press, then start the timer
   if (event instanceof NoteOn && start==0) {
      start = now();
      cc.value = 0;
      cc.send();
      cc.trace();
   }
   event.send();
}

function ProcessMIDI() {
   if(start>0 && cc.value < fullLevel) {
       var level = getLevel();
       if (level != cc.value) {
          cc.value = level;
          cc.send();
          cc.trace();
       }
   }
}

function now() {
   return Date.now();
}

function getLevel() {
   return Math.trunc((now()-start)/totalMS*fullLevel);
}

Edited by Dewdman42
Link to comment
Share on other sites

Thanks for checking that.

 

I'm using Latest OS/ MS version - 10.13.4/ 3.3.2

 

All I've added to the script is a MIDI passthrough and I've changed the CC from CC7 to CC11. My script is copied below - but to be clear this issue occurs on a completely blank MS concert using ANY factory script that accesses the command - so it's not just your script. This is also tested on a second mac with the same OS/ MS version.

 

var fullLevel = 127;

var totalBeats = 90;

 

var cc = new ControlChange;

cc.channel = 1;

cc.number = 11;

cc.value = 0;

 

var NeedsTimingInfo = true;

var startBeat = 0;

 

function ProcessMIDI() {

var ctx = GetTimingInfo();

if(ctx.playing && startBeat > 0) {

 

var level = Math.round(((ctx.blockStartBeat-startBeat)/totalBeats) * fullLevel);

if (level != cc.value) {

cc.value = level;

cc.trace();

cc.send();

}

}

}

 

 

function HandleMIDI(event) {

 

// if this is first note press, then start the timer

if (event instanceof NoteOn && startBeat==0) {

startBeat = event.beatPos;

cc.value = 0;

cc.trace();

cc.send();

}

event.send(); //Pass MIDI events through the plug-in.

}

 

function Reset() {

startBeat = 0;

}

Link to comment
Share on other sites

Wow! Dewdman.

 

Thank you so much! There is almost everything I am yet to understand about scripting but this has done the trick perfectly. I really appreciate you taking the time.

 

BTW, with that CPU spike thing I even tried starting from a blank MS concert file and it still had the problem. If you're on Sierra perhaps it's a High Sierra issue.

 

Anyway, thanks agin.

Link to comment
Share on other sites

  • 4 months later...

Hi,

 

I'm a newcomer here but I've been scripting on MainStage for some time, albeit it seems I still have a lot to learn by the look of what Dewdman42 has written!

None the less, I have created many useful scripts and can also confirm massive CPU spikes when using timing in the scripts, in my case the sendAfterMilliseconds() command.

I'm using MainStage on High Sierra, I didn't notice the issue on Sierra.

 

The CPU spikes are so bad that it causes audio dropouts on certain concerts/patches. I'd be really grateful if anyone has a solution.

 

Regards,

Ant

Link to comment
Share on other sites

  • 3 weeks later...

Here my pitch bend script...

function HandleMIDI(event){

var pb = new PitchBend
var trig = GetParameter("MIDI Control Trigger")


	if (event instanceof ControlChange){
		if (event.number == trig){
		
			if (event.value ==0){
			var dly = 0;
			var relspeed = GetParameter("Release speed (ms)");
			//bend up/pedal up
				
				var range = GetParameter("Range")
				if (range < 0) {
				range = range * -1}
				
				if (range > 0) {
				range = relspeed/(range/GetParameter("Step size"))
				} 
				
				if (relspeed > 0){
				for (var n=GetParameter("Range");n<=0;n+=GetParameter("Step size")){
				pb.value = n
				pb.sendAfterMilliseconds(dly)
	//pb.trace();
	Trace (dly + " pb =" + n);
				
				dly = dly + range

				//event.trace()
				} //end for
				} // end if the relspeed is 0
			n = 0
			pb.value = n
			pb.sendAfterMilliseconds(GetParameter("Release speed (ms)"))
			}
		else if (event.value==127){
		//bend down
	var dly = 0;
	var pspeed = GetParameter("Press speed (ms)");
	var range = GetParameter("Range")
	var step = GetParameter("Step size")
				if (range < 0) {
				range = range * -1}
				
				if (range > 0) {
				range = pspeed/(range/GetParameter("Step size"))
				} 

	if (pspeed > 0){
			for (var n=0;n>=GetParameter("Range");n-=step){
			
				pb.value = n
				pb.sendAfterMilliseconds(dly)
			
				
						Trace (dly + " pb =" + n);
				
					dly = dly + range
				//pb.trace()
				//event.trace()
				} //end for
				} // end pspeed 0
		n=GetParameter("Range")
		pb.value = n
		pb.sendAfterMilliseconds(GetParameter("Press speed (ms)"))
			
		}
		}
		else {event.send()
		//event.trace()
		}
		}
	


else {

//event.trace()
   event.send(); //Pass MIDI events through the plug-in.

} //end of else
} //end of routine


var PluginParameters =
[
{name:"MIDI Control Trigger", type:"lin",
 minValue:0, maxValue:127, numberOfSteps:127, defaultValue:67},

{name:"Press speed (ms)", type:"lin", 
  minValue:0, maxValue:1000, numberOfSteps:100, defaultValue:10},

{name:"Release speed (ms)", type:"lin", 
  minValue:0, maxValue:1000, numberOfSteps:100, defaultValue:30},
  
  {name:"Step size", type:"lin",
  minValue:64, maxValue:1024, numberOfSteps:15, defaultValue:256},
  
 {name:"Range", type:"lin",
  minValue:-8192, maxValue:0, numberOfSteps:1024, defaultValue:-4096}  
];

 

BTW, I've just upgraded to MS3.4 and the high CPU issue is still present, although it's nice to see many other bugs squashed!

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...