Skip to content

Instantly share code, notes, and snippets.

@gekart
Last active April 29, 2020 21:55
Show Gist options
  • Save gekart/561e13e917e5acf13f1dd79423831327 to your computer and use it in GitHub Desktop.
Save gekart/561e13e917e5acf13f1dd79423831327 to your computer and use it in GitHub Desktop.
MIDI Fx PolyMono for Logic Pro X: Send MIDI notes of chords to a mono synth voice by voice
// PolyMono: Play polyphonic material on external mono synths
// Logic Pro X MIDI-FX Scripter script to separate single notes (voices) out of chords
//
// Install: On a MIDI track click on MIDI-FX and select Scripter,
// paste this script into the script window and hit Run Script,
// save script as PolyMono.
//
// How to use: create a polyphonic track (e.g. a chord progression using a poly plugin),
// drop PolyMono Scripter MIDI-FX on the track,
// set polyphony to max notes played at once,
// create as many audio tracks as polyphony (with audio input of external synth set),
// change plugin instrument to Utility/External Instrument (mono or stereo depending on your synth),
// in the External Instrument settings set MIDI channel and audio input correctly for your synth,
// Loop: set voice number in PolyMono to 1,
// arm first audio track
// hit "[R]ecord" to record the first voice from the synth
// repeat Loop for each voice number (2, 3, 4, ...) of your polyphony
// mix down the tracks or create a track stack
// done
//
// Remarks: CC and other MIDI stuff is passed on to each voice, so filter sweeps should work nicely.
// If your synth doesnt support MIDI sweeps, with a DC coupled interface you might be using CVs.
// Voice assignment is done similarly to how polyphonic synths assign voices to their "voice boards".
// You must record as many tracks as polyphony even if you play less notes.
// When your chords vary in polyphony, voice assignment will look random.
// polyphony of the PolyMono tool
var polyphony = 4
// voice number to output (simulates voice assignment)
var voiceNumber = 1
// count the notes played so far
var noteCounter = 1
// start with first voice when transport starts
function Reset() {
noteCounter = 1;
}
var PluginParameters = [
{
name: 'Voice Number',
type: 'linear',
minValue: 1,
maxValue: 16,
numberOfSteps: 15,
defaultValue: 1,
unit: '. voice'
},
{
name: 'Polyphony',
type: 'linear',
minValue: 1,
maxValue: 16,
numberOfSteps: 15,
defaultValue: 4,
unit: ' voices'
}
];
function ParameterChanged(param, value) {
polyphony = GetParameter('Polyphony');
voiceNumber = GetParameter('Voice Number');
// don't let polyphony be less than voice number
if(voiceNumber > polyphony) {
voiceNumber = polyphony;
SetParameter('Voice Number', voiceNumber);
}
}
function HandleMIDI(event) {
if(event instanceof NoteOn) {
// check if voice number equals note counter (modulo polyphony)
if((noteCounter - 1) % polyphony == voiceNumber - 1) {
event.send();
}
noteCounter++;
} else {
// send all other events unmodified
event.send();
// TODO: double-check if synths handle this nicely (they should!)
// send note off events even when they do not correspond to voice number
// if the synth cant handle this, remember the current note pitch played and then only send if pitch match
}
}
@gekart
Copy link
Author

gekart commented Apr 29, 2020

This is where I got the idea from: https://www.logicprohelp.com/forum/viewtopic.php?f=45&t=115798#p594990

Unfortunately, I had to do everything from the start.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment