From 68e6eaff32d4041448176785ada89c275038255c Mon Sep 17 00:00:00 2001 From: Stepland <10530295-Buggyroom@users.noreply.gitlab.com> Date: Thu, 6 Oct 2022 00:43:17 +0200 Subject: [PATCH] HOLY FUCK I FIXED THIS BUG Turns out I was mutiating timeOffset in each loop iteration instead of just pre-computing the pre-pitched timeoffset once before setting it, so these mutations added up, Also there was something to do with the fact that SynchedSoundStream should be informed of a pitch change *before* asking it to update the streams --- .../synced_sound_streams.cpp | 35 ++++++++++++------- .../synced_sound_streams.hpp | 4 +-- src/editor_state.cpp | 4 ++- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/custom_sfml_audio/synced_sound_streams.cpp b/src/custom_sfml_audio/synced_sound_streams.cpp index 9bd1e8c..bc1c9f4 100644 --- a/src/custom_sfml_audio/synced_sound_streams.cpp +++ b/src/custom_sfml_audio/synced_sound_streams.cpp @@ -70,8 +70,8 @@ void SyncedSoundStreams::change_streams(std::function callback) { callback(); reload_sources(); - setPlayingOffset(position); setPitch(pitch); + setPlayingOffset(position); if (oldStatus == sf::SoundSource::Playing) { play(); } @@ -215,22 +215,31 @@ sf::SoundSource::Status SyncedSoundStreams::getStatus() const } -void SyncedSoundStreams::setPlayingOffset(sf::Time timeOffset) { +void SyncedSoundStreams::setPlayingOffset(const sf::Time timeOffset) { // Get old playing status auto oldStatus = getStatus(); // Stop the stream stop(); + const auto pre_pitched_time_offset = timeOffset / pitch; // Let the derived class update the current position for (auto& [_, s]: streams) { s.stream->public_seek_callback(timeOffset); // Restart streaming - if (s.reconstruct_on_pitch_change) { - timeOffset /= pitch; + if (s.bypasses_openal_pitch) { + s.buffers.m_samplesProcessed = time_to_samples( + pre_pitched_time_offset, + s.buffers.m_sampleRate, + s.buffers.m_channelCount + ); + } else { + s.buffers.m_samplesProcessed = time_to_samples( + timeOffset, + s.buffers.m_sampleRate, + s.buffers.m_channelCount + ); } - - s.buffers.m_samplesProcessed = time_to_samples(timeOffset, s.buffers.m_sampleRate, s.buffers.m_channelCount); } if (oldStatus == sf::SoundSource::Stopped) { @@ -259,7 +268,7 @@ sf::Time SyncedSoundStreams::getPlayingOffset(const InternalStream& s) const { s.buffers.m_sampleRate, s.buffers.m_channelCount ); - if (s.reconstruct_on_pitch_change) { + if (s.bypasses_openal_pitch) { return openal_seconds * pitch; } else { return openal_seconds; @@ -284,7 +293,7 @@ sf::Time SyncedSoundStreams::getPrecisePlayingOffset(const InternalStream& s) co void SyncedSoundStreams::setPitch(float new_pitch) { pitch = new_pitch; for (auto& [_, s] : streams) { - if (not s.reconstruct_on_pitch_change) { + if (not s.bypasses_openal_pitch) { s.stream->setPitch(new_pitch); } } @@ -309,10 +318,10 @@ void SyncedSoundStreams::display_debug() const { ImGui::TableHeadersRow(); ImGui::TableNextRow(); ImGui::TableNextColumn(); - ImGui::TextUnformatted("reconstruct on pitch change"); + ImGui::TextUnformatted("bypasses OpenAL Pitch"); for (const auto& [_, s] : streams) { ImGui::TableNextColumn(); - ImGui::TextUnformatted(fmt::format("{}", s.reconstruct_on_pitch_change).c_str()); + ImGui::TextUnformatted(fmt::format("{}", s.bypasses_openal_pitch).c_str()); } ImGui::TableNextRow(); ImGui::TableNextColumn(); @@ -358,10 +367,12 @@ void SyncedSoundStreams::display_debug() const { } ImGui::TableNextRow(); ImGui::TableNextColumn(); - ImGui::TextUnformatted("internal stream pitch"); + ImGui::TextUnformatted("AL_PITCH"); for (const auto& [_, s] : streams) { ImGui::TableNextColumn(); - ImGui::TextUnformatted(fmt::format("x{}", s.stream->getPitch()).c_str()); + ALfloat pitch; + alCheck(alGetSourcef(s.stream->get_source(), AL_PITCH, &pitch)); + ImGui::TextUnformatted(fmt::format("x{}", pitch).c_str()); } ImGui::TableNextRow(); ImGui::TableNextColumn(); diff --git a/src/custom_sfml_audio/synced_sound_streams.hpp b/src/custom_sfml_audio/synced_sound_streams.hpp index eb99903..604e14d 100644 --- a/src/custom_sfml_audio/synced_sound_streams.hpp +++ b/src/custom_sfml_audio/synced_sound_streams.hpp @@ -47,7 +47,7 @@ struct NewStream { struct InternalStream { std::shared_ptr stream; Buffers buffers; - bool reconstruct_on_pitch_change; + bool bypasses_openal_pitch; void clear_queue(); }; @@ -68,7 +68,7 @@ public: sf::SoundSource::Status getStatus() const; - void setPlayingOffset(sf::Time timeOffset); + void setPlayingOffset(const sf::Time timeOffset); sf::Time getPlayingOffset() const; sf::Time getPrecisePlayingOffset() const; diff --git a/src/editor_state.cpp b/src/editor_state.cpp index 320f263..9035d12 100644 --- a/src/editor_state.cpp +++ b/src/editor_state.cpp @@ -155,8 +155,10 @@ void EditorState::set_pitch(float pitch) { beat_ticks = beat_ticks->with_pitch(pitch); update[beat_tick_stream] = {beat_ticks, true}; } - audio.update_streams(update); + // setPitch has to be called before update_streams to avoid problems in + // the internal call to setPlaybackPosition audio.setPitch(pitch); + audio.update_streams(update); } float EditorState::get_pitch() const {