Possibly improve Nearest Neighbor filter

Started by PiotrGrochowski, September 11, 2017, 09:46:46

Previous topic - Next topic

PiotrGrochowski

That's because the current "No Interpolation" filter is simply wrong.

manx

"No interpolation" is strictly speaking mathematically wrong already by the very definition of what it does. The only remaining sensible goal is to make it fast. The implementation you request would require an unbounded amount of processing time and an unbounded amount of memory (the symbolic fractions could grow arbitrarily large in case of continuing pitch changes). This makes no sense whatsoever.

PiotrGrochowski

#17
Why 64-bit floating point division would need unbounded memory? If you type 7/7 into calculator, it works. So please for my sake please make it mathematically correct operation instead of rounding errors introduced by adding a magic number over and over. While adding 0.1428571428571429 7 times may not be exact, 7/7 is.

There is no sliding resampling option, like there is sliding time scale/pitch shift in Audacity. So I don't see why this would need to support sliding. The current algorithm has an issue with integer scaling, but sliding resampling will cause a lot of aliasing anyway, not so with integer scaling if the nearest neighbor worked.

manx

Solving the one single special case where there is actually no remainder does not solve the problem in the general case. This is completely and utterly useless as an implementation. I have already explained that in order to devise an implementation you absolutely have to consider ALL POSSIBLE input parameter instead of just one single (or a group of) special case. In the general case, the pitch CAN change during playback, and the fraction will not evaluate without a remainder in almost all cases. The fraction can in fact grow arbitrarily large, as already stated.
Floating point does not solve anything here. Any non-power-of-2 fraction remainder will already have rounding errors by the very definition of how binary floating point works.

For reference: The way this actually works is that, for every output sample frame (i.e. counting output sample rate), the playback position of the sample is incremented by the amount calculated from the sample playback rate relative to output sample rate. Mathematically you have: pos(n) = Sum(increment(0) + increment(1) + increment(1) + ... + increment(n-1)) ;  (n is output sample frame). The sample playback rate can change arbitrarily over time, thus increment can also change dynamically, and is a fraction with (in the precise case) varying denominator. Adding fractions with arbitrary denominator precisely requires unbounded memory and compute time.

As Saga Musix already explained, OpenMPT 1.27 uses 64 bit (32.32) integer fixed-point here, which already has better precision and rounding characteristics as 64bit floating point would have.

Quote
There is no sliding resampling option, like there is sliding time scale/pitch shift in Audacity. So I don't see why this would need to support sliding. The current algorithm has an issue with integer scaling, but sliding resampling will cause a lot of aliasing anyway, not so with integer scaling if the nearest neighbor worked.
https://wiki.openmpt.org/Manual:_Effect_Reference
Portamento, Vibrato, Arpeggio, Pitch Envelope, ...

PiotrGrochowski

32.32 fixed point? That's even worse! It only supports less than 10 decimal places (2^32 is less than 10^10) and only numbers from -2 billion to 2 billion. Only the old and destroyed PCs do that.

Even though pitch may change in the song, the sample rate does not. The data of the song doesn't matter in nearest neighbor.

"The way this actually works is that, for every output sample frame (i.e. counting output sample rate), the playback position of the sample is incremented by the amount calculated from the sample playback rate relative to output sample rate."

I already know that adding magic number thing.

My idea, is, that, for resampling, nearest neighbor should use correct (7/7), not risky (0.14285714+0.14285714+...) operations. If the conversion to number storage always rounds down (can be an issue if division algorithm generates 0.1111... in binary) it should be calculated to one more bit which determines rounding.

If you don't use integer resamplings, this: (n*x)/y is the right operation. n is current sample, x is old sample rate, y is new sample rate.

dv_

#20
You do understand that a symbolic calculator is an insanely complex undertaking, particularly for such miniscule and irrelevant goals? It is like insisting on positioning objects in a 3D scene correct down to the molecule and therefore requiring bigint libraries for everything.

The human ear cannot perceive this supposed "error". Perhaps if you remastered the audio a billion times it would become relevant, but pretty much *everything* else is more relevant than *that*.

Saga Musix

Quote32.32 fixed point? That's even worse! It only supports less than 10 decimal places (2^32 is less than 10^10) and only numbers from -2 billion to 2 billion. Only the old and destroyed PCs do that.
The decimal precision is more than enough and is in fact identical to what many other samplers use. Even if we used 64-bit floating point, the exactly same problem would exist - (1/7)*7 would still not equal 1.0.
Also, OpenMPT does not support samples longer than 256 megasamples at the moment so it does not matter that the integer part of the position cannot exceed 4 (not 2) billion.

QuoteIf you don't use integer resamplings, this: (n*x)/y is the right operation. n is current sample, x is old sample rate, y is new sample rate.
Division is the slowest arithmetic operation even on a modern CPU and while it may not matter if you are playing a single channel, it very much can still matter if you are playing hundreds of channels at the same time, which is what OpenMPT is designed for.

If you assume that we are lazy and know nothing about audio programming after spending (more than) ten years in this field, then please learn how to program and create a better sampler. I will be excited to see it and how well it performs on the type of hardware that OpenMPT supports.

I am fed up with this topic now. Call me lazy as much as you want but I will ignore any further replies that tell me how to write my sampler.
» No support, bug reports, feature requests via private messages - they will not be answered. Use the forums and the issue tracker so that everyone can benefit from your post.

LPChip

