summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/audio_core/sink/sink_stream.cpp34
-rw-r--r--src/audio_core/sink/sink_stream.h3
2 files changed, 20 insertions, 17 deletions
diff --git a/src/audio_core/sink/sink_stream.cpp b/src/audio_core/sink/sink_stream.cpp
index 404dcd0e9..6081352a2 100644
--- a/src/audio_core/sink/sink_stream.cpp
+++ b/src/audio_core/sink/sink_stream.cpp
@@ -12,6 +12,7 @@
12#include "audio_core/sink/sink_stream.h" 12#include "audio_core/sink/sink_stream.h"
13#include "common/common_types.h" 13#include "common/common_types.h"
14#include "common/fixed_point.h" 14#include "common/fixed_point.h"
15#include "common/scope_exit.h"
15#include "common/settings.h" 16#include "common/settings.h"
16#include "core/core.h" 17#include "core/core.h"
17#include "core/core_timing.h" 18#include "core/core_timing.h"
@@ -19,9 +20,12 @@
19namespace AudioCore::Sink { 20namespace AudioCore::Sink {
20 21
21void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span<s16> samples) { 22void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span<s16> samples) {
22 if (type == StreamType::In) { 23 SCOPE_EXIT({
23 queue.enqueue(buffer); 24 queue.enqueue(buffer);
24 queued_buffers++; 25 ++queued_buffers;
26 });
27
28 if (type == StreamType::In) {
25 return; 29 return;
26 } 30 }
27 31
@@ -66,16 +70,17 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span<s16> samples) {
66 static_cast<s16>(std::clamp(right_sample, min, max)); 70 static_cast<s16>(std::clamp(right_sample, min, max));
67 } 71 }
68 72
69 samples = samples.subspan(0, samples.size() / system_channels * device_channels); 73 samples_buffer.Push(samples.subspan(0, samples.size() / system_channels * device_channels));
74 return;
75 }
70 76
71 } else if (system_channels == 2 && device_channels == 6) { 77 if (system_channels == 2 && device_channels == 6) {
72 // We need moar samples! Not all games will provide 6 channel audio. 78 // We need moar samples! Not all games will provide 6 channel audio.
73 // TODO: Implement some upmixing here. Currently just passthrough, with other 79 // TODO: Implement some upmixing here. Currently just passthrough, with other
74 // channels left as silence. 80 // channels left as silence.
75 auto new_size = samples.size() / system_channels * device_channels; 81 std::vector<s16> new_samples(samples.size() / system_channels * device_channels);
76 tmp_samples.resize_destructive(new_size);
77 82
78 for (u32 read_index = 0, write_index = 0; read_index < new_size; 83 for (u32 read_index = 0, write_index = 0; read_index < samples.size();
79 read_index += system_channels, write_index += device_channels) { 84 read_index += system_channels, write_index += device_channels) {
80 const auto left_sample{static_cast<s16>(std::clamp( 85 const auto left_sample{static_cast<s16>(std::clamp(
81 static_cast<s32>( 86 static_cast<s32>(
@@ -83,7 +88,7 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span<s16> samples) {
83 volume), 88 volume),
84 min, max))}; 89 min, max))};
85 90
86 tmp_samples[write_index + static_cast<u32>(Channels::FrontLeft)] = left_sample; 91 new_samples[write_index + static_cast<u32>(Channels::FrontLeft)] = left_sample;
87 92
88 const auto right_sample{static_cast<s16>(std::clamp( 93 const auto right_sample{static_cast<s16>(std::clamp(
89 static_cast<s32>( 94 static_cast<s32>(
@@ -91,20 +96,21 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span<s16> samples) {
91 volume), 96 volume),
92 min, max))}; 97 min, max))};
93 98
94 tmp_samples[write_index + static_cast<u32>(Channels::FrontRight)] = right_sample; 99 new_samples[write_index + static_cast<u32>(Channels::FrontRight)] = right_sample;
95 } 100 }
96 samples = std::span<s16>(tmp_samples);
97 101
98 } else if (volume != 1.0f) { 102 samples_buffer.Push(new_samples);
99 for (u32 i = 0; i < samples.size(); i++) { 103 return;
104 }
105
106 if (volume != 1.0f) {
107 for (u32 i = 0; i < samples.size(); ++i) {
100 samples[i] = static_cast<s16>( 108 samples[i] = static_cast<s16>(
101 std::clamp(static_cast<s32>(static_cast<f32>(samples[i]) * volume), min, max)); 109 std::clamp(static_cast<s32>(static_cast<f32>(samples[i]) * volume), min, max));
102 } 110 }
103 } 111 }
104 112
105 samples_buffer.Push(samples); 113 samples_buffer.Push(samples);
106 queue.enqueue(buffer);
107 queued_buffers++;
108} 114}
109 115
110std::vector<s16> SinkStream::ReleaseBuffer(u64 num_samples) { 116std::vector<s16> SinkStream::ReleaseBuffer(u64 num_samples) {
diff --git a/src/audio_core/sink/sink_stream.h b/src/audio_core/sink/sink_stream.h
index 98d72ace1..6a4996ca3 100644
--- a/src/audio_core/sink/sink_stream.h
+++ b/src/audio_core/sink/sink_stream.h
@@ -16,7 +16,6 @@
16#include "common/polyfill_thread.h" 16#include "common/polyfill_thread.h"
17#include "common/reader_writer_queue.h" 17#include "common/reader_writer_queue.h"
18#include "common/ring_buffer.h" 18#include "common/ring_buffer.h"
19#include "common/scratch_buffer.h"
20#include "common/thread.h" 19#include "common/thread.h"
21 20
22namespace Core { 21namespace Core {
@@ -256,8 +255,6 @@ private:
256 /// Signalled when ring buffer entries are consumed 255 /// Signalled when ring buffer entries are consumed
257 std::condition_variable_any release_cv; 256 std::condition_variable_any release_cv;
258 std::mutex release_mutex; 257 std::mutex release_mutex;
259 /// Temporary buffer for appending samples when upmixing
260 Common::ScratchBuffer<s16> tmp_samples{};
261}; 258};
262 259
263using SinkStreamPtr = std::unique_ptr<SinkStream>; 260using SinkStreamPtr = std::unique_ptr<SinkStream>;