DGB111 Posted February 8, 2018 Share Posted February 8, 2018 I love using the modulator to warp sounds, but the only problem I find is that the LFO is set to some internal clock, instead of being aligned to a beat. Even if you have the "Rate" set at 1/4, the timing is a quarter note, but when you hit the transport it starts wherever the LFO is in its waveform, so one time it may be all the way at the top, then the next time it may be all the way at the bottom, so if you want the loud part of the modulation always to be on the beat it's impossible. In Kontakt it's easy because you can always set what part of the wave it should start on (not sure why that's not an option in LPX, or am I missing it?!?!) Anyway, is there a way to script this so you can get LFOs that can be set to the beat and always start where you want? Thanks! Quote Link to comment Share on other sites More sharing options...
Eric Cardenas Posted February 8, 2018 Share Posted February 8, 2018 Open the extended parameters and enable Env Sync. Quote Link to comment Share on other sites More sharing options...
DGB111 Posted February 9, 2018 Author Share Posted February 9, 2018 Thanks Eric! The only thing that's missing is that always starts you in the middle of the waveform, so its impossible (as far as I can tell) to start at the top or bottom of a sine wave LFO (without tweaking the shape until it's not a sine anymore). Do you know if there's a way to set where it starts in the waveform, or are we just locked into the beat = the middle? And if there isn't a way, is there a way to script it? Thanks!!!! Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted February 10, 2018 Share Posted February 10, 2018 Yes you can write a script to do it, but I don't have time to work out the math for you. In order to plot a sine wave in Scripter use the Math.sin() function. You'll have to figure out the rest of the math so that it has the amplitude you want, the frequency you want and starts 90 degrees into the cycle... then just generate a CC event that is scaled appropriately. If I were going to write it I would just plot a CC event for every call to ProcessMIDI(), using the start beat number. Quote Link to comment Share on other sites More sharing options...
DGB111 Posted February 12, 2018 Author Share Posted February 12, 2018 Yes you can write a script to do it, but I don't have time to work out the math for you. In order to plot a sine wave in Scripter use the Math.sin() function. You'll have to figure out the rest of the math so that it has the amplitude you want, the frequency you want and starts 90 degrees into the cycle... then just generate a CC event that is scaled appropriately. If I were going to write it I would just plot a CC event for every call to ProcessMIDI(), using the start beat number. Thanks! I'll take a stab at it when I get a chance!!! Quote Link to comment Share on other sites More sharing options...
wonshu Posted May 1, 2022 Share Posted May 1, 2022 (edited) Did anyone write an LFO in the Logic scripter and is willing to share that script? I would like to transform velocities using a scripter LFO... Edited May 1, 2022 by wonshu Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted May 2, 2022 Share Posted May 2, 2022 I don't have any time to customize any of this for you, but this can get you started. var NeedsTimingInfo = true; var CYCLE_LENGTH = 4; // cycle length in beats var cc = new ControlChange; cc.number = 1; cc.channel = 1; function HandleMIDI(event) { event.send(); } var lastVal = 0; function ProcessMIDI() { var timing = GetTimingInfo(); if(timing.playing) { lastSendBeat = timing.blockStartBeat; cc.value = modulator(timing.blockStartBeat); if(cc.value != lastVal) { cc.send(); lastVal = cc.value; } } } // produce modulation value based on Beat function modulator(beat) { let radians = radsFromBeat(beat); let plot = (Math.sin(radians)+1)/2; // convert to 0-1 range return Math.round(plot*127); } // convert beat value to radians function radsFromBeat(beat) { let percent = (beat-1)/CYCLE_LENGTH; let frac = percent - Math.floor(percent); return frac * (2 * Math.PI); } 2 Quote Link to comment Share on other sites More sharing options...
wonshu Posted May 27, 2022 Share Posted May 27, 2022 Thank you! I want to keep this thread and idea alive and customised the script so that it modifies the velocity of the notes played, so you can have an LFO that will trigger different velocities. It produces hanging notes when stopping Logic, I haven't figured out why, but perhaps whoever is interested in growing this little script finds out why. /* With Scripter, you can use JavaScript to create your own custom MIDI processing effects, including slider controls for real-time interaction. For detailed information about using Scripter, including code samples, see the MIDI plug-ins chapter of the Logic Pro X Effects or MainStage 3 Effects manual. */ var NeedsTimingInfo = true; var CYCLE_LENGTH = 3; // cycle length in beats // var PluginParameters = [{name:"Cycle Length", type:"lin", minValue:1, maxValue:16, numberOfSteps:15, defaultValue:4}]; // cycle length in beats var cc = new ControlChange; cc.number = 1; cc.channel = 1; function HandleMIDI(event) { var note = new NoteOn; var noteOff = new NoteOff note.pitch = event.pitch; note.velocity = event.velocity - cc.value; // have to get the values inside 1-127 velocity if(note.velocity < 0) { note.velocity = 0; } if(note.velocity > 127) { note.velocity = 127; } // note.trace(); cc.trace(); note.send(); noteOff.send() } var lastVal = 0; function ProcessMIDI() { var timing = GetTimingInfo(); if(timing.playing) { lastSendBeat = timing.blockStartBeat; cc.value = modulator(timing.blockStartBeat); if(cc.value != lastVal) { //cc.send(); lastVal = cc.value; } } } // example: simple pass through and MIDI monitor // function HandleMIDI(event) // { // event.trace(); // event.send(); //} // produce modulation value based on Beat function modulator(beat) { let radians = radsFromBeat(beat); let plot = (Math.sin(radians)+1)/2; // convert to 0-1 range return Math.round(plot*127); } // convert beat value to radians function radsFromBeat(beat) { let percent = (beat-1)/CYCLE_LENGTH; let frac = percent - Math.floor(percent); return frac * (2 * Math.PI); } Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted May 27, 2022 Share Posted May 27, 2022 You don't need to create new NoteOn events. The event you need to modify is passed into HandleMIDI. Just assign a velocity value to that one. Get rid of ProcessMIDI function entirely. Quote Link to comment Share on other sites More sharing options...
wonshu Posted May 28, 2022 Share Posted May 28, 2022 Thank you! Yes, next time I will think of removing all the unnecessary comments from the code... Yes, I've tried that, but I was doing it wrong somehow and was getting syntax errors left and right, so I decided to do it another wrong way that at least produced the result I wanted. I don't understand how to modify the velocity of the event directly and from the tutorial scripts it was easier for me to learn how to do it this way. I would be very happy if you could share that one line of how to subtract a variable from the velocity of the current event. Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted May 28, 2022 Share Posted May 28, 2022 remove the ProcessMIDI function and change the HandleMIDI function like this: function HandleMIDI(event) { var timing = GetTimingInfo(); if(timing.playing) { lastSendBeat = timing.blockStartBeat; event.velocity = modulator(timing.blockStartBeat); } event.send(); } Quote Link to comment Share on other sites More sharing options...
frankfaruk Posted February 13, 2023 Share Posted February 13, 2023 On 5/28/2022 at 8:35 AM, Dewdman42 said: remove the ProcessMIDI function and change the HandleMIDI function like this: function HandleMIDI(event) { var timing = GetTimingInfo(); if(timing.playing) { lastSendBeat = timing.blockStartBeat; event.velocity = modulator(timing.blockStartBeat); } event.send(); } var NeedsTimingInfo = true; var CYCLE_LENGTH = 3; function HandleMIDI(event) { var timing = GetTimingInfo(); if (timing.playing) { event.velocity = modulator(timing.blockStartBeat); } event.send(); } function modulator(beat) { let radians = radsFromBeat(beat); let plot = (Math.sin(radians) + 1) / 2; return Math.round(plot * 127); } function radsFromBeat(beat) { let percent = (beat - 1) / CYCLE_LENGTH; let frac = percent - Math.floor(percent); return frac * (2 * Math.PI); } Quote Link to comment Share on other sites More sharing options...
anp27 Posted May 12, 2023 Share Posted May 12, 2023 (edited) This works really great, thank you all! Is there an easy way to edit this script so that we can choose between sine/saw/square/etc? I know you can do this with Modulator but having this Scripter "print" these patterns directly saves quite a bit of time and steps! Edited May 12, 2023 by anp27 Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted May 12, 2023 Share Posted May 12, 2023 (edited) modify the modulator function math for whatever waveform you want. Unfortunately I don't have access to my mac or time really to help you work out the math required for different kinds of waveforms, but some google searches should get you there pretty easily. Another way to approach this would be to fill an array with the desired waveform points...rather then calculating math on the fly, but again, I don't have access to my mac at the moment to give you an example...sorry. Edited May 12, 2023 by Dewdman42 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.