Go Back   Cockos Incorporated Forums > REAPER Forums > REAPER for Live Use

Reply
 
Thread Tools Display Modes
Old 02-07-2018, 04:02 PM   #1
pipelineaudio
Mortal
 
pipelineaudio's Avatar
 
Join Date: Jan 2006
Location: Wickenburg, Arizona
Posts: 14,047
Default Could a spreadsheet action script be made?

I would love to see a script like this.

The second column, "Action to activate row" should be learnable,ideally, but assigning it would be ok.

Hopefully cells' contents could be copy and pastable.

Unfilled cells in columns 3 and 4 would be ignored

Cells in column 4 would be triggered when any other row is selected (might have to think about this last a bit, as you may want to use it to toggle on and off signal paths, but for now this should be good)

Oops, should probably have a column for name and comments


Last edited by pipelineaudio; 02-07-2018 at 04:16 PM.
pipelineaudio is offline   Reply With Quote
Old 02-07-2018, 06:18 PM   #2
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

That is a very specific request, I dont see it that usable in the long run.

Anyway, what you can do is to use the Web Interface API, an HTML interactive table, and some JavaScript to wrap all that.

If you are patient, it may worth it. ^^
X-Raym is offline   Reply With Quote
Old 02-07-2018, 06:44 PM   #3
pipelineaudio
Mortal
 
pipelineaudio's Avatar
 
Join Date: Jan 2006
Location: Wickenburg, Arizona
Posts: 14,047
Default

Trying to reduce the number of crazy macros it takes to make complicated switching setups in SWS Live Configs.
pipelineaudio is offline   Reply With Quote
Old 02-08-2018, 05:01 PM   #4
jico27
Human being with feelings
 
jico27's Avatar
 
Join Date: Oct 2009
Location: Paris / France
Posts: 429
Default

I like the idea! +1
jico27 is offline   Reply With Quote
Old 02-17-2018, 08:08 PM   #5
pipelineaudio
Mortal
 
pipelineaudio's Avatar
 
Join Date: Jan 2006
Location: Wickenburg, Arizona
Posts: 14,047
Default

Would this really have to be an extension instead?
pipelineaudio is offline   Reply With Quote
Old 02-18-2018, 01:27 AM   #6
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,686
Default

Supposedly an extension could be made (similar to LiveConfigs) that fires actions as a result of a single Reaper Action or Midi message received.

Unfortunately LiveConfigs can perform multiple activities but only fire a single action when entering and leaving a state (line).

Hence this extension at best could be an extended version of LiveConfigs.

I am considering to do a JSFX that works a bit like LiveConfigs, in that it is supposed to receive a Midi message to enter a "state" (similar to a line of a Spreadsheet) and sends out a bunch of Midi messages that are defined in that line when entering / leaving a stage.

Some of those Midi messages can now be routed down to the Control Path by MidiToReaControlPath and then be learned to Actions.

-Michael
mschnell is offline   Reply With Quote
Old 02-18-2018, 02:17 AM   #7
pipelineaudio
Mortal
 
pipelineaudio's Avatar
 
Join Date: Jan 2006
Location: Wickenburg, Arizona
Posts: 14,047
Default

Where exactly are the live configs files? Are they a dll or something?
pipelineaudio is offline   Reply With Quote
Old 02-18-2018, 04:22 AM   #8
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,686
Default

AFAI understand, LiveConfigs is an integral part of the SWS extension (supposedly residing in reaper_sws64.dll (or reaper_sws.dll) ) .

In fact I would be inclined to take on the task of being a maintainer for LiveConfigs (ands with that would be able to do an update as you requested), but as I can't just try to install the sources and compile test and release LiveConfigs, but need to install, compile, test and release the complete SWS extension, I don't dare to start with that.

-Michael

Last edited by mschnell; 02-18-2018 at 03:06 PM.
mschnell is offline   Reply With Quote
Old 02-18-2018, 02:08 PM   #9
pipelineaudio
Mortal
 
pipelineaudio's Avatar
 
Join Date: Jan 2006
Location: Wickenburg, Arizona
Posts: 14,047
Default

Man that sounds brutal!

I’m going to see if I can look inside a smaller extension and see just how insane they are
pipelineaudio is offline   Reply With Quote
Old 02-19-2018, 11:03 PM   #10
pipelineaudio
Mortal
 
pipelineaudio's Avatar
 
Join Date: Jan 2006
Location: Wickenburg, Arizona
Posts: 14,047
Default

So this should really be an extension and not a script right?
pipelineaudio is offline   Reply With Quote
Old 02-20-2018, 07:49 AM   #11
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,686
Default

