Cherry Audio GX-80

Perhaps a solution is to precede each new note with a zero. Each new note must in theory start from that position while previously held notes retain their last value until release.

1 Like

Thanks, @Ade and @Torsten!

I will think about how to deal with this “stuck AT” problem. I have to figure out all possible combinations and how to deal with them.

Gabriel

1 Like

FWIW, my system is only two years old and I have no problems with other plugins. I run windows 10.
For the Elka-X, I can understand why it could be so heavy: it is actually two synths in one (two layers, each one a complete synth). For Sines, it could be that the oscillators are so computational expensive that everything you can do with effects, release times etc, has a small effect with respect to the actual waveform calculation.

It could also be that I am not running my system at his best, but I can’t think of anything else that I could do to get a better performance. I know that audio programs are strange beasts…but it still bothers me to see a CPU load below 25% while my Time Load is over 100%! :rofl:

Gabriel

1 Like

After some thinking about possible cases, it seems to me that

  1. a null (i.e. zero) poly-AT value should be sent for each new note played (i.e. each NOTE ON message);
  2. when a new note is pressed, a null poly-AT value should be sent for the second to last note played (the one which was getting poly-AT until then, i.e. the one latched by the script);
  3. when a note is released (even if it’s not the one currently getting poly-AT, just to be sure), its poly-AT should be set to null; for this one needs to listen also for NOTE OFF messages or (for some old keyboard) to NOTE ON values with a velocity=0;

Of course, there will be sudden jumps in poly-AT values. To implement some kind of “lag” I would need to study a little bit how to deal with buffers/offsets etc in ReaJS.

Cheers!
gabriel

Edit: an improvement with respect to the above scheme could be to cascade my script with a MIDI smoother like this one:

which is for pitch bend. Abrupt transitions would be replaced by smoother ones, with an adjustable decay/rise time. However, unlike pitch bend, the smoother should keep track of poly-AT for each one of the 128 midi notes. :scream:

2 Likes

I like that idea - so you could actually leave some notes with AT>0 while they’re still held. Makes more sense…

1 Like

I love Cherry Audio, but most of their synth are heavy. I see low Time Load (8%) only on Miniverse, which is monophonic. With Elka-X, GX-80, Memorymode, and Eight Voice I have TL about 25 to 45%.

1 Like

Here’s what the GX-80 appears to do:
A single note applies aftertouch ‘normally’. Note off, understandably, brings AT back to zero.
A second note zeros the first sounding note and applies the current AT value to the new note. This approach is maintained for all further note ons, where existing notes zero their AT value and the new note picks up the last AT value.

Now, a script could get really interesting.
For example, a user CC to switch to bypass the pseudo poly and apply the channel pressure normally. GX-80 handles this with its front panel switch which can be MIDI controlled. The current AT value immediately applies to all sounding notes. Switching back to pseudo zeros all sounding notes but maintains the last note played, even if it’s a new note played during ‘normal’ mode, at the current pressure value. MIDI control of this allows the performer to switch between pseudo and normal, which could enhance the ‘illusion’ of Poly AT further.
Or a timer where only notes played within a user defined range get channel aftertouch (chords for example) and notes outside that range (melody) get pseudo poly.
Anyway … I’m rambling.

3 Likes

Hi Gabriel,
Back on main forum - sorry if that caused some confusion.
The script is WAY better and works nearly faultlessly with DIVA as the test subject. I’m just trying to nail down exactly what causes occasional failure.
If it might be possible to try a version where held notes do not zero, just retain their current value when a new note is pressed, but new notes do get a zero before continuing to receive AT, it would interesting to see what the down side is. One has to really watch what is happening with pressure on held notes when a new note is introduced to avoid jumps. I suspect @Torsten is right, that some kind of smoothing ramp is being employed by Cherry when the reset is issued.
This is MUCH appreciated! :+1: :+1: :+1:

1 Like

