summaryrefslogtreecommitdiffstats
path: root/src/audio_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio_core')
-rw-r--r--src/audio_core/audio_renderer.cpp19
-rw-r--r--src/audio_core/audio_renderer.h13
-rw-r--r--src/audio_core/cubeb_sink.cpp2
-rw-r--r--src/audio_core/stream.cpp23
-rw-r--r--src/audio_core/stream.h9
5 files changed, 46 insertions, 20 deletions
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp
index 50846a854..d64452617 100644
--- a/src/audio_core/audio_renderer.cpp
+++ b/src/audio_core/audio_renderer.cpp
@@ -180,11 +180,12 @@ ResultVal<std::vector<u8>> AudioRenderer::UpdateAudioRenderer(const std::vector<
// Copy output header
UpdateDataHeader response_data{worker_params};
- std::vector<u8> output_params(response_data.total_size);
if (behavior_info.IsElapsedFrameCountSupported()) {
- response_data.frame_count = 0x10;
- response_data.total_size += 0x10;
+ response_data.render_info = sizeof(RendererInfo);
+ response_data.total_size += sizeof(RendererInfo);
}
+
+ std::vector<u8> output_params(response_data.total_size);
std::memcpy(output_params.data(), &response_data, sizeof(UpdateDataHeader));
// Copy output memory pool entries
@@ -219,6 +220,17 @@ ResultVal<std::vector<u8>> AudioRenderer::UpdateAudioRenderer(const std::vector<
return Audren::ERR_INVALID_PARAMETERS;
}
+ if (behavior_info.IsElapsedFrameCountSupported()) {
+ const std::size_t renderer_info_offset{
+ sizeof(UpdateDataHeader) + response_data.memory_pools_size + response_data.voices_size +
+ response_data.effects_size + response_data.sinks_size +
+ response_data.performance_manager_size + response_data.behavior_size};
+ RendererInfo renderer_info{};
+ renderer_info.elasped_frame_count = elapsed_frame_count;
+ std::memcpy(output_params.data() + renderer_info_offset, &renderer_info,
+ sizeof(RendererInfo));
+ }
+
return MakeResult(output_params);
}
@@ -447,6 +459,7 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
}
}
audio_out->QueueBuffer(stream, tag, std::move(buffer));
+ elapsed_frame_count++;
}
void AudioRenderer::ReleaseAndQueueBuffers() {
diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h
index 1f9114c07..f0b691a86 100644
--- a/src/audio_core/audio_renderer.h
+++ b/src/audio_core/audio_renderer.h
@@ -196,6 +196,12 @@ struct EffectOutStatus {
};
static_assert(sizeof(EffectOutStatus) == 0x10, "EffectOutStatus is an invalid size");
+struct RendererInfo {
+ u64_le elasped_frame_count{};
+ INSERT_PADDING_WORDS(2);
+};
+static_assert(sizeof(RendererInfo) == 0x10, "RendererInfo is an invalid size");
+
struct UpdateDataHeader {
UpdateDataHeader() {}
@@ -209,7 +215,7 @@ struct UpdateDataHeader {
mixes_size = 0x0;
sinks_size = config.sink_count * 0x20;
performance_manager_size = 0x10;
- frame_count = 0;
+ render_info = 0;
total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size + voices_size +
effects_size + sinks_size + performance_manager_size;
}
@@ -223,8 +229,8 @@ struct UpdateDataHeader {
u32_le mixes_size{};
u32_le sinks_size{};
u32_le performance_manager_size{};
- INSERT_PADDING_WORDS(1);
- u32_le frame_count{};
+ u32_le splitter_size{};
+ u32_le render_info{};
INSERT_PADDING_WORDS(4);
u32_le total_size{};
};
@@ -258,6 +264,7 @@ private:
std::unique_ptr<AudioOut> audio_out;
StreamPtr stream;
Core::Memory::Memory& memory;
+ std::size_t elapsed_frame_count{};
};
} // namespace AudioCore
diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp
index c4e0e30fe..41bf5cd4d 100644
--- a/src/audio_core/cubeb_sink.cpp
+++ b/src/audio_core/cubeb_sink.cpp
@@ -193,7 +193,7 @@ long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const
const std::size_t samples_to_write = num_channels * num_frames;
std::size_t samples_written;
- if (Settings::values.enable_audio_stretching) {
+ if (Settings::values.enable_audio_stretching.GetValue()) {
const std::vector<s16> in{impl->queue.Pop()};
const std::size_t num_in{in.size() / num_channels};
s16* const out{reinterpret_cast<s16*>(buffer)};
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp
index 4ca98f8ea..aab3e979a 100644
--- a/src/audio_core/stream.cpp
+++ b/src/audio_core/stream.cpp
@@ -38,7 +38,7 @@ Stream::Stream(Core::Timing::CoreTiming& core_timing, u32 sample_rate, Format fo
sink_stream{sink_stream}, core_timing{core_timing}, name{std::move(name_)} {
release_event = Core::Timing::CreateEvent(
- name, [this](u64 userdata, s64 cycles_late) { ReleaseActiveBuffer(); });
+ name, [this](u64 userdata, s64 cycles_late) { ReleaseActiveBuffer(cycles_late); });
}
void Stream::Play() {
@@ -59,15 +59,15 @@ Stream::State Stream::GetState() const {
return state;
}
-s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const {
+s64 Stream::GetBufferReleaseNS(const Buffer& buffer) const {
const std::size_t num_samples{buffer.GetSamples().size() / GetNumChannels()};
- const auto us =
- std::chrono::microseconds((static_cast<u64>(num_samples) * 1000000) / sample_rate);
- return Core::Timing::usToCycles(us);
+ const auto ns =
+ std::chrono::nanoseconds((static_cast<u64>(num_samples) * 1000000000ULL) / sample_rate);
+ return ns.count();
}
static void VolumeAdjustSamples(std::vector<s16>& samples, float game_volume) {
- const float volume{std::clamp(Settings::values.volume - (1.0f - game_volume), 0.0f, 1.0f)};
+ const float volume{std::clamp(Settings::Volume() - (1.0f - game_volume), 0.0f, 1.0f)};
if (volume == 1.0f) {
return;
@@ -80,7 +80,7 @@ static void VolumeAdjustSamples(std::vector<s16>& samples, float game_volume) {
}
}
-void Stream::PlayNextBuffer() {
+void Stream::PlayNextBuffer(s64 cycles_late) {
if (!IsPlaying()) {
// Ensure we are in playing state before playing the next buffer
sink_stream.Flush();
@@ -105,14 +105,17 @@ void Stream::PlayNextBuffer() {
sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples());
- core_timing.ScheduleEvent(GetBufferReleaseCycles(*active_buffer), release_event, {});
+ core_timing.ScheduleEvent(
+ GetBufferReleaseNS(*active_buffer) -
+ (Settings::values.enable_audio_stretching.GetValue() ? 0 : cycles_late),
+ release_event, {});
}
-void Stream::ReleaseActiveBuffer() {
+void Stream::ReleaseActiveBuffer(s64 cycles_late) {
ASSERT(active_buffer);
released_buffers.push(std::move(active_buffer));
release_callback();
- PlayNextBuffer();
+ PlayNextBuffer(cycles_late);
}
bool Stream::QueueBuffer(BufferPtr&& buffer) {
diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h
index 1708a4d98..524376257 100644
--- a/src/audio_core/stream.h
+++ b/src/audio_core/stream.h
@@ -90,13 +90,16 @@ public:
private:
/// Plays the next queued buffer in the audio stream, starting playback if necessary
- void PlayNextBuffer();
+ void PlayNextBuffer(s64 cycles_late = 0);
/// Releases the actively playing buffer, signalling that it has been completed
- void ReleaseActiveBuffer();
+ void ReleaseActiveBuffer(s64 cycles_late = 0);
/// Gets the number of core cycles when the specified buffer will be released
- s64 GetBufferReleaseCycles(const Buffer& buffer) const;
+ s64 GetBufferReleaseNS(const Buffer& buffer) const;
+
+ /// Gets the number of core cycles when the specified buffer will be released
+ s64 GetBufferReleaseNSHostTiming(const Buffer& buffer) const;
u32 sample_rate; ///< Sample rate of the stream
Format format; ///< Format of the stream