Browse Source

Correctly get music position from BASS

kiwec 2 months ago
parent
commit
5a44f2a8e6
5 changed files with 52 additions and 34 deletions
  1. 2 4
      src/App/Osu/Beatmap.cpp
  2. 0 4
      src/App/Osu/MainMenu.cpp
  3. 0 1
      src/App/Osu/MainMenu.h
  4. 42 18
      src/Engine/Sound.cpp
  5. 8 7
      src/Engine/SoundEngine.cpp

+ 2 - 4
src/App/Osu/Beatmap.cpp

@@ -57,8 +57,6 @@ ConVar osu_draw_hitobjects("osu_draw_hitobjects", true, FCVAR_DEFAULT);
 ConVar osu_draw_beatmap_background_image("osu_draw_beatmap_background_image", true, FCVAR_DEFAULT);
 
 ConVar osu_universal_offset("osu_universal_offset", 0.0f, FCVAR_DEFAULT);
-ConVar osu_universal_offset_hardcoded_fallback_dsound("osu_universal_offset_hardcoded_fallback_dsound", -15.0f,
-                                                      FCVAR_DEFAULT);
 ConVar osu_old_beatmap_offset(
     "osu_old_beatmap_offset", 24.0f, FCVAR_DEFAULT,
     "offset in ms which is added to beatmap versions < 5 (default value is hardcoded 24 ms in stable)");