No doubt it isn’t as good as a new one, but its a six core Xeon clocked at 3.4 GHz, so it still can handle a pretty hairy mix project… That said, I’ll try Sines on the box I recently built for the kids to run MS Flight Simulator…if it has problems on that box its going to have problems on anything. Its very high spec. Will report the findings…

[edit] Sines behave well on that box. Guess I have to upgrade hardware if I want to run it on my mix box. Fortunately GX-80 runs fine on it.

Gotta confess - another attack of GAS; having a lot of fun with GX-80!

BUT: same problems as with Surge XT - window keeps shrinking whenever I move it or just change the tab when docked; only way to avoid is to turn off HiDPI altogether, which I don’t really want to do…

@brad: I reeeeeally hope you have a workaround up your sleeve to fix this behavior - it works perfectly in HiDPI with Cubase and REAPER, so there should be a way to make it cooperate with Cantabile - pretty pleeeease…

Cheers,

Torsten

Hi Adrian,

I attach here a new version of the script. It required a bit of work, especially since something strange is still happening (at least on my system).
In principle, this version will allow you to choose if held notes must be reset (AT=0) or not. You can also set it to Bypass or Active.
The correct behavior should be as follows:

  • if a NOTE ON is received, the note is latched, a poly-AT=0 is sent for that note, the NOTE ON message is forwarded to the midi output (to be received, e.g., by Sines). Before that, however, if “reset held notes” has been selected, the poly-AT is set to zero for the previously latched note.
  • if a NOTE OFF is received, a poly-AT=0 is sent for that note, if the released note is the one latched for poly-AT then the latched value is reset (set to -1), NOTE OFF is forwarded to the midi output
  • if a CHANNEL PRESSURE message is received and the latched note is not =-1, a poly-AT message is sent for that note (with the value of the pressure taken from the received message)

However, there are situations in which the script starts passing through the channel pressure messages, as I have checked with MIDI monitors in Cantabile. What is even worse, sometimes even messages on other midi channels (not the selected one) are able to pass. I couldn’t spot any obvious mistakes in the code…but of course they could be there nevertheless.

On a more positive note, if I place a “Suppress event” filter at the MIDI output of ReaJS, suppressing all pressure events, the beast behaves reasonably. :laughing:

Cheers!
Gabriel

P.S. The zip file is called midipressuretopoly2.zip, but the script name is still the same as before.

Update: Even Pitch Bend is passing through, in spite of the fact that I call the midisend() function only for note messages and poly-AT. This means that not all MIDI events are received in the main loop of the script…some events are not caught by the script and they simply go through it. I didn’t expect that! :sweat_smile: I would need some time studying ReaJS and googling around…

UPDATE 2: Forget about it! There is an obvious mistake! I thought I was using a C-like while statement, while in fact I was using a peculiar form…ignore this version of the script. I will upload a new one after some test.

UPDATE 3: After correcting the bug, the strange behavior is gone. Basically, the form of the while statement that I was using was supposed to stop looping when the last statement in the loop became false (and in some phase I must have deleted or moved just that statement…oops!). Now I am using a more familiar (to me) form, in which the while loop evaluates a condition and executes the loop basing on that (loop executes if condition is true). As I said…I am new to this business… :blush:
Down here you should find a midipressuretopoly3.zip (version 3! I have almost reached Cantabile!) with the (hopefully) working script. BTW, I have added a new feature: all messages that are not NOTE on/off or PRESSURE are forwarded to the output, even when the script is active.

midipressuretopoly3.zip (973 Bytes)

3 Likes

For most simple MIDI processing in ReaJS, the following loop will do the job:

  @block
    while (midirecv(offset,msg1,msg2,msg3)) ( // look through all MIDI events in buffer
       ( <<some condition of msg1,2,3>>) ? (  // identify the events you want to process
         // now do something magic with the identified event you found
         // ...
         // magic is done - now output
         midisend(offset,newMsg1, newMsg2, newMsg3); // send modified event
         midisend(offset,anotherMsg1, anotherMsg2, anotherMsg3); // maybe generate new events?
         // ...
       ) : ( // else - not the note you are looking for
         midisend(offset,msg1,msg2,msg3); // passthrough other events if you want
       ); // end of else
    ); // end of while loop

