1

I'm trying to upsample 44100 Hz to 96000 Hz and I've tried this.

sum1 = mPastWavBuffer[(int)mOffset];
sum2 = mPastWavBuffer[(int)mOffset+1];
double sum = (sum1 + (sum2-sum1)) * (mOffset-(int)mOffset);

mOffset is a double value and contains the step factor incremented to move through the 44100 Hz sample file and make it 96000 Hz. This linear interpolation was taken from Wiki Linear Interpolation from two known points But this isn't giving me the result I want, it sounds terrible.

Am I using it wrong here or what am I supposed to do with this formula if this isn't the way to use it??

Regards, Morgan

Magnus
  • 379
  • 1
  • 15

1 Answers1

3

This is probably because linear interpolation isn't really what you want here. It might work reasonably well if you were just doubling the sample rate, but with a non-integer factor I would be surprised if you got good results.

I would suggest either trying a higher-order polynomial interpolation, or doing something in frequency-space (the first would be easier than the second).

EDIT: From the comments I also noticed that your sum calculation is off:

double sum = sum1 + (sum2-sum1) * (mOffset-(int)mOffset);

is what you want.

zebediah49
  • 7,467
  • 1
  • 33
  • 50
  • 1
    +1 for the edit. Your warnings about linear interpolation I think are a little too harsh when going to a higher rate. I haven't tried it but I'll bet you're unlikely to even notice it's not perfect. – Mark Ransom Nov 06 '13 at 21:21
  • I didn't think it would be that bad, apparently I was wrong. First order polynomial is linear interpolation, what order might be good, the fifth order? The biggest problem for me is to understand all the Greek signs in math, and that is all I can see when googling about it. – Magnus Nov 06 '13 at 22:13
  • @Mark that was exactly what I had in mind when going for the linear interpolation, that it shouldn't be much of a big fuzz. You think I might be doing something else wrong? Because the result I get is awful, really awful. – Magnus Nov 06 '13 at 22:17
  • The issue here is that when upsampling, a low-pass filter is required with cutoff (ideally brick-wall) at the Nyquiest limit of the original signal. Linear interpolation is in effect a 2-tap FIR, most likely with its cutoff in the wrong place and a lousy response. – marko Nov 06 '13 at 22:22
  • @marko I can understand and see what you mean that its cutoff will be in the wrong place in linear interpolation, accually I didn't know I had to do low pass on upsampling since the Nyquist limit is a dead cut serious cutout. – Magnus Nov 06 '13 at 23:06
  • @marko: let's assume the input is a sine at exactly Nyquist. The sampled signal will be `+x, -x, +x, -x` etc (and you have lost the analog amplitude). Interpolation will turn this into a triangle signal. Bad, but all resulting harmonics are at or above 22kHz and inaudible. Even if you did use a low-pass filter, why would you need a brick wall at 22 kHz? – MSalters Nov 06 '13 at 23:21
  • Beyond Fs is precisely where the first alias occurs. . – marko Nov 06 '13 at 23:22
  • @MSalters that is hypothetical case since it above the nyquist limit - which, remember, is the upper limit to the range of frequencies in a continuous signal that can be represented in a sampled system and reconstructed into an identical continuous signal. Take a look at (http://en.wikipedia.org/wiki/Aliasing)[http://en.wikipedia.org/wiki/Aliasing] - the theory behind this is a bit counterintuitive, and there is really no substitute for seeing the derivation from first principles. This is why DSP is hard. – marko Nov 06 '13 at 23:31
  • @marko: Don't worry, I do audio processing for a living. I might have misunderstood what you meant, in particular _when_ you'd filter. Math is easier than English :P – MSalters Nov 06 '13 at 23:37
  • @Morgan did you notice the difference in parentheses between this answer and your original? After you fix that does it still sound awful? – Mark Ransom Nov 07 '13 at 00:46
  • Yes I have made the changes to it, but still nothing was changed into something better sadly. Now I'm trying to implement cubic spline interpolation here and I've made some short tests against some samples and it seems to fit my needs, trying everything to get something better out of all this. I'm not a DSP hero just more like a DSP wannabe :) – Magnus Nov 07 '13 at 17:22
  • @MarkRansom but I can only make the cubic spline to work over a complete sample buffer at once, if I try to split it up for realtime use over sets of 3 samples at time it's not working. I'm using the Cubic.h c++ class in the end of this pdf file http://www.mcm.edu/mathdept/lynn_blair/thesis.pdf – Magnus Nov 07 '13 at 18:59
  • I made some new calculations on my linear interpolation and they are wrong! The way I've done it the waveform is worse than it should have been if it was done right. The result is the same as without interpolation but also lowering DB at samples, no wonder if I didn't get good results. I'll have to go back to the drawingboard again for awhile.. sigh – Magnus Nov 07 '13 at 20:02
  • 1
    @Morgan, I've done my own experiment to see how bad linear interpolation is and I can't hear the difference. The [sample](http://www.marksblog.com/share/440hz.wav) contains 2 seconds of a 440 hz tone at 44100hz sampling rate, the next 2 seconds is a 20258hz sampling interpolated to 44100hz (which is the same ratio as 44100 to 96000). The program I used to generate the sample is [wav.py](http://www.marksblog.com/share/wav.py.txt). Your problems seem to lie outside of the interpolation. – Mark Ransom Nov 13 '13 at 04:37
  • @MarkRansom I've found that the result of my interpolation is wrong, it's the way I'm reading the samples from the 44.1k and playing them in realtime 96k, because I'm getting duplicates in my new 96k buffer and sometimes a much lower DB on some samples. I made it even worse than it would be with proper interpolation. Thank you for the .py file, I'll look at this to see if I can find my failure. – Magnus Nov 17 '13 at 19:07