@@ -1900,9 +1898,9 @@ void Beatmap::playMissSound() {
 }
 
 unsigned long Beatmap::getMusicPositionMSInterpolated() {
-    if(!osu_interpolate_music_pos.getBool() || isLoading())
+    if(!osu_interpolate_music_pos.getBool() || isLoading()) {
         return m_music->getPositionMS();
-    else {
+    } else {
         const double interpolationMultiplier = 1.0;
 
         // TODO: fix snapping at beginning for maps with instant start

+ 0 - 4
src/App/Osu/MainMenu.cpp

@@ -139,7 +139,6 @@ ConVar osu_main_menu_banner_ifupdatedfromoldversion_le3303_text(
 ConVar *MainMenu::m_osu_universal_offset_ref = NULL;
 ConVar *MainMenu::m_osu_universal_offset_hardcoded_ref = NULL;
 ConVar *MainMenu::m_osu_old_beatmap_offset_ref = NULL;
-ConVar *MainMenu::m_osu_universal_offset_hardcoded_fallback_dsound_ref = NULL;
 ConVar *MainMenu::m_osu_mod_random_ref = NULL;
 ConVar *MainMenu::m_osu_songbrowser_background_fade_in_duration_ref = NULL;
 
@@ -149,9 +148,6 @@ MainMenu::MainMenu() : OsuScreen() {
         m_osu_universal_offset_hardcoded_ref = convar->getConVarByName("osu_universal_offset_hardcoded");
     if(m_osu_old_beatmap_offset_ref == NULL)
         m_osu_old_beatmap_offset_ref = convar->getConVarByName("osu_old_beatmap_offset");
-    if(m_osu_universal_offset_hardcoded_fallback_dsound_ref == NULL)
-        m_osu_universal_offset_hardcoded_fallback_dsound_ref =
-            convar->getConVarByName("osu_universal_offset_hardcoded_fallback_dsound");
     if(m_osu_mod_random_ref == NULL) m_osu_mod_random_ref = convar->getConVarByName("osu_mod_random");
     if(m_osu_songbrowser_background_fade_in_duration_ref == NULL)
         m_osu_songbrowser_background_fade_in_duration_ref =

+ 0 - 1
src/App/Osu/MainMenu.h

@@ -76,7 +76,6 @@ class MainMenu : public OsuScreen, public MouseListener {
     static ConVar *m_osu_universal_offset_ref;
     static ConVar *m_osu_universal_offset_hardcoded_ref;
     static ConVar *m_osu_old_beatmap_offset_ref;
-    static ConVar *m_osu_universal_offset_hardcoded_fallback_dsound_ref;
     static ConVar *m_osu_mod_random_ref;
     static ConVar *m_osu_songbrowser_background_fade_in_duration_ref;
 

+ 42 - 18
src/Engine/Sound.cpp

@@ -209,16 +209,22 @@ void Sound::setPosition(double percent) {
         return;
     }
 
-    f64 lengthInSeconds = BASS_ChannelBytes2Seconds(m_stream, length);
-    if(!BASS_ChannelSetPosition(m_stream, (i64)(length * percent), BASS_POS_BYTE | BASS_POS_FLUSH)) {
-        if(Osu::debug->getBool()) {
-            debugLog("Sound::setPosition( %f ) BASS_ChannelSetPosition() error %i on file %s\n", percent,
-                     BASS_ErrorGetCode(), m_sFilePath.c_str());
+    if(isPlaying()) {
+        if(!BASS_Mixer_ChannelSetPosition(m_stream, (i64)(length * percent), BASS_POS_BYTE)) {
+            if(Osu::debug->getBool()) {
+                debugLog("Sound::setPosition( %f ) BASS_ChannelSetPosition() error %i on file %s\n", percent,
+                         BASS_ErrorGetCode(), m_sFilePath.c_str());
+            }
         }
-    }
 
-    if(m_bStarted) {
-        m_fLastPlayTime = m_fChannelCreationTime - (lengthInSeconds * percent);
+        m_fLastPlayTime = m_fChannelCreationTime - ((f64)m_length * percent / 1000.0);
+    } else {
+        if(!BASS_ChannelSetPosition(m_stream, (i64)(length * percent), BASS_POS_BYTE | BASS_POS_FLUSH)) {
+            if(Osu::debug->getBool()) {
+                debugLog("Sound::setPosition( %f ) BASS_ChannelSetPosition() error %i on file %s\n", percent,
+                         BASS_ErrorGetCode(), m_sFilePath.c_str());
+            }
+        }
     }
 }
 
@@ -235,15 +241,22 @@ void Sound::setPositionMS(unsigned long ms) {
         return;
     }
 
-    if(!BASS_ChannelSetPosition(m_stream, position, BASS_POS_BYTE | BASS_POS_FLUSH)) {
-        if(Osu::debug->getBool()) {
-            debugLog("Sound::setPositionMS( %lu ) BASS_ChannelSetPosition() error %i on file %s\n", ms,
-                     BASS_ErrorGetCode(), m_sFilePath.c_str());
+    if(isPlaying()) {
+        if(!BASS_Mixer_ChannelSetPosition(m_stream, position, BASS_POS_BYTE)) {
+            if(Osu::debug->getBool()) {
+                debugLog("Sound::setPositionMS( %lu ) BASS_ChannelSetPosition() error %i on file %s\n", ms,
+                         BASS_ErrorGetCode(), m_sFilePath.c_str());
+            }
         }
-    }
 
-    if(m_bStarted) {
         m_fLastPlayTime = m_fChannelCreationTime - ((f64)ms / 1000.0);
+    } else {
+        if(!BASS_ChannelSetPosition(m_stream, position, BASS_POS_BYTE | BASS_POS_FLUSH)) {
+            if(Osu::debug->getBool()) {
+                debugLog("Sound::setPositionMS( %lu ) BASS_ChannelSetPosition() error %i on file %s\n", ms,
+                         BASS_ErrorGetCode(), m_sFilePath.c_str());
+            }
+        }
     }
 }
 
@@ -329,7 +342,13 @@ float Sound::getPosition() {
         return 1.f;
     }
 
-    i64 positionBytes = BASS_ChannelGetPosition(m_stream, BASS_POS_BYTE);
+    i64 positionBytes = 0;
+    if(isPlaying()) {
+        positionBytes = BASS_Mixer_ChannelGetPosition(m_stream, BASS_POS_BYTE);
+    } else {
+        positionBytes = BASS_ChannelGetPosition(m_stream, BASS_POS_BYTE);
+    }
+
     const float position = (float)((double)(positionBytes) / (double)(lengthBytes));
     return position;
 }
@@ -344,13 +363,18 @@ u32 Sound::getPositionMS() {
         return m_paused_position_ms;
     }
 
-    i64 position = BASS_ChannelGetPosition(m_stream, BASS_POS_BYTE);
-    if(position < 0) {
+    i64 positionBytes = 0;
+    if(isPlaying()) {
+        positionBytes = BASS_Mixer_ChannelGetPosition(m_stream, BASS_POS_BYTE);
+    } else {
+        positionBytes = BASS_ChannelGetPosition(m_stream, BASS_POS_BYTE);
+    }
+    if(positionBytes < 0) {
         // The stream ended and got freed by BASS_STREAM_AUTOFREE -> invalid handle!
         return m_length;
     }
 
-    f64 positionInSeconds = BASS_ChannelBytes2Seconds(m_stream, position);
+    f64 positionInSeconds = BASS_ChannelBytes2Seconds(m_stream, positionBytes);
     f64 positionInMilliSeconds = positionInSeconds * 1000.0;
     u32 positionMS = (u32)positionInMilliSeconds;
     if(!isPlaying()) {

+ 8 - 7
src/Engine/SoundEngine.cpp

@@ -143,7 +143,7 @@ SoundEngine::SoundEngine() {
     // all beatmaps timed to non-iTunesSMPB + 529 sample deletion offsets on old dlls pre 2015
     BASS_SetConfig(BASS_CONFIG_MP3_OLDGAPS, 1);
 
-    // avoids lag/jitter in BASS_ChannelGetPosition() shortly after a BASS_ChannelPlay() after loading/silence
+    // avoids lag/jitter in BASS_Mixer_ChannelGetPosition() shortly after a BASS_ChannelPlay() after loading/silence
     BASS_SetConfig(BASS_CONFIG_DEV_NONSTOP, 1);
 
     // if set to 1, increases sample playback latency by 10 ms
@@ -470,18 +470,16 @@ bool SoundEngine::init_bass_mixer(OUTPUT_DEVICE device) {
     }
 
     if(device.driver == OutputDriver::BASS) {
-        if(!BASS_Init(device.id, freq, bass_flags, NULL, NULL)) {
+        if(!BASS_Init(device.id, freq, bass_flags | BASS_DEVICE_SOFTWARE, NULL, NULL)) {
             ready_since = -1.0;
             debugLog("BASS_Init(%d) errored out.\n", device.id);
             display_bass_error();
             return false;
         }
-
-        osu_universal_offset_hardcoded.setValue(-25.f);
     }
 
     auto mixer_flags = BASS_SAMPLE_FLOAT | BASS_MIXER_NONSTOP | BASS_MIXER_RESUME;
-    if(device.driver != OutputDriver::BASS) mixer_flags |= BASS_STREAM_DECODE;
+    if(device.driver != OutputDriver::BASS) mixer_flags |= BASS_STREAM_DECODE | BASS_MIXER_POSEX;
     g_bassOutputMixer = BASS_Mixer_StreamCreate(freq, 2, mixer_flags);
     if(g_bassOutputMixer == 0) {
         ready_since = -1.0;
@@ -501,6 +499,9 @@ bool SoundEngine::initializeOutputDevice(OUTPUT_DEVICE device) {
 
     shutdown();
 
+    // We compensate for latency via BASS_ATTRIB_MIXER_LATENCY
+    osu_universal_offset_hardcoded.setValue(0.f);
+
     if(device.driver == OutputDriver::NONE || (device.driver == OutputDriver::BASS && device.id == 0)) {
         ready_since = -1.0;
         m_currentOutputDevice = device;
@@ -593,7 +594,7 @@ bool SoundEngine::initializeOutputDevice(OUTPUT_DEVICE device) {
 
         double wanted_latency = 1000.0 * asio_buffer_size.getFloat() / sample_rate;
         double actual_latency = 1000.0 * (double)BASS_ASIO_GetLatency(false) / sample_rate;
-        osu_universal_offset_hardcoded.setValue(-(actual_latency + 25.0f));
+        BASS_ChannelSetAttribute(g_bassOutputMixer, BASS_ATTRIB_MIXER_LATENCY, actual_latency / 1000.0);
         debugLog("ASIO: wanted %f ms, got %f ms latency. Sample rate: %f Hz\n", wanted_latency, actual_latency,
                  sample_rate);
     }
@@ -637,7 +638,7 @@ bool SoundEngine::initializeOutputDevice(OUTPUT_DEVICE device) {
             return false;
         }
 
-        osu_universal_offset_hardcoded.setValue(-(25.0f + win_snd_wasapi_buffer_size.getFloat() * 1000.0f));
+        BASS_ChannelSetAttribute(g_bassOutputMixer, BASS_ATTRIB_MIXER_LATENCY, win_snd_wasapi_buffer_size.getFloat());
     }
 #endif