# Change_tune relative bit bug - any solution?



## Andrew Aversa (Oct 18, 2012)

I'm working on implementing a custom pitch bend function in a particular script. Essentially it functions like this:

$i contains an event ID.

On controller checks for CC 11. If it has been moved, it runs the following:

change_tune($i,(%CC[11] * 1574),0)

The idea here is to bend the pitch of $i up to a range of approximately 200k millicents, or one whole note. This MOSTLY works. However, it's buggy. Sometimes, at pure random when moving the CC11 knob up and down, you can end up BELOW the original pitch, or beyond the theoretical max of one whole note. Sometimes the minimum pitch ends up higher than the original pitch.

It just isn't reliable... in Kontakt 4 or 5. Has anyone encountered this problem using a relative bit of 0 and MIDI control? Is there a solution or is this just an unavoidable Kontakt bug? I don't understand how it could ever end up BELOW the original pitch with a relative bit of 0.


----------



## mk282 (Oct 19, 2012)

Are you using $i elsewhere? Try having a dedicated variable for this. ($i is in 99.99% of cases just used as a counter for while loops, at least from my practice )


Also, I presume that $i is not a polyphonic variable? You might need this (however you won't be able to change this outside of NCB/RCB). Or rather, have an array of 128 indices that will pick up IDs for each key, then deal with that.


----------



## Andrew Aversa (Oct 19, 2012)

Well, that was just a simplification. In the actual script I use a unique variable to store the event, so it isn't a problem with the script not tuning the wrong event.


----------



## polypx (Oct 19, 2012)

I think mk's point is that you need to account for polyphony somehow.

Maybe like this?


```
on init
declare $i
declare %notes[127]
end on

on note
%notes[$EVENT_NOTE] := $EVENT_ID
change_tune(%notes[$EVENT_NOTE],(%CC[1] * 1574),0) 
end on

on controller
$i := 0
while ($i < 127)
change_tune(%notes[$i],(%CC[11] * 1574),0) 
inc($i)
end while
end on
```


----------



## Andrew Aversa (Oct 19, 2012)

Well, we're only dealing with one voice at a time and one note at a time. This is in a MUCH larger context but there is literally only one note, and one event ID, at a time that can possibly be re-tuned. 

I encourage you to try this script with a MIDI controller for yourself and see if it works. You will see and hear the same problem I'm describing.

HOWEVER! After some browsing, a Big Bob post inspired the idea of trying set_event_par to change tuning, as opposed to change_tune. And THIS apparently works properly! I will have to test it further, but it definitely seems to get the job done.


----------



## Alesis (Jun 26, 2017)

I feel like I'm getting a similar bug. I'm trying to script my own pitch bend using change_tune, and scaling the positive VCC_PITCH_BEND value to change tune by up to one octave (1200000). 

Using the script below, any time my scaled pitch bend value reaches about 256000, it jumps down to about -248000 then climbs until it repeats that process, never reaching 1200000. I'm expecting to hear a smooth pitch bend up one octave but instead am getting a bipolar saw pattern. I get the same result when using set_event_par(). Any idea why this is? 


```
on init
  declare $pitchBendMax := 1200000
  declare $note_id
  declare $detune
end on

on note
  $note_id := $EVENT_ID
end on

on controller
  if ($CC_NUM=$VCC_PITCH_BEND)
    ignore_controller
    $detune := (%CC[$CC_NUM]*$pitchBendMax)/8191
    message($detune)
    change_tune($note_id,$detune,0)
  end if
end on
```


----------



## Alesis (Jun 26, 2017)

I found a snippet by Nils on the NI forums that works, although I'm still not entirely sure why this method of scaling works and my previous one didn't:


```
{ A script by Nils L that expands the pitch-bend range }
on init
  declare $tune
  declare ui_knob $Range(1*1000, 50*1000, 1000)
  make_persistent($Range)
end on

on note
  change_tune($EVENT_ID, $tune, 0)
end on

on controller
  if ($CC_NUM = $VCC_PITCH_BEND)
    ignore_controller
    $tune := %CC[$VCC_PITCH_BEND]*$Range/80
    change_tune($ALL_EVENTS, $tune, 0)
  end if
end on
```


----------



## andreasOL (Jun 28, 2017)

Alesis said:


> I feel like I'm getting a similar bug. I'm trying to script my own pitch bend using change_tune, and scaling the positive VCC_PITCH_BEND value to change tune by up to one octave (1200000).
> 
> Using the script below, any time my scaled pitch bend value reaches about 256000, it jumps down to about -248000 then climbs until it repeats that process, never reaching 1200000. I'm expecting to hear a smooth pitch bend up one octave but instead am getting a bipolar saw pattern. I get the same result when using set_event_par(). Any idea why this is?
> 
> ...



Kontakt uses 32bit integer arithmetics which goes from -‭21474836478 to ‭2147483647‬

For pitchbend that goes from -8192 to 8191 you exceed this range by multiplying with 1200000
You reach the limit at a pb value of 1790 (1790*1200000=2148000000).

As there's no exception handling or the like the calculation still gives _some_ result which suddenly has bit 31 set which makes it negative so the value of $detune jumps from a positive value to a negative value and then it all starts again.

Instead of using 8191 I would use 8192 and then reduce the fraction to something like 150000/1024, i.e.


```
declare const $pitchBendMax := 1200000
  declare const $pitchBendMax_8 := $pitchBendMax/8
  .
  .
  .
  $detune := (%CC[$CC_NUM]*$pitchBendMax_8)/1024
```

It's good to always keep an eye on the range of intermediate results when multiplying values.


----------

