Jump to content

EoinF

Member
  • Posts

    7
  • Joined

  • Last visited

EoinF's Achievements

Newbie

Newbie (1/14)

0

Reputation

  1. Hello Dewdman22, Yes, this is intended to correct for articulation latency (in this case Cinematic Studio Strings). I am using articulation sets and these are set up to send the information required to switch articulations using CC58. I do intend to use a negative track delay (probably ~300ms). I have thought about the separate treatment of NoteOffs, and what you have suggested is what I had originally hoped for, although I thought that perhaps this could cause more trouble than it is worth - If two notes are supposed to be non-slurred long notes (not overlapping on piano roll), this might cause the instrument to think that they are in fact overlapping, and trigger a transition sample. I imagine adjusting for this on piano roll could be tedious, and it would probably be easier to make adjustments to the note ends at the ends of phrases where necessary (besides, these often need to be adjusted anyway, as the release trigger samples for long notes in CSS are not super distinct - I believe they are designed to naturally trail off). I have tried implementing what you have suggested for legato transitions, and the delay is working as it should, however it is only letting NoteOns through to the instrument, so articulations are not switched. NoteOffs and modulation data is also lost. Here is the code. /* Editable Delay Times */ LegatoStartSlow = 0; LegatoStartMedium = 500; LegatoStartFast = 1000; LegatoSlow = 1500; LegatoMedium = 2000; LegatoFast = 2500; Spiccato = 250; Staccatissimo = 245; Staccato = 240; Sfz = 240; Pizzicato = 250; BartokSnap = 250; ColLegno = 250; Trills = 250; Harmonics = 200; Tremolo = 200; MeasuredTremolo = 200; Marcato = 250; MarcatoOverlay = 250; /* Keyswitch CC */ var ccnum = 58; var lastCC = 0; var delay = 0; function HandleMIDI(event) { if(event instanceof ControlChange && event.number == ccnum) { lastCC = event.value; return; } if(event instanceof NoteOn) { if(lastCC >=6 && lastCC <=8) { if(event.velocity >=1 && event.velocity <=64) { delay = LegatoStartSlow; } else if(event.velocity >=65 && event.velocity <=100) { delay = LegatoStartMedium; } else if(event.velocity >=101 && event.velocity <=127) { delay = LegatoStartFast; } } else if(lastCC >= 9 && lastCC <= 10) { if(event.velocity >=1 && event.velocity <=64) { delay = LegatoSlow; } else if(event.velocity >=65 && event.velocity <=100) { delay = LegatoMedium; } else if(event.velocity >=101 && event.velocity <=127) { delay = LegatoFast; } } /* . . . More conditions here . . */ event.trace(); event.sendAfterMilliseconds(delay); } } And here is the trace for a couple of notes, each with a different articulation selected and some modulation drawn in. Before script: [ControlChange channel:1 number:1 [Modulation] value:0] [ControlChange channel:1 number:13 [Effect #2 MSB] value:127] [NoteOn channel:1 pitch:55 [G2] velocity:110] [ControlChange channel:1 number:1 [Modulation] value:0] [ControlChange channel:1 number:1 [Modulation] value:1] [ControlChange channel:1 number:1 [Modulation] value:2] [ControlChange channel:1 number:1 [Modulation] value:3] [ControlChange channel:1 number:1 [Modulation] value:4] [ControlChange channel:1 number:1 [Modulation] value:5] [ControlChange channel:1 number:1 [Modulation] value:6] [NoteOff channel:1 pitch:55 [G2] velocity:64] [ControlChange channel:1 number:58 [#26 LSB] value:36] [NoteOn channel:1 pitch:56 [G#2] velocity:110] [ControlChange channel:1 number:58 [#26 LSB] value:0] [ControlChange channel:1 number:1 [Modulation] value:7] [ControlChange channel:1 number:1 [Modulation] value:8] [ControlChange channel:1 number:1 [Modulation] value:9] [ControlChange channel:1 number:1 [Modulation] value:10] [ControlChange channel:1 number:1 [Modulation] value:11] [ControlChange channel:1 number:1 [Modulation] value:12] [ControlChange channel:1 number:1 [Modulation] value:13] [ControlChange channel:1 number:1 [Modulation] value:14] [NoteOff channel:1 pitch:56 [G#2] velocity:64] [ControlChange channel:1 number:58 [#26 LSB] value:41] [NoteOn channel:1 pitch:57 [A2] velocity:110] [ControlChange channel:1 number:58 [#26 LSB] value:0] [ControlChange channel:1 number:1 [Modulation] value:15] [ControlChange channel:1 number:1 [Modulation] value:16] [ControlChange channel:1 number:1 [Modulation] value:17] [ControlChange channel:1 number:1 [Modulation] value:18] [ControlChange channel:1 number:1 [Modulation] value:19] [ControlChange channel:1 number:1 [Modulation] value:20] [ControlChange channel:1 number:1 [Modulation] value:21] [ControlChange channel:1 number:1 [Modulation] value:22] [NoteOff channel:1 pitch:57 [A2] velocity:64] ...and after script: [NoteOn channel:1 pitch:55 [G2] velocity:110] [NoteOn channel:1 pitch:56 [G#2] velocity:110] [NoteOn channel:1 pitch:57 [A2] velocity:110] As you can see, only the NoteOns are retained after passing through the script, so this is all the information the instrument receives. I tried this with the last version of this script I had worked on and all data was passing through unaffected apart from the CC58 values that were specified in the script (They passed through but were given a value of 0) - all other values for CC58 passed through it unaffected. I'm guessing I'm probably missing something simple in each script that causes this behaviour - although it is definitely not simple to me! I hope I'll be able to get this up and running quite easily once this problem is solved, and then I can begin testing it and working on the delay times so that everything plays back tight to the click with minimal adjustments on piano roll. I hope eventually to do a version for every instrument in CSS, CSSS, CSB (and hopefully soon CSW/CSP?) including the necessary articulation sets, and would be very happy to post links to everything here if people are interested. The aim of this project is to allow MIDI imported from a notation program such as Sibelius to be relatively quickly turned into a tight mockup without spending lots of time nudging notes around on the piano roll. I may eventually try to create a sound set in Sibelius that will automatically select the required articulation when imported into Logic. Thanks again, Eoin
  2. With thanks to Dewdman42 I'm making some good progress with this script. I decided to go with the original method he suggested (and not the array two posts above) as I feel it would be easier to make quick changes to the delay times on the script if I need to in the future. Here it is as it stands, including some script that is not working towards the end. /* Editable Delay Times */ LegatoStartSlow = 0; LegatoStartMedium = 100; LegatoStartFast = 200; LegatoSlow = 0; LegatoMedium = 100; LegatoFast = 200; Spiccato = 250; Staccatissimo = 245; Staccato = 240; Sfz = 240; Pizzicato = 250; BartokSnap = 250; ColLegno = 250; Trills = 250; Harmonics = 200; Tremolo = 200; MeasuredTremolo = 200; Marcato = 250; MarcatoOverlay = 250; /* Keyswitch CC */ var ccnum = 58; var lastDelay = 0; function HandleMIDI(event) { if(event instanceof ControlChange && event.number == ccnum && event.value >= 11 && event.value <= 15) { lastDelay = Spiccato; return; } else if(event instanceof ControlChange && event.number == ccnum && event.value >= 16 && event.value <= 20) { lastDelay = Staccatissimo; return; } else if(event instanceof ControlChange && event.number == ccnum && event.value >= 21 && event.value <= 25) { lastDelay = Staccato; return; } else if(event instanceof ControlChange && event.number == ccnum && event.value >= 26 && event.value <= 30) { lastDelay = Sfz; return; } else if(event instanceof ControlChange && event.number == ccnum && event.value >= 31 && event.value <= 35) { lastDelay = Pizzicato; return; } else if(event instanceof ControlChange && event.number == ccnum && event.value >= 36 && event.value <= 40) { lastDelay = BartokSnap; return; } else if(event instanceof ControlChange && event.number == ccnum && event.value >= 41 && event.value <= 45) { lastDelay = ColLegno; return; } else if(event instanceof ControlChange && event.number == ccnum && event.value >= 46 && event.value <= 50) { lastDelay = Trills; return; } else if(event instanceof ControlChange && event.number == ccnum && event.value >= 51 && event.value <= 55) { lastDelay = Harmonics; return; } else if(event instanceof ControlChange && event.number == ccnum && event.value >= 56 && event.value <= 60) { lastDelay = Tremolo; return; } else if(event instanceof ControlChange && event.number == ccnum && event.value >= 61 && event.value <= 65) { lastDelay = MeasuredTremolo; return; } else if(event instanceof ControlChange && event.number == ccnum && event.value >= 66 && event.value <= 70) { lastDelay = Marcato; return; } else if(event instanceof ControlChange && event.number == ccnum && event.value >= 71 && event.value <= 75) { lastDelay = MarcatoOverlay; return; } /* Not Yet Working */ else if(event instanceof NoteOn && event.velocity > 0 && event.velocity <= 64 && event instanceof ControlChange && event.number == ccnum && event.value >= 6 && event.value <= 8) { lastDelay = LegatoStartSlow; return; } event.sendAfterMilliseconds(lastDelay); } Everything receiving just a cc event.value to specify the delay time seems to be working as expected, but I have not yet figured out how to specify a delay time for articulations that require a cc event.value and NoteOn velocity. I have written an attempt at this towards the end of the script labelled "Not Yet Working". In the case of the attempt above, the delay time for LegatoStartSlow should be used if (and only if) both the cc event.value is between 6 and 8, and the NoteOn velocity is between 1 and 64. There will eventually be more cases that will use the same event.value range, but with different velocities, and another few cases that will use the same NoteOn velocity range but with different event.value ranges. The NoteOn velocity should not affect the delay time of the articulations that require only cc event.value ranges (the working cases above). Hopefully all of this makes sense. In my attempt, I have tested each part of it separately... if(event instanceof NoteOn && event.velocity > 0 && event.velocity <= 64) { lastDelay = LegatoStartSlow; return; } event.sendAfterMilliseconds(lastDelay); } and if(event instanceof ControlChange && event.number == ccnum && event.value >= 6 && event.value <= 8) { lastDelay = LegatoStartSlow; return; } event.sendAfterMilliseconds(lastDelay); } ...and alone they work as expected, but I have not been able to figure out how to combine the two so that they work together. As it stands the code labelled "Not Yet Working" has no effect on the output (and yes, I have tested it giving a value other than zero for LegatoStartSlow!). Any help with this problem would be greatly appreciated. Thanks, Eoin
  3. Thank you so much for your help! You definitely have given me enough info to get started, and then some! I'll spend some more time learning the language and working on this script, and report back here when I have made some progress (or more likely when I come to a point where I haven't a clue what I am doing!). Eoin
  4. Hello Dewdman42, Thank you so much for taking the time to help me with this - I really appreciate it. I have tried both of your scripts and they are both working as expected (if my understanding of them is correct). Am I right in saying each of these scripts will create a delay where the the delay time in milliseconds is equal to the event.value (between 0 and 127)? I tried adding a multiplier (event.value * 10) on line 6 of your first example and it seems this is the case. I'm hoping that the event.value can change the delay time to specified values that are independent of the event.value itself (that is, not a multiple of the event.value in any way), as this event.value will also be used to change the articulation. It will have to be set up as a table of specified numbers. For example: event.value 0 to 9 = 200ms delay event.value 10 to 19 = 100ms delay event.value 20 to 29 = 250ms delay etc. I've tried editing your original script to do something like this. I am very new to this language, so perhaps I am not doing everything correctly, or in the most efficient way, but hopefully what I've done here makes sense. var ccnum = 11; var lastDelay = 0; delaytime1 = 1000; delaytime2 = 2000; function HandleMIDI(event) { if(event instanceof ControlChange && event.number == ccnum && event.value >= 0 && event.value <= 9) { lastDelay = delaytime1; return; } else if(event instanceof ControlChange && event.number == ccnum && event.value >= 10 && event.value <= 19) { lastDelay = delaytime2; return; } event.sendAfterMilliseconds(lastDelay); } It seems to be doing what I want it to do (I'm going to forget about the separate treatment of NoteOffs for now). I'll spend some more time with this tomorrow and actually input what I hope to do with it and give it an initial test. One question - does this script delay all MIDI messages (modulation, pitch bend, etc.) or just notes? Thank you again for your help, Eoin
  5. Atlas007, yes, I’m pretty sure it sends the message contained in the ArtID either at the same instant or just before sending the NoteOn. In my experience it is a lot quicker to use than key switches or drawing in CC data, and is more reliable/foolproof.
  6. Atlas007, Thanks for your reply. Similar to yourself, I feel it should be possible, although I don’t know enough about Scripter to say for sure. I do hope you’re right! fuzzfilth, Thank you for your reply. I have tried to research how to implement something like this, but haven’t been able to find much information relating to what I am trying to do, and my experience with Scripter is very limited, so it is not something I would be likely to work out on my own. I would be very appreciative if someone could point me in the direction of somewhere I could learn about similar processes, or share a commonly available and easily repeatable string of code that I could try to implement myself. However, if the process is not entirely trivial like you say, I would be very happy to pay someone to write a script for me - I definitely do not want someone to do a not-insubstantial amount of work for no reward. Here is a more specific version of what I am trying to do (leaving out the velocity sensitive information for now): I am using articulation sets with instruments that have different note onset times for each articulation (say 50ms for staccato, 100ms for legato, etc.). The articulation sets change articulations on each instrument using values of a CC. I want the value of this CC to also control the value of a specified delay for each note sent to the instrument, so that when I change articulations on notes in the piano roll, the timing of each note onset does not become a problem, and I do not have to manually nudge each note into time. Hopefully what I have just said makes sense. I am not sure that the NoteOff data needs to be treated in the way I had mentioned in my original post here (that the NoteOff needs to be treated with the same delay as the NoteOn of same note, regardless of what CC change has been made between NoteOn and NoteOff) - I thought, perhaps naively, this option would have been the easier option to implement, but if it’s easier to let the note releases follow the delay time of any CC change that happens between NoteOn and NoteOff, this may well be a preferable option. I will consider/test this with situations that may arise. Thanks again for your reply, Eoin
  7. Hello from a first-time poster, I'm wondering if the following is possible using Logic's Scripter? Hopefully some experienced users of Scripter would be able give some advice - of which I would be extremely grateful. I'm looking for a script that can delay sending MIDI notes (note on, note release, and velocity) to an instrument based on the value of a CC: For instance, if the value of CC11 is between 11 and 20, delay the note by 250ms, If the value of CC11 is between 21 and 30 delay the note by 100ms, and other similar conditions. Another slightly more complex conditional message, would include an 'and' statement: For instance, if CC11 is between 31 and 40, and note velocity is between 1 and 64, delay the note by 200ms, or if CC11 is between 31 and 40, and note velocity is between 65 and 127, delay the note by 100ms. I'm hoping something like this could be possible, as it could potentially save me an awful lot of time on projects. If anyone has done something like this before, or feels they know how to, I would be extremely grateful to hear from you, and please do let me know if any more information is required. Many thanks, Eoin
×
×
  • Create New...