Actually, I think I must be doing something wrong. Comparing recordings side by side the interpolated version has much less low end, whereas I’d be expecting it to be the other way, due to the high harmonics that were removed.

Gradius 3 SCC without interpolation

Gradius 3 SCC with linear interpolation

The interpolated one sounds cleaner without too much impact on the sound I think!

This time I took a different approach, in stead of interpolating on the fly (which had a bug), I increase the wavetable length from 32 to 512 samples with linear interpolation. Diff’s a bit bigger now so I won’t paste unless someone wants it.

Would probably also be nice to try proper upsampling, but I’d need to figure out the algorithm. Maybe calculate the FFT, pad it with zeroes, and then apply an inverse FFT?

(If the wave contains a sine at nyquist frequency, [ 127, -128, 127, -128, ... ], with proper upsampling it “should” produce a sine wave 5 octaves higher than the note played, however on SCC it will produce a square wave and with the linear interpolation it produces a triangle wave. Relatively close to the sine in terms of harmonics (it hasn’t much), but not quite there yet (none at all). Though the triangle may actually be a nice middle ground between authenticity and smoothness, as it has the same harmonic frequencies as the square, just attenuated.)

That does sound cleaner, quite interesting

I wonder what it would sound like with proper filtering instead of interpolation (maybe with a steep butterworth filter or something similar while also increasing accuracy to 16bit), although that could indeed lose some of it's authenticity.

*Grauw*wrote:

Would probably also be nice to try proper upsampling, but I’d need to figure out the algorithm. Maybe calculate the FFT, pad it with zeroes, and then apply an inverse FFT?

That's one (generally very good) possibility. An possible alternative is sinc-interpolation. The FFT approach has complexity O(n.log(n)), the sinc stuff is O(n^2), but n is small in this case.

Note that (unlike linear interpolation) the resulting sample values are not guaranteed to be inside the range [-128, 127]. So in some cases you'll introduce clipping.

Here you have a fixed SCC wavetable. But if you want an algorithm that works on a stream of audio data, you can look at the openMSX source code for some inspiration.

For fun, I've uploaded an mp3 of Nemesis 3 too, with drum samples:

http://www.gaga-play.com/test/nemesis-3.mp3

I've added 8x oversampling on the SCC (but no interpolation or anything).

About the interpolation, you'd probably want to increase the SCC's accuracy to 16 bit too when interpolating.

I'd be very interested to know the outcome of that with 'perfect' interpolation. I've got the feeling it might sound too clean, but maybe it'll just sound better :)

If it's too clean, it could even be an option to do it selectively; for example for certain waveforms that sound better all cleaned up, and leave the rest as they are.

Regarding the interpolation, it seems that sinc-interpolation is probably the way to go, interesting stuff!

Doing all that FFT+inverse FFT seems quite expensive to do on all channels; I wonder if it'd be worth it.

You only need to do it when the waveform changes, so that’s not too bad.

I think for an audio stream you can use a low pass filter, at least that’s what Wikipedia says. If I’m not mistaken (I’m still pretty new to signal processing), this can be implemented without FFT, using a simple IIR filter in stead.

@wouter Thanks for the pointers.

You can use a low-pass filter, but that'll also come with phase shifts, so I'm not sure how that will work out if you want to do that just once at wave changes; you should probably do that continuously on the streams.

I have a DSP project on SF with lots of DSP code that might be interesting for some code examples of filters and such:

https://sourceforge.net/projects/jmodsyn/

Most DSP specific code is here:

https://sourceforge.net/p/jmodsyn/code/HEAD/tree/trunk/ModSy...

The whole thing is basically a real-time modular software synthesizer (I actually use it sometimes in live performances), but while I don't pretend to be very good with DSP, I think there might be some useful code there if you're interested in DSP (but I'm sure there are better sources out there).

Here is an MSX-Music track from Greatest Driver with drums:

www.gaga-play.com/test/greatest-driver.mp3

*erikd*wrote:

You can use a low-pass filter, but that'll also come with phase shifts, so I'm not sure how that will work out if you want to do that just once at wave changes; you should probably do that continuously on the streams.

As long as the phase shifts are linear there's no problem. And for audio non-linear phase is often acceptable. FIR filters are relatively easy to make linear phase. For IIR filters it's much harder.

To resample a continuous audio stream in openMSX we offer two options, both are variations on (windowed-)sinc-interpolation. I didn't invent the algorithms myself, so see here for more details:

blip-buffer

Secret Rabbit Code