1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

How can I get smooth midi CC automation in Reaper ?

Discussion in 'Your DAW (Digital Audio Workstation)' started by Lim, Jul 15, 2016.

  1. James Marshall

    James Marshall Senior Member

    Apr 26, 2017
    Excellent! Can confirm that works for me too.

    Thanks so much for looking into that and for your time, it's a great little plugin :thumbsup:
  2. pbattersby

    pbattersby Senior Member

    Jul 6, 2016
    I'm curious. How is it that CCenv_(CC0-CC63).jsfx, is able to properly record CC01, but ReaControlMIDI can't? What is the magic that enables this to work when it fails for me with ReaControlMIDI? In both cases I'm using CCenv_input.jsfx as an input FX, and I have record mode set to "Latch."
    Last edited: Apr 13, 2018
  3. pmcrockett

    pmcrockett Senior Member

    Nov 3, 2014
    Saint Louis
    I've not personally used ReaControlMIDI to record CC envelopes, but my understanding is that because it can't stop the CC events from being recorded and/or passing through it, you end up with the both the MIDI data and the envelope recorded unless you use something else to filter the data as well. My impression is that it's not really designed for people who want to replace CC events with envelopes as part of a permanent workflow modification.

    CCEnv works by reading the CC values at input (in CCEnv Input), blocking the CCs you've selected so they won't record as MIDI on the track, and instead sending that CC data directly to CCEnv (CC0-CC63) and CCEnv (CC64-CC127) which convert the CCs to slider motion that can be recorded. CCEnv (CC0-CC63) and CCEnv (CC64-CC127) then pass the CC data equivalent of the slider motion on down the chain to the instrument. If there were no input component to the plugin, the MIDI track couldn't be bypassed while recording, and if there were no output component, there would be no way to read the envelopes during playback, but having both an input and an output component allows us to skip the MIDI track entirely for both recording and playback.

    I just checked, and it's actually possible to use CCEnv Input to filter out a CC by checkingboxing it and then use ReaControlMIDI's learn feature to link that CC to its automatable CC parameter which lets you record the automation with the CC input without recording the MIDI data on the track -- so you end up in pretty much the same place as if you use CCEnv (CC0-CC63) and CCEnv (CC64-CC127), just with fewer available CCs and more setup required.
  4. pbattersby

    pbattersby Senior Member

    Jul 6, 2016
    By "checkboxing it" do you mean enabling it?

    I've only just started playing with CCEnv but it seems to solve the problem (recording smooth MIDI automation) so thanks for your work on this.

    The CCEnv scripts seem to work well, so I'll probably stick with it rather than continuing to struggle with ReaControlMIDI since I'm just not making any progress with getting it to recognize (learn) the MOD wheel and behave as well as CCEnv.

    Will you eventually upload CCEnv to the Reaper Reapack repository or some external location? So far it seems it's only available to members of this forum as an attachment to this thread.
  5. pmcrockett

    pmcrockett Senior Member

    Nov 3, 2014
    Saint Louis
    Yes, by checkboxing I mean enabling.

    If ReaControlMIDI isn't seeing the mod wheel as a learn source, you may need to change your MIDI controller's mode in the MIDI devices section of the preferences. You can set input devices as enable input and/or enable input for control messages by right clicking on them. Both can be selected at the same time for any device, and enable input for control messages allows Reaper to see the device as a learn source.

    As far as distribution goes, I'll probably at least put it up in the Reaper forum thread where the script originated and maybe look into Reapack. It hadn't occurred to me that putting it as a message board attachment restricted it to forum members, so in the meantime, I'll maybe find a spot to upload it that's generally accessible.
  6. robgb

    robgb I Have Strong Opinions

    Apr 6, 2016
    Yes, that's more than possible. But I'll try the work arounds and see what happens.
  7. robgb

    robgb I Have Strong Opinions

    Apr 6, 2016
    Both workarounds seem to work. I'm wondering if there's a way to "embed" certain CC values into a track template without adding a midi item (not that this is a bad thing).
  8. robgb

    robgb I Have Strong Opinions

    Apr 6, 2016
    I've found another workaround (I think). In Kontakt I used the factory multiscript Transformer to send CC7 and CC10 to unused values (100, 101) so that they don't affect the instruments in any way. Obviously, if you do this you have to make sure your instruments don't use those new values for anything. But so far it seems to work. I tried hammering the track with CC7 and it made no difference.

    The problem I had with adding a CC7 command to the track was that it set all the instrument values to the same volume, and destroyed the volume balance I had worked out for that multi.
  9. EvilDragon

    EvilDragon KSP Wizard

    May 25, 2010
    Not that I know. Best have an item in the template.
    robgb likes this.
  10. James Marshall

    James Marshall Senior Member

    Apr 26, 2017
    I'm finding that 'on/off' CC's (I'm use sustain pedal: CC64), seem to be a little inaccurate when being run through CCEnv. It seems that it can be a bit erratic with the 0 (off) and 127 (on) values. Sometimes CC64 get's stuck on 127 keeping the sustain on, despite letting go of the pedal. Screenshot of ReaControl MIDI attached.

    The easiest way to recreate the issue is to turn sustain on and off rapidly. I know it's not normal to do this but it can occasionally "stick" on (127) when playing normally too. With CCEnv off I can mash the sustain pedal as much as I like and always finishes on 0.

    Apart from that, the regular CC's that aren't on/off work beautifully :thumbsup:

    Any ideas?

    Attached Files:

  11. pmcrockett

    pmcrockett Senior Member

    Nov 3, 2014
    Saint Louis
    Haven't had time to actually get into the code to fix it, but I have at least recreated the bug. It seems to be happening only with input/recording and not with playback, so I have a general sense of where in the code things are going wrong.
    James Marshall likes this.
  12. jadedsean

    jadedsean Senior Member

    Jun 28, 2016
    How can i add this script to Reaper?
  13. robgb

    robgb I Have Strong Opinions

    Apr 6, 2016
    Download and copy the text into your clipboard. Open your FX browser, right click on JS, choose create a new effect, name it, and paste the text. Save.
    MartinH. likes this.
  14. jadedsean

    jadedsean Senior Member

    Jun 28, 2016
    Cheers Rob much appreciated.
  15. pmcrockett

    pmcrockett Senior Member

    Nov 3, 2014
    Saint Louis
    Alternately, the .jsfx files can be placed directly in the Effects folder in the Reaper resource location (Options > Show REAPER resource path in explorer/finder), which is where create new JS FX puts things by default. You may have to scan for new plugins to get it to appear if you do it this way.
    jadedsean likes this.
  16. Fujosej

    Fujosej New Member

    Jun 11, 2018
    Hey guys ,there is a bug or something like that with CC_env scripts.
    As you can see in the video , i cant adjust each track individually.

    The routing for midi track 1-16 is like that , First track All>1 , secod All>2 etc.

    Could someone please fix this issue?
    Last edited: Jun 18, 2018
  17. pmcrockett

    pmcrockett Senior Member

    Nov 3, 2014
    Saint Louis
    So, the issue is that the input plugin isn't distinguishing among the possible output plugins it can send data to, and it doesn't naturally know which instances of the output plugins are in its own signal chain because plugins don't know what tracks they exist on. And the data can't be passed down the chain as normal MIDI data because the whole point is to avoid doing that. It's a problem leftover from the original code that I didn't catch in my modifications.

    There are a few possible approaches to fixing it. The most straightforward is either to have the user manually set ID numbers on each plugin instance so the input plugins know which output plugins to route their data to, or to have a sync button on each plugin where you would press sync on the input plugin and it would match to the next output plugins that you pressed sync on. Or possibly instruct the user to briefly turn on record monitoring during plugin setup, which would let the input plugin send a MIDI signal down the chain to see which output plugins were in the chain with it.

    Another possibility would be to add a Lua component that runs in the background independently of the plugins and tells each plugin what track it's on (ReaScript can gather this sort of data, whereas JSFX can't). It would be a little cumbersome to have a separate script that needs to run in addition to the plugins, though, so I'd like to avoid this if I can.

    The best solution, which I haven't thought through in detail yet because I've never done audio processing in JSFX before, is that I may be able to use the audio output routing from the plugins to send the MIDI data as a dummy audio signal that won't actually be output as sound but will properly travel down the signal chain to be read by the appropriate output plugin.

    I'll explore these options and make the fix when I'm able, but unfortunately my current job situation has left me without much free time to work on these sorts of projects, so I can't guarantee any kind of timetable on this.

    EDIT: Just realized that Reaper lets you set the record mode to record the MIDI output rather than input. Haven't played around with it yet, but this might let me restructure the entire plugin so it all sits in the output FX section, which would make everything a lot simpler.
    Last edited: Jun 18, 2018
    Fujosej likes this.
  18. EvilDragon

    EvilDragon KSP Wizard

    May 25, 2010
    Do note that recording the output of MIDI track probably adds a buffer of latency compared to recording the input.
    Fujosej and pmcrockett like this.
  19. Fujosej

    Fujosej New Member

    Jun 11, 2018
    Ok Thanks for the answer, that sounds really kinda complicated for me to handle.

    The setup i am using right now
    I use MidiNotch in INPUTfx , and set it to filter all CC inputs. (like that)
    And then for Regular FX slot ,i use your two JS plugins.

    And after that i just choose what cc's i need in envelope lane and learn them with my midi device

    That requires some extra work because of learning process.

    The only problem i have with this setup, is if i try to record in midi output mode (records all cc's in midi items).
  20. impakt

    impakt New Member

    Jun 21, 2018
    Thanks to pmcrockett and his CCenv, I am now able to record automation with my outboard gears such as a Nord Lead 2. It's working really great!

    Below are the parameter definitions for anyone who may find it useful.

    Here is a question about possible optimisation:

    For Nord Lead 2, only seven parameters are needed from the cc64-cc127 JS, and cc47-cc63 are unused. The first CCenv would have plenty of room to account for cc70-80.

    Can the code be altered in a simple way so that, for example, cc50-cc63 becomes cc70-83? I'm guessing a simple math formula will do?

    This would help immensely because then Synth settings can be stored, recalled, and transmitted with a single JS preset. I hope it can work out this way.

    desc:CCEnv (Nord Lead 2) A
    slider1:0<0,127,1>-slider1 CC0
    slider2:0<0,127,1>-Modwheel CC1
    slider3:0<0,127,1>-Breath Ctrl CC2
    slider4:0<0,127,1>-slider4 CC3
    slider5:0<0,127,1>-slider5 CC4
    slider6:0<0,127,1>Portamento CC5
    slider7:0<0,127,1>-slider7 CC6
    slider8:100<0,127,1>Gain CC7
    slider9:0<0,127,1>Oscillator Mix CC8
    slider10:0<0,127,1>-slider10 CC9
    slider11:0<0,127,1>-slider11 CC10
    slider12:0<0,127,1>-slider12 CC11
    slider13:0<0,127,1>-slider13 CC12
    slider14:0<0,127,1>-slider14 CC13
    slider15:0<0,127,1>-slider15 CC14
    slider16:0<0,2,1{Mono,Legato,Poly}>-Oscillator Mode CC15
    slider17:0<0,1,1{off,ON}>-Unison CC16
    slider18:0<0,127,1>-slider18 CC17
    slider19:0<0,4,1{Filter,FM,OSC2,LFO1,Morph}>-ModWh Destination CC18
    slider20:80<0,127,1>LFO1 Rate CC19
    slider21:0<0,4,1{S&H,Saw,Tri,Sqr,soft Rnd>LFO1 Waveform CC20
    slider22:0<0,4,1{PW,Filter,Osc2,Osc1+2,FM>LFO1 Destination CC21
    slider23:0<0,127,1>LFO1 Amount CC22
    slider24:80<0,127,1>LFO2 Rate CC23
    slider25:0<0,8,1{hold-DN,hold-UP,UP,hold-UD,AMP,Osc1+2,hold-RND,hold-Echo,Filter,Arp Off (filter)}>LFO2 hold / dest CC24
    slider26:0<0,127,1>LFO2 Amt / Arp Range CC25
    slider27:0<0,127,1>Mod Attack CC26
    slider28:127<0,127,1>Mod Decay CC27
    slider29:0<0,3,1{Osc2,FM,PW,off}>Mod Destination CC28
    slider30:64<0,127,1>Mod Amount CC29
    slider31:1<0,3,1{Pulse,Sawtooh,Triangle,Sine}>Osc 1 Waveform CC30
    slider32:1<0,3,1{Pulse,Sawtooh,Triangle,Noise}>Osc 2 Waveform CC31
    slider33:0<0,127,1>-slider33 CC32
    slider34:64<0,127,1>Osc 2 fine tune CC33
    slider35:0<0,1,1{off,ON}>Osc 2 keytrack CC34
    slider36:0<0,3,1{off,Sync,Ring,SyncRng}>Osc Ring / Sync CC35
    slider37:64<0,127,1>Amp Decay CC36
    slider38:127<0,127,1>Amp Sustain CC37
    slider39:0<0,127,1>FLT Attack CC38
    slider40:64<0,127,1>FLT Decay CC39
    slider41:127<0,127,1>FLT Sustain CC40
    slider42:0<0,127,1>FLT Release CC41
    slider43:0<0,127,1>Resonance CC42
    slider44:64<0,127,1>Env Amt CC43
    slider45:0<0,4,1{LP 12 db,LP 24 db,HP 24 db,BP,Notch + LP}>Filter Type CC44
    slider46:0<0,1,1{off,ON}>Velocity CC45
    slider47:0<0,3,1{off,1/3,2/3,full}>Kbd Track CC46
    slider48:0<0,127,1>-slider48 CC47
    slider49:0<0,127,1>-slider49 CC48
    slider50:0<0,127,1>-slider50 CC49
    slider51:0<0,127,1>-slider51 CC50
    slider52:0<0,127,1>-slider52 CC51
    slider53:0<0,127,1>-slider53 CC52
    slider54:0<0,127,1>-slider54 CC53
    slider55:0<0,127,1>-slider55 CC54
    slider56:0<0,127,1>-slider56 CC55
    slider57:0<0,127,1>-slider57 CC56
    slider58:0<0,127,1>-slider58 CC57
    slider59:0<0,127,1>-slider59 CC58
    slider60:0<0,127,1>-slider60 CC59
    slider61:0<0,127,1>-slider61 CC60
    slider62:0<0,127,1>-slider62 CC61
    slider63:0<0,127,1>-slider63 CC62
    slider64:0<0,127,1>-slider64 CC63
    desc:CCEnv (Nord Lead 2) B
    slider1:0<0,127,1>-slider1 CC64
    slider2:0<0,1,1{off,ON}>Auto Portamento CC65
    slider3:0<0,127,1>-slider3 CC66
    slider4:0<0,127,1>-slider4 CC67
    slider5:0<0,127,1>-slider5 CC68
    slider6:0<0,127,1>-slider6 CC69
    slider7:0<0,127,1>FM Amt / Tune CC70
    slider8:0<0,127,1>-slider8 CC71
    slider9:0<0,127,1>Amp Release CC72
    slider10:0<0,127,1>Amp Attack CC73
    slider11:127<0,127,1>Cutoff Frequency CC74
    slider12:0<0,127,1>-slider12 CC75
    slider13:0<0,127,1>-slider13 CC76
    slider14:0<0,127,1>-slider14 CC77
    slider15:60<0,120,1>Semi/ NoisClr/ Sync wfm sel CC78
    slider16:0<0,127,1>Osc1 PW CC79
    slider17:0<0,1,1{off,ON}>Distortion on/off CC80
    slider18:0<0,127,1>-slider18 CC81
    slider19:0<0,127,1>-slider19 CC82
    slider20:0<0,127,1>-slider20 CC83
    slider21:0<0,127,1>-slider21 CC84
    slider22:0<0,127,1>-slider22 CC85
    slider23:0<0,127,1>-slider23 CC86
    slider24:0<0,127,1>-slider24 CC87
    slider25:0<0,127,1>-slider25 CC88
    slider26:0<0,127,1>-slider26 CC89
    slider27:0<0,127,1>-slider27 CC90
    slider28:0<0,127,1>-slider28 CC91
    slider29:0<0,127,1>-slider29 CC92
    slider30:0<0,127,1>-slider30 CC93
    slider31:0<0,127,1>-slider31 CC94
    slider32:0<0,127,1>-slider32 CC95
    slider33:0<0,127,1>-slider33 CC96
    slider34:0<0,127,1>-slider34 CC97
    slider35:0<0,127,1>-slider35 CC98
    slider36:0<0,127,1>-slider36 CC99
    slider37:0<0,127,1>-slider37 CC100
    slider38:0<0,127,1>-slider38 CC101
    slider39:0<0,127,1>-slider39 CC102
    slider40:0<0,127,1>-slider40 CC103
    slider41:0<0,127,1>-slider41 CC104
    slider42:0<0,127,1>-slider42 CC105
    slider43:0<0,127,1>-slider43 CC106
    slider44:0<0,127,1>-slider44 CC107
    slider45:0<0,127,1>-slider45 CC108
    slider46:0<0,127,1>-slider46 CC109
    slider47:0<0,127,1>-slider47 CC110
    slider48:0<0,127,1>-slider48 CC111
    slider49:0<0,127,1>-slider49 CC112
    slider50:0<0,127,1>-slider50 CC113
    slider51:0<0,127,1>-slider51 CC114
    slider52:0<0,127,1>-slider52 CC115
    slider53:0<0,127,1>-slider53 CC116
    slider54:0<0,127,1>-slider54 CC117
    slider55:0<0,127,1>-slider55 CC118
    slider56:0<0,127,1>-slider56 CC119
    slider57:0<0,127,1>-slider57 CC120
    slider58:0<0,127,1>-slider58 CC121
    slider59:0<0,127,1>-slider59 CC122
    slider60:0<0,127,1>-slider60 CC123
    slider61:0<0,127,1>-slider61 CC124
    slider62:0<0,127,1>-slider62 CC125
    slider63:0<0,127,1>-slider63 CC126
    slider64:0<0,127,1>-slider64 CC127

    In the end, these would be nice minor tweaks to something that is already working perfectly. Thanks for making this possible!

    Last edited: Jul 10, 2018

Share This Page