Wow Saga Musix. It took you this long to get fed up. That must be a new record. :)

I totally agree with you though. Precision is one thing, but optimization for performance is another. And they often don't go hand-in-hand.
"Heh, maybe I should've joined the compo only because it would've meant I wouldn't have had to worry about a damn EQ or compressor for a change. " - Atlantis
"yes.. I think in this case it was wishful thinking: MPT is makng my life hard so it must be wrong" - Rewbs

PiotrGrochowski

How can I spend (more than) ten years when I'm 12? Serious? Use your common sense.

Do you think it's not noticeable? Clearly a wave with 11111111000000 is different than 11111110000000 at 8000Hz, clearly not a square wave. It's noticeable in loops if you use integer scaling, as you get 8777...7776 instead of 7777...7777, and the transition from end to beginning makes the loop imperfect.

Saga Musix

Quote from: PiotrGrochowski on September 13, 2017, 05:41:14How can I spend (more than) ten years when I'm 12? Serious? Use your common sense
I was talking about the OpenMPT developers. Both OpenMPT developers have spent more than ten years developing audio software. Do you really think that you are an expert on audio programming and know what you are saying while we don't know what we're doing?
I learned to program when I was at your age. You should do the same and prove that you are better than us.
» No support, bug reports, feature requests via private messages - they will not be answered. Use the forums and the issue tracker so that everyone can benefit from your post.

PiotrGrochowski

Quote from: Saga Musix on September 13, 2017, 09:38:51
Quote from: PiotrGrochowski on September 13, 2017, 05:41:14How can I spend (more than) ten years when I'm 12? Serious? Use your common sense
I was talking about the OpenMPT developers. Both OpenMPT developers have spent more than ten years developing audio software. Do you really think that you are an expert on audio programming and know what you are saying while we don't know what we're doing?
I learned to program when I was at your age. You should do the same and prove that you are better than us.
Actually that would be very bad. I shouldn't do 18+ things at age of 12.

Rakib

OpenMPT is open source, fix it yourself.
^^

Saga Musix

Quote from: PiotrGrochowski on September 13, 2017, 09:48:47
Actually that would be very bad. I shouldn't do 18+ things at age of 12.
Programming is not (only) an occupation for adults. It can be an exciting hobby if you learn it early and open the doors to your future, since more and more jobs will require programming knowledge. The later you start with it, the harder it will become to understand it.
» No support, bug reports, feature requests via private messages - they will not be answered. Use the forums and the issue tracker so that everyone can benefit from your post.

manx


Quote from: PiotrGrochowski on September 12, 2017, 17:56:13
32.32 fixed point? That's even worse!
Wrong. In the general case (long samples), 32.32 fixed point provides better precision than 64bit floating point.

Quote from: PiotrGrochowski on September 12, 2017, 17:56:13
If you don't use integer resamplings, this: (n*x)/y is the right operation. n is current sample, x is old sample rate, y is new sample rate.
And again you are trying to solve the general case by providing an example for a special case. The sample playback rate might change at a point n that does not allow the fraction to be reduced. You cannot devise a LCM for all possible denominators, you either have to choose a time base and round, or store arbitrarily large integers.


Quote from: PiotrGrochowski on September 13, 2017, 05:41:14
Do you think it's not noticeable?
Yes, it is not noticeable. The precision error in pitch is less than 1 cent even for extreme resampling ratios. This is not noticeable: https://en.wikipedia.org/wiki/Cent_(music). Stop thinking in the time domain, this will get you nowhere here. And if you do not know what I am talking about, you absolutely will have to do the required background research, even if it takes you multiple years.

The case you describe is AGAIN a special case. The general case has varying pitches where nearest neighbour interpolation is by definition already broken way more than a single sample phase difference or rounding error.

If you for whatever reason need sample-accurate nearest neighbour resampling, and do not care about varying pitches whatsoever at all, use some software that actually tries to solve that use case. OpenMPT surely does not. Your usecase is absolutely meaningless in practice.


However, all of that is even completely irrelevant if you take a closer look at what the sample playback rate actually is supposed to be in practice. It is not an integer and not even a precise fraction. In the nowadays overwhelmingly common default case of equal temperament scale tuning, all but one of the note playback rates per octave are non-integer and non-rational. Your idea is already flawed at the preconditions. There is no precise fraction to even work with in the first place.


Quote from: PiotrGrochowski on September 13, 2017, 05:41:14
How can I spend (more than) ten years when I'm 12? Serious? Use your common sense.
So, it should not be that surprising at all to you that people who have worked more than 10 years in the field actually know things better than you, right? You have demonstrated multiple times that you did not think through your ideas thoroughly (which is totally fine, given the age), but when we tell you multiple times that your ideas are flawed, you absolutely have to step back somewhen and accept that you do not have the required background knowledge yet to fully understand all aspects (which again would be fine). But then, you not only expect us to explain things in a couple of forum posts that would normally take years to learn, and additionally also keep insisting on the same flawed concept over and over again? How are we supposed to solve that? By now, you are honestly only wasting everyones time, including your own, here.

Also, kindly asking how and why the mixer and resampler is implemented the way it is would probably have been more helpful for you and everyone else, rather than repeatedly insulting the developers and insisting on impractical ideas. Please reconsider your attitude.

PiotrGrochowski

Stop thinking in frequency domain, it's not relevant.

Please kindly add that nearest neighbor that even works as an option and everything will be okay. No other program has rounding errors with integer scaling, so copy source code of them.