While of course an extension would provide the most desigh freedom (e.g. creating an editable "Spreadsheet view" like LiveConfig does, I suppose that for the purpose we have in mind, doing a JSFX that is configurable (e.g. by having it read a text file) and sends out Midi events and (via MidiToReaConptrolPath) have events learn those is a lot more easily doable.

-Michael
mschnell is offline   Reply With Quote
Old 02-20-2018, 12:21 PM   #12
pipelineaudio
Mortal
 
pipelineaudio's Avatar
 
Join Date: Jan 2006
Location: Wickenburg, Arizona
Posts: 14,047
Default

Jsfx can do that? It wouldn’t be as convenient as clicking in it and being able to pick commands from the command window though right? Or maybe you could copy command ids from the action window and paste them in...the assignment is part of the big deal to me, being able to tell it what action or cc you want to use to make it fire that row
pipelineaudio is offline   Reply With Quote
Old 02-20-2018, 01:28 PM   #13
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,686
Default

I suppose, as a proof of concept, tomorrow I'll try to draft a JSFX that reads "something" that denotes an Action a file and converts it to a CC to be sent down to trigger that action, when that CC reads some Midi messages or similar.

I understand that an Action can be learned to a CC# (and hopefully Midi channel, but not to the CC value). Am I right.

OTOH, I found that the action that triggers a "config" in LiveConfigs obviously comes with a "value",that denotes the row to be activated.

Does anybody know what happens to the CC value when an action is triggered by a CC # ? Is this value available in a script that is started by that action ?

-Michael
mschnell is offline   Reply With Quote
Old 02-20-2018, 01:45 PM   #14
pipelineaudio
Mortal
 
pipelineaudio's Avatar
 
Join Date: Jan 2006
Location: Wickenburg, Arizona
Posts: 14,047
Default

Quote:
Originally Posted by mschnell View Post
I understand that an Action can be learned to a CC# (and hopefully Midi channel, but not to the CC value). Am I right.
I think this is true, I tried to confirm last night by assigning actions to different values of the same CC# and it said it was already mapped to another and couldn't.
pipelineaudio is offline   Reply With Quote
Old 02-20-2018, 02:05 PM   #15
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,686
Default

Quote:
Originally Posted by pipelineaudio View Post
I think this is true, I tried to confirm last night by assigning actions to different values of the same CC# and it said it was already mapped to another and couldn't.
So where does the CC value go ??!!?? I don't believe it is just ignored.

-Michael
mschnell is offline   Reply With Quote
Old 02-20-2018, 02:43 PM   #16
pipelineaudio
Mortal
 
pipelineaudio's Avatar
 
Join Date: Jan 2006
Location: Wickenburg, Arizona
Posts: 14,047
Default

Quote:
Originally Posted by mschnell View Post
So where does the CC value go ??!!?? I don't believe it is just ignored.

-Michael
I dont think it is either, since the same cc can both mute and unmute things for instance. I keep hammering Justin about it, but maybe we need to make a coherent, clean, specific thread in the feature request about it.

I would love to see something basically like this (though more "REAPERish" of course)

pipelineaudio is offline   Reply With Quote
Old 02-20-2018, 03:21 PM   #17
karbomusic
Human being with feelings
 
karbomusic's Avatar
 
Join Date: May 2009
Posts: 29,260
Default

Quote:
Originally Posted by pipelineaudio View Post
I think this is true, I tried to confirm last night by assigning actions to different values of the same CC# and it said it was already mapped to another and couldn't.
If you guys remember from the other thread where I mentioned there are scenarios where it will not warn - I'd have to look at my reply to remember how that happens.
__________________
Music is what feelings sound like.
karbomusic is offline   Reply With Quote
Old 02-20-2018, 04:45 PM   #18
pipelineaudio
Mortal
 
pipelineaudio's Avatar
 
Join Date: Jan 2006
Location: Wickenburg, Arizona
Posts: 14,047
Default

Which thread? THis is all so exciting and so confusing at the same time
pipelineaudio is offline   Reply With Quote
Old 02-20-2018, 05:11 PM   #19
briandress
Human being with feelings
 
Join Date: Dec 2016
Posts: 96
Default

Quote:
Originally Posted by mschnell View Post
So where does the CC value go ??!!?? I don't believe it is just ignored.

-Michael
so as far as i am aware CC comes in a specific format. I learned this from writing the arduino program for my midi controller.

when we write usbSendMidi command there are three values. CC control, CC Value, and Midi Channel

So reaper has 16 midi channels. and then there are 127 cc controls and each cc control has 127 cc values. right?

so I program the button to send the code. usbSendMidi (0,64,1) so this sends Midi Control Code 0 Value 64 on Midi Channel 1.

I think it is up to the specific software to decide which portion of that data it uses for its triggering.
briandress is offline   Reply With Quote
Old 02-20-2018, 05:15 PM   #20
briandress
Human being with feelings
 
Join Date: Dec 2016
Posts: 96
Default

Quote:
Originally Posted by pipelineaudio View Post
I think this is true, I tried to confirm last night by assigning actions to different values of the same CC# and it said it was already mapped to another and couldn't.
This means that whatever is doing the mapping is only using the D1 value of the CC code. There is Data 1 and Data 2 in CC Data 1 is the control Code, which was mapped with your first value. You tried the same D1 but changed D2 and it wouldnt map because it was already taken.
briandress is offline   Reply With Quote
Old 02-20-2018, 06:08 PM   #21
pipelineaudio
Mortal
 
pipelineaudio's Avatar
 
Join Date: Jan 2006
Location: Wickenburg, Arizona
Posts: 14,047
Default

its affected by the third byte value, but it won't let you assign the same second byte value to two things. I think...since it allows a cc for volume faders for example and responds correctly.

What we're talking about here is the very few (or very many) cases where reaper will not let you directly assign a midi value to it, but insists on learn only, and with no further parameter control over how it behaves.

This is worlds different than say the parameter automation, which gives you all sorts of control over what midi it uses and how it behaves (though still, I don't think quite enough)
pipelineaudio is offline   Reply With Quote
Old 02-20-2018, 06:09 PM   #22
karbomusic
Human being with feelings
 
karbomusic's Avatar
 
Join Date: May 2009
Posts: 29,260
Default

Quote:
Originally Posted by pipelineaudio View Post
Which thread? THis is all so exciting and so confusing at the same time
It was one of yours concerning MIDI or one you entered on the same subject.
__________________
Music is what feelings sound like.
karbomusic is offline   Reply With Quote
Old 02-21-2018, 08:37 AM   #23
karbomusic
Human being with feelings
 
karbomusic's Avatar
 
Join Date: May 2009
Posts: 29,260
Default

Quote:
Originally Posted by pipelineaudio View Post
Which thread? THis is all so exciting and so confusing at the same time

Here it is... It's the difference between learning a CC from a VST vs learning one from an action. Via action, it will complain/overwrite a previous action using the same CC. However, when using learn for VST FX, you can learn the same CC for as many params as you wish and control them all with the single CC. There is a twist to that, if you assign a CC to an action, forget about it, then assign the same CC to a VST param via learn, it will not complain but the VST param will not work because it is being intercepted by the CC tied to the previously learned action...

https://forum.cockos.com/showpost.ph...1&postcount=13

Quote:
It will, but it if you also assign the same CC to an action, that will override the plugin CC but you can assign the same CC to more than one plugin control so long as there are no bound actions involved. Action or no action is the key thing to remember here.

The only thing that denies or cares about duplicates, is duplicate key or CC bindings IN the actions window. Unless my very short test was flawed it's likely that the listener for MIDI attaches any matching actions first and if there is a match it runs the action and doesn't send the CC "down the line" and the plugin never sees it.
__________________
Music is what feelings sound like.
karbomusic is offline   Reply With Quote
Old 02-21-2018, 12:22 PM   #24
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,686
Default

Hmmm.

I don't even think it's an obvious or logical design decision that you can't learn a CC to multiple actions so that all of them would be fired when the CC is detected in the Control Path.

-Michael
mschnell is offline   Reply With Quote
Old 02-21-2018, 12:38 PM   #25
karbomusic
Human being with feelings
 
karbomusic's Avatar
 
Join Date: May 2009
Posts: 29,260
Default

It makes a lot of sense to write the original code that way because it is more rare to need multiple actions with the same CC when contrasted with the confusion it would cause users who were unaware. If use cases justify it down the road (such as pipe's need now) then it makes sense to revisit - my suggestion would be to simply throw the same warning it does now with an option to duplicate, overwrite, cancel.

However, what I described above isn't about multiple actions, it's about 1 action + 1 learned VST param which is a very similar but different issue.
__________________
Music is what feelings sound like.

Last edited by karbomusic; 02-21-2018 at 12:47 PM.
karbomusic is offline   Reply With Quote
Old 02-21-2018, 02:04 PM   #26
briandress
Human being with feelings
 
Join Date: Dec 2016
Posts: 96
Default

Quote:
Originally Posted by karbomusic View Post
It makes a lot of sense to write the original code that way because it is more rare to need multiple actions with the same CC when contrasted with the confusion it would cause users who were unaware. If use cases justify it down the road (such as pipe's need now) then it makes sense to revisit - my suggestion would be to simply throw the same warning it does now with an option to duplicate, overwrite, cancel.

However, what I described above isn't about multiple actions, it's about 1 action + 1 learned VST param which is a very similar but different issue.
so right now you cannot use the same CC code to turn off a VST and also have an action take place, basically?
briandress is offline   Reply With Quote
Old 02-21-2018, 02:14 PM   #27
karbomusic
Human being with feelings
 
karbomusic's Avatar
 
Join Date: May 2009
Posts: 29,260
Default

Quote:
Originally Posted by briandress View Post
so right now you cannot use the same CC code to turn off a VST and also have an action take place, basically?
I don't "think". It was just something I noticed when I was designing a small DIY controller over the last couple weeks. It wasn't something I personally needed, I had just been testing and couldn't understand why the VST param I just set wouldn't work, then realized I had set it to an action earlier.

I wouldn't discourage anyone from testing/confirming further to be sure since it wasn't something I put any time in, just noticed and moved on to finishing my work with testing my controller. Repro/test...

1. Assign an action to a controller knob via MIDI learn.
2. Now assign a VST parameter/knob to that same CC using MIDI learn.

#2 may not work if #1 is set if I didn't miss something which is possible.
__________________
Music is what feelings sound like.
karbomusic is offline   Reply With Quote
Old 02-21-2018, 02:24 PM   #28
briandress
Human being with feelings
 
Join Date: Dec 2016
Posts: 96
Default

Quote:
Originally Posted by karbomusic View Post
I don't "think". It was just something I noticed when I was designing a small DIY controller over the last couple weeks. It wasn't something I personally needed, I had just been testing and couldn't understand why the VST param I just set wouldn't work, then realized I had set it to an action earlier.

I wouldn't discourage anyone from testing/confirming further to be sure since it wasn't something I put any time in, just noticed and moved on to finishing my work with testing my controller. Repro/test...

1. Assign an action to a controller knob via MIDI learn.
2. Now assign a VST parameter/knob to that same CC using MIDI learn.

#2 may not work if #1 is set if I didn't miss something which is possible.

gotcha. Im making a midi controller right now and im working with how i want the coding of the controller based on how reaper handles this switching.

The best I can come up with right now is having tracks loaded with "Presets" using Live Configs to switch them by using CC 0 values and then using the rest of CC 1-127 to switch VST parameters within individual tracks or "presets"

so the controller will default to sending banks of CC0 values but when one is selected will toggle to send CC s for VST parameters.
briandress is offline   Reply With Quote
Old 02-21-2018, 02:39 PM   #29
pipelineaudio
Mortal
 
pipelineaudio's Avatar
 
Join Date: Jan 2006
Location: Wickenburg, Arizona
Posts: 14,047
Default

Oh yeah, shit....Karbo, meet Brian, he's making a midi controller too! Hopefully Justin lets us have a live forum section and we can really post some killer DIY's
pipelineaudio is offline   Reply With Quote
Old 02-21-2018, 02:43 PM   #30
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,686
Default

Quote:
Originally Posted by briandress View Post
Im making a midi controller right now and im working with how i want the coding of the controller based on how reaper handles this switching.
Not really necessary. If you know how to do it. Recoding the midi-messages that come in from the controller is not hard at all.

-Michael
mschnell is offline   Reply With Quote
Old 02-21-2018, 02:55 PM   #31
karbomusic
Human being with feelings
 
karbomusic's Avatar
 
Join Date: May 2009
Posts: 29,260
Default

Ah nice! Welcome Brain. My small project is here, it's just a personal thing using an Arduino:

https://forum.cockos.com/showpost.ph...2&postcount=61

As far as the configs thing, I'm not familiar with it enough to know the answer. I have in the past emulated amp channel switching by placing VSTs then using MIDI CC to toggle the bypass state. For example, imagine two AMP sim VSTs... I assigned toggle bypass to both but set one of them enabled and one bypassed initially - thusly hitting the MIDI controller switch toggled both, effectively resulting in the equivalent of channel switching (think clean/dirty channels).

That's entirely possible because it uses the bypass CC on the actual sim, bypassing the restriction of the same CC we have in actions if that makes any sense. In reality, it looks like from within the actions window, Justin is just checking the list to see if another of the same CC exists then warns. What I don't know is if that causes other issues and that's why it exists or he did it as a safety feature for the user. I would suspect a little of both since an action triggered via CC doesn't seem to fall through to a VST CC but that's visibility I don't have to know for sure.
__________________
Music is what feelings sound like.

Last edited by karbomusic; 02-21-2018 at 03:08 PM.
karbomusic is offline   Reply With Quote
Old 02-27-2018, 12:31 PM   #32
briandress
Human being with feelings
 
Join Date: Dec 2016
Posts: 96
Default

hows your testing going @pipelineaudio?
briandress is offline   Reply With Quote
Old 02-27-2018, 02:28 PM   #33
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,686
Default

Hi Pipe,
I did a preview release of a a "spreadsheet" or a kind of "Configs" JSFX. It's called "Midi CC Table".

The JSFX reads a file (the filename is selectable if multiple files are present). The file(s) must have a ".txt" extension and need to be located in a directory called "cc table" that needs to be located in the "Data" directory, which is right besides Reaper's "Effects" directory.

A sample file content is given below.

The file format is:
- Each line is associated with an incoming CC # (similar to LiveConfigs) (0, 1, 2, ...).
- Each line has up to 64 CC definitions which are separated by a blank (a "/" starts a comment up to the end of the line)
- empty lines are allowed, resulting in a nonexistent row that will not respond to it's input CC value.
- a CC definition can have two or three elements:
. - Midi Channel followed by a colon
. - CC #
. - CC value (optionally, if present separated by a "="), otherwise Zero is assumed)

The JSFX shows the first relevant rows of the table in it's graphic.

You can select an input channel and CC # by "sliders" (as usual).

The current functionality is, that it sends the CCs in the appropriate row whenever it receives an appropriate CC with this row number as it's value (similar as LiveConfigs).

Right now, we don't support a "State" (the number of the latest row that had been accessed and would be "selected").

I think the final version should additionally feature a set of CCs per row to be sent out when a row is left/deselected, and should not send out anything if the already selected row is accessed again. I suppose, with this, you can get rid of LiveConfigs in your setup.

If you want to fire actions (as stated in the original request), you need to use MidiToReaControlPath to send the CCs "down" into the guts of Reaper and "learn" your actions to the appropriate CCs.

Please test and let me know what you find !
Thanks,

Have fun !
-Michael

Code:
// Author: Michael Schnell, 

desc:Midi CC Table

slider1:/cc table:none:CC Table
slider2:0<0,15,1{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}>MIDI Input Channel
slider3:1<0,127,1{0 Bank Sel M,1 Mod Wheel M,2 Breath M,3,4 Foot P M,5 Porta M,6 Data Entry M,7 Vol M,8 Balance M,9,10 Pan M,11 Expression M,12 Ctrl 1 M,13 Ctrl 2 M,14,15,16 GP Slider 1,17 GP Slider 2,18 GP Slider 3,19 GP Slider 4,20,21,22,23,24,25,26,27,28,29,30,31,32 Bank Sel L,33 Mod Wheel L,34 Breath L,35,36 Foot P L,37 Porta L,38 Data Entry L,39 Vol L,40 Balance L,41,42 Pan L,43 Expression L,44 Ctrl 1 L,45 Ctrl 2 L,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64 Hold P sw,65 Porta sw,66 Sustenuto sw,67 Soft P sw,68 Legato P sw,69 Hold 2 P sw,70 S.Variation,71 S.Timbre,72 S.Release,73 S.Attack,74 S.Brightness,75 S.Ctrl 6,76 S.Ctrl 7,77 S.Ctrl 8,78 S.Ctrl 9,79 S.Ctrl 10,80 GP B.1 sw,81 GP B.2 sw,82 GP B.3 sw,83 GP B.4 sw,84,85,86,87,88,89,90,91 Effects Lv,92 Trem Lv,93 Chorus Lv,94 Celeste Lv,95 Phaser Lv,96 Data B. Inc,97 Data B. Dec,98 NRP L,99 NRP M,100 RP L,101 RP M,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127}>CC Input

@init

//FUNCTIONS for reading .txt files
//offset = starting string number
//returns number of lines read

cols  = 64;
cols3 = cols*3;
//cc_nr_i  = 0*rows;
//cc_val_i = 1*rows;

ssb = 0;             // Spread sheet base


function slider_file_to_numbered_strings(slidernumber,offset)local(handle,lastvalue,lines)
//USE ONLY THE NUMBER OF THE SLIDER FOR "slidernumber"  - do not use "sliderx"
(

  slider(slidernumber) != lastvalue ? reload=0;
  
  !reload ? (
    handle=file_open(slider(slidernumber));
    file_string(handle,offset);  
    while( strlen(offset) && offset < 1023 )
      ( offset+=1;
        file_string(handle,offset);      
      );
    file_close(file);
    lines=offset;
    lastvalue=slider(slidernumber);
    reload=1;
  );
  lines;
); 
  
@slider
  inChannel   = slider2;
  modcc       = slider3; 

  lines = slider_file_to_numbered_strings(1, 0);

  row = 0; 
  loop(lines, 
    #s = strcpy(#, row);
    o   = 0;
    col = 0;
    cc  = -1;
    l   = strlen(#s);
    src = ssb + row*cols3+ col*3;
    src[0] = -1;
    while (o < l) (
      c = '0';
      j = 0;
      while ((c >= '0') && (c <= '9')) (
        j *= 10;
        j += c-'0';
        c = str_getchar(#s, o, 'c');
        o += 1;
      );  
      c == ':' ? (                           // Channel
        src[0] = j-1;
//        ___0 = j;
       ) : c == '=' ? (                      // CC #
        src[1] = j;       
        cc = j;
//        ___1 = j;
       ) : (c == ' ') || (c == 13) || (c == '/') ? (       // Value
        cc >= 0 ? (
          src[2] = j;
//          ___2 = j;
         ) : (
          src[1] = j;
//          ___1 = j;
          src[2] = 0;
//          ___2 = 0;
        );  
        col += 1;
        cc = -1;
        src = ssb + row*cols3+ col*3;
        src[0] = -1;
      );  
    );
    row+=1;
  );

@block
  while (midirecv(offset, msg1, msg2, msg3)) (
    status = msg1 & $xF0;      // Extract message type
    channel = msg1 & $x0F;
    channel == inChannel ? (   // Is it on our channel?
      status == $xB0 ? (       // Is it a controller event?
        msg2 == modcc ? (      // Is it the right CC?
          ci = msg3;
          ci < row ? (
            cj  = 0;
            coli = ci * cols3;
            src = ssb + coli /*+ cj*3*/;
            while (src[0] >= 0) ( 
              midisend(offset, $xB0+src[0],  src[1],  src[2]); 
              cj += 1;
//            src = ssb + coli + cj*3;
              src += 3;
            );  
          );
        );
      );
    );          
    midisend(offset, msg1, msg2, msg3); // pass through
  );
  
@gfx 650 450  
  //display file
  gfx_r=gfx_g=gfx_b=0; gfx_a=1;
  gfx_x=gfx_y=0;
  gfx_rectto(gfx_w,gfx_h);
  
  gfx_setfont(2, Ariel,18);
  gfx_r=1;gfx_g=gfx_b=1;
  xx=10;
  yy=10;
  gfx_x=xx;gfx_y=yy;
  i=0;
  loop ( row,
    #t = sprintf(#, "%d >> ", i);
    j = 0;
    srb = ssb + i*cols3 /*+ j*3*/;
    while (srb[0] >= 0) ( 
      #s = sprintf(#, "%d:%d=%d  ", srb[0]+1, srb[1], srb[2]); 
      #t += #s;
      j += 1;
//    srb = ssb + i*cols3 + j*3;
      srb += 3;
    );  
    ssb[i*cols3 /* + 0*3 + 0 */  ] >= 0 ? (
      gfx_drawstr(#t);
      gfx_x=xx;
      gfx_y+=gfx_texth+3;
    );  
    i+=1;
  );
Code:
1:1=1 1:1=2   // CC # 0
2:2=2
// CC #2 empty
3:3=1 3:3=2 3:3=3 3:3=4
7:7=1 7:7=2 7:7=3 7:7=4 7:7=5 7:7=6 7:7=7 7:7=8

Last edited by mschnell; 02-27-2018 at 02:57 PM.
mschnell is offline   Reply With Quote
Old 02-27-2018, 02:48 PM   #34
pipelineaudio
Mortal
 
pipelineaudio's Avatar
 
Join Date: Jan 2006
Location: Wickenburg, Arizona
Posts: 14,047
Default

allll right!

I'll be trying this today as time allows, awesome!
pipelineaudio is offline   Reply With Quote
Old 02-27-2018, 08:09 PM   #35
pipelineaudio
Mortal
 
pipelineaudio's Avatar
 
Join Date: Jan 2006
Location: Wickenburg, Arizona
Posts: 14,047
Default

I'm not exactly sure how to fill out the lines
pipelineaudio is offline   Reply With Quote
Old 02-27-2018, 10:42 PM   #36
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,686
Default

I'm not exactly sure what you are asking.

I suppose you are able to use a text editor to create an appropriate file .


Have you been able to make the JSFX show the content of the example file ?


Do you mean the syntax ?

The example shows how to define the elements in a line. e.g. the two elements in the first line mean:

When a CC (with correct input channel and CC #) with value 0 is detected, send out CC #1 with value 1 on channel 1, and then CC#1 on channel 1 with value 2.

Of you just want to trigger actions, (AFAIK) the CC value is ignored by "learn", and hence not necessary to be written in the fileThe JSFX will assume 0 in that case.. Syntax just 3:4 -> CC# 4 on channel 3 with value 0.


Or do you mean the purpose / usage ?

I am not fluent with "learning" actions. Maybe you need to do second file that just sends out single CCs for dong the "learning" of different CC#s to dedicated actions.

Once that done, you have a list of CC#s with associated actions and from this you can construct a file that sends out multiple CCs per "row" and hence will trigger multiple actions when receiving a single CC message.

-Michael

Last edited by mschnell; 02-28-2018 at 12:50 AM.
mschnell is offline   Reply With Quote
Old 02-28-2018, 12:10 AM   #37
pipelineaudio
Mortal
 
pipelineaudio's Avatar
 
Join Date: Jan 2006
Location: Wickenburg, Arizona
Posts: 14,047
Default

Just the syntax, I'll try it again, I think I understand it better now
pipelineaudio is offline   Reply With Quote
Old 02-28-2018, 12:48 AM   #38
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,686
Default

I improved the messages above...
-Michael
mschnell is offline   Reply With Quote
Old 02-28-2018, 10:39 AM   #39
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,686
Default

New version.
You now can select either the "Map" or the "Configs" mode.

In "Map" mode the CCs denoted in a row are sent out whenever a CC that points to that row is received.

In "Configs" mode an incoming CC selects a row. The sected Row is highlighted in the graph. Only if the selection is changed the JSFX will send out the appropriate "activate" CCs of the newly selected row. Moreover before that, it will send out the "deactivate" CCs for the formerly selected row. (This works similar as SWS LiveConfigs.)

To support the "Configs" Mode, an additional key-character is introduced in the table file: "<" as a seperatopr (instead of blank) starts the definition of "deactivate" CCs.

An example file see below.

-Michael

Code:
// Author: Michael Schnell, 

desc:Midi CC Table

slider1:/cc table:none:CC Table
slider2:0<0,1,1{Map,Configs}>Function
slider3:0<0,15,1{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}>MIDI Input Channel
slider4:1<0,127,1{0 Bank Sel M,1 Mod Wheel M,2 Breath M,3,4 Foot P M,5 Porta M,6 Data Entry M,7 Vol M,8 Balance M,9,10 Pan M,11 Expression M,12 Ctrl 1 M,13 Ctrl 2 M,14,15,16 GP Slider 1,17 GP Slider 2,18 GP Slider 3,19 GP Slider 4,20,21,22,23,24,25,26,27,28,29,30,31,32 Bank Sel L,33 Mod Wheel L,34 Breath L,35,36 Foot P L,37 Porta L,38 Data Entry L,39 Vol L,40 Balance L,41,42 Pan L,43 Expression L,44 Ctrl 1 L,45 Ctrl 2 L,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64 Hold P sw,65 Porta sw,66 Sustenuto sw,67 Soft P sw,68 Legato P sw,69 Hold 2 P sw,70 S.Variation,71 S.Timbre,72 S.Release,73 S.Attack,74 S.Brightness,75 S.Ctrl 6,76 S.Ctrl 7,77 S.Ctrl 8,78 S.Ctrl 9,79 S.Ctrl 10,80 GP B.1 sw,81 GP B.2 sw,82 GP B.3 sw,83 GP B.4 sw,84,85,86,87,88,89,90,91 Effects Lv,92 Trem Lv,93 Chorus Lv,94 Celeste Lv,95 Phaser Lv,96 Data B. Inc,97 Data B. Dec,98 NRP L,99 NRP M,100 RP L,101 RP M,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127}>CC Input

@init

//FUNCTIONS for reading .txt files
//offset = starting string number
//returns number of lines read

cols   = 32;
cols3  = cols*3;
cols23 = cols3*2;
//cc_nr_i  = 0*rows;
//cc_val_i = 1*rows;

ssb = 0;             // Spread sheet base


function slider_file_to_numbered_strings(slidernumber,offset)local(handle,lastvalue,lines)
//USE ONLY THE NUMBER OF THE SLIDER FOR "slidernumber"  - do not use "sliderx"
(

  slider(slidernumber) != lastvalue ? reload=0;
  
  !reload ? (
    handle=file_open(slider(slidernumber));
    file_string(handle,offset);  
    while( strlen(offset) && offset < 1023 )
      ( offset+=1;
        file_string(handle,offset);      
      );
    file_close(file);
    lines=offset;
    lastvalue=slider(slidernumber);
    reload=1;
  );
  lines;
); 
  
@slider
  conf        = slider2;
  inChannel   = slider3;
  modcc       = slider4;
  
  act = -1;
  pre = -1;

  lines = slider_file_to_numbered_strings(1, 0);

  row = 0; 
  loop(lines, 
    #s = strcpy(#, row);
    o   = 0;
    col = 0;
    cc  = -1;
    l   = strlen(#s);
    src = ssb + row*cols23 + col*3;
    src[0]     = -1;
    src[cols3] = -1;
    while (o < l) (
      c = '0';
      j = 0;
      while ((c >= '0') && (c <= '9')) (
        j *= 10;
        j += c-'0';
        c = str_getchar(#s, o, 'c');
        o += 1;
      );  
      c == ':' ? (                           // Channel
        src[0] = j-1;
//        ___0 = j;
       ) : c == '=' ? (                      // CC #
        src[1] = j;       
        cc = j;
//        ___1 = j;
       ) : (c == ' ') || (c == 13) || (c == '<') || (c == '/' || (o > l) )? (       // Value
        cc >= 0 ? (
          src[2] = j;
//          ___2 = j;
         ) : (
          src[1] = j;
//          ___1 = j;
          src[2] = 0;
//          ___2 = 0;
        );  
        col += 1;
        cc = -1;
        src = ssb + row*cols23 + col*3;
//        ___s = src; 
        src[0] = -1;
        c == '/' ? o = 999;              // abort line
        c == '<' ? (
          col = cols;                    // go on in this row
          src = ssb + row*cols23 + col*3;   
//          ___s1 = src; 
//          c = '0';
//          j = 0;
//          src[0] = -1;      
        );
      );  
    );
    row+=1;
  );
//  ___n  = 5*cols23;
//  ___x  = ssb[___n];
//  ___n1 = 5*cols23 + cols3;
//  ___x1 = ssb[___n1];
//  ___n2 = 5*cols23 + cols3 + 1;
//  ___x2 = ssb[___n2];
    

@block
  while (midirecv(offset, msg1, msg2, msg3)) (
    status = msg1 & $xF0;      // Extract message type
    channel = msg1 & $x0F;
    channel == inChannel ? (   // Is it on our channel?
      status == $xB0 ? (       // Is it a controller event?
        msg2 == modcc ? (      // Is it the right CC?
          ci = msg3;
          ci < row ? (
            conf ? (
              act = ci;
            );  
            act != pre ? (
              conf ? (
                cj  = 0;
                coli = pre * cols23 + cols3;
                src = ssb + coli /*+ cj*3*/;
                while (src[0] >= 0) ( 
                  midisend(offset, $xB0+src[0],  src[1],  src[2]); 
                  cj += 1;
                  src += 3;
                );
              );  
              cj  = 0;
              coli = ci * cols23;
              src = ssb + coli /*+ cj*3*/;
              while (src[0] >= 0) ( 
                midisend(offset, $xB0+src[0],  src[1],  src[2]); 
                cj += 1;
                src += 3;
              );
              pre = act;
            );  
          );
        );
      );
    );          
    midisend(offset, msg1, msg2, msg3); // pass through
  );
  
@gfx 650 450  
  //display file
  gfx_r=gfx_g=gfx_b=0; gfx_a=1;
  gfx_x=gfx_y=0;
  gfx_rectto(gfx_w,gfx_h);
  
  gfx_setfont(2, Ariel,18);
  gfx_r=1;gfx_g=gfx_b=1;
  xx=10;
  yy=10;
  gfx_x=xx;gfx_y=yy;
  i=0;
  loop ( row,
    #t = sprintf(#, "%d >> ", i);
    j = 0;
    srb = ssb + i*cols23 /*+ j*3*/;
    while ((srb[0] >= 0) && (j < cols)) ( 
      #s = sprintf(#, "%d:%d=%d  ", srb[0]+1, srb[1], srb[2]); 
      #t += #s;
      j += 1;
//    srb = ssb + i*cols3 + j*3;
      srb += 3;
    );  
    j = 0;
    srb = ssb + i*cols23 + cols3;
    srb[0] >= 0 ? #t += " << ";
    
    while ((srb[0] >= 0) && (j < cols)) ( 
      #s = sprintf(#, "%d:%d=%d  ", srb[0]+1, srb[1], srb[2]); 
      #t += #s;
      j += 1;
//    srb = ssb + i*cols3 + j*3;
      srb += 3;
    );  
    
    ssb[i*cols23 /* + 0*3 + 0 */  ] >= 0 ? (
      i == act ? (
        gfx_r=1;gfx_g=1;gfx_b=0;
       ) : (
        gfx_r=0.7;gfx_g=0.7;gfx_b=0.7;
      ); 
      gfx_drawstr(#t);
      gfx_x=xx;
      gfx_y+=gfx_texth+3;
    );  
    i+=1;
  );
example table file:
Code:
1:1=1 1:1=2   // CC # 0
2:2=2
// CC #2 empty
// 4
3:3=1 3:3=2 3:3=3 3:3=4<10:11
7:7=1 7:7=2 7:7=3 7:7=4 7:7=5 7:7=6 7:7=7 7:7=8<9:9=9 10:11=127

Last edited by mschnell; 02-28-2018 at 10:48 AM.
mschnell is offline   Reply With Quote
Old 02-28-2018, 11:47 AM   #40
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,686
Default

BTW.:

If you want to learn a dedicated CC # to an action you might want to use the "Midi CC LFO Generator". If sends out an infinite series of CCs with dedicated Channel,CC#, and (if you want to) CC value.

-Michael
mschnell is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 10:30 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.