mirror of
https://gitlab.com/square-game-liberation-front/F.E.I.S.git
synced 2025-03-01 07:50:25 +01:00
Small rewrites on how the audio callback works ... no good indication that this solved the problem but who knows ?
This commit is contained in:
parent
8515f16d87
commit
2cac1645fa
@ -2,60 +2,84 @@
|
|||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
std::optional<Slice> compute_sample_slice(
|
||||||
|
const std::int64_t buffer_start,
|
||||||
|
const std::int64_t buffer_size,
|
||||||
|
const std::int64_t sample_start,
|
||||||
|
const std::int64_t sample_size,
|
||||||
|
const std::optional<std::int64_t> next_sample_start
|
||||||
|
) {
|
||||||
|
const auto buffer_end = buffer_start + buffer_size;
|
||||||
|
const auto sample_end = sample_start + sample_size;
|
||||||
|
const auto sample_deoverlapped_end = [&](){
|
||||||
|
if (next_sample_start.has_value()) {
|
||||||
|
return std::min(*next_sample_start, sample_end);
|
||||||
|
} else {
|
||||||
|
return sample_end;
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
const auto sample_slice_start = std::max(sample_start, buffer_start);
|
||||||
|
const auto sample_slice_end = std::min(sample_deoverlapped_end, buffer_end);
|
||||||
|
const auto slice_size = sample_slice_end - sample_slice_start;
|
||||||
|
const auto slice_start_relative_to_sample_start = sample_slice_start - sample_start;
|
||||||
|
const auto slice_start_relative_to_buffer_start = sample_slice_start - buffer_start;
|
||||||
|
// all the possible error cases I could think of
|
||||||
|
if (
|
||||||
|
sample_deoverlapped_end <= buffer_start
|
||||||
|
or sample_start >= buffer_end
|
||||||
|
or slice_size <= 0
|
||||||
|
) {
|
||||||
|
return {};
|
||||||
|
} else {
|
||||||
|
return Slice{
|
||||||
|
.start_in_sample=slice_start_relative_to_sample_start,
|
||||||
|
.size=slice_size,
|
||||||
|
.start_in_buffer=slice_start_relative_to_buffer_start,
|
||||||
|
.ends_in_this_buffer=sample_deoverlapped_end <= buffer_end
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void copy_sample_at_points(
|
void copy_sample_at_points(
|
||||||
const std::shared_ptr<FakePitchedSoundStream::sound_buffer_type>& sample,
|
const std::shared_ptr<FakePitchedSoundStream::sound_buffer_type>& sample,
|
||||||
std::span<sf::Int16> output_buffer,
|
std::span<sf::Int16> output_buffer,
|
||||||
std::set<std::int64_t>& starting_points,
|
std::set<std::int64_t>& starting_points,
|
||||||
std::int64_t absolute_buffer_start
|
std::int64_t buffer_start
|
||||||
) {
|
) {
|
||||||
std::ranges::fill(output_buffer, 0);
|
std::ranges::fill(output_buffer, 0);
|
||||||
for (auto it = starting_points.begin(); it != starting_points.end();) {
|
for (auto it = starting_points.begin(); it != starting_points.end();) {
|
||||||
const auto absolute_sample_start = *it;
|
const auto next_sample_start = [&]() -> std::optional<std::int64_t> {
|
||||||
const auto absolute_buffer_end = absolute_buffer_start + static_cast<std::int64_t>(output_buffer.size());
|
const auto next = std::next(it);
|
||||||
const auto absolute_sample_end = absolute_sample_start + static_cast<std::int64_t>(sample->getSampleCount());
|
if (next == starting_points.end()) {
|
||||||
const auto absolute_sample_deoverlapped_end = std::min(
|
return {};
|
||||||
absolute_sample_end,
|
} else {
|
||||||
[&](const auto& it){
|
return *next;
|
||||||
const auto next = std::next(it);
|
}
|
||||||
if (next != starting_points.end()) {
|
}();
|
||||||
return *next;
|
const auto slice = compute_sample_slice(
|
||||||
} else {
|
buffer_start,
|
||||||
return INT64_MAX;
|
static_cast<std::int64_t>(output_buffer.size()),
|
||||||
}
|
*it,
|
||||||
}(it)
|
static_cast<std::int64_t>(sample->getSampleCount()),
|
||||||
|
next_sample_start
|
||||||
);
|
);
|
||||||
const auto absolute_sample_slice_start = std::max(
|
|
||||||
absolute_sample_start,
|
|
||||||
absolute_buffer_start
|
|
||||||
);
|
|
||||||
const auto absolute_sample_slice_end = std::min(
|
|
||||||
absolute_sample_deoverlapped_end,
|
|
||||||
absolute_buffer_end
|
|
||||||
);
|
|
||||||
const auto slice_size = absolute_sample_slice_end - absolute_sample_slice_start;
|
|
||||||
const auto slice_start_relative_to_sample_start = absolute_sample_slice_start - absolute_sample_start;
|
|
||||||
const auto slice_start_relative_to_buffer_start = absolute_sample_slice_start - absolute_buffer_start;
|
|
||||||
|
|
||||||
// Exit early in all the possible error case I could think of
|
// bounds checking failed somehow
|
||||||
if (
|
if (not slice) {
|
||||||
absolute_sample_deoverlapped_end <= absolute_buffer_start
|
|
||||||
or absolute_sample_start >= absolute_buffer_end
|
|
||||||
or slice_size <= 0
|
|
||||||
) {
|
|
||||||
it = starting_points.erase(it);
|
it = starting_points.erase(it);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto input_start = sample->getSamples() + slice_start_relative_to_sample_start;
|
const auto input_start = sample->getSamples() + slice->start_in_sample;
|
||||||
const auto input_end = input_start + slice_size;
|
const auto input_end = input_start + slice->size;
|
||||||
const auto output_start = output_buffer.begin() + slice_start_relative_to_buffer_start;
|
const auto output_start = output_buffer.begin() + slice->start_in_buffer;
|
||||||
std::copy(
|
std::copy(
|
||||||
input_start,
|
input_start,
|
||||||
input_end,
|
input_end,
|
||||||
output_start
|
output_start
|
||||||
);
|
);
|
||||||
// has this sample been fully played in this buffer ?
|
// has this sample been fully played in this buffer ?
|
||||||
if (absolute_sample_deoverlapped_end <= absolute_buffer_end) {
|
if (slice->ends_in_this_buffer) {
|
||||||
it = starting_points.erase(it);
|
it = starting_points.erase(it);
|
||||||
} else {
|
} else {
|
||||||
++it;
|
++it;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <span>
|
#include <span>
|
||||||
|
|
||||||
@ -10,6 +11,22 @@
|
|||||||
#include <SFML/Config.hpp>
|
#include <SFML/Config.hpp>
|
||||||
|
|
||||||
#include "fake_pitched_sound_stream.hpp"
|
#include "fake_pitched_sound_stream.hpp"
|
||||||
|
#include "fmt/core.h"
|
||||||
|
|
||||||
|
struct Slice {
|
||||||
|
std::int64_t start_in_sample;
|
||||||
|
std::int64_t size;
|
||||||
|
std::int64_t start_in_buffer;
|
||||||
|
bool ends_in_this_buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::optional<Slice> compute_sample_slice(
|
||||||
|
const std::int64_t buffer_start,
|
||||||
|
const std::int64_t buffer_size,
|
||||||
|
const std::int64_t sample_start,
|
||||||
|
const std::int64_t sample_size,
|
||||||
|
const std::optional<std::int64_t> next_sample_start
|
||||||
|
);
|
||||||
|
|
||||||
void copy_sample_at_points(
|
void copy_sample_at_points(
|
||||||
const std::shared_ptr<FakePitchedSoundStream::sound_buffer_type>& sample,
|
const std::shared_ptr<FakePitchedSoundStream::sound_buffer_type>& sample,
|
||||||
@ -23,56 +40,42 @@ void copy_sample_at_points(
|
|||||||
const std::shared_ptr<FakePitchedSoundStream::sound_buffer_type>& sample,
|
const std::shared_ptr<FakePitchedSoundStream::sound_buffer_type>& sample,
|
||||||
std::span<sf::Int16> output_buffer,
|
std::span<sf::Int16> output_buffer,
|
||||||
std::map<std::int64_t, T>& starting_points,
|
std::map<std::int64_t, T>& starting_points,
|
||||||
std::int64_t absolute_buffer_start
|
std::int64_t buffer_start
|
||||||
) {
|
) {
|
||||||
std::ranges::fill(output_buffer, 0);
|
std::ranges::fill(output_buffer, 0);
|
||||||
for (auto it = starting_points.begin(); it != starting_points.end();) {
|
for (auto it = starting_points.begin(); it != starting_points.end();) {
|
||||||
const auto absolute_sample_start = it->first;
|
const auto next_sample_start = [&]() -> std::optional<std::int64_t> {
|
||||||
const auto absolute_buffer_end = absolute_buffer_start + static_cast<std::int64_t>(output_buffer.size());
|
const auto next = std::next(it);
|
||||||
const auto absolute_sample_end = absolute_sample_start + static_cast<std::int64_t>(sample->getSampleCount());
|
if (next == starting_points.end()) {
|
||||||
const auto absolute_sample_deoverlapped_end = std::min(
|
return {};
|
||||||
absolute_sample_end,
|
} else {
|
||||||
[&](const auto& it){
|
return next->first;
|
||||||
const auto next = std::next(it);
|
}
|
||||||
if (next != starting_points.end()) {
|
}();
|
||||||
return next->first;
|
const auto slice = compute_sample_slice(
|
||||||
} else {
|
buffer_start,
|
||||||
return INT64_MAX;
|
static_cast<std::int64_t>(output_buffer.size()),
|
||||||
}
|
it->first,
|
||||||
}(it)
|
static_cast<std::int64_t>(sample->getSampleCount()),
|
||||||
|
next_sample_start
|
||||||
);
|
);
|
||||||
const auto absolute_sample_slice_start = std::max(
|
|
||||||
absolute_sample_start,
|
|
||||||
absolute_buffer_start
|
|
||||||
);
|
|
||||||
const auto absolute_sample_slice_end = std::min(
|
|
||||||
absolute_sample_deoverlapped_end,
|
|
||||||
absolute_buffer_end
|
|
||||||
);
|
|
||||||
const auto slice_size = absolute_sample_slice_end - absolute_sample_slice_start;
|
|
||||||
const auto slice_start_relative_to_sample_start = absolute_sample_slice_start - absolute_sample_start;
|
|
||||||
const auto slice_start_relative_to_buffer_start = absolute_sample_slice_start - absolute_buffer_start;
|
|
||||||
|
|
||||||
// Exit early in all the possible error cases I could think of
|
// bounds checking failed somehow
|
||||||
if (
|
if (not slice) {
|
||||||
absolute_sample_deoverlapped_end <= absolute_buffer_start
|
|
||||||
or absolute_sample_start >= absolute_buffer_end
|
|
||||||
or slice_size <= 0
|
|
||||||
) {
|
|
||||||
it = starting_points.erase(it);
|
it = starting_points.erase(it);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto input_start = sample->getSamples() + slice_start_relative_to_sample_start;
|
const auto input_start = sample->getSamples() + slice->start_in_sample;
|
||||||
const auto input_end = input_start + slice_size;
|
const auto input_end = input_start + slice->size;
|
||||||
const auto output_start = output_buffer.begin() + slice_start_relative_to_buffer_start;
|
const auto output_start = output_buffer.begin() + slice->start_in_buffer;
|
||||||
std::copy(
|
std::copy(
|
||||||
input_start,
|
input_start,
|
||||||
input_end,
|
input_end,
|
||||||
output_start
|
output_start
|
||||||
);
|
);
|
||||||
// has this sample been fully played in this buffer ?
|
// has this sample been fully played in this buffer ?
|
||||||
if (absolute_sample_deoverlapped_end <= absolute_buffer_end) {
|
if (slice->ends_in_this_buffer) {
|
||||||
it = starting_points.erase(it);
|
it = starting_points.erase(it);
|
||||||
} else {
|
} else {
|
||||||
++it;
|
++it;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user