View Issue Details
|ID||Project||Category||View Status||Date Submitted||Last Update|
|0001006||OpenMPT||[All Projects] Audio I/O||public||2017-08-10 17:43||2017-08-20 16:40|
|Status||closed||Resolution||no change required|
|Product Version||OpenMPT 1.26.12.00 / libopenmpt 0.2-beta26 (upgrade first)|
|Target Version||Fixed in Version|
|Summary||0001006: 2 and 3 sample loops play wrong|
The sounds are in 8000Hz. Here are samples looped:
They are not played as sine wave (making it sound higher quality than it actually is), and every 0.683 seconds there is a little click.
|Steps To Reproduce|
Make a 8000Hz sound with 2 or 3 samples, they are 1 and -1 or 1, 1 and -1. Loop them, and play.
|Tags||No tags attached.|
|Has the bug occurred in previous versions?|
|Tested code revision (in case you know it)||1.26.12.00 (not sure why there is duplicate of "Product Version")|
Indeed they aren't, and there is no requirement for them to be played as sine waves. OpenMPT would require much higher-quality (and thus much slower) reconstruction filters for that to work. And no, that is not going to happen.
This sounds like your audio buffer settings are too small. Playing such extremely short samples requires more CPU power than playing a sample with a longer loop, so OpenMPT might not be able to keep up with the audio device. You will notice that these clicks are not present if you export the sample to WAV.
Because the OpenMPT version is not the same as code revision. You only need to fill in this field if you are running a test version. In this case, you will see the revision number in the about dialog.
If I repeat the loop twice (1 -1 1 -1) it comes out correctly (sine wave, no clicks). But solution is always better than workarounds.
Sounds should not be played with frequencies above Nyquist. So 4000Hz wave (max frequency) should not have harmonics at 8000Hz sample rate. Same with 2666.666667Hz wave.
Which part of the code would this most likely be?
2 and 3 sample at 8000Hz seem to be handled differently than 4+.
do you think it's somewhere in common/Endiannes.h ??
No, the code for all loop lengths is the same.
I forgot to mention that I made some adjustments to the mixer which improve this situation; however they will not be backported to OpenMPT 1.26. You will have to wait until OpenMPT 1.27 is out or use one of the current test builds from https://builds.openmpt.org/builds/
Completely wrong place, common/ does not contain audio-related code (Endianness.h deals with Endianness as the name suggests).
Even the sample viewer is different. With 2 or 3 samples (8000Hz), the last sample doesn't connect to first.
sigh and if you actually try the 1.27 test builds as I said, you will notice that it will not do this for any sample length, not just 2 and 3.
PS: The 8000 Hz sample frequency has nothing to do with that. You can stop mentioning it in every other comment. And please stop commenting on this issue. The fact that I closed it means that we are not going to change anything about the current behaviour, if you like it or not.
I think the resampling is horrible. This is fixed by automatically setting sample rate of sound card based on samples (maximum sample rate of samples is used). Since all samples are 8000Hz in my period template, it should be set so to avoid artifacts.
Please stop discussing this. I already said that you can try the current 1.27 test builds where resampling of very short samples sounds better, but it will of course not be "perfcet" and that is also not our intention. OpenMPT is not a tool to do perfect resampling of 2-sample loops.
To give some other perspective to what Saga Musix is trying to say here:
These two goals are not always compatible (accuracy of loops is not even well-defined; it kind of needs to take into account both the sample that exists beyond the end loop point as well as the sample data right after the loop start point in order to do interpolation at the loop point (in the case of forward loops)). I did not even research what OpenMPT is exactly doing here, because it does not even matter There is just no globally correct way to handle it.
Additionally, the loop handling is tuned for actually mathematical meaningful interpolation (i.e. long filters instead of nearest neighbour or linear).
The unavoidable rounding inaccuracies when converting between frequency and period (which needs to happen in multiple places internally) do not matter for interpolation filters other than nearest neighbour.
In addition to that, actually resampling with proper anti-aliasing in a sampler context like OpenMPT is complicated and CPU intensive because we cannot use pre-calculated filter coefficients specifically tuned for the rate ratio at hand because that ratio might change dynamically. This in particular means that there will be compromises to be made with choosing the filter cutoff frequency and stopband attenuation (OpenMPT only even does something remotely close to that when using the Polyphase 8tap filter (not with the XMMS modplug 8tap filter) (to my knowledge, none of the other open source trackers or mod playback libraries even tries at all to properly implement a cutoff in resampling). However, because of the short length of the filter and the fact that only 3 different cutoff ratios are actually implemented, stopband cutoff and attenuation are far from perfect. This is actually not solvable without either increasing filter length to at least 32 taps and using way more cutoff steps or pre-calculated sample mip-maps, or oversampling the whole mixer (all of this has of course performance costs). Oversampling the whole mixer is, I think, what we are planning long-term. Short-term, you can set the sample rate of the sound card higher (like 96kHz or 192kHz), which would move the most severe of the aliasing above audible range, and rely on the driver or sound card (or anything later in the audio chain) to properly downsample and/or filter (but do note that this also is not only a performance tradeoff but also again an accuracy tradeoff because of the limited filter accuracy and length).
Another area where sample-accurate soundwave modelling and musically useful playback conflict, for example, is volume ramping.
Please realize that there are a ton of different aspects to consider here, and OpenMPT tries to optimize for the common case here, as optimizing for every case is either outright impossible or would incur a huge development endeavour which is currently not worth the effort.
No, that would be horrible. We cannot predict the future which might play the samples at other rates, which would incur and audio device sample rate change at that point which would incur a discontinuation in playback because no audio API does allow change sampling rate sample-accurate on the fly. Not all rates that are theoretically possible are settable in the sound device. This makes just no sense, sorry.
Also, please be aware of the fact that the issue tracker is not only the place for users like you to report issues but also a tool for the developers to organize and plan work that has to be done. Repeatedly re-opening the issue after it has been explained why it had been closed interferes with that.
Did you read closely? I didn't mean to change with samples. I mean to set sample rate to maximum sample rate of samples used.
No. What you describe is logically impossible. It is unknown upfront what the maximum sample playback rate would be, and even if it was known upfront, it is not guaranteed by any means that the sound driver would support that rate at all (in fact, it wont for almost all rates).
Very please take this discussion to the forum. The issue tracker is not the right place to discuss or explain fundamental basics of audio mixing.
|2017-08-10 17:43||Piotr||New Issue|
|2017-08-10 17:47||Piotr||Description Updated||View Revisions|
|2017-08-10 20:24||Saga Musix||Note Added: 0003149|
|2017-08-10 20:24||Saga Musix||Status||new => closed|
|2017-08-10 20:24||Saga Musix||Resolution||open => no change required|
|2017-08-10 20:25||Saga Musix||Note Edited: 0003149||View Revisions|
|2017-08-11 04:22||Piotr||Status||closed => feedback|
|2017-08-11 04:22||Piotr||Resolution||no change required => reopened|
|2017-08-11 04:22||Piotr||Note Added: 0003150|
|2017-08-11 04:28||Piotr||Note Added: 0003151|
|2017-08-11 04:28||Piotr||Status||feedback => new|
|2017-08-11 06:25||areckx||Note Added: 0003152|
|2017-08-11 08:08||Piotr||Note Added: 0003153|
|2017-08-11 08:44||areckx||Note Added: 0003154|
|2017-08-11 10:44||Saga Musix||Status||new => closed|
|2017-08-11 10:44||Saga Musix||Resolution||reopened => no change required|
|2017-08-11 10:44||Saga Musix||Note Added: 0003155|
|2017-08-17 08:41||Piotr||Status||closed => feedback|
|2017-08-17 08:41||Piotr||Resolution||no change required => reopened|
|2017-08-17 08:41||Piotr||Note Added: 0003179|
|2017-08-17 09:41||Saga Musix||Note Added: 0003180|
|2017-08-17 09:41||Saga Musix||Status||feedback => closed|
|2017-08-17 09:41||Saga Musix||Resolution||reopened => no change required|
|2017-08-18 06:27||Piotr||Status||closed => feedback|
|2017-08-18 06:27||Piotr||Resolution||no change required => reopened|
|2017-08-18 06:27||Piotr||Note Added: 0003181|
|2017-08-18 13:44||Saga Musix||Status||feedback => closed|
|2017-08-18 13:44||Saga Musix||Resolution||reopened => no change required|
|2017-08-18 13:44||Saga Musix||Note Added: 0003182|
|2017-08-19 09:04||manx||Note Added: 0003183|
|2017-08-20 16:08||Piotr||Status||closed => feedback|
|2017-08-20 16:08||Piotr||Resolution||no change required => reopened|
|2017-08-20 16:08||Piotr||Note Added: 0003184|
|2017-08-20 16:39||manx||Status||feedback => closed|
|2017-08-20 16:39||manx||Note Added: 0003185|
|2017-08-20 16:40||manx||Resolution||reopened => no change required|