summaryrefslogtreecommitdiff
path: root/src/audio_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio_core')
-rw-r--r--src/audio_core/algorithm/filter.cpp12
-rw-r--r--src/audio_core/algorithm/filter.h4
-rw-r--r--src/audio_core/algorithm/interpolate.cpp12
-rw-r--r--src/audio_core/algorithm/interpolate.h4
-rw-r--r--src/audio_core/audio_out.cpp3
-rw-r--r--src/audio_core/audio_out.h2
-rw-r--r--src/audio_core/audio_renderer.cpp64
-rw-r--r--src/audio_core/audio_renderer.h51
-rw-r--r--src/audio_core/codec.cpp20
-rw-r--r--src/audio_core/codec.h2
-rw-r--r--src/audio_core/cubeb_sink.cpp31
-rw-r--r--src/audio_core/null_sink.h2
-rw-r--r--src/audio_core/stream.cpp9
-rw-r--r--src/audio_core/stream.h13
-rw-r--r--src/audio_core/time_stretch.cpp7
-rw-r--r--src/audio_core/time_stretch.h3
16 files changed, 129 insertions, 110 deletions
diff --git a/src/audio_core/algorithm/filter.cpp b/src/audio_core/algorithm/filter.cpp
index 9fcd0614d..f65bf64f7 100644
--- a/src/audio_core/algorithm/filter.cpp
+++ b/src/audio_core/algorithm/filter.cpp
@@ -35,12 +35,12 @@ Filter::Filter(double a0, double a1, double a2, double b0, double b1, double b2)
35 : a1(a1 / a0), a2(a2 / a0), b0(b0 / a0), b1(b1 / a0), b2(b2 / a0) {} 35 : a1(a1 / a0), a2(a2 / a0), b0(b0 / a0), b1(b1 / a0), b2(b2 / a0) {}
36 36
37void Filter::Process(std::vector<s16>& signal) { 37void Filter::Process(std::vector<s16>& signal) {
38 const size_t num_frames = signal.size() / 2; 38 const std::size_t num_frames = signal.size() / 2;
39 for (size_t i = 0; i < num_frames; i++) { 39 for (std::size_t i = 0; i < num_frames; i++) {
40 std::rotate(in.begin(), in.end() - 1, in.end()); 40 std::rotate(in.begin(), in.end() - 1, in.end());
41 std::rotate(out.begin(), out.end() - 1, out.end()); 41 std::rotate(out.begin(), out.end() - 1, out.end());
42 42
43 for (size_t ch = 0; ch < channel_count; ch++) { 43 for (std::size_t ch = 0; ch < channel_count; ch++) {
44 in[0][ch] = signal[i * channel_count + ch]; 44 in[0][ch] = signal[i * channel_count + ch];
45 45
46 out[0][ch] = b0 * in[0][ch] + b1 * in[1][ch] + b2 * in[2][ch] - a1 * out[1][ch] - 46 out[0][ch] = b0 * in[0][ch] + b1 * in[1][ch] + b2 * in[2][ch] - a1 * out[1][ch] -
@@ -54,14 +54,14 @@ void Filter::Process(std::vector<s16>& signal) {
54/// Calculates the appropriate Q for each biquad in a cascading filter. 54/// Calculates the appropriate Q for each biquad in a cascading filter.
55/// @param total_count The total number of biquads to be cascaded. 55/// @param total_count The total number of biquads to be cascaded.
56/// @param index 0-index of the biquad to calculate the Q value for. 56/// @param index 0-index of the biquad to calculate the Q value for.
57static double CascadingBiquadQ(size_t total_count, size_t index) { 57static double CascadingBiquadQ(std::size_t total_count, std::size_t index) {
58 const double pole = M_PI * (2 * index + 1) / (4.0 * total_count); 58 const double pole = M_PI * (2 * index + 1) / (4.0 * total_count);
59 return 1.0 / (2.0 * std::cos(pole)); 59 return 1.0 / (2.0 * std::cos(pole));
60} 60}
61 61
62CascadingFilter CascadingFilter::LowPass(double cutoff, size_t cascade_size) { 62CascadingFilter CascadingFilter::LowPass(double cutoff, std::size_t cascade_size) {
63 std::vector<Filter> cascade(cascade_size); 63 std::vector<Filter> cascade(cascade_size);
64 for (size_t i = 0; i < cascade_size; i++) { 64 for (std::size_t i = 0; i < cascade_size; i++) {
65 cascade[i] = Filter::LowPass(cutoff, CascadingBiquadQ(cascade_size, i)); 65 cascade[i] = Filter::LowPass(cutoff, CascadingBiquadQ(cascade_size, i));
66 } 66 }
67 return CascadingFilter{std::move(cascade)}; 67 return CascadingFilter{std::move(cascade)};
diff --git a/src/audio_core/algorithm/filter.h b/src/audio_core/algorithm/filter.h
index a41beef98..3546d149b 100644
--- a/src/audio_core/algorithm/filter.h
+++ b/src/audio_core/algorithm/filter.h
@@ -30,7 +30,7 @@ public:
30 void Process(std::vector<s16>& signal); 30 void Process(std::vector<s16>& signal);
31 31
32private: 32private:
33 static constexpr size_t channel_count = 2; 33 static constexpr std::size_t channel_count = 2;
34 34
35 /// Coefficients are in normalized form (a0 = 1.0). 35 /// Coefficients are in normalized form (a0 = 1.0).
36 double a1, a2, b0, b1, b2; 36 double a1, a2, b0, b1, b2;
@@ -46,7 +46,7 @@ public:
46 /// Creates a cascading low-pass filter. 46 /// Creates a cascading low-pass filter.
47 /// @param cutoff Determines the cutoff frequency. A value from 0.0 to 1.0. 47 /// @param cutoff Determines the cutoff frequency. A value from 0.0 to 1.0.
48 /// @param cascade_size Number of biquads in cascade. 48 /// @param cascade_size Number of biquads in cascade.
49 static CascadingFilter LowPass(double cutoff, size_t cascade_size); 49 static CascadingFilter LowPass(double cutoff, std::size_t cascade_size);
50 50
51 /// Passthrough. 51 /// Passthrough.
52 CascadingFilter(); 52 CascadingFilter();
diff --git a/src/audio_core/algorithm/interpolate.cpp b/src/audio_core/algorithm/interpolate.cpp
index 11459821f..3aea9b0f2 100644
--- a/src/audio_core/algorithm/interpolate.cpp
+++ b/src/audio_core/algorithm/interpolate.cpp
@@ -14,7 +14,7 @@
14namespace AudioCore { 14namespace AudioCore {
15 15
16/// The Lanczos kernel 16/// The Lanczos kernel
17static double Lanczos(size_t a, double x) { 17static double Lanczos(std::size_t a, double x) {
18 if (x == 0.0) 18 if (x == 0.0)
19 return 1.0; 19 return 1.0;
20 const double px = M_PI * x; 20 const double px = M_PI * x;
@@ -37,15 +37,15 @@ std::vector<s16> Interpolate(InterpolationState& state, std::vector<s16> input,
37 } 37 }
38 state.nyquist.Process(input); 38 state.nyquist.Process(input);
39 39
40 constexpr size_t taps = InterpolationState::lanczos_taps; 40 constexpr std::size_t taps = InterpolationState::lanczos_taps;
41 const size_t num_frames = input.size() / 2; 41 const std::size_t num_frames = input.size() / 2;
42 42
43 std::vector<s16> output; 43 std::vector<s16> output;
44 output.reserve(static_cast<size_t>(input.size() / ratio + 4)); 44 output.reserve(static_cast<std::size_t>(input.size() / ratio + 4));
45 45
46 double& pos = state.position; 46 double& pos = state.position;
47 auto& h = state.history; 47 auto& h = state.history;
48 for (size_t i = 0; i < num_frames; ++i) { 48 for (std::size_t i = 0; i < num_frames; ++i) {
49 std::rotate(h.begin(), h.end() - 1, h.end()); 49 std::rotate(h.begin(), h.end() - 1, h.end());
50 h[0][0] = input[i * 2 + 0]; 50 h[0][0] = input[i * 2 + 0];
51 h[0][1] = input[i * 2 + 1]; 51 h[0][1] = input[i * 2 + 1];
@@ -53,7 +53,7 @@ std::vector<s16> Interpolate(InterpolationState& state, std::vector<s16> input,
53 while (pos <= 1.0) { 53 while (pos <= 1.0) {
54 double l = 0.0; 54 double l = 0.0;
55 double r = 0.0; 55 double r = 0.0;
56 for (size_t j = 0; j < h.size(); j++) { 56 for (std::size_t j = 0; j < h.size(); j++) {
57 l += Lanczos(taps, pos + j - taps + 1) * h[j][0]; 57 l += Lanczos(taps, pos + j - taps + 1) * h[j][0];
58 r += Lanczos(taps, pos + j - taps + 1) * h[j][1]; 58 r += Lanczos(taps, pos + j - taps + 1) * h[j][1];
59 } 59 }
diff --git a/src/audio_core/algorithm/interpolate.h b/src/audio_core/algorithm/interpolate.h
index c79c2eef4..edbd6460f 100644
--- a/src/audio_core/algorithm/interpolate.h
+++ b/src/audio_core/algorithm/interpolate.h
@@ -12,8 +12,8 @@
12namespace AudioCore { 12namespace AudioCore {
13 13
14struct InterpolationState { 14struct InterpolationState {
15 static constexpr size_t lanczos_taps = 4; 15 static constexpr std::size_t lanczos_taps = 4;
16 static constexpr size_t history_size = lanczos_taps * 2 - 1; 16 static constexpr std::size_t history_size = lanczos_taps * 2 - 1;
17 17
18 double current_ratio = 0.0; 18 double current_ratio = 0.0;
19 CascadingFilter nyquist; 19 CascadingFilter nyquist;
diff --git a/src/audio_core/audio_out.cpp b/src/audio_core/audio_out.cpp
index 12632a95c..0c8f5b18e 100644
--- a/src/audio_core/audio_out.cpp
+++ b/src/audio_core/audio_out.cpp
@@ -39,7 +39,8 @@ StreamPtr AudioOut::OpenStream(u32 sample_rate, u32 num_channels, std::string&&
39 sink->AcquireSinkStream(sample_rate, num_channels, name), std::move(name)); 39 sink->AcquireSinkStream(sample_rate, num_channels, name), std::move(name));
40} 40}
41 41
42std::vector<Buffer::Tag> AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count) { 42std::vector<Buffer::Tag> AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream,
43 std::size_t max_count) {
43 return stream->GetTagsAndReleaseBuffers(max_count); 44 return stream->GetTagsAndReleaseBuffers(max_count);
44} 45}
45 46
diff --git a/src/audio_core/audio_out.h b/src/audio_core/audio_out.h
index 39b7e656b..df9607ac7 100644
--- a/src/audio_core/audio_out.h
+++ b/src/audio_core/audio_out.h
@@ -25,7 +25,7 @@ public:
25 Stream::ReleaseCallback&& release_callback); 25 Stream::ReleaseCallback&& release_callback);
26 26
27 /// Returns a vector of recently released buffers specified by tag for the specified stream 27 /// Returns a vector of recently released buffers specified by tag for the specified stream
28 std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count); 28 std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(StreamPtr stream, std::size_t max_count);
29 29
30 /// Starts an audio stream for playback 30 /// Starts an audio stream for playback
31 void StartStream(StreamPtr stream); 31 void StartStream(StreamPtr stream);
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp
index a75cd3be5..83b75e61f 100644
--- a/src/audio_core/audio_renderer.cpp
+++ b/src/audio_core/audio_renderer.cpp
@@ -3,9 +3,12 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "audio_core/algorithm/interpolate.h" 5#include "audio_core/algorithm/interpolate.h"
6#include "audio_core/audio_out.h"
6#include "audio_core/audio_renderer.h" 7#include "audio_core/audio_renderer.h"
8#include "audio_core/codec.h"
7#include "common/assert.h" 9#include "common/assert.h"
8#include "common/logging/log.h" 10#include "common/logging/log.h"
11#include "core/hle/kernel/event.h"
9#include "core/memory.h" 12#include "core/memory.h"
10 13
11namespace AudioCore { 14namespace AudioCore {
@@ -13,6 +16,41 @@ namespace AudioCore {
13constexpr u32 STREAM_SAMPLE_RATE{48000}; 16constexpr u32 STREAM_SAMPLE_RATE{48000};
14constexpr u32 STREAM_NUM_CHANNELS{2}; 17constexpr u32 STREAM_NUM_CHANNELS{2};
15 18
19class AudioRenderer::VoiceState {
20public:
21 bool IsPlaying() const {
22 return is_in_use && info.play_state == PlayState::Started;
23 }
24
25 const VoiceOutStatus& GetOutStatus() const {
26 return out_status;
27 }
28
29 const VoiceInfo& GetInfo() const {
30 return info;
31 }
32
33 VoiceInfo& Info() {
34 return info;
35 }
36
37 void SetWaveIndex(std::size_t index);
38 std::vector<s16> DequeueSamples(std::size_t sample_count);
39 void UpdateState();
40 void RefreshBuffer();
41
42private:
43 bool is_in_use{};
44 bool is_refresh_pending{};
45 std::size_t wave_index{};
46 std::size_t offset{};
47 Codec::ADPCMState adpcm_state{};
48 InterpolationState interp_state{};
49 std::vector<s16> samples;
50 VoiceOutStatus out_status{};
51 VoiceInfo info{};
52};
53
16AudioRenderer::AudioRenderer(AudioRendererParameter params, 54AudioRenderer::AudioRenderer(AudioRendererParameter params,
17 Kernel::SharedPtr<Kernel::Event> buffer_event) 55 Kernel::SharedPtr<Kernel::Event> buffer_event)
18 : worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count) { 56 : worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count) {
@@ -27,6 +65,8 @@ AudioRenderer::AudioRenderer(AudioRendererParameter params,
27 QueueMixedBuffer(2); 65 QueueMixedBuffer(2);
28} 66}
29 67
68AudioRenderer::~AudioRenderer() = default;
69
30u32 AudioRenderer::GetSampleRate() const { 70u32 AudioRenderer::GetSampleRate() const {
31 return worker_params.sample_rate; 71 return worker_params.sample_rate;
32} 72}
@@ -52,8 +92,8 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_
52 memory_pool_count * sizeof(MemoryPoolInfo)); 92 memory_pool_count * sizeof(MemoryPoolInfo));
53 93
54 // Copy VoiceInfo structs 94 // Copy VoiceInfo structs
55 size_t offset{sizeof(UpdateDataHeader) + config.behavior_size + config.memory_pools_size + 95 std::size_t offset{sizeof(UpdateDataHeader) + config.behavior_size + config.memory_pools_size +
56 config.voice_resource_size}; 96 config.voice_resource_size};
57 for (auto& voice : voices) { 97 for (auto& voice : voices) {
58 std::memcpy(&voice.Info(), input_params.data() + offset, sizeof(VoiceInfo)); 98 std::memcpy(&voice.Info(), input_params.data() + offset, sizeof(VoiceInfo));
59 offset += sizeof(VoiceInfo); 99 offset += sizeof(VoiceInfo);
@@ -72,7 +112,7 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_
72 112
73 // Update memory pool state 113 // Update memory pool state
74 std::vector<MemoryPoolEntry> memory_pool(memory_pool_count); 114 std::vector<MemoryPoolEntry> memory_pool(memory_pool_count);
75 for (size_t index = 0; index < memory_pool.size(); ++index) { 115 for (std::size_t index = 0; index < memory_pool.size(); ++index) {
76 if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestAttach) { 116 if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestAttach) {
77 memory_pool[index].state = MemoryPoolStates::Attached; 117 memory_pool[index].state = MemoryPoolStates::Attached;
78 } else if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestDetach) { 118 } else if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestDetach) {
@@ -93,7 +133,7 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_
93 response_data.memory_pools_size); 133 response_data.memory_pools_size);
94 134
95 // Copy output voice status 135 // Copy output voice status
96 size_t voice_out_status_offset{sizeof(UpdateDataHeader) + response_data.memory_pools_size}; 136 std::size_t voice_out_status_offset{sizeof(UpdateDataHeader) + response_data.memory_pools_size};
97 for (const auto& voice : voices) { 137 for (const auto& voice : voices) {
98 std::memcpy(output_params.data() + voice_out_status_offset, &voice.GetOutStatus(), 138 std::memcpy(output_params.data() + voice_out_status_offset, &voice.GetOutStatus(),
99 sizeof(VoiceOutStatus)); 139 sizeof(VoiceOutStatus));
@@ -103,12 +143,12 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_
103 return output_params; 143 return output_params;
104} 144}
105 145
106void AudioRenderer::VoiceState::SetWaveIndex(size_t index) { 146void AudioRenderer::VoiceState::SetWaveIndex(std::size_t index) {
107 wave_index = index & 3; 147 wave_index = index & 3;
108 is_refresh_pending = true; 148 is_refresh_pending = true;
109} 149}
110 150
111std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(size_t sample_count) { 151std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(std::size_t sample_count) {
112 if (!IsPlaying()) { 152 if (!IsPlaying()) {
113 return {}; 153 return {};
114 } 154 }
@@ -117,9 +157,9 @@ std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(size_t sample_count)
117 RefreshBuffer(); 157 RefreshBuffer();
118 } 158 }
119 159
120 const size_t max_size{samples.size() - offset}; 160 const std::size_t max_size{samples.size() - offset};
121 const size_t dequeue_offset{offset}; 161 const std::size_t dequeue_offset{offset};
122 size_t size{sample_count * STREAM_NUM_CHANNELS}; 162 std::size_t size{sample_count * STREAM_NUM_CHANNELS};
123 if (size > max_size) { 163 if (size > max_size) {
124 size = max_size; 164 size = max_size;
125 } 165 }
@@ -184,7 +224,7 @@ void AudioRenderer::VoiceState::RefreshBuffer() {
184 case 1: 224 case 1:
185 // 1 channel is upsampled to 2 channel 225 // 1 channel is upsampled to 2 channel
186 samples.resize(new_samples.size() * 2); 226 samples.resize(new_samples.size() * 2);
187 for (size_t index = 0; index < new_samples.size(); ++index) { 227 for (std::size_t index = 0; index < new_samples.size(); ++index) {
188 samples[index * 2] = new_samples[index]; 228 samples[index * 2] = new_samples[index];
189 samples[index * 2 + 1] = new_samples[index]; 229 samples[index * 2 + 1] = new_samples[index];
190 } 230 }
@@ -210,7 +250,7 @@ static constexpr s16 ClampToS16(s32 value) {
210} 250}
211 251
212void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) { 252void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
213 constexpr size_t BUFFER_SIZE{512}; 253 constexpr std::size_t BUFFER_SIZE{512};
214 std::vector<s16> buffer(BUFFER_SIZE * stream->GetNumChannels()); 254 std::vector<s16> buffer(BUFFER_SIZE * stream->GetNumChannels());
215 255
216 for (auto& voice : voices) { 256 for (auto& voice : voices) {
@@ -218,7 +258,7 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
218 continue; 258 continue;
219 } 259 }
220 260
221 size_t offset{}; 261 std::size_t offset{};
222 s64 samples_remaining{BUFFER_SIZE}; 262 s64 samples_remaining{BUFFER_SIZE};
223 while (samples_remaining > 0) { 263 while (samples_remaining > 0) {
224 const std::vector<s16> samples{voice.DequeueSamples(samples_remaining)}; 264 const std::vector<s16> samples{voice.DequeueSamples(samples_remaining)};
diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h
index 6d069d693..2c4f5ab75 100644
--- a/src/audio_core/audio_renderer.h
+++ b/src/audio_core/audio_renderer.h
@@ -8,16 +8,20 @@
8#include <memory> 8#include <memory>
9#include <vector> 9#include <vector>
10 10
11#include "audio_core/algorithm/interpolate.h"
12#include "audio_core/audio_out.h"
13#include "audio_core/codec.h"
14#include "audio_core/stream.h" 11#include "audio_core/stream.h"
12#include "common/common_funcs.h"
15#include "common/common_types.h" 13#include "common/common_types.h"
16#include "common/swap.h" 14#include "common/swap.h"
17#include "core/hle/kernel/event.h" 15#include "core/hle/kernel/object.h"
16
17namespace Kernel {
18class Event;
19}
18 20
19namespace AudioCore { 21namespace AudioCore {
20 22
23class AudioOut;
24
21enum class PlayState : u8 { 25enum class PlayState : u8 {
22 Started = 0, 26 Started = 0,
23 Stopped = 1, 27 Stopped = 1,
@@ -158,6 +162,8 @@ static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size
158class AudioRenderer { 162class AudioRenderer {
159public: 163public:
160 AudioRenderer(AudioRendererParameter params, Kernel::SharedPtr<Kernel::Event> buffer_event); 164 AudioRenderer(AudioRendererParameter params, Kernel::SharedPtr<Kernel::Event> buffer_event);
165 ~AudioRenderer();
166
161 std::vector<u8> UpdateAudioRenderer(const std::vector<u8>& input_params); 167 std::vector<u8> UpdateAudioRenderer(const std::vector<u8>& input_params);
162 void QueueMixedBuffer(Buffer::Tag tag); 168 void QueueMixedBuffer(Buffer::Tag tag);
163 void ReleaseAndQueueBuffers(); 169 void ReleaseAndQueueBuffers();
@@ -166,45 +172,12 @@ public:
166 u32 GetMixBufferCount() const; 172 u32 GetMixBufferCount() const;
167 173
168private: 174private:
169 class VoiceState { 175 class VoiceState;
170 public:
171 bool IsPlaying() const {
172 return is_in_use && info.play_state == PlayState::Started;
173 }
174
175 const VoiceOutStatus& GetOutStatus() const {
176 return out_status;
177 }
178
179 const VoiceInfo& GetInfo() const {
180 return info;
181 }
182
183 VoiceInfo& Info() {
184 return info;
185 }
186
187 void SetWaveIndex(size_t index);
188 std::vector<s16> DequeueSamples(size_t sample_count);
189 void UpdateState();
190 void RefreshBuffer();
191
192 private:
193 bool is_in_use{};
194 bool is_refresh_pending{};
195 size_t wave_index{};
196 size_t offset{};
197 Codec::ADPCMState adpcm_state{};
198 InterpolationState interp_state{};
199 std::vector<s16> samples;
200 VoiceOutStatus out_status{};
201 VoiceInfo info{};
202 };
203 176
204 AudioRendererParameter worker_params; 177 AudioRendererParameter worker_params;
205 Kernel::SharedPtr<Kernel::Event> buffer_event; 178 Kernel::SharedPtr<Kernel::Event> buffer_event;
206 std::vector<VoiceState> voices; 179 std::vector<VoiceState> voices;
207 std::unique_ptr<AudioCore::AudioOut> audio_out; 180 std::unique_ptr<AudioOut> audio_out;
208 AudioCore::StreamPtr stream; 181 AudioCore::StreamPtr stream;
209}; 182};
210 183
diff --git a/src/audio_core/codec.cpp b/src/audio_core/codec.cpp
index c3021403f..454de798b 100644
--- a/src/audio_core/codec.cpp
+++ b/src/audio_core/codec.cpp
@@ -8,27 +8,27 @@
8 8
9namespace AudioCore::Codec { 9namespace AudioCore::Codec {
10 10
11std::vector<s16> DecodeADPCM(const u8* const data, size_t size, const ADPCM_Coeff& coeff, 11std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM_Coeff& coeff,
12 ADPCMState& state) { 12 ADPCMState& state) {
13 // GC-ADPCM with scale factor and variable coefficients. 13 // GC-ADPCM with scale factor and variable coefficients.
14 // Frames are 8 bytes long containing 14 samples each. 14 // Frames are 8 bytes long containing 14 samples each.
15 // Samples are 4 bits (one nibble) long. 15 // Samples are 4 bits (one nibble) long.
16 16
17 constexpr size_t FRAME_LEN = 8; 17 constexpr std::size_t FRAME_LEN = 8;
18 constexpr size_t SAMPLES_PER_FRAME = 14; 18 constexpr std::size_t SAMPLES_PER_FRAME = 14;
19 constexpr std::array<int, 16> SIGNED_NIBBLES = { 19 constexpr std::array<int, 16> SIGNED_NIBBLES = {
20 {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}}; 20 {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}};
21 21
22 const size_t sample_count = (size / FRAME_LEN) * SAMPLES_PER_FRAME; 22 const std::size_t sample_count = (size / FRAME_LEN) * SAMPLES_PER_FRAME;
23 const size_t ret_size = 23 const std::size_t ret_size =
24 sample_count % 2 == 0 ? sample_count : sample_count + 1; // Ensure multiple of two. 24 sample_count % 2 == 0 ? sample_count : sample_count + 1; // Ensure multiple of two.
25 std::vector<s16> ret(ret_size); 25 std::vector<s16> ret(ret_size);
26 26
27 int yn1 = state.yn1, yn2 = state.yn2; 27 int yn1 = state.yn1, yn2 = state.yn2;
28 28
29 const size_t NUM_FRAMES = 29 const std::size_t NUM_FRAMES =
30 (sample_count + (SAMPLES_PER_FRAME - 1)) / SAMPLES_PER_FRAME; // Round up. 30 (sample_count + (SAMPLES_PER_FRAME - 1)) / SAMPLES_PER_FRAME; // Round up.
31 for (size_t framei = 0; framei < NUM_FRAMES; framei++) { 31 for (std::size_t framei = 0; framei < NUM_FRAMES; framei++) {
32 const int frame_header = data[framei * FRAME_LEN]; 32 const int frame_header = data[framei * FRAME_LEN];
33 const int scale = 1 << (frame_header & 0xF); 33 const int scale = 1 << (frame_header & 0xF);
34 const int idx = (frame_header >> 4) & 0x7; 34 const int idx = (frame_header >> 4) & 0x7;
@@ -53,9 +53,9 @@ std::vector<s16> DecodeADPCM(const u8* const data, size_t size, const ADPCM_Coef
53 return static_cast<s16>(val); 53 return static_cast<s16>(val);
54 }; 54 };
55 55
56 size_t outputi = framei * SAMPLES_PER_FRAME; 56 std::size_t outputi = framei * SAMPLES_PER_FRAME;
57 size_t datai = framei * FRAME_LEN + 1; 57 std::size_t datai = framei * FRAME_LEN + 1;
58 for (size_t i = 0; i < SAMPLES_PER_FRAME && outputi < sample_count; i += 2) { 58 for (std::size_t i = 0; i < SAMPLES_PER_FRAME && outputi < sample_count; i += 2) {
59 const s16 sample1 = decode_sample(SIGNED_NIBBLES[data[datai] >> 4]); 59 const s16 sample1 = decode_sample(SIGNED_NIBBLES[data[datai] >> 4]);
60 ret[outputi] = sample1; 60 ret[outputi] = sample1;
61 outputi++; 61 outputi++;
diff --git a/src/audio_core/codec.h b/src/audio_core/codec.h
index 3f845c42c..ef2ce01a8 100644
--- a/src/audio_core/codec.h
+++ b/src/audio_core/codec.h
@@ -38,7 +38,7 @@ using ADPCM_Coeff = std::array<s16, 16>;
38 * @param state ADPCM state, this is updated with new state 38 * @param state ADPCM state, this is updated with new state
39 * @return Decoded stereo signed PCM16 data, sample_count in length 39 * @return Decoded stereo signed PCM16 data, sample_count in length
40 */ 40 */
41std::vector<s16> DecodeADPCM(const u8* const data, size_t size, const ADPCM_Coeff& coeff, 41std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM_Coeff& coeff,
42 ADPCMState& state); 42 ADPCMState& state);
43 43
44}; // namespace AudioCore::Codec 44}; // namespace AudioCore::Codec
diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp
index 79155a7a0..392039688 100644
--- a/src/audio_core/cubeb_sink.cpp
+++ b/src/audio_core/cubeb_sink.cpp
@@ -63,8 +63,8 @@ public:
63 // Downsample 6 channels to 2 63 // Downsample 6 channels to 2
64 std::vector<s16> buf; 64 std::vector<s16> buf;
65 buf.reserve(samples.size() * num_channels / source_num_channels); 65 buf.reserve(samples.size() * num_channels / source_num_channels);
66 for (size_t i = 0; i < samples.size(); i += source_num_channels) { 66 for (std::size_t i = 0; i < samples.size(); i += source_num_channels) {
67 for (size_t ch = 0; ch < num_channels; ch++) { 67 for (std::size_t ch = 0; ch < num_channels; ch++) {
68 buf.push_back(samples[i + ch]); 68 buf.push_back(samples[i + ch]);
69 } 69 }
70 } 70 }
@@ -75,7 +75,7 @@ public:
75 queue.Push(samples); 75 queue.Push(samples);
76 } 76 }
77 77
78 size_t SamplesInQueue(u32 num_channels) const override { 78 std::size_t SamplesInQueue(u32 num_channels) const override {
79 if (!ctx) 79 if (!ctx)
80 return 0; 80 return 0;
81 81
@@ -119,10 +119,10 @@ CubebSink::CubebSink(std::string target_device_name) {
119 LOG_WARNING(Audio_Sink, "Audio output device enumeration not supported"); 119 LOG_WARNING(Audio_Sink, "Audio output device enumeration not supported");
120 } else { 120 } else {
121 const auto collection_end{collection.device + collection.count}; 121 const auto collection_end{collection.device + collection.count};
122 const auto device{std::find_if(collection.device, collection_end, 122 const auto device{
123 [&](const cubeb_device_info& device) { 123 std::find_if(collection.device, collection_end, [&](const cubeb_device_info& info) {
124 return target_device_name == device.friendly_name; 124 return target_device_name == info.friendly_name;
125 })}; 125 })};
126 if (device != collection_end) { 126 if (device != collection_end) {
127 output_device = device->devid; 127 output_device = device->devid;
128 } 128 }
@@ -159,15 +159,16 @@ long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const
159 return {}; 159 return {};
160 } 160 }
161 161
162 const size_t num_channels = impl->GetNumChannels(); 162 const std::size_t num_channels = impl->GetNumChannels();
163 const size_t samples_to_write = num_channels * num_frames; 163 const std::size_t samples_to_write = num_channels * num_frames;
164 size_t samples_written; 164 std::size_t samples_written;
165 165
166 if (Settings::values.enable_audio_stretching) { 166 if (Settings::values.enable_audio_stretching) {
167 const std::vector<s16> in{impl->queue.Pop()}; 167 const std::vector<s16> in{impl->queue.Pop()};
168 const size_t num_in{in.size() / num_channels}; 168 const std::size_t num_in{in.size() / num_channels};
169 s16* const out{reinterpret_cast<s16*>(buffer)}; 169 s16* const out{reinterpret_cast<s16*>(buffer)};
170 const size_t out_frames = impl->time_stretch.Process(in.data(), num_in, out, num_frames); 170 const std::size_t out_frames =
171 impl->time_stretch.Process(in.data(), num_in, out, num_frames);
171 samples_written = out_frames * num_channels; 172 samples_written = out_frames * num_channels;
172 173
173 if (impl->should_flush) { 174 if (impl->should_flush) {
@@ -184,7 +185,7 @@ long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const
184 } 185 }
185 186
186 // Fill the rest of the frames with last_frame 187 // Fill the rest of the frames with last_frame
187 for (size_t i = samples_written; i < samples_to_write; i += num_channels) { 188 for (std::size_t i = samples_written; i < samples_to_write; i += num_channels) {
188 std::memcpy(buffer + i * sizeof(s16), &impl->last_frame[0], num_channels * sizeof(s16)); 189 std::memcpy(buffer + i * sizeof(s16), &impl->last_frame[0], num_channels * sizeof(s16));
189 } 190 }
190 191
@@ -197,7 +198,7 @@ std::vector<std::string> ListCubebSinkDevices() {
197 std::vector<std::string> device_list; 198 std::vector<std::string> device_list;
198 cubeb* ctx; 199 cubeb* ctx;
199 200
200 if (cubeb_init(&ctx, "Citra Device Enumerator", nullptr) != CUBEB_OK) { 201 if (cubeb_init(&ctx, "yuzu Device Enumerator", nullptr) != CUBEB_OK) {
201 LOG_CRITICAL(Audio_Sink, "cubeb_init failed"); 202 LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
202 return {}; 203 return {};
203 } 204 }
@@ -206,7 +207,7 @@ std::vector<std::string> ListCubebSinkDevices() {
206 if (cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_OUTPUT, &collection) != CUBEB_OK) { 207 if (cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_OUTPUT, &collection) != CUBEB_OK) {
207 LOG_WARNING(Audio_Sink, "Audio output device enumeration not supported"); 208 LOG_WARNING(Audio_Sink, "Audio output device enumeration not supported");
208 } else { 209 } else {
209 for (size_t i = 0; i < collection.count; i++) { 210 for (std::size_t i = 0; i < collection.count; i++) {
210 const cubeb_device_info& device = collection.device[i]; 211 const cubeb_device_info& device = collection.device[i];
211 if (device.friendly_name) { 212 if (device.friendly_name) {
212 device_list.emplace_back(device.friendly_name); 213 device_list.emplace_back(device.friendly_name);
diff --git a/src/audio_core/null_sink.h b/src/audio_core/null_sink.h
index 2ed0c83b6..a78d78893 100644
--- a/src/audio_core/null_sink.h
+++ b/src/audio_core/null_sink.h
@@ -22,7 +22,7 @@ private:
22 struct NullSinkStreamImpl final : SinkStream { 22 struct NullSinkStreamImpl final : SinkStream {
23 void EnqueueSamples(u32 /*num_channels*/, const std::vector<s16>& /*samples*/) override {} 23 void EnqueueSamples(u32 /*num_channels*/, const std::vector<s16>& /*samples*/) override {}
24 24
25 size_t SamplesInQueue(u32 /*num_channels*/) const override { 25 std::size_t SamplesInQueue(u32 /*num_channels*/) const override {
26 return 0; 26 return 0;
27 } 27 }
28 28
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp
index 84dcdd98d..449db2416 100644
--- a/src/audio_core/stream.cpp
+++ b/src/audio_core/stream.cpp
@@ -7,6 +7,7 @@
7 7
8#include "audio_core/sink.h" 8#include "audio_core/sink.h"
9#include "audio_core/sink_details.h" 9#include "audio_core/sink_details.h"
10#include "audio_core/sink_stream.h"
10#include "audio_core/stream.h" 11#include "audio_core/stream.h"
11#include "common/assert.h" 12#include "common/assert.h"
12#include "common/logging/log.h" 13#include "common/logging/log.h"
@@ -17,7 +18,7 @@
17 18
18namespace AudioCore { 19namespace AudioCore {
19 20
20constexpr size_t MaxAudioBufferCount{32}; 21constexpr std::size_t MaxAudioBufferCount{32};
21 22
22u32 Stream::GetNumChannels() const { 23u32 Stream::GetNumChannels() const {
23 switch (format) { 24 switch (format) {
@@ -52,7 +53,7 @@ void Stream::Stop() {
52} 53}
53 54
54s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const { 55s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const {
55 const size_t num_samples{buffer.GetSamples().size() / GetNumChannels()}; 56 const std::size_t num_samples{buffer.GetSamples().size() / GetNumChannels()};
56 return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate); 57 return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate);
57} 58}
58 59
@@ -122,9 +123,9 @@ bool Stream::ContainsBuffer(Buffer::Tag tag) const {
122 return {}; 123 return {};
123} 124}
124 125
125std::vector<Buffer::Tag> Stream::GetTagsAndReleaseBuffers(size_t max_count) { 126std::vector<Buffer::Tag> Stream::GetTagsAndReleaseBuffers(std::size_t max_count) {
126 std::vector<Buffer::Tag> tags; 127 std::vector<Buffer::Tag> tags;
127 for (size_t count = 0; count < max_count && !released_buffers.empty(); ++count) { 128 for (std::size_t count = 0; count < max_count && !released_buffers.empty(); ++count) {
128 tags.push_back(released_buffers.front()->GetTag()); 129 tags.push_back(released_buffers.front()->GetTag());
129 released_buffers.pop(); 130 released_buffers.pop();
130 } 131 }
diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h
index 049b92ca9..27db1112f 100644
--- a/src/audio_core/stream.h
+++ b/src/audio_core/stream.h
@@ -11,13 +11,16 @@
11#include <queue> 11#include <queue>
12 12
13#include "audio_core/buffer.h" 13#include "audio_core/buffer.h"
14#include "audio_core/sink_stream.h"
15#include "common/assert.h"
16#include "common/common_types.h" 14#include "common/common_types.h"
17#include "core/core_timing.h" 15
16namespace CoreTiming {
17struct EventType;
18}
18 19
19namespace AudioCore { 20namespace AudioCore {
20 21
22class SinkStream;
23
21/** 24/**
22 * Represents an audio stream, which is a sequence of queued buffers, to be outputed by AudioOut 25 * Represents an audio stream, which is a sequence of queued buffers, to be outputed by AudioOut
23 */ 26 */
@@ -49,7 +52,7 @@ public:
49 bool ContainsBuffer(Buffer::Tag tag) const; 52 bool ContainsBuffer(Buffer::Tag tag) const;
50 53
51 /// Returns a vector of recently released buffers specified by tag 54 /// Returns a vector of recently released buffers specified by tag
52 std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(size_t max_count); 55 std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(std::size_t max_count);
53 56
54 /// Returns true if the stream is currently playing 57 /// Returns true if the stream is currently playing
55 bool IsPlaying() const { 58 bool IsPlaying() const {
@@ -57,7 +60,7 @@ public:
57 } 60 }
58 61
59 /// Returns the number of queued buffers 62 /// Returns the number of queued buffers
60 size_t GetQueueSize() const { 63 std::size_t GetQueueSize() const {
61 return queued_buffers.size(); 64 return queued_buffers.size();
62 } 65 }
63 66
diff --git a/src/audio_core/time_stretch.cpp b/src/audio_core/time_stretch.cpp
index da094c46b..fc14151da 100644
--- a/src/audio_core/time_stretch.cpp
+++ b/src/audio_core/time_stretch.cpp
@@ -26,7 +26,8 @@ void TimeStretcher::Flush() {
26 m_sound_touch.flush(); 26 m_sound_touch.flush();
27} 27}
28 28
29size_t TimeStretcher::Process(const s16* in, size_t num_in, s16* out, size_t num_out) { 29std::size_t TimeStretcher::Process(const s16* in, std::size_t num_in, s16* out,
30 std::size_t num_out) {
30 const double time_delta = static_cast<double>(num_out) / m_sample_rate; // seconds 31 const double time_delta = static_cast<double>(num_out) / m_sample_rate; // seconds
31 32
32 // We were given actual_samples number of samples, and num_samples were requested from us. 33 // We were given actual_samples number of samples, and num_samples were requested from us.
@@ -61,8 +62,8 @@ size_t TimeStretcher::Process(const s16* in, size_t num_in, s16* out, size_t num
61 LOG_DEBUG(Audio, "{:5}/{:5} ratio:{:0.6f} backlog:{:0.6f}", num_in, num_out, m_stretch_ratio, 62 LOG_DEBUG(Audio, "{:5}/{:5} ratio:{:0.6f} backlog:{:0.6f}", num_in, num_out, m_stretch_ratio,
62 backlog_fullness); 63 backlog_fullness);
63 64
64 m_sound_touch.putSamples(in, num_in); 65 m_sound_touch.putSamples(in, static_cast<u32>(num_in));
65 return m_sound_touch.receiveSamples(out, num_out); 66 return m_sound_touch.receiveSamples(out, static_cast<u32>(num_out));
66} 67}
67 68
68} // namespace AudioCore 69} // namespace AudioCore
diff --git a/src/audio_core/time_stretch.h b/src/audio_core/time_stretch.h
index 7e39e695e..decd760f1 100644
--- a/src/audio_core/time_stretch.h
+++ b/src/audio_core/time_stretch.h
@@ -4,7 +4,6 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <array>
8#include <cstddef> 7#include <cstddef>
9#include <SoundTouch.h> 8#include <SoundTouch.h>
10#include "common/common_types.h" 9#include "common/common_types.h"
@@ -20,7 +19,7 @@ public:
20 /// @param out Output sample buffer 19 /// @param out Output sample buffer
21 /// @param num_out Desired number of output frames in `out` 20 /// @param num_out Desired number of output frames in `out`
22 /// @returns Actual number of frames written to `out` 21 /// @returns Actual number of frames written to `out`
23 size_t Process(const s16* in, size_t num_in, s16* out, size_t num_out); 22 std::size_t Process(const s16* in, std::size_t num_in, s16* out, std::size_t num_out);
24 23
25 void Clear(); 24 void Clear();
26 25