Request: Bit-depth Interpolation

I’d like to request a script that interpolates a waveform of arbitrary bit depth into the track’s format (32-bit float, 24-bit PCM, 16-bit PCM, or just 32-bit float and give an error if the track isn’t 32-bit float if that makes it easier) by using the point of change between groups of samples with the same value as points to interpolate. It seems as though there’s enough data to take a bitcrunched sine wave and return a clean sine wave.

It should be able to work with user-chosen assumptions that the value changes as if the original signal was floored to 8-bit, or as if it was rounded.

With floored it should use the first sample with a new value if the slope is positive, and the last sample of a new value if the slope is negative.
With rounded it should use the middle of each area with a constant value.

Audacity’s unsigned 8-bit seemed to be floored and the u-law output seems to be rounded in the waveforms. I reckon these two methods cover everything that would be used, unless something uses floor for positive and ceiling for negative. I’m not sure if that would need something else or if it would be used at all.

There should be an option to detect dithering, which as best as I can imagine would detect regions that go ±± every sample with a change of only 1 unit and treat that region as a solid area with a value of the (min+max)*0.5.

This would be useful for uncrunching retro sounds from games or drum samplers or any other low bit-depth sound.

I don’t think that is possible for anything other than extremely low frequencies.

In the case of extremely low frequencies, we will see a “staircase” type effect, as shown in your “bit-crunch sine” image. In this case, we could interpolate from one 8-bit value to the next. However for higher frequencies and/or more complex waveforms, there is no such “staircase” and sequential samples with the same 8-bit value will be extremely rare. For example, here’s a section of some music. The first track is 32-bit float, the second track is 8-bit, and the third track shows the difference between the two tracks (zoomed in very close). Notice how the third track appears to be random.


If this wasn’t the case, then CD’s could have been made with 8-bit audio data, which would double the capacity, and we could simply process the audio to eliminate the quantization noise by interpolating 16-bit values from the 8-bit data. Unsurprisingly, that does not work.

This is all true, but I do still have tonal / bassy drum sounds that could benefit from having their bassy elements de-crunched, if nothing else.

Have you tried Eq’ing it?

Yeah, but the bitcrush distortion shares frequency ranges with other intended / desireable sounds so it doesn’t really help.

You’re welcome to play with this code - it basically does what you originally requested and interpolates between sample values whenever the value changes. Note that this code will only work on short, mono selections. The code may be run in the “Nyquist Prompt” effect (

;version 4
;type process

(setf dur (get-duration 1))
(setf val0 (snd-fetch (snd-copy *track*)))
(setf deltas (list val0))
(setf dt (/ 20.0 *sound-srate*))
(setf oldval val0)
(do ((val (snd-fetch *track*)(snd-fetch *track*))
     (i dt (+ i dt)))
    ((not val))
   (when (/= val oldval)
      (push i deltas)
      (push val deltas)
      (setf oldval val)))

(push dur deltas)
(push oldval deltas)
(abs-env (pwlv-list (reverse deltas)))

This really cleans up the crunchy kick drums of a few drum machines, thanks.