- Generally Supports either ITG (9ms) or NULL (0ms).
- Alternatively, one could edit the preference manually to put a different value
- Name/Description probably worth ironing out
- Adjust the variable scope of group attributes
- Remove the now redundant GroupBannerPaths vector and replace its usage.
- Migrate ini loading logic to Group class
- Better clarity on comments for Group
- Remove GetTotalSongs in favor of GetSongs.
- Add Year as a value to Group.ini
- Ensure new group and song maps are cleared properly when freeing songs
In the song wheel, if you scroll back and forth over an MP3 song very fast, you might get some audible corruption at the beginning of the song preview, and it might even crash the game.
This fixes both of those problems.
Resolves#610.
`RageSoundReader_MP3` has three different methods of setting the position. The default choice of `SetPosition_toc` is unable to provide an accurate result. The reason Edit Mode has such a severe desync when working with MP3's is due to the preference of using `SetPosition_toc`.
We can prevent this by using `SetPosition_hard` which works very well. Judging by comments in the file, it seems like `SetPosition_hard` was too resource intensive to use as the default method, 20+ years ago.
The only downside is, if you start from an arbitrary position (which is **only** possible in Edit Mode), you have a few milliseconds of corrupted audio, but then the sync is perfect. You can hear this in the demonstration video below.
When we start from the beginning of a file, such as playing a song, or using `Play whole song` in edit mode, `MADLIB_rewind` will be used.
`SetPosition_hard` provides an accurate result, and is consistent with the offset provided by `MADLIB_rewind`. The result is a consistent sync experience whether the MP3 is started from the beginning, or from an arbitrary position midway thru the file.
The `m_bAccurateSync` boolean dependency has been removed from SetPosition since it does not seem to provide any benefit on modern hardware. It seems fine to remove it so that we can call `MADLIB_rewind` or `SetPosition_hard` as fast as possible.
In my testing I never got `SetPosition_estimate` to be used, but I've left it in as a backup option.
Interface with libudev to get notified when a new joystick appears.
The code is in IH_Linux_Event rather than IH_Linux_Joystick because it
seemed like the former uses evdev (standard for most devices nowadays)
whereas the latter uses the old joydev API. The result should be the
same in any case...
Implementation is a bit messy due to LinuxInputManager only scanning for
devices from its constructor, this forces RageInput to have an exception
for LinuxInputManager. Possibly with more involved surgery a cleaner
solution could be devised...
This is the fixed Merge from the 2025-1-26 test build. It will more strictly check the drift with each iteration of the m_aSounds loop, whereas the original implementation can allow small amounts of desync to accumulate over time if none of them exceed the threshold.
I've fixed the issues with the DirectSound driver which a number of commits from 2016 attempted to address. Additionally, build testers strongly prefer the fixed DirectSound to WaveOut (the current default driver for Windows) in terms of both game stability and sync stability, so I'm making it the default driver as well.
StepMania commit 75a9532 from 2006 had a subtle error, the declaration of len and locked_buf will hide the previous local declaration of these variables. The issues causing the DirectSound driver to be unreliable in terms of sync were due to this. This PR renames the variables from the 2006 commit to prevent this, and also ensures all variables are properly initialized.
Renamed `locked_buf` and `len` in `MixerThread` to `locked_buf_init` and `len_init` to avoid shadowing.
Prevent use of uninitialized member variables by initializing `m_pPCM`, `m_iSampleRate`, and `m_bShutdownMixerThread` in the constructor.
Preferred in Windows, especially when we can't guarantee that we are able to perform a proper clean-up before terminating. Halt may be called with the Kill flag which indicates everything must shut down. This is the preferred approach in the Windows API.
Another preferred option is to use WaitForSingleObject with a timeout, but Halt with the Kill flag is being called when the game is about to crash, so that's not a realistic option and may cause the program to hang indefinitely.