Maybe this helps for future experiments :wink: . BTW: sysex events will always be passed through when you use midirecv(…) - if you want to deal with sysex, you’ll need to work with buffers (midirecv_buf).

Cheers,

Torsten

2 Likes

That’s what I am using now. The code I got “inspiration” from, instead, used this other kind of loop:

   while(

     a += b;

     b *= 1.5;

     a < 1000; // as long as a is below 1000, we go again.

   );

which “Evaluates the first parameter until the last statement in the code block evaluates to zero.”, according to this page

https://www.reaper.fm/sdk/js/basiccode.php#loops

Well, at least I have learnt something. :wink:

Thanks!
Gabriel

1 Like

This is great!
We should raise a digital mug of mulled wine in your direction!!
I’ll check it out after dinner tonight. :wine_glass:

1 Like

If it is what we call “vin brulé” here in Italy, then…I like mulled wine quite a lot! :yum:
Anyway, let’s hope it will work this time!
Cheers! :wine_glass:
Gabriel

1 Like

I think it’s brilliant Gabriel.
I mapped a CC to the Bypass and to color ON/OFF status of the plugin.
Works seamlessly. Can go from pseudo poly to channel pressure with a click, while holding notes. Swell a full chord… pull it back a little and switch to pseudo … just as I imagined it could work, it’s there.
Full Poly AT is great, but I can imagine some players finding this script and putting the purchase on hold.
Thank you!

1 Like

Gabriels Script.zip (965.5 KB)
Thought ya’ll might like to hear a little of Cherry’s Dreamsynth backed up by DIVA employing Gabriel’s script on filters and pitchbend. All real time, no dubs or edits, just captured with Cantabile’s record function. Being able to bend one note, even inside a chord, is a really lovely effect, and it’s quite tricky to do with Poly AT because you apply pressure which starts wobbling other notes. With pseudo Poly AT you can target only the last note played,
Also, Gabriel’s reset option is crucial with this kind of bend because you can end up putting the whole instrument out of tune if you really work at it!! :grinning:
FYI, I did this on my old Lenovo and I placed a Vienna Ensemble into Cantabile which sub hosted Metaplugin. Metaplugin hosted Dreamsynth, DIVA and Gabriel’s script and was able to run my system at 256 with the 4x buffer operating on VEP.
That allows stuff directly hosted in Cantabile to run at a low buffer, I could run the GX in Cantabile simultaneously and have headroom using this approach.

4 Likes

Great! Nice to know that I have been of help! And it makes me want to practice this kind of stuff.
Now, if you ever develop this idea into a track, “Gabriel’s Script” could be at least a nice working title! :grin:

Gabriel

2 Likes

I’ve been thinking about picking up Metaplugin for a while to use as a portable guitar rack. I tend to have complex signal chains and like the idea of Meta to have portability from live to DAW. Do you use it that way and if so has it worked out? Sorry everyone for the tangent…but I suppose it is kind of the norm around here… :grin:

Metaplugin is a very useful toolbox to have. As you said, it can transport entire setups into different platforms.
I did, now that I think about it, actually attempt to use it for guitar stuff and ended up bringing most of the plugins back into Cubase inserts and also directly into Cantabile for that environment.
That additional layer of hosting lacked useful visual feedback.
There may have been some components left in metaplugin purely for ease of routing, but I was finding automating functions to be quite a bear.
Metaplugjn is my go to when routing via ‘normal’ methods is too convoluted, such as getting this script distributed to a couple of plugins easily. Vienna Ensemble has no MIDI routing and I wanted to bring that into the picture to take advantage of its extra buffers.
There is a trial period. Check it out; you will definitely find it a useful addition.