View Issue Details

IDProjectCategoryView StatusLast Update
0001006OpenMPTAudio I/Opublic2017-08-22 11:01
ReporterPiotr Assigned To 
PrioritynormalSeveritytweakReproducibilityalways
Status closedResolutionno change required 
Platformx64OSWindowsOS Version10
Product VersionOpenMPT 1.26.12.00 / libopenmpt 0.2-beta26 (upgrade first) 
Summary0001006: 2 and 3 sample loops play wrong
Description

The sounds are in 8000Hz. Here are samples looped:

1 -1
1 1 -1

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.

TagsNo 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")

Activities

Saga Musix

Saga Musix

2017-08-10 20:24

administrator   ~0003149

Last edited: 2017-08-10 20:25

They are not played as sine wave

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.

and every 0.683 seconds there is a little click.

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.

1.26.12.00 (not sure why there is duplicate of "Product Version")

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.

Piotr

Piotr

2017-08-11 04:22

viewer   ~0003150

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.

Piotr

Piotr

2017-08-11 04:28

viewer   ~0003151

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.

areckx

areckx

2017-08-11 06:25

reporter   ~0003152

Which part of the code would this most likely be?

Piotr

Piotr

2017-08-11 08:08

viewer   ~0003153

2 and 3 sample at 8000Hz seem to be handled differently than 4+.

areckx

areckx

2017-08-11 08:44

reporter   ~0003154

do you think it's somewhere in common/Endiannes.h ??

Saga Musix

Saga Musix

2017-08-11 10:44

administrator   ~0003155

2 and 3 sample at 8000Hz seem to be handled differently than 4+.

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/
Do not ask to fix this in OpenMPT 1.26, it's out of scope.

do you think it's somewhere in common/Endiannes.h ??

Completely wrong place, common/ does not contain audio-related code (Endianness.h deals with Endianness as the name suggests).
The mixer code is in soundlib/, in MixerInterface.h, IntMixer.h and Fastmix.cpp.

Piotr

Piotr

2017-08-17 08:41

viewer   ~0003179

Even the sample viewer is different. With 2 or 3 samples (8000Hz), the last sample doesn't connect to first.

Saga Musix

Saga Musix

2017-08-17 09:41

administrator   ~0003180

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.

Piotr

Piotr

2017-08-18 06:27

viewer   ~0003181

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.

Saga Musix

Saga Musix

2017-08-18 13:44

administrator   ~0003182

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.

manx

manx

2017-08-19 09:04

administrator   ~0003183

To give some other perspective to what Saga Musix is trying to say here:
OpenMPT is meant to play back common meaningful samples in the context of music and other kinds of audio production.
It is especially not meant as a sample-accurate single-sample-accurate soundwave modelling tool.

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.
The use case and rendering aspects you are describing and concerned with here, is really an uncommon edge and corner case. It might seem that a simple naive implementation might actually work better in that case. However, it would work worse in the common case.

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 artefacts.

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.
If you really need or want more explanation, I highly suggest taking this discussion to the forum where it wont re-open this issue every time.

Piotr

Piotr

2017-08-20 16:08

viewer   ~0003184

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.

manx

manx

2017-08-20 16:39

administrator   ~0003185

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.

Piotr

Piotr

2017-08-22 09:07

viewer   ~0003186

I don't have a forum account. Besides, that would be a bad idea to move.

Seriously, if you have a sample with 8000Hz rate, a sample with 16000Hz rate and a sample with 11025Hz rate, you wouldn't know which is the maximum?

And after picking the maximum, it will pick a sample rate that is supported, and is as small as possible, but not smaller than maximum.

Saga Musix

Saga Musix

2017-08-22 11:01

administrator   ~0003187

I don't have a forum account.

You can create one. You already bothered with creating an issue tracker account, so creating a forum account is little extra work.

Besides, that would be a bad idea to move.

No, it wouldn't for exactly the reasons manx stated.

Seriously, if you have a sample with 8000Hz rate, a sample with 16000Hz rate and a sample with 11025Hz rate, you wouldn't know which is the maximum?

You assume that the samples will always be played at this rate and not be pitched up and down in any way. Maybe that's how you use OpenMPT but I can tell you that this is not how pretty much everyone else uses it.

Anyway, last warning. Do not re-open this issue again. We seriously mean it.

Issue History

Date Modified Username Field Change
2017-08-10 17:43 Piotr New Issue
2017-08-10 17:47 Piotr Description Updated
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
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
2017-08-22 09:07 Piotr Status closed => feedback
2017-08-22 09:07 Piotr Resolution no change required => reopened
2017-08-22 09:07 Piotr Note Added: 0003186
2017-08-22 11:01 Saga Musix Note Added: 0003187
2017-08-22 11:01 Saga Musix Status feedback => closed
2017-08-22 11:01 Saga Musix Resolution reopened => no change required