Samples and linear interpolation

Hello,

I’m attempting to implement a sampler from scratch (without using SamplerVoice, etc). I’m using a simple linear interpolator so the sample plays back at different pitch/rates when different notes are played.

Unfortunately, however, the pitch/rate shifting is creating a lot of high-frequency artifacts. I know that artifacts would be expected if I’m using a linear interpolator (as opposed to, say, sinc) and keeping the sample length the same, but my in my implementation playing lower/higher pitches will lengthen/shorten the sample playback also. E.g playing the sample an octave higher will half the total playback time.

Are these artifacts expected? If so, should I be using a filter to remove them?

I based my implementation on this and this.

Care to post some of your code?

You’d expect aliasing going up, and loss of high frequencies going down, but you would not expect artifacts which produce any sort of clicks, it should basically just sound like a record player

Ok the issue ended up being my how my samples were being loaded. It was loading L/R channels of the sample buffer sequentially into an audio buffer, which sounded fine if played an octave up (because it was skipping every other sample), but created terrible artifacts everywhere else.

In case someone else finds this question, I’ve put a simplified version of my interpolator below.

class PitchConverter {
public:
	float generate(float input) {
		while (x >= 1.0) {
			interpolator.next_sample(player.generate());
			x -= 1.0;
		}

		float output = interpolator.interpolate(x);
		x += ratio;
		return output;
	}
private:
	SamplePlayer player;
	Interpolator interpolator;
	float x;
	float ratio;
};

class Interpolator {
public:
	float next_sample(float input) {
		last = prev;
		prev = input;
	}

	float interpolate(float x) {
		return ((prev - last) * x) + last;
	}
private:
	float prev;
	float last;
};