Hoooly shit it seems to be working now

This commit is contained in:
Stepland 2022-10-08 01:01:49 +02:00
parent beaea91380
commit 59b714c342
5 changed files with 47 additions and 20 deletions

View File

@ -2,6 +2,7 @@
#include <SFML/Audio/SoundBuffer.hpp> #include <SFML/Audio/SoundBuffer.hpp>
#include <SFML/System/Time.hpp> #include <SFML/System/Time.hpp>
#include <algorithm>
#include <limits> #include <limits>
#include <memory> #include <memory>
#include <stdexcept> #include <stdexcept>
@ -96,6 +97,7 @@ std::shared_ptr<NoteClaps> NoteClaps::with(
bool NoteClaps::onGetData(sf::SoundStream::Chunk& data) { bool NoteClaps::onGetData(sf::SoundStream::Chunk& data) {
if (timing != nullptr and notes != nullptr) { if (timing != nullptr and notes != nullptr) {
long_note_ends.clear();
const auto absolute_buffer_start = first_sample_of_next_buffer; const auto absolute_buffer_start = first_sample_of_next_buffer;
const std::int64_t absolute_buffer_end = first_sample_of_next_buffer + static_cast<std::int64_t>(output_buffer.size()); const std::int64_t absolute_buffer_end = first_sample_of_next_buffer + static_cast<std::int64_t>(output_buffer.size());
const auto start_time = samples_to_music_time(absolute_buffer_start); const auto start_time = samples_to_music_time(absolute_buffer_start);
@ -112,6 +114,16 @@ bool NoteClaps::onGetData(sf::SoundStream::Chunk& data) {
} }
}; };
const auto add_long_note_end = [&](const Fraction beat){
const auto time = timing->time_at(beat);
const auto sample = static_cast<std::int64_t>(music_time_to_samples(time));
// we don't want claps that *start* at the end sample since
// absolute_buffer_end is an *exculsive* end
if (sample < absolute_buffer_end) {
long_note_ends.insert(sample);
}
};
const auto add_claps_of_note = VariantVisitor { const auto add_claps_of_note = VariantVisitor {
[&](const better::TapNote& t) { [&](const better::TapNote& t) {
count_clap_at(t.get_time()); count_clap_at(t.get_time());
@ -119,7 +131,7 @@ bool NoteClaps::onGetData(sf::SoundStream::Chunk& data) {
[&](const better::LongNote& l) { [&](const better::LongNote& l) {
count_clap_at(l.get_time()); count_clap_at(l.get_time());
if (play_long_note_ends) { if (play_long_note_ends) {
count_clap_at(l.get_end()); add_long_note_end(l.get_end());
} }
}, },
}; };
@ -130,6 +142,11 @@ bool NoteClaps::onGetData(sf::SoundStream::Chunk& data) {
if (not play_chords) { if (not play_chords) {
std::erase_if(notes_at_sample, [](const auto& it){return it.second > 1;}); std::erase_if(notes_at_sample, [](const auto& it){return it.second > 1;});
} }
if (play_long_note_ends) {
for (const auto& it : long_note_ends) {
notes_at_sample[it] = 1;
}
}
copy_sample_at_points( copy_sample_at_points(
sample, sample,
output_buffer, output_buffer,

View File

@ -52,6 +52,7 @@ protected:
private: private:
std::map<std::int64_t, unsigned int> notes_at_sample; std::map<std::int64_t, unsigned int> notes_at_sample;
std::set<std::int64_t> long_note_ends;
bool play_chords = true; bool play_chords = true;
bool play_long_note_ends = false; bool play_long_note_ends = false;

View File

@ -63,16 +63,20 @@ SyncedSoundStreams::~SyncedSoundStreams() {
awaitStreamingThread(); awaitStreamingThread();
} }
void SyncedSoundStreams::change_streams(std::function<void()> callback) { void SyncedSoundStreams::change_streams(
std::function<void()> callback,
std::optional<float> new_pitch
) {
const auto oldStatus = getStatus(); const auto oldStatus = getStatus();
pause();
setPitch(pitch);
const auto position = getPlayingOffset(); const auto position = getPlayingOffset();
stop(); stop();
callback(); callback();
reload_sources(); reload_sources();
if (new_pitch) {
setPitch(*new_pitch);
}
setPlayingOffset(position); setPlayingOffset(position);
if (oldStatus == sf::SoundSource::Playing) { if (oldStatus == sf::SoundSource::Playing) {
play(); play();
@ -81,17 +85,21 @@ void SyncedSoundStreams::change_streams(std::function<void()> callback) {
void SyncedSoundStreams::update_streams( void SyncedSoundStreams::update_streams(
const std::map<std::string, NewStream>& to_add, const std::map<std::string, NewStream>& to_add,
const std::initializer_list<std::string>& to_remove const std::initializer_list<std::string>& to_remove,
std::optional<float> new_pitch
) { ) {
change_streams([&](){ change_streams(
for (const auto& name : to_remove) { [&](){
remove_stream_internal(name); for (const auto& name : to_remove) {
} remove_stream_internal(name);
for (const auto& [name, new_stream] : to_add) { }
remove_stream_internal(name); for (const auto& [name, new_stream] : to_add) {
add_stream_internal(name, new_stream); remove_stream_internal(name);
} add_stream_internal(name, new_stream);
}); }
},
new_pitch
);
} }

View File

@ -59,7 +59,8 @@ public:
void update_streams( void update_streams(
const std::map<std::string, NewStream>& to_add, const std::map<std::string, NewStream>& to_add,
const std::initializer_list<std::string>& to_remove = {} const std::initializer_list<std::string>& to_remove = {},
std::optional<float> new_pitch = {}
); );
void add_stream(const std::string& name, NewStream s); void add_stream(const std::string& name, NewStream s);
void remove_stream(const std::string& name); void remove_stream(const std::string& name);
@ -86,7 +87,10 @@ protected:
void setProcessingInterval(sf::Time interval); void setProcessingInterval(sf::Time interval);
private: private:
void change_streams(std::function<void()> callback); void change_streams(
std::function<void()> callback,
std::optional<float> new_pitch = {}
);
void add_stream_internal(const std::string& name, NewStream s); void add_stream_internal(const std::string& name, NewStream s);
void remove_stream_internal(const std::string& name); void remove_stream_internal(const std::string& name);
void streamData(); void streamData();

View File

@ -216,10 +216,7 @@ void EditorState::set_pitch(float pitch) {
chord_claps = chord_claps->with_pitch(pitch); chord_claps = chord_claps->with_pitch(pitch);
update[chord_clap_stream] = {chord_claps, true}; update[chord_clap_stream] = {chord_claps, true};
} }
// setPitch has to be called before update_streams to avoid problems in audio.update_streams(update, {}, pitch);
// the internal call to setPlaybackPosition
audio.setPitch(pitch);
audio.update_streams(update);
} }
float EditorState::get_pitch() const { float EditorState::get_pitch() const {