From b6e8d2b6225d6e7cfab983faeca14d02761956c2 Mon Sep 17 00:00:00 2001 From: Stepland <10530295-Buggyroom@users.noreply.gitlab.com> Date: Thu, 9 Jun 2022 00:28:21 +0200 Subject: [PATCH] More things working with claps --- src/custom_sfml_audio/meson.build | 2 +- .../{clap_player.cpp => note_claps.cpp} | 22 +++---- .../{clap_player.hpp => note_claps.hpp} | 6 +- .../synced_sound_streams.cpp | 8 +-- .../synced_sound_streams.hpp | 2 +- src/editor_state.cpp | 18 ++++-- src/editor_state.hpp | 5 +- src/main.cpp | 60 ++++++------------- 8 files changed, 53 insertions(+), 70 deletions(-) rename src/custom_sfml_audio/{clap_player.cpp => note_claps.cpp} (87%) rename src/custom_sfml_audio/{clap_player.hpp => note_claps.hpp} (89%) diff --git a/src/custom_sfml_audio/meson.build b/src/custom_sfml_audio/meson.build index 9e1aedc..00d4772 100644 --- a/src/custom_sfml_audio/meson.build +++ b/src/custom_sfml_audio/meson.build @@ -2,7 +2,7 @@ sources += files([ 'al_check.cpp', 'al_resource.cpp', 'audio_device.cpp', - 'clap_player.cpp', + 'note_claps.cpp', 'open_music.cpp', 'open_sound_stream.cpp', 'precise_sound_stream.cpp', diff --git a/src/custom_sfml_audio/clap_player.cpp b/src/custom_sfml_audio/note_claps.cpp similarity index 87% rename from src/custom_sfml_audio/clap_player.cpp rename to src/custom_sfml_audio/note_claps.cpp index f2a2359..3a6efb4 100644 --- a/src/custom_sfml_audio/clap_player.cpp +++ b/src/custom_sfml_audio/note_claps.cpp @@ -1,36 +1,32 @@ -#include "clap_player.hpp" +#include "note_claps.hpp" #include #include #include "../better_note.hpp" -ClapPlayer::ClapPlayer( +NoteClaps::NoteClaps( const better::Notes* notes_, const better::Timing* timing_, const std::filesystem::path& assets ) : notes(notes_), timing(timing_), - note_clap(), - chord_clap() + note_clap() { if (not note_clap.loadFromFile(assets / "sounds" / "note.wav")) { throw std::runtime_error("Could not load note clap audio file"); } - if (not chord_clap.loadFromFile(assets / "sounds" / "chord.wav")) { - throw std::runtime_error("Could not load chord clap audio file"); - } sf::SoundStream::initialize(note_clap.getChannelCount(), note_clap.getSampleRate()); samples.resize(note_clap.getChannelCount() * note_clap.getSampleRate(), 0); } -void ClapPlayer::set_notes_and_timing(const better::Notes* notes_, const better::Timing* timing_) { +void NoteClaps::set_notes_and_timing(const better::Notes* notes_, const better::Timing* timing_) { notes = notes_; timing = timing_; } -bool ClapPlayer::onGetData(sf::SoundStream::Chunk& data) { +bool NoteClaps::onGetData(sf::SoundStream::Chunk& data) { samples.assign(samples.size(), 0); if (timing != nullptr and notes != nullptr) { const auto start_sample = current_sample; @@ -51,7 +47,7 @@ bool ClapPlayer::onGetData(sf::SoundStream::Chunk& data) { // Should we still be playing the clap ? const auto next = std::next(it); const auto last_audible_start = start_sample - static_cast(note_clap.getSampleCount()); - if (it->first <= last_audible_start) { + if (it->first <= last_audible_start or ((not play_chords) and it->second > 1)) { it = notes_at_sample.erase(it); } else { const auto full_clap_start_in_buffer = static_cast(it->first) - static_cast(start_sample); @@ -92,12 +88,12 @@ bool ClapPlayer::onGetData(sf::SoundStream::Chunk& data) { return true; }; -void ClapPlayer::onSeek(sf::Time timeOffset) { +void NoteClaps::onSeek(sf::Time timeOffset) { current_sample = timeToSamples(timeOffset); notes_at_sample.clear(); }; -std::int64_t ClapPlayer::timeToSamples(sf::Time position) const { +std::int64_t NoteClaps::timeToSamples(sf::Time position) const { // Always ROUND, no unchecked truncation, hence the addition in the numerator. // This avoids most precision errors arising from "samples => Time => samples" conversions // Original rounding calculation is ((Micros * Freq * Channels) / 1000000) + 0.5 @@ -105,7 +101,7 @@ std::int64_t ClapPlayer::timeToSamples(sf::Time position) const { return ((static_cast(position.asMicroseconds()) * note_clap.getSampleRate() * note_clap.getChannelCount()) + 500000) / 1000000; } -sf::Time ClapPlayer::samplesToTime(std::int64_t samples) const { +sf::Time NoteClaps::samplesToTime(std::int64_t samples) const { sf::Time position = sf::Time::Zero; // Make sure we don't divide by 0 diff --git a/src/custom_sfml_audio/clap_player.hpp b/src/custom_sfml_audio/note_claps.hpp similarity index 89% rename from src/custom_sfml_audio/clap_player.hpp rename to src/custom_sfml_audio/note_claps.hpp index 387a3c7..9ec7eeb 100644 --- a/src/custom_sfml_audio/clap_player.hpp +++ b/src/custom_sfml_audio/note_claps.hpp @@ -10,15 +10,16 @@ #include "../better_timing.hpp" #include "precise_sound_stream.hpp" -class ClapPlayer: public PreciseSoundStream { +class NoteClaps: public PreciseSoundStream { public: - ClapPlayer( + NoteClaps( const better::Notes* notes_, const better::Timing* timing_, const std::filesystem::path& assets ); void set_notes_and_timing(const better::Notes* notes, const better::Timing* timing); + std::atomic play_chords = true; protected: bool onGetData(Chunk& data) override; @@ -35,5 +36,4 @@ private: const better::Notes* notes; const better::Timing* timing; sf::SoundBuffer note_clap; - sf::SoundBuffer chord_clap; }; \ No newline at end of file diff --git a/src/custom_sfml_audio/synced_sound_streams.cpp b/src/custom_sfml_audio/synced_sound_streams.cpp index a091a61..50ef592 100644 --- a/src/custom_sfml_audio/synced_sound_streams.cpp +++ b/src/custom_sfml_audio/synced_sound_streams.cpp @@ -83,10 +83,10 @@ void SyncedSoundStreams::unsafe_update_streams() { bool modified_stuff = false; auto _do_request = VariantVisitor { [this](const AddStream& a) { - InternalStream internal_stream{a.s, {}}; - internal_stream.buffers.m_channelCount = a.s->getChannelCount(); - internal_stream.buffers.m_sampleRate = a.s->getSampleRate(); - internal_stream.buffers.m_format = AudioDevice::getFormatFromChannelCount(a.s->getChannelCount()); + InternalStream internal_stream{a.stream, {}}; + internal_stream.buffers.m_channelCount = a.stream->getChannelCount(); + internal_stream.buffers.m_sampleRate = a.stream->getSampleRate(); + internal_stream.buffers.m_format = AudioDevice::getFormatFromChannelCount(a.stream->getChannelCount()); streams.emplace(a.name, internal_stream); }, [this](const RemoveStream& r) { diff --git a/src/custom_sfml_audio/synced_sound_streams.hpp b/src/custom_sfml_audio/synced_sound_streams.hpp index c98c383..d0f55e4 100644 --- a/src/custom_sfml_audio/synced_sound_streams.hpp +++ b/src/custom_sfml_audio/synced_sound_streams.hpp @@ -49,7 +49,7 @@ struct InternalStream { struct AddStream { std::string name; - std::shared_ptr s; + std::shared_ptr stream; }; struct RemoveStream { diff --git a/src/editor_state.cpp b/src/editor_state.cpp index 48356bb..4c6271c 100644 --- a/src/editor_state.cpp +++ b/src/editor_state.cpp @@ -35,7 +35,7 @@ #include "variant_visitor.hpp" EditorState::EditorState(const std::filesystem::path& assets_) : - clap_player(std::make_shared(nullptr, nullptr, assets_)), + note_claps(std::make_shared(nullptr, nullptr, assets_)), playfield(assets_), linear_view(assets_), applicable_timing(song.timing), @@ -43,7 +43,7 @@ EditorState::EditorState(const std::filesystem::path& assets_) : { reload_music(); reload_jacket(); - audio.add_stream(note_clap_stream, clap_player); + audio.add_stream(note_clap_stream, note_claps); }; EditorState::EditorState( @@ -53,7 +53,7 @@ EditorState::EditorState( ) : song(song_), song_path(song_path), - clap_player(std::make_shared(nullptr, nullptr, assets_)), + note_claps(std::make_shared(nullptr, nullptr, assets_)), playfield(assets_), linear_view(assets_), applicable_timing(song.timing), @@ -65,7 +65,7 @@ EditorState::EditorState( } reload_music(); reload_jacket(); - audio.add_stream(note_clap_stream, clap_player); + audio.add_stream(note_clap_stream, note_claps); }; int EditorState::get_volume() const { @@ -110,6 +110,14 @@ const Interval& EditorState::get_editable_range() { return editable_range; }; +void EditorState::toggle_playback() { + if (get_status() != sf::SoundSource::Playing) { + play(); + } else { + pause(); + } +} + void EditorState::play() { audio.play(); } @@ -795,7 +803,7 @@ void EditorState::open_chart(const std::string& name) { chart_state.emplace(chart, name_ref, assets); reload_editable_range(); reload_applicable_timing(); - clap_player->set_notes_and_timing(&chart.notes, &applicable_timing); + note_claps->set_notes_and_timing(&chart.notes, &applicable_timing); }; void EditorState::update_visible_notes() { diff --git a/src/editor_state.hpp b/src/editor_state.hpp index fa710d0..ecd0e05 100644 --- a/src/editor_state.hpp +++ b/src/editor_state.hpp @@ -8,7 +8,7 @@ #include -#include "custom_sfml_audio/clap_player.hpp" +#include "custom_sfml_audio/note_claps.hpp" #include "custom_sfml_audio/open_music.hpp" #include "custom_sfml_audio/synced_sound_streams.hpp" #include "widgets/linear_view.hpp" @@ -46,7 +46,7 @@ public: std::optional chart_state; SyncedSoundStreams audio; - std::shared_ptr clap_player; + std::shared_ptr note_claps; std::optional> music = {}; int get_volume() const; @@ -76,6 +76,7 @@ public: const Interval& get_editable_range(); + void toggle_playback(); void play(); void pause(); void stop(); diff --git a/src/main.cpp b/src/main.cpp index 9838803..bee2411 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -63,9 +64,9 @@ int main() { 16.f); ImGui::SFML::UpdateFontTexture(); - SoundEffect beatTick {assets_folder / "sounds" / "beat.wav"}; - SoundEffect noteTick {assets_folder / "sounds" / "note.wav"}; - SoundEffect chordTick {assets_folder / "sounds" / "chord.wav"}; + // SoundEffect beatTick {assets_folder / "sounds" / "beat.wav"}; + // SoundEffect noteTick {assets_folder / "sounds" / "note.wav"}; + // SoundEffect chordTick {assets_folder / "sounds" / "chord.wav"}; // Loading markers preview std::map markerPreviews; @@ -297,6 +298,7 @@ int main() { * F keys */ case sf::Keyboard::F3: + /* if (beatTick.toggle()) { notificationsQueue.push(std::make_shared( "Beat tick : on")); @@ -304,8 +306,10 @@ int main() { notificationsQueue.push(std::make_shared( "Beat tick : off")); } + */ break; case sf::Keyboard::F4: + /* if (event.key.shift) { if (chordTick.toggle()) { noteTick.shouldPlay = true; @@ -325,11 +329,12 @@ int main() { "Note tick : off")); } } + */ break; case sf::Keyboard::Space: if (not ImGui::GetIO().WantTextInput) { if (editor_state) { - editor_state->playing = not editor_state->playing; + editor_state->toggle_playback(); } } break; @@ -416,34 +421,13 @@ int main() { // Audio playback management if (editor_state) { editor_state->update_visible_notes(); - if (editor_state->playing) { + if (editor_state->get_status() == sf::SoundSource::Playing) { editor_state->previous_playback_position = editor_state->playback_position; - editor_state->playback_position = editor_state->current_time() + delta * (editor_state->get_speed() / 10.f); - switch (editor_state->get_status()) { - case sf::Music::Stopped: - case sf::Music::Paused: - editor_state->set_playback_position(editor_state->current_time()); - editor_state->play(); - break; - case sf::Music::Playing: - editor_state->playback_position = editor_state->get_precise_playback_position(); - break; - default: - break; - } - if (beatTick.shouldPlay) { - const auto previous_beat = editor_state->previous_exact_beats(); - const auto current_beat = editor_state->current_exact_beats(); - if (floor_fraction(previous_beat) != floor_fraction(current_beat)) { - beatTick.play(); - } - } + editor_state->playback_position = editor_state->get_precise_playback_position(); + // editor_state->playback_position = editor_state->current_time() + delta * (editor_state->get_speed() / 10.f); if (editor_state->current_time() > editor_state->get_editable_range().end) { - editor_state->playing = false; - editor_state->playback_position = editor_state->get_editable_range().end; + editor_state->pause(); } - } else if (editor_state->get_status() == sf::SoundSource::Playing) { - editor_state->pause(); } } @@ -495,24 +479,18 @@ int main() { } else { chartPropertiesDialog.should_refresh_values = true; } - if (editor_state->showSoundSettings) { - ImGui::Begin("Sound Settings", &editor_state->showSoundSettings, ImGuiWindowFlags_AlwaysAutoResize); - { - if (ImGui::TreeNode("Beat Tick")) { - beatTick.displayControls(); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Note Tick")) { - noteTick.displayControls(); - ImGui::Checkbox("Chord sound", &chordTick.shouldPlay); + ImGui::Begin("Sound Settings", &editor_state->showSoundSettings, ImGuiWindowFlags_AlwaysAutoResize); { + if (ImGui::TreeNode("Note Clap")) { + static auto play_chords = editor_state->note_claps->play_chords.load(); + if (ImGui::Checkbox("Play on chords", &play_chords)) { + editor_state->note_claps->play_chords.store(play_chords); + } ImGui::TreePop(); } } ImGui::End(); } - } else { bg.render(window); }