Fascinating. I implemented a small proof of concept of Mathematica and it sounds remarkably well, especially for such an extremely simple idea.
Maybe a small nitpick, but by using the filter described in this article (taking the average with the next sample), the frequency isn't exactly equal to sample rate / samples per buffer, as the filtering method is asymmetric, and it shifts the signal half a sample to the left every pass. With a more symmetric method, like replacing each value by the average of the surrounding values, that doesn't happen. It may sound pedantic, but the difference is quite clear audible
Mathematica is one the most useful tools for this kind of experimental programming. A minimum implementation can be a single REPL line (if you prefer FP style). That's one line from blank page to "play audio"; it's hard to understand how enabling it is to have such shallow barriers to experimenting, it's like cheating.
Interesting! I gave that a shot and definitely do hear the difference. I believe the difference you hear is due to the fact that it's a stronger low pass filter to average 3 samples instead of 2. In any case, the result is much less harsh on the ears. I'm adding that to the post, thanks!
Oh, changing the filter definitely changes the timbre, but that's not what I meant. Even with a symmetric filter using only two values[0], there will still be an audible difference. The point of using the symmetric filter wasn't to get a more correct timbre, but to avoid changing the fundamental frequency.
Timbre is not the same as fundamental frequency. A guitar, a piano or a violin playing the same note, say, a middle C, will have wildly different timbres, but they should have the same fundamental frequency (261 Hz). That's what allows them to play together in orchestras. However, if you use, say 50 samples per buffer and a sample rate of 8192, with your original filter you won't get a frequency of 163.84 Hz, but 8192/49.5 = 165.49 Hz. That might look like a small difference, but to our ears it sounds wildly out of tune. You can use a tone analyzer app to verify it.
Thanks for the shout out :) I know I'm nitpicking :p
0: like for example, replacing with the average of the two surrounding values
Maybe a small nitpick, but by using the filter described in this article (taking the average with the next sample), the frequency isn't exactly equal to sample rate / samples per buffer, as the filtering method is asymmetric, and it shifts the signal half a sample to the left every pass. With a more symmetric method, like replacing each value by the average of the surrounding values, that doesn't happen. It may sound pedantic, but the difference is quite clear audible