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/System/Time.hpp>
#include <algorithm>
#include <limits>
#include <memory>
#include <stdexcept>
@ -96,6 +97,7 @@ std::shared_ptr<NoteClaps> NoteClaps::with(
bool NoteClaps::onGetData(sf::SoundStream::Chunk& data) {
if (timing != nullptr and notes != nullptr) {
long_note_ends.clear();
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 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 better::TapNote& t) {
count_clap_at(t.get_time());
@ -119,7 +131,7 @@ bool NoteClaps::onGetData(sf::SoundStream::Chunk& data) {
[&](const better::LongNote& l) {
count_clap_at(l.get_time());
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) {
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(
sample,
output_buffer,

View File

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

View File

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

View File

@ -59,7 +59,8 @@ public:
void update_streams(
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 remove_stream(const std::string& name);
@ -86,7 +87,10 @@ protected:
void setProcessingInterval(sf::Time interval);
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 remove_stream_internal(const std::string& name);
void streamData();

View File

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