Sending OSC values as Doubles Instead of Floats

Hello,

I’m developing a GUI for my GP rig + its instances with OpenStageControl. In order to sync OpenStageControl on patch changes, I wrote a script that sends the values of widgets in my Global Rackspace to OpenStageControl (to be triggered song, variation changes, etc).

Unfortunately, floats are not precise enough to correctly trigger dropdown menus in OpenStageControl (ie a 0.96 float translates to 0.9599999785423279).

How can I send widget values as Doubles instead of Floats over OSC with GPScript?

Thanks!

var
NeveBypass, NeveGUI, NeveGain, NeveMic, NeveLowFreq, NeveLow, NevePresFreq, NevePres, NeveHigh, NeveHPF, NeveOutput, 
SatBypass, SatGUI, SatBands, SatIn, SatOut, SatMix, SatDrive1, SatFBFreq1, SatFeedbck1, SatTyp1, SatBass1, SatMid1, SatTreb1, SatDyn1, SatPres1, SatLvl1, SatState1, SatEnabld1, SatMix1, SatDrive2, SatFBFreq2, SatFeedbck2, SatTyp2, SatBass2, SatXOvrFreq2, SatMid2, SatXOvrSlope2, SatTreb2, SatDyn2, SatPres2, SatLvl2, SatState2, SatEnabld2, SatMix2, SatDrive3, SatFBFreq3, SatFeedbck3, SatTyp3, SatBass3, SatXOvrFreq3, SatMid3, SatXOvrSlope3, SatTreb3, SatDyn3, SatPres3, SatLvl3, SatState3, SatEnabld3, SatMix3,
FETBypass, FETGUI, FETInput, FETOutput, FETAttack, FETRelease, FETRatio, LA2ABypass, LA2AGUI, LA2AGain, LA2ALimit, LA2APeak,
EQPBypass, EQPGUI, EQPBoostLow, EQPCPS, EQPAttenLow, EQPBandwidth, EQPBoostHigh, EQPKCS, EQPAttenHigh, EQPAttenSel, EQPOutput,
DelayBypass, DelayGUI, DelayMix, DelayMode, DelayStyle, DelayEra, DelayL, DelayR, DelayLSync, DelayRepeatSwell, DelayRSync, TapA, TapB, TapC, TapD, DelayFeedback, DelayWidth, DelayDrive, DelayAge, DelayDiff, DelaySize, DelayWow, DelayFlutter, DelayHigh, DelayLow,
ReverbBypass, ReverbGUI, ReverbMode, ReverbMix, ReverbColor, ReverbPreDelay, ReverbDecay, ReverbHighFreq, ReverbHighShelf, ReverbBassXover, ReverbBassMult, ReverbSize, ReverbAttack, ReverbEarly, ReverbLate, ReverbRate, ReverbDepth, ReverbHighCut, ReverbLowCut, PhaseBypass, PhaseGUI, PhaseSpeed, PhaseIn, PhaseOut, PhaseMix, PhaseP45, PhaseVintage, PhaseSync,
DubBypass, DubGUI, DubInput, DubDryWet, DubMode, DubBass, DubTreb, DubRevVol, DubRevPan, DubRate, DubFeedback, DubDelVol, DubDelPan, DubHPF, DubLPF, DubDucking, DubStereoRev, DubFXFeed, DubNoise, DubTapeAge, DubSync, DubHead1, DubHead2, DubHead3: widget

WidgetArray : widget array

