# Adding velocity scaling to samples/patches without it (Spitfire Percussion related)



## bwherry (Apr 6, 2011)

Hi guys,

Like many of you I've recently purchased Spitfire Percussion and have fallen in love with many of the sounds. Especially the timpani. Yum. I love that so many round robin samples were recorded at each velocity level but as there's no velocity scaling (for timpani, snares, ... anyway) small changes in note velocity don't necessarily affect the output note volume/loudness. That is, note velocities from 0 to, say, 17 are all within the lowest velocity zone. So what you would expect (or want) to be a crescendo from note velocity 0 to note velocity 17 would actually produce what sounds like a constant velocity roll (all triggering samples in the same velocity zone). This was a slight problem for me in a recent cue I was working on where the timpani samples from velocity zone N were slightly too soft but those from velocity zone N+1 were slightly too loud. Dag nabit.

Are there good solutions to this problem? Yes, I could change the CC11 or CC7 but those would also affect whatever note may be ringing out (which would be especially problematic with Spitfire due to the gloriousness of the Air Studios Lyndhurst Hall sound).

I figure I can probably "normalize" (not sure that's the correct word in this context) all the velocity zones such that they all play at the same perceived loudness, then turn on velocity scaling for all the groups. But that seems a tad drastic, and I worry about sound quality degradation due to pumping something way up then bringing it way back down again (for the soft samples, anyway)... Is there a better way? If a certain zone has a velocity range, can I make the notes lower in that velocity range get attenuated a certain amount? And/or have the notes on the upper end of the velocity range get amplified a bit?

Any ideas are appreciated. Sorry if I rambled and none of this makes any sense! I've created a fair number of Kontakt instruments, but basically by choosing samples from some patches and moving them into others, changing the key ranges, velocity maps, etc. I haven't done any Kontakt scripting yet (although I really should, as I'm a software developer by day).

Thanks in advance!

Brian


----------



## bwherry (Aug 14, 2011)

Hi all,

I finally got around to trying a simple script to get some velocity scaling happening in some of the Spitfire percussion patches (below). The basic idea is that the top velocity value in each zone's velocity range should result in the sample being played back at the normal (unaffected) volume. A velocity value less than that but in the same velocity range (same zone) should have the volume of its resultant sample playback attenuated an amount such that the lowest velocity value in the zone's range is only barely louder than the loudest sample from the zone in the velocity range just below it. Make sense? It's a fairly wordy description, sorry. Anyway, the script:


```
on init
  declare $num_ranges := 7 { number of velocity ranges in the zones }
  declare $range_count { loop counter used later }
  declare $diff_from_max { used to hold an intermediate result later }
  { each set of two elements in array below holds the min/max velocity values for that velocity range }
  declare %range_values[14] := (1, 19, 20, 37, 38, 55, 56, 73, 74, 91, 92, 109, 110, 127)
  { each value below corresponds to the number of milli-dB attenuation per velocity value below max in that velocity range }
  declare %vol_scalings[7] := (-600, -250, -200, -250, -250, -300, -150)
end on

on note
  $range_count := 0
  while ($range_count < $num_ranges)
    if ($EVENT_VELOCITY >= %range_values[$range_count * 2] and $EVENT_VELOCITY <= %range_values[$range_count * 2 + 1])
      $diff_from_max := %range_values[$range_count * 2 + 1] - $EVENT_VELOCITY
      change_vol($EVENT_ID, $diff_from_max * %vol_scalings[$range_count], 0)
      { break? }
    end if
    inc($range_count)
  end while
end on
```

The script above is custom-tailored to the timpani (ringing out, not the muted ones). It will *NOT* work with any old patch - customization per instrument/patch is needed. More on that later. Anyway, there are seven velocity ranges of the zones within the different RR groups in the timpani patch:
1) 1 to 19
2) 20 to 37
3) 38 to 55
4) 56 to 73
5) 74 to 91
6) 92 to 109
7) 110 to 127

