Program Change for roland FA and other external devices


Hi guys
I created this script to make me more friendly to sending PC to Roland FA keyboard and other external devices.

Roland performance user presets are 512.

MSB 85, LSB 0, PC 0-127 for presets from 1 to 128
MSB 85, LSB 1, PC 0-127 for presets from 129 to 256
MSB 85, LSB 2, PC 0-127 for presets from 257 to 384
MSB 85, LSB 3, PC 0-127 for presets from 385 to 512

So, if you want to load, for example, the preset number 200 to the Roland FA you must to send PC 71 with MSB 85 and LSB 1.
With this script, if you slide on “Presets Range Roland” it sets automatically the LSB value from 0 to 3 and the corresponding label of PC widget from 1 to 512…so you can see the number of the Roland preset …The labels of the PC widgets (Roland and MODX) are set to display the value from 1 to 128 but the real value trasmitted is on the midi range of 0-127.
PC, MSB and LSB widgets are assigned by script.
Delay widgets are assigned to parameter “delay” of Scriptlet blocks.
Minimum delay is set to 20ms, in this way you are sure that the PC will be sent after the MSB and LSB.
If you have any advice to improve the code you are welcome :grinning:

here the code:

var
active    : boolean = false
//Yamaha
y_val     : integer
prev_y    : double
val_pot_Y : integer
prevlsby  : integer
prevmsby  : integer
lsby      : integer
msby      : integer
//Roland
r_val     : integer
prev_r    : integer
sel_val   : integer
prevlsbr  : integer
prevmsbr  : integer
lsbr      : integer
msbr      : integer
//Selector
lab       : double
lab_val   : integer

pc_r, lsb_r, msb_r, sel, pc_y, lsb_y, msb_y : Widget
R_gp, Y_gp : MidiInBlock
Rout, Yout : MidiOutBlock

Function sendPCr()
 if active then
 SendNow(R_gp, MakeProgramChangeMessage(ParamToMidi(GetWidgetValue(pc_r))))
 prev_r=ParamToMidi(GetWidgetValue(pc_r))
 end
End

Function sendPCy()
 if active then
 SendNow(Y_gp, MakeProgramChangeMessage(ParamToMidi(GetWidgetValue(pc_y))))
 prev_y=ParamToMidi(GetWidgetValue(pc_y))
 end
End

Function sendBKr()
      msbr=ParamToMidi(GetWidgetValue(msb_r))
      lsbr=ParamToMidi(GetWidgetValue(lsb_r))
      if active then
      SendNowExternal(Rout, MakeControlChangeMessage(0,msbr));      
      SendNowExternal(Rout,MakeControlChangeMessage(32, lsbr));
      prevmsbr = msbr;
      prevlsbr = lsbr;
      end
End

Function sendBKy()
      msby=ParamToMidi(GetWidgetValue(msb_y))
      lsby=ParamToMidi(GetWidgetValue(lsb_y))
      if active then
      SendNowExternal(Yout, MakeControlChangeMessage(0,msby));      
      SendNowExternal(Yout,MakeControlChangeMessage(32, lsby));
      prevmsby = msby;
      prevlsby = lsby;
      end
End
On activate
 active=true // to prevent double messages
 //Roland PC + Bank
 sendBKr()
 sendPCr()

 // Yamaha PC + Bank     
 sendBKy()
 sendPCy()

End
//LSB roland
On WidgetValueChanged(val : double) from lsb_r
 lsbr=ParamToMidi(val)
 SetWidgetLabel(lsb_r, ParamToMidi(GetWidgetValue(lsb_r)))
 if prevlsbr != lsbr && prevmsbr == msbr then
 sendBKr()
 sendPCr()
 end
End
//MSB Roland
On WidgetValueChanged(val : double) from msb_r
 msbr=ParamToMidi(val)
 SetWidgetLabel(msb_r, ParamToMidi(GetWidgetValue(msb_r)))
 if prevmsbr != msbr && prevlsbr == lsbr then
 sendBKr()
 sendPCr()
 end
End

//LSB Yamaha
On WidgetValueChanged(val : double) from lsb_y
 lsby=ParamToMidi(val)
 SetWidgetLabel(lsb_y, ParamToMidi(GetWidgetValue(lsb_y)))
 if prevlsby != lsby && prevmsby == msby then
 sendBKy()
 sendPCy()
 end
End
//MSB Yamaha
On WidgetValueChanged(val : double) from msb_y
 msby=ParamToMidi(val)
 SetWidgetLabel(msb_y, ParamToMidi(GetWidgetValue(msb_y)))
 if prevmsby != msby && prevlsby == lsby then
 sendBKy()
 sendPCy()
 end
End

//PC Roland
On WidgetValueChanged(val : double) from pc_r
 r_val = ParamToMidi(val)

 select
 sel_val==0 do
 SetWidgetLabel(pc_r, r_val+1)
 sel_val==1 do
 SetWidgetLabel(pc_r, r_val+129)
 sel_val==2 do
 SetWidgetLabel(pc_r, r_val+257)
 sel_val==3 do
 SetWidgetLabel(pc_r, r_val+385)
 
 end
  if prev_r != r_val  then
  sendPCr()
  end
End 
  
// PC Yamaha
On WidgetValueChanged(val : double) from pc_y
 val_pot_Y = ScaleRange(val, 1, 128)
 SetWidgetLabel(pc_y, val_pot_Y)
 if prev_y != ParamToMidi(val) then
 sendPCy()
 end
End

//selector preset
On WidgetValueChanged(val : double) from sel
sel_val = ScaleRange(val, 0, 3)
 
 select
  sel_val==0 do
  SetWidgetValue(lsb_r, 0.00)
  lab = GetWidgetValue(pc_r)
  lab_val = ParamToMidi(lab)
  SetWidgetLabel(pc_r, lab_val+1) 
  sel_val == 1 do
  SetWidgetValue(lsb_r, 0.01)
  lab = GetWidgetValue(pc_r)
  lab_val = ParamToMidi(lab)
  SetWidgetLabel(pc_r, lab_val+129)
  sel_val == 2 do
  SetWidgetValue(lsb_r, 0.018)
  lab = GetWidgetValue(pc_r)
  lab_val = ParamToMidi(lab)
  SetWidgetLabel(pc_r, lab_val+257)
  sel_val == 3 do
  SetWidgetValue(lsb_r, 0.025)
  lab = GetWidgetValue(pc_r)
  lab_val = ParamToMidi(lab)
  SetWidgetLabel(pc_r, lab_val+385)  
 end
End

On Deactivate
active=false
End

PresetsFA.gig (357.7 KB)

4 Likes

You are not the first to have this kind of needs… :wink:

1 Like

Yes @David-san, I read it a while ago when I was not yet a member of the community, and I think you did a really good job :+1: In the meantime I wanted to try to create one myself and I thought it might be of interest to something alternative with target on roland FA users. I hope it didn’t bother you and if I did I apologize :pray:

Of course not, don’t apologize, we are happy to have one more GPScripter in the community. :wink::+1:

2 Likes