Bramas / Ultratools

Editor for Ultrastar songs
5 stars 5 forks source link

some fixes and improvements #1

Closed s09bQ5 closed 8 years ago

s09bQ5 commented 8 years ago

Here are some changes I made to the Ultratools editor. Most notable new features are:

I have added code to synchronize the audio playback, key presses, and Midi input to a QElapsedTimer. Please test if this breaks anything on Windows or Mac OS X. I can only test on Linux. Usually the refinement done in 905dce733b isn't worth it because my tests show that I can't hit keys with less than +-50ms jitter and fmod tries to use a 4kB buffer (21.3ms @ 16 bits 48kHz stereo), but we need a common clock anyway.

I didn't add license headers to the new files. I'm not a fan of beer and I'm fine with them being public domain. If you want, we can use another license.

Bramas commented 8 years ago

Wow, this looks really great!! Thanks a lot for the contributions. using a midi controller to create song must be so cool!. too bad I don't have a midi controller to try that :(

I build your PR on windows and everything works great, except for the recording. Actually it didn't work before and thanks to your fix, a word is created when releasing a key, but the timing of the note is wrong. Is see that the timing is based on the event timestamp (added in f1fe9b4). for the key input the time sent is guiDelta + event->timestamp() does recording from keyboard works well on linux?

For the licence, I can definitly change it :) . maybe MIT licence.

s09bQ5 commented 8 years ago

Is the timing wrong by a constant value or does it vary? How much is it approximately? Is it too late or too early? guiDelta should converge to the correct offset very fast. On the first call of updateGuiDelta() guiDelta is 0, so it is set to now()-event->timestamp(), making keyPressEvent being emitted with now() as timestamp. From then on only smaller values for guiDelta are accepted, i.e. calculated from events where the latency was smaller, and deltas which are off by a huge value (>10s). There could be a problem if the event->timestamp() values are jumping around wildly.

I suspect the problem to be in the UAudioManager timestamp code. UAudioManager::_granularity is the smallest difference observed in values returned by FMOD_Channel_GetPosition > 0. This is assumed to be the interval of sound card interrupts. On my system this is 21ms and it takes a fraction of a second to find that value after starting playback. _granularity serves as a limit to quickly adapt to jumps in _delta. UAudioManager::_delta contains the difference between the audio position and the QElapsedTimer read by now().

On Windows QElapsedTimer tries to use QueryPerformanceCounter, so it should be way more precise than the audio timestamps.

I'll see if I can build Ultratools editor with MXE to debug this issue. I have an old Win XP box for these special occasions.

Bramas commented 8 years ago

The timing is wrong (its greater than what is expected) by a constant value that seems to be the GAP. This appears only while playing. If I stop and then hit a key, the timing looks good.

I don't understand very well how the timestamp of the event is used to get the current position in the song. Doesn't the granularity of GetPosition precise enough for what we want to achieve?

s09bQ5 commented 8 years ago

Will make a new pull request that contains a fix for the issue (and some others).