The number of velocity ranges is given in $num_ranges and the min/max velocities of the zones are stored in %range_values. Finally, the "volume scale amount" (in milli-dB) for each "velocity value below the max in the range" is given in %vol_scalings. The values in %vol_scalings will take some fiddling to get right for each instrument/patch. I arrived at these for the timpani (using just the tree mics). Note that I made the attenuation amount for the lowest range larger, so really small velocity values will be super quiet. Nice.

The same approach works for other instruments/patches, but as not all of them have seven velocity ranges of zones per note (some have four, some have eight, ...) some modification of the init function will be necessary. For instance, an instrument with only four velocity ranges of zones per note (celeste?), the init function would look something like this:


```
on init
  declare $num_ranges := 4 { number of velocity ranges in the zones }
  declare $range_count { loop counter used later }
  declare $diff_from_max { used to hold an intermediate result later }
  { each set of two elements in array below holds the min/max velocity values for that velocity range }
  declare %range_values[8] := (1, 30, 31, 61, 62, 93, 94, 127)
  { each value below corresponds to the number of milli-dB attenuation per velocity value below max in that velocity range }
  declare %vol_scalings[4] := (-600, -350, -250, -200)
end on
```

(and the "on note" callback would be the same)

Again, the min/max velocity values of the ranges would have to be set correctly (easily found in the mapping editor) and attenuation amounts chosen to taste. I've added this script to several of my customized Spitfire percussion patches with carefully chosen attenuation values and the results are really good. I can share the patches if anyone is interested.

Oh, caveats - use this code at your own risk, blah blah blah. Although I'm a professional software developer I'm fairly new to KSP, so there's likely a slicker way to do this sort of thing... (BTW, is there a way to break out of a while loop?)

Cheers!

Brian


----------



## Justus (Aug 15, 2011)

Yes, that's the only problem I have with Spitfire Percussion. The velocity curve could be smoother.


----------



## windshore (Aug 15, 2011)

I've run into the same issue with Mallet instruments and the Harp. I'm loving the sound of the Spitfire libs. but I end up back to tweaking velocities a lot... like I did 15 years ago with older sample libs. 

I'd love to see this kind of scripting added to their other libs!... Thanks for posting!


----------



## robh (Aug 15, 2011)

Have you tried the amplifier Mod velocity to volume?

If you have any of the Tonehammer percussion libraries, take a look under the hood of those. From the few different ones I checked out, none of the samples are normalized, and they use the amplifier mod velocity to volume set around 10% with a customized table. Seems much simpler than a script.

Rob


----------



## Big Bob (Aug 15, 2011)

> (BTW, is there a way to break out of a while loop?)



There are two ways that I know of to terminate a while loop prematurely. One of course is to alter the expression read by the while to force an exit. However, this will only cause an exit on the next attempted pass. The 2nd method would be to embed the code in a user function and then use the word 'exit'. Normally, exit causes the callback to terminate but when exit occurs within a user function, it causes the function itself to terminate.

Rejoice,

Bob

EDIT: Whoops! Just for kicks I ran a quick test of the exit function embedded in a user function and guess what? NI must have changed the way this used to work because now an embedded exit seems to terminate the hosting callback.

Sorry, but I guess that only leaves method 1 :cry:


----------



## Synesthesia (Aug 15, 2011)

robh @ Mon Aug 15 said:


> Have you tried the amplifier Mod velocity to volume?
> 
> If you have any of the Tonehammer percussion libraries, take a look under the hood of those. From the few different ones I checked out, none of the samples are normalized, and they use the amplifier mod velocity to volume set around 10% with a customized table. Seems much simpler than a script.
> 
> Rob



This is how we've been doing it as we work through updating the patches. It does need to be slightly different for each instrument, and some of them don't need it, but its the simplest way.

Although I love Brian's elegant scripted way of doing it too!


----------

