-
-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Problems with stereo playback at specific speeds #56
Comments
I'll have a quick look if I can find some time. yes sorry the interpolation code is horrific, I've been wanting to sort it out for a while, theres a few things wrong... the earlier versions of this library had a better approach for interpolation, there was an array containing the last 4 samples (per channel) which were sampled on a whole number... |
Hmmm ... I thought that was pretty much the current approach?! It just seems that the "last 4" are not managing to be the actual last 4, but have gaps in. Something to do with how you do the calculations with On the value getting, I did a fix putting in a protected function
and then using that everywhere |
By the way, thanks for (possibly!) taking time to have a look - much appreciated. And I forgot to say, the overflow protection code in |
https://github.com/newdigate/teensy-variable-playback/tree/fix/rate_two_and_a_half does that fix the issue? Edit: diff is here |
I think I just spotted something ... every other time through, |
Ah! yes its all coming back now... For interpolation, I used to store the X and Y values of the previous 4 samples, then I changed it to just the Y values... and the X values were hardcoded to 0,1,2,3. I think this issue was introduced then. Give me some time, I'll fix it. Thank you very much for your help and time! |
No worries, always a pleasure to help make something good even better! And thank you for giving of your valuable bandwidth.... |
@h4yn0nnym0u5e can you try this? I think the bad logic was if remaider was 0 then it was assuming there was no wholenumber jump. Sorry my brain is a bit broken. I'm hopeful this is an improvement.... Cheers. |
Better, in some small way, but still not right, I'm afraid. Lines like A good test case for this is a stereo file with radically different audio in the two channels - I crafted one with an up-sweep on one, and a reverse of that on the other. The other issue is this:
This puts in As an experiment I changed |
Hey @h4yn0nnym0u5e. Thanks for the testing/feedback/investigation. I've had another attempt to improve the interpolation (there is still a tiny error of the first 4 samples will be zero), but I think it works slightly better, now on this branch - If it works for you then I will try to fix the first 4 samples.... |
Not working for me, still :( I've been having a go myself, as your changes were helping me understand what is intended (I think...) - you might want to have a crack at this branch. I think I have interpolation working, and also repeat or pingpong looping with and without cross-fades. I've only tested on-screen using a single file (250ms stereo tone sweep, left rising and right falling), at ±2.5x. I'm hoping to try a wider range of settings tomorrow, using an oscilloscope. Is it intentional that there seems to be no way to set linear interpolation, just none or quadratic? |
I was able to reproduce the issue before, but I'm no longer able to reproduce now, using the fix/interpolation2 branch. The issue with the 2.5 x rate (and 1.5x, etc....) was that when the remainder was 0.0 (i,e. every second sample...), it was assuming there was no jump over a whole number. This is fine when the rate is < 1.0, but when rate = 2.5, it was not detecting the jump and not updating the interpolation buffer. So a better mechanism fixed that issue, storing the last sample index at which the interpolation buffer was updated (per channel). I tried processing a stereo sweep @ +2.5x with the left channel reversed.... Inspecting the output in audacity looks perfect. |
I think linear interpolation should be working, I just haven't enabled or tested it for years. It is there for reference and if somebody has a need to reduce the potentially heavy/broken quad interpolation |
looking at it..... linear interpolation has the same bug!!! doh! I don't think it'll work well with 1.5, 2.5, 1.25, very well... |
ops, sorry correction on line 504 ResamplingReader, should be: for(int i=0;i<8;i++) {
_numInterpolationPoints[i] = 0;
_lastInterpolationPosition[i] = _header_offset/_numChannels;
} it was... for(int i=0;i++;i<8)
_numInterpolationPoints[i] = 0; ....which makes no sense |
I have reverted all the changes locally, so I just have fix/interpolation2 branch, re-ran my 2.5 x tests and all seems fine to me... Unfortunately I'm running these tests on x86 cpu, not on a teensy - so the only thing I can say is that the algorithm now works on x86 for 2.5 x playback rate. I thinks its highly unlikely, but it could be a processor architecture issue. I might move the dual playback head to a different branch because It makes the interpolation code pretty messy... |
I've been having another play, and I think my confusion arises from leaving useDualPlaybackHead enabled - this breaks your branch pretty severely, though I know it wasn't on your radar right now. Observations:
On my branch I think I got all loop and dual playback working, though I completely re-wrote your crossfade start / stop logic because I simply couldn't fathom it, and it gets really weird if you were doing a crossfade on a pingpong loop, as the bufferPosition indexes are going in the opposite direction during the crossfade. I do need to do more testing, but would welcome any comments you might have. |
Its a bit of an experimental feature. The concept is easy, but it starts getting a bit tricky when doing the interpolation. Maybe one-day when Im inspired I will reimplement it. For the meantime, its going on a
goitcha. I had noticed the left and right channels were swapped but didnt know why. Thanks.
dual playback heads dont need to switch when doing a ping pong, no fade is required when the loop end is hit or the begging is hit, so maybe disable dualplayback head when ping ponging.... |
I'm finding pingpong not working at all, dual heads or not. I'm not 100% sure if cross-fading is unnecessary for pingpong: obviously the sample level is the same but the rate of change could reverse rapidly, which may give an audible click similar to a level change. For people tuning their loop points via a front panel control it might be worth leaving in / implementing. Very weird, I've just noticed my code puts in a glitch, in the left channel only, just after a pingpong reverse! (Without crossfade; with, it either doesn't happen or the crossfade has masked it). Most odd, have to fix that. |
Found the glitch - you've got it too... In ResamplingReader.h, line 173, we have If the read fails (because the loop is ended), then the |
ah! makes sense now. well spotted. thank you Johnathan! |
There appear to be issues with playing back stereo files at specific rates - I've tested 2.5x and 2.25x, but suspect it can be generalised to rates of the form N+1/(2^m) (N and m are integers).
There may be more than one issue here. I'm highly suspicious of, for example, ResamplingReader.h:359
_interpolationPoints[channel][3].y = getSourceBufferValue(_bufferPosition1-(i*_numChannels)+1+channel);
which looks suspiciously as if it's going to read data from the wrong channel - I did a quick fix of
_interpolationPoints[channel][3].y = getSourceBufferValue(_bufferPosition1-(i*_numChannels)+_numChannels+channel);
and the output was better, but not entirely fixed.
I think the main issue could be due to differences shuffling the interpolation values around - I've added a few lines to fill in the
x
member with the buffer position used to generate they
value, and got some weird results where values looked to be older than expected (I'd expect, for a stereo file, to getx
values of X, X-2, X-4 and X-6 - but I don't).Having said all that, I don't fully understand the code and there's a lot of repeats of "shuffle up the interpolation points and refill" with subtle differences, so I'd rather you have a look and do the thing properly, if possible! If I do it, I'm liable to leave a few cases untouched, or even more broken than before...
The text was updated successfully, but these errors were encountered: