|
Post by Rob on May 26, 2018 10:19:48 GMT 1
Also, I realized that all of the sub controls, that don't upate after I type in a new value are using RH-Rescale. Unpin RH-Rescale & re-route, then entered values update the control. Of course they aren't scaled any more, but they will update. There seem to be several problems with my Rescale module while checking it. So, my advice for now is to switch to Roy ScaleUp(Float) or Roy ScaleDown(Float).
|
|
|
Post by Rob on May 26, 2018 16:59:22 GMT 1
|
|
|
Post by twoifbysea on May 26, 2018 19:40:18 GMT 1
While not bi-directional, the new RH-Rescaler2 now works as expected.
Example: Using the older RH-Rescale on a subcontrol knob to adjust a VCA module set to decibel mode, I set the knobs low value to 7 volts and the high to 13 volts in order to apply +/- 12 dB of actual gain. So, to have the knob to display -12 dB to +12 dB rather than 7 & 13, I used the rescaler within the subcontrol set to:
In Low = 0 In High = 10 Out Low = -40 Out High = 0
It made no sense, but those are settings it took.
RH-Rescale2 setting to achieve the same results:
In Min = 7 In Max = 13 Out Min = -12 Out Max = 12
No more trial and error looking for the correct values to scale by!
|
|
|
Post by Rob on May 26, 2018 23:40:10 GMT 1
Yeah, I tried to make it bidirectional but it didn’t work as intended. So for now I just have the output value sent back to the input when it changes, or doesn’t that work when you try it?
Good that the formula works now!
|
|
|
Post by twoifbysea on May 27, 2018 2:20:39 GMT 1
Output value to input doesn't work for me.
Using the aforementioned sub control as an example, if a new value is entered that is within the range of the controls low/high voltage parameters (7-13), then the actual value changes, but the displayed value is "-". If the entered value is above or below the low/high voltage parameters, then the knob and actual value go to the extreme min/max, position/values. I hope that makes some sense?
|
|
|
Post by Rob on May 27, 2018 7:59:26 GMT 1
Can you provide me a testproject with just that structure? It would help me understand it better. I built a third version, where the output becomes the input for the formula. In my opinion it was wrong, but maybe it's just what you want. Link: rhmodules.nl/temp/SE/Rhrescale3.zip
|
|
|
Post by twoifbysea on May 27, 2018 22:57:56 GMT 1
Test project sent to your PM's.
|
|
|
Post by Rob on May 28, 2018 19:49:02 GMT 1
Thanks for sending the project.
I'm having trouble rewriting the rescale formula to go back from output to input ( should have paid more attention in school ). To be continued..
Original formula:
y = ( x - oldmin ) * ( ( newmax - newmin ) / oldmax - oldmin ) + newmin
Wrongly rewritten formula:
x = y + oldmin * ( ( oldmax - oldmin ) + newmin ) / ( newmax - newmin )
|
|
Andrew
Developer
Posts: 110
Posts: 110
|
Post by Andrew on May 29, 2018 13:35:37 GMT 1
I'm having trouble rewriting the rescale formula to go back from output to input ( should have paid more attention in school ). To be continued.. Original formula: y = ( x - oldmin ) * ( ( newmax - newmin ) / oldmax - oldmin ) + newmin Wrongly rewritten formula: x = y + oldmin * ( ( oldmax - oldmin ) + newmin ) / ( newmax - newmin ) In this rare case i.e. no powers or transcendental functions(i.e. linear addition and multiplication), you can calculate the inverse by simply substituting 'values'. I'm adding the descriptor "pin" to the formula - because "value" doesn't make much sense with bi-directional stuff for me.
Original formula:
pinY = ( pinX - pinOldmin ) * ( ( pinNewmax - pinNewmin ) / pinOldmax - pinOldmin ) + pinNewmin
Inverse via linear substitution:
pinX = ( pinY - pinNewmin ) * ( ( pinOldmax - pinOldmin ) / pinNewmax - pinNewmin ) + pinOldmin
It's almost like cheating.
|
|
Andrew
Developer
Posts: 110
Posts: 110
|
Post by Andrew on May 29, 2018 17:12:22 GMT 1
In simpler terms, rescaling is the inverse of rescaling.
|
|
|
Post by Rob on May 29, 2018 19:43:58 GMT 1
Andrew , thanks for pitching in. Tried it, but while testing several values I do still get wrong results. There's probably still something wrong in my module.
in_min = 7 in_max = 13 out_min = -12 out_max = 12
Check what happens when inputting 12 in TextEntry 3, value out says 307 now instead of 13.
#include "mp_sdk_gui2.h"
using namespace gmpi;
class RhrescaleGui : public SeGuiInvisibleBase { void onSetInput() { // pinInput changed pinY = (pinX - pinOldmin) * ((pinNewmax - pinNewmin) / pinOldmax - pinOldmin) + pinNewmin; }
void onSetIn_Low() { // pinIn_Low changed pinY = (pinX - pinOldmin) * ((pinNewmax - pinNewmin) / pinOldmax - pinOldmin) + pinNewmin; }
void onSetIn_High() { // pinIn_High changed pinY = (pinX - pinOldmin) * ((pinNewmax - pinNewmin) / pinOldmax - pinOldmin) + pinNewmin; }
void onSetOut_Low() { // pinOut_Low changed pinY = (pinX - pinOldmin) * ((pinNewmax - pinNewmin) / pinOldmax - pinOldmin) + pinNewmin; }
void onSetOut_High() { // pinOut_High changed pinY = (pinX - pinOldmin) * ((pinNewmax - pinNewmin) / pinOldmax - pinOldmin) + pinNewmin; }
void onSetOutput() { // pinOutput changed
// In this rare case i.e. no powers or transcendental functions(i.e. linear addition and multiplication), // you can calculate the inverse by simply substituting 'values'. // http://syntheditforum.boards.net/post/1934 // Inverse via linear substitution:
pinX = (pinY - pinNewmin) * ((pinOldmax - pinOldmin) / pinNewmax - pinNewmin) + pinOldmin; }
FloatGuiPin pinX; FloatGuiPin pinOldmin; FloatGuiPin pinOldmax; FloatGuiPin pinNewmin; FloatGuiPin pinNewmax; FloatGuiPin pinY;
public: RhrescaleGui() { initializePin( pinX, static_cast<MpGuiBaseMemberPtr2>(&RhrescaleGui::onSetInput) ); initializePin( pinOldmin, static_cast<MpGuiBaseMemberPtr2>(&RhrescaleGui::onSetIn_Low) ); initializePin( pinOldmax, static_cast<MpGuiBaseMemberPtr2>(&RhrescaleGui::onSetIn_High) ); initializePin( pinNewmin, static_cast<MpGuiBaseMemberPtr2>(&RhrescaleGui::onSetOut_Low) ); initializePin( pinNewmax, static_cast<MpGuiBaseMemberPtr2>(&RhrescaleGui::onSetOut_High) ); initializePin( pinY, static_cast<MpGuiBaseMemberPtr2>(&RhrescaleGui::onSetOutput) );
onSetInput(); onSetIn_High(); onSetIn_Low(); onSetOut_High(); onSetOut_Low(); onSetOutput(); }
};
namespace { auto r = Register<RhrescaleGui>::withId(L"RH-Rescale2"); }
|
|
Andrew
Developer
Posts: 110
Posts: 110
|
Post by Andrew on May 30, 2018 6:48:18 GMT 1
Andrew , thanks for pitching in. Tried it, but while testing several values I do still get wrong results. There's probably still something wrong in my module. Check what happens when inputting 12 in TextEntry 3, value out says 307 now instead of 13
Hmmm, I think I don't understand what your module is suppose to do in practical terms. Can you PM me the source code and maybe a actual use example(default skin plz)?
Think their might also be some confusion about how the module is used. Just to make sure - do you want to change only the display values? Or both the display values and output values(prom patchmem)? If you want to do the latter - you actually need two modules, like the Float Function module that has two(one sub-control/one dsp float).
|
|
Andrew
Developer
Posts: 110
Posts: 110
|
Post by Andrew on May 30, 2018 12:14:02 GMT 1
Okay, now I'm even more confused - I plugged your original formula into a Float Function module(DSP one under conversion, not bi-directional), got wrong result, used my own formula - wrong result. This was just for re-scaling not the inverse. Don't think either of us is wrong(my formula works fine in an audio module) but there must be something fundamentally that we are missing about using floats.
|
|
|
Post by Rob on May 30, 2018 13:15:30 GMT 1
I got the original formula from here: stackoverflow.com/a/1456023And it's exactly like yours, so indeed something else is off here.. I PM-ed you the project plus source and SEM. What Dave wants is: - To have the option to either set what the knob (subcontrol) sends to patch mem value out(dsp), or set it thru Text-entry 3 (subcontrol). - When it's set thru the Text-entry 3 the correct value should be reflected by the position of the knob, so it works bi-directional. I'm not sure we can help with the second bit, as it goes back from value ( subcontrol 0-10v ) on the patch memory to animation position ( subcontrol 0-1v ). You answered it probably by suggesting a second module to work that out. This might suggest Jeff did not foresee this use-case, but is relevant ( I would want it too when building a VST with knobcontrols and value input ).
|
|
Andrew
Developer
Posts: 110
Posts: 110
|
Post by Andrew on May 30, 2018 14:14:41 GMT 1
I PM-ed you the project plus source and SEM. What Dave wants is: - To have the option to either set what the knob (subcontrol) sends to patch mem value out(dsp), or set it thru Text-entry 3 (subcontrol). - When it's set thru the Text-entry 3 the correct value should be reflected by the position of the knob, so it works bi-directional. I'm not sure we can help with the second bit, as it goes back from value ( subcontrol 0-10v ) on the patch memory to animation position ( subcontrol 0-1v ). You answered it probably by suggesting a second module to work that out. This might suggest Jeff did not foresee this use-case, but is relevant ( I would want it too when building a VST with knobcontrols and value input ).
It's probably something to do with the order of pin updates or the math, I'll check it out. You really need two modules if you want to change both the display and the output - Jeff designed it that way, it might sound weird but it is actually more flexible. If you do something wrong with the sub-controls - it may change the output of the patchmem - but that's an error, SE doesn't guarantee to initialize to the correct value(this is correct behavior)! Say a EQ module takes on kHz values, but you want to display Hz, you change the subcontrols only. Say, like my EQ(personal project) half of the knob travel goes from 0.05kHz to 1Hz and the other half of the knob travel goes from 1kHz to 18kHz - i.e. - the knob response is curved - I do that with two Float Function modules, one subcontrol one DSP.
|
|
Andrew
Developer
Posts: 110
Posts: 110
|
Post by Andrew on May 30, 2018 17:59:05 GMT 1
I got the sub-controls version working, including bi-directional. Math was right, might be pin updates or something with your module. I ended up modifying the Float Scaler2 example from the SDK examples because I have no idea how GUI modules work(this was my first GUI side module) and the Scaler2 example was close to what I wanted to do(too lazy to type, lol). My formula looks a bit different but it is actually 100% the same, just rearranged - no idea why I wrote it like that, just copy n pasted it from my audio module.
Feel free to use/modify code(I'm not releasing the module):
.h class TD_FloatRescaler : public MpGuiBase { public: TD_FloatRescaler( IMpUnknown* host );
private: void onSetValueOut(); void onSetValueIn();
FloatGuiPin valueOut; FloatGuiPin InLow; FloatGuiPin InHi; FloatGuiPin OutLow; FloatGuiPin OutHi; FloatGuiPin valueIn; };
float frescaler(float in_min, float in_max, float out_min, float out_max, float in) { if ((in_min-in_max) == 0.f) //avoid divide by zero return out_min; else return out_min + ((out_max-out_min) * ((in_min-in) / (in_min-in_max))); }
.cpp TD_FloatRescaler::TD_FloatRescaler( IMpUnknown* host ) : MpGuiBase(host) { // initialise pins. valueOut.initialize( this, 0, static_cast<MpGuiBaseMemberPtr>(&TD_FloatRescaler::onSetValueOut) ); InLow.initialize( this, 1, static_cast<MpGuiBaseMemberPtr>(&TD_FloatRescaler::onSetValueIn) ); InHi.initialize( this, 2, static_cast<MpGuiBaseMemberPtr>(&TD_FloatRescaler::onSetValueIn) ); OutLow.initialize( this, 3, static_cast<MpGuiBaseMemberPtr>(&TD_FloatRescaler::onSetValueIn) ); OutHi.initialize( this, 4, static_cast<MpGuiBaseMemberPtr>(&TD_FloatRescaler::onSetValueIn) ); valueIn.initialize( this, 5, static_cast<MpGuiBaseMemberPtr>(&TD_FloatRescaler::onSetValueIn) ); }
// handle pin updates. void TD_FloatRescaler::onSetValueOut() { valueIn = frescaler(OutLow,OutHi,InLow,InHi,valueOut); }
void TD_FloatRescaler::onSetValueIn() { valueOut = frescaler(InLow,InHi,OutLow,OutHi,valueIn); }
Cheers
|
|
|
Post by twoifbysea on May 30, 2018 18:20:19 GMT 1
Thank you guys for working on this!
|
|
|
Post by Rob on May 30, 2018 19:37:06 GMT 1
Andrew : Now it works here as well! Great, thanks a lot for helping out.. The SDK has changed a lot, I used to place a formula in every parameter pin so it would update properly. Now there is only void for input and output, and the parameter pins share the same void input. Dave, try it: Download ( testproject and SEMs ): rhmodules.nl/temp/SE/NewVersion_RH-Rescale2.zipCheers!
|
|
Andrew
Developer
Posts: 110
Posts: 110
|
Post by Andrew on May 30, 2018 20:13:15 GMT 1
Cool beans! Btw, you might wanna clip the in/out values to make it end-user proof i.e. if a user inputs +100 into that list, there might be issues.
|
|
|
Post by twoifbysea on May 30, 2018 20:46:16 GMT 1
Wow, thank you so much guys, it works great!
|
|