Initialization
WidgetArray = [NeveBypass, NeveGUI, NeveGain, NeveMic, NeveLowFreq, NeveLow, NevePresFreq, NevePres, NeveHigh, NeveHPF, NeveOutput, 
SatBypass, SatGUI, SatBands, SatIn, SatOut, SatMix, SatDrive1, SatFBFreq1, SatFeedbck1, SatTyp1, SatBass1, SatMid1, SatTreb1, SatDyn1, SatPres1, SatLvl1, SatState1, SatEnabld1, SatMix1, SatDrive2, SatFBFreq2, SatFeedbck2, SatTyp2, SatBass2, SatXOvrFreq2, SatMid2, SatXOvrSlope2, SatTreb2, SatDyn2, SatPres2, SatLvl2, SatState2, SatEnabld2, SatMix2, SatDrive3, SatFBFreq3, SatFeedbck3, SatTyp3, SatBass3, SatXOvrFreq3, SatMid3, SatXOvrSlope3, SatTreb3, SatDyn3, SatPres3, SatLvl3, SatState3, SatEnabld3, SatMix3,
FETBypass, FETGUI, FETInput, FETOutput, FETAttack, FETRelease, FETRatio, LA2ABypass, LA2AGUI, LA2AGain, LA2ALimit, LA2APeak,
EQPBypass, EQPGUI, EQPBoostLow, EQPCPS, EQPAttenLow, EQPBandwidth, EQPBoostHigh, EQPKCS, EQPAttenHigh, EQPAttenSel, EQPOutput,
DelayBypass, DelayGUI, DelayMix, DelayMode, DelayStyle, DelayEra, DelayL, DelayR, DelayLSync, DelayRepeatSwell, DelayRSync, TapA, TapB, TapC, TapD, DelayFeedback, DelayWidth, DelayDrive, DelayAge, DelayDiff, DelaySize, DelayWow, DelayFlutter, DelayHigh, DelayLow,
ReverbBypass, ReverbGUI, ReverbMode, ReverbMix, ReverbColor, ReverbPreDelay, ReverbDecay, ReverbHighFreq, ReverbHighShelf, ReverbBassXover, ReverbBassMult, ReverbSize, ReverbAttack, ReverbEarly, ReverbLate, ReverbRate, ReverbDepth, ReverbHighCut, ReverbLowCut, PhaseBypass, PhaseGUI, PhaseSpeed, PhaseIn, PhaseOut, PhaseMix, PhaseP45, PhaseVintage, PhaseSync,
DubBypass, DubGUI, DubInput, DubDryWet, DubMode, DubBass, DubTreb, DubRevVol, DubRevPan, DubRate, DubFeedback, DubDelVol, DubDelPan, DubHPF, DubLPF, DubDucking, DubStereoRev, DubFXFeed, DubNoise, DubTapeAge, DubSync, DubHead1, DubHead2, DubHead3]
End

On OSCMessageReceived(message : OSCMessage) Matching "/WidgetSync"

var x : integer
    WidgetValue : double
    WidgetName : string
    WidgetAddress : string
    OSCWidgetSync : OSCMessage
    
For x=0 ; x<Size(WidgetArray) ; x=x+1 Do 

   WidgetName = GetWidgetScriptName(WidgetArray[x])
   WidgetValue = GetWidgetValue(WidgetArray[x])
   WidgetAddress = "/Bubble" + WidgetName + "/SetValue"
   
   OSC_SetAddress(OSCWidgetSync, WidgetAddress)
   OSC_ClearArgs(OSCWidgetSync)
   OSC_AppendDoubleArg(OSCWidgetSync, WidgetValue)

   OSC_SendSpecific(OSCWidgetSync, "127.0.0.1", 8080)
   OSC_SendSpecific(OSCWidgetSync, "127.0.0.1", 9018)
   
   Print("WidgetSync'd")
End
End

I apologize, I believe I was reading old documentation. I found some functions that should do the trick:

OSC_SendDouble and OSC_SendDoubleSpecific

I’ll give it a shot when I’m back in the studio. Leaving this up for reference.

It is quite easy to help you as you find the right answer by yourself :wink:

1 Like

Unfortunately, in the current version, those doubles actually get converted to floats.

Hmm…I think I found a workaround in OpenStageControl. I can send floats from GP to a variable in openstagecontrol, and then have that variable duplicate that OSC message with OSC typetag “d” selected in the variable’s OSC properties. I’ll let you know if this works.

Luckily, it’s only for a few widgets. A few dropdowns and labeled switches. The rest of the knobs/sliders work just fine.

Many years ago I worked for a company that made the first capturing protocol analyzers; long since disrupted by what is now WireShark.

The head of engineering had a mug on his desk that said “DEATH TO FLOATING POINT”

2 Likes

Spent way too long trying to primp the float with translations and applied logic but instead found a workaround where a variable uses an if/else to trigger a hard-coded double when a float triggers its number range. Not elegant, but it does the trick.

if (value < 0.03) {
set('ChoirSaturnType3', 0)
}

else if (value < 0.07) {
set('ChoirSaturnType3', 0.04)
}

else if (value < 0.10) {
set('ChoirSaturnType3', 0.07)
} etc...