Help with [n-1] sample for interpolation
-
- KVRer
- 9 posts since 25 Jun, 2012
Hi there,
I'm trying to create a sampler using Hermite Interpolation and was wondering how to go about getting sample [n - 1] for the very first sample in the buffer i.e. x[0].
i'm new to dsp and have been pretty much blagging it up to this point, yet this has got me stumped!
Thanks in advance to anyone with any advice.
Cheers,
James
I'm trying to create a sampler using Hermite Interpolation and was wondering how to go about getting sample [n - 1] for the very first sample in the buffer i.e. x[0].
i'm new to dsp and have been pretty much blagging it up to this point, yet this has got me stumped!
Thanks in advance to anyone with any advice.
Cheers,
James
- KVRian
- 1091 posts since 8 Feb, 2012 from South - Africa
Hey James, think you should state for what the hermite interpolator is for/used in. If it's for a delay - you just add an extra read pointer. Check this link for some useful code: http://www.xoxos.net/sem/dsp2public.pdf
I highly recommend it - got me going in the right direction.
If you need a simple n-1 unit delay - as in what you'd use for filters - it might become a bit "what framework are you using" specific. I use the Synthedit SDK3 - if you want a unit-delay with it - you need to declare it first in the constructor - i.e in the .h file - say something like
Regards
Andrew
I highly recommend it - got me going in the right direction.
If you need a simple n-1 unit delay - as in what you'd use for filters - it might become a bit "what framework are you using" specific. I use the Synthedit SDK3 - if you want a unit-delay with it - you need to declare it first in the constructor - i.e in the .h file - say something like
Now, just use as normal.//in .h file
float sampledelay1;
//and then (initialize it!) in the .cpp file under
YourFunction::YourFunction( IMpUnknown* host ) : MpBase( host )
,sampledelay1(0.0f)
Regards
Andrew
-
- KVRAF
- 2460 posts since 3 Oct, 2002 from SF CA USA NA Earth
If you have a previous buffer in a stream to work with, then the last sample of that buffer would be the n-1 for the first sample in the current buffer. If you don't have a previous buffer, it's usually best to pretend the previous value was 0.JSMilton wrote:I'm trying to create a sampler using Hermite Interpolation and was wondering how to go about getting sample [n - 1] for the very first sample in the buffer i.e. x[0].
- KVRAF
- 9590 posts since 17 Sep, 2002 from Gothenburg Sweden
Ichad.c wrote:Hey James, think you should state for what the hermite interpolator is for/used in.
It would depend me thinks. If i were to make a sample based oscillator i would take the last sample (x[length-1]).JSMilton wrote:I'm trying to create a sampler
If it were just straight playback i'd just set it to zero and see what happens. Most likely nothing bad so it's probably the easiest solution. At least the easiest one i can think of.
-
- KVRer
- Topic Starter
- 9 posts since 25 Jun, 2012
Hey guys,
Thanks for the replies!
I plugged the hermite in with n-1 set to 0 for the first sample. it works really well for most audio files (16 bit wav, 44100), except some have a lot of crackling sound at the start of playback. if the sample is longer than about 1 second the crackling eventually dies away and playback is normal. this only happens when the sample is lowered below the original sample rate (played lower than the root). higher up its fine.
when using a techno drum loop sample, this doesn't happen. it does when i use a live recording of a ukelele.
if i'm just playing through the original buffer at different speeds, do i need any anti alias filter? could this be the problem?
i should mention that this is for an iPad app that allows the user to load one sample and map it to a key range for playback.
heres the code i'm using for the interpolation. the audio is being processed in blocks of 1024 frames at a time for the output buffer.
Anyway thanks again. It's good to get some advice, as this stuff makes my head swim!
Thanks for the replies!
I plugged the hermite in with n-1 set to 0 for the first sample. it works really well for most audio files (16 bit wav, 44100), except some have a lot of crackling sound at the start of playback. if the sample is longer than about 1 second the crackling eventually dies away and playback is normal. this only happens when the sample is lowered below the original sample rate (played lower than the root). higher up its fine.
when using a techno drum loop sample, this doesn't happen. it does when i use a live recording of a ukelele.
if i'm just playing through the original buffer at different speeds, do i need any anti alias filter? could this be the problem?
i should mention that this is for an iPad app that allows the user to load one sample and map it to a key range for playback.
heres the code i'm using for the interpolation. the audio is being processed in blocks of 1024 frames at a time for the output buffer.
Code: Select all
int index = (int)sampleNumber;
float frac_pos = sampleNumber - index;
float xm1;
float x0 = inBuffer[index];
float x1;
float x2;
if(index + 1 > frameTotalForSound)x1 = 0;
else x1 = inBuffer[index + 1];
if(index + 2 > frameTotalForSound)x1 = 0;
else x2 = inBuffer[index + 2];
if(index == 0)xm1 = 0;
else xm1 = inBuffer[index - 1];
float c = (x1 - xm1) * 0.5f;
float v = x0 - x1;
float w = c + v;
float a = w + v + (x2 - x0) * 0.5f;
float b_neg = w + a;
outBuffer[frameNumber] = ((((a*frac_pos) - b_neg)*frac_pos + c)*frac_pos + x0);
sampleNumber += ratio;
- KVRAF
- 9590 posts since 17 Sep, 2002 from Gothenburg Sweden
That's odd,if anything you would get a click on a single sample (the first one) and that should hardly be audible. I can't see any obvious faults in your code however without the whole deal it's hard to say.
-
- KVRer
- Topic Starter
- 9 posts since 25 Jun, 2012
yeh i think there must be a problem with another part of the callback. i even tried 2 alternate interpolators (linear and optimal) and got the same results. i also loaded the problematic audio into Nano Studio's sampler and that managed to pitched it up and down with no problems.
i'll let you know if i find anything.
thanks again!
i'll let you know if i find anything.
thanks again!
-
- KVRist
- 205 posts since 12 Feb, 2009 from Perú
I don't know a thing about this kind of interpolation. However, this looks suspicious:
Should'nt that lines read:
?
Of course this would cause trouble at the end of the audio file, not at the beginning.
Code: Select all
if(index + 2 > frameTotalForSound)x1 = 0;
else x2 = inBuffer[index + 2];Code: Select all
if(index + 2 > frameTotalForSound)x2 = 0;
else x2 = inBuffer[index + 2];?
Of course this would cause trouble at the end of the audio file, not at the beginning.
-
- KVRer
- Topic Starter
- 9 posts since 25 Jun, 2012
solved it.
i was being an idiot
i was using apples Mixer Host code as a template for the callback. i forgot that the sample number was being stored as an unsigned int instead of a float, so obviously the fractional part was being lost between callbacks. changed it to a float and everything is fine.
sorry for the confusion.
thanks for all the replies to the original question and the follow up, really cool forum here.
Cheers,
James
i was being an idiot
i was using apples Mixer Host code as a template for the callback. i forgot that the sample number was being stored as an unsigned int instead of a float, so obviously the fractional part was being lost between callbacks. changed it to a float and everything is fine.
sorry for the confusion.
thanks for all the replies to the original question and the follow up, really cool forum here.
Cheers,
James
- KVRAF
- 9590 posts since 17 Sep, 2002 from Gothenburg Sweden
Don't beat yourself up becauseJSMilton wrote:solved it.
i was being an idiot![]()
1. There will be more moments like these. Many,many more....
2. Not making any mistakes is only the second most important thing for a programmer. The most important is finding faults. And you seem to have a knack for it.
Not completely sure what's going on here but i would have a separate variable for the current position. That's all you're really interested in,not the number of samples that has occurred since <something>.JSMilton wrote: i was using apples Mixer Host code as a template for the callback. i forgot that the sample number was being stored as an unsigned int instead of a float, so obviously the fractional part was being lost between callbacks. changed it to a float and everything is fine.
-
- KVRer
- Topic Starter
- 9 posts since 25 Jun, 2012
really starting to understand this! when i first started getting into all this i would solve a problem then think "thats it! plain sailing from here". boy was i wrong.There will be more moments like these. Many,many more....
Not completely sure what's going on here but i would have a separate variable for the current position. That's all you're really interested in,not the number of samples that has occurred since <something>.
i think im doing it the way you say. basically each audio file has a struct that contains it's data i.e. root note, key range, pointer to the buffer data etc.. as well as the current sample number. this struct is passed into the callback each time its called, which is once 1024 frames have been filled for the output buffer. the callback then effectively resets, so before it finishes the current sample number is stored in the struct, so that the callback can pick up where it left off from next time around.
i hope thats how it works anyway
or am i missing the point?
cheers,
- KVRist
- 92 posts since 24 Jan, 2012
I don't know your specific needs, but I use an herrmite interpolation method and can't you just substitute
n-1
n
n+1
n+2
with
n
n+1
n+2
n+3
I use that for sample playing. If you extend your sample of 4 samples, by copying the first 4 samples into the last 4 samples you'll avoid to face array bounds problems.
I use one of the implementations found here (modified to work in paralled with SIMD instructions):
http://musicdsp.org/showArchiveComment.php?ArchiveID=93
Paolo
n-1
n
n+1
n+2
with
n
n+1
n+2
n+3
I use that for sample playing. If you extend your sample of 4 samples, by copying the first 4 samples into the last 4 samples you'll avoid to face array bounds problems.
I use one of the implementations found here (modified to work in paralled with SIMD instructions):
http://musicdsp.org/showArchiveComment.php?ArchiveID=93
Paolo
-
- KVRer
- Topic Starter
- 9 posts since 25 Jun, 2012
Hey Paolo,
I actually just set [n - 1] to 0 for the first sample and it sounds fine. I'm also using the same code from the link you posted. the musicdsp archive is a godsend!
cheers,
James
I actually just set [n - 1] to 0 for the first sample and it sounds fine. I'm also using the same code from the link you posted. the musicdsp archive is a godsend!
cheers,
James
- KVRist
- 92 posts since 24 Jan, 2012
I'm absolutely no math expert but to me that 0 thing sounds like a little lowpass effect. Have you tried how it sounds with high frequency material?

