summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_core/audio_out.cpp2
-rw-r--r--src/audio_core/audio_out.h2
-rw-r--r--src/audio_core/buffer.h13
-rw-r--r--src/audio_core/cubeb_sink.cpp11
-rw-r--r--src/audio_core/null_sink.h3
-rw-r--r--src/audio_core/sink_stream.h4
-rw-r--r--src/audio_core/stream.cpp19
-rw-r--r--src/audio_core/stream.h3
-rw-r--r--src/core/hle/service/audio/audout_u.cpp6
9 files changed, 27 insertions, 36 deletions
diff --git a/src/audio_core/audio_out.cpp b/src/audio_core/audio_out.cpp
index eb9db755a..12632a95c 100644
--- a/src/audio_core/audio_out.cpp
+++ b/src/audio_core/audio_out.cpp
@@ -51,7 +51,7 @@ void AudioOut::StopStream(StreamPtr stream) {
51 stream->Stop(); 51 stream->Stop();
52} 52}
53 53
54bool AudioOut::QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector<u8>&& data) { 54bool AudioOut::QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector<s16>&& data) {
55 return stream->QueueBuffer(std::make_shared<Buffer>(tag, std::move(data))); 55 return stream->QueueBuffer(std::make_shared<Buffer>(tag, std::move(data)));
56} 56}
57 57
diff --git a/src/audio_core/audio_out.h b/src/audio_core/audio_out.h
index d564ff91a..39b7e656b 100644
--- a/src/audio_core/audio_out.h
+++ b/src/audio_core/audio_out.h
@@ -34,7 +34,7 @@ public:
34 void StopStream(StreamPtr stream); 34 void StopStream(StreamPtr stream);
35 35
36 /// Queues a buffer into the specified audio stream, returns true on success 36 /// Queues a buffer into the specified audio stream, returns true on success
37 bool QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector<u8>&& data); 37 bool QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector<s16>&& data);
38 38
39private: 39private:
40 SinkPtr sink; 40 SinkPtr sink;
diff --git a/src/audio_core/buffer.h b/src/audio_core/buffer.h
index 4bf5fd58a..a323b23ec 100644
--- a/src/audio_core/buffer.h
+++ b/src/audio_core/buffer.h
@@ -18,11 +18,16 @@ class Buffer {
18public: 18public:
19 using Tag = u64; 19 using Tag = u64;
20 20
21 Buffer(Tag tag, std::vector<u8>&& data) : tag{tag}, data{std::move(data)} {} 21 Buffer(Tag tag, std::vector<s16>&& samples) : tag{tag}, samples{std::move(samples)} {}
22 22
23 /// Returns the raw audio data for the buffer 23 /// Returns the raw audio data for the buffer
24 const std::vector<u8>& GetData() const { 24 std::vector<s16>& Samples() {
25 return data; 25 return samples;
26 }
27
28 /// Returns the raw audio data for the buffer
29 const std::vector<s16>& GetSamples() const {
30 return samples;
26 } 31 }
27 32
28 /// Returns the buffer tag, this is provided by the game to the audout service 33 /// Returns the buffer tag, this is provided by the game to the audout service
@@ -32,7 +37,7 @@ public:
32 37
33private: 38private:
34 Tag tag; 39 Tag tag;
35 std::vector<u8> data; 40 std::vector<s16> samples;
36}; 41};
37 42
38using BufferPtr = std::shared_ptr<Buffer>; 43using BufferPtr = std::shared_ptr<Buffer>;
diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp
index 0b0e9a053..1501ef1f4 100644
--- a/src/audio_core/cubeb_sink.cpp
+++ b/src/audio_core/cubeb_sink.cpp
@@ -61,25 +61,24 @@ public:
61 cubeb_stream_destroy(stream_backend); 61 cubeb_stream_destroy(stream_backend);
62 } 62 }
63 63
64 void EnqueueSamples(u32 num_channels, const s16* samples, size_t sample_count) override { 64 void EnqueueSamples(u32 num_channels, const std::vector<s16>& samples) override {
65 if (!ctx) { 65 if (!ctx) {
66 return; 66 return;
67 } 67 }
68 68
69 queue.reserve(queue.size() + sample_count * GetNumChannels()); 69 queue.reserve(queue.size() + samples.size() * GetNumChannels());
70 70
71 if (is_6_channel) { 71 if (is_6_channel) {
72 // Downsample 6 channels to 2 72 // Downsample 6 channels to 2
73 const size_t sample_count_copy_size = sample_count * num_channels * 2; 73 const size_t sample_count_copy_size = samples.size() * 2;
74 queue.reserve(sample_count_copy_size); 74 queue.reserve(sample_count_copy_size);
75 for (size_t i = 0; i < sample_count * num_channels; i += num_channels) { 75 for (size_t i = 0; i < samples.size(); i += num_channels) {
76 queue.push_back(samples[i]); 76 queue.push_back(samples[i]);
77 queue.push_back(samples[i + 1]); 77 queue.push_back(samples[i + 1]);
78 } 78 }
79 } else { 79 } else {
80 // Copy as-is 80 // Copy as-is
81 std::copy(samples, samples + sample_count * GetNumChannels(), 81 std::copy(samples.begin(), samples.end(), std::back_inserter(queue));
82 std::back_inserter(queue));
83 } 82 }
84 } 83 }
85 84
diff --git a/src/audio_core/null_sink.h b/src/audio_core/null_sink.h
index 66041ea3f..f235d93e5 100644
--- a/src/audio_core/null_sink.h
+++ b/src/audio_core/null_sink.h
@@ -20,8 +20,7 @@ public:
20 20
21private: 21private:
22 struct NullSinkStreamImpl final : SinkStream { 22 struct NullSinkStreamImpl final : SinkStream {
23 void EnqueueSamples(u32 /*num_channels*/, const s16* /*samples*/, 23 void EnqueueSamples(u32 /*num_channels*/, const std::vector<s16>& /*samples*/) override {}
24 size_t /*sample_count*/) override {}
25 } null_sink_stream; 24 } null_sink_stream;
26}; 25};
27 26
diff --git a/src/audio_core/sink_stream.h b/src/audio_core/sink_stream.h
index e7a3f01b0..41b6736d8 100644
--- a/src/audio_core/sink_stream.h
+++ b/src/audio_core/sink_stream.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <memory> 7#include <memory>
8#include <vector>
8 9
9#include "common/common_types.h" 10#include "common/common_types.h"
10 11
@@ -22,9 +23,8 @@ public:
22 * Feed stereo samples to sink. 23 * Feed stereo samples to sink.
23 * @param num_channels Number of channels used. 24 * @param num_channels Number of channels used.
24 * @param samples Samples in interleaved stereo PCM16 format. 25 * @param samples Samples in interleaved stereo PCM16 format.
25 * @param sample_count Number of samples.
26 */ 26 */
27 virtual void EnqueueSamples(u32 num_channels, const s16* samples, size_t sample_count) = 0; 27 virtual void EnqueueSamples(u32 num_channels, const std::vector<s16>& samples) = 0;
28}; 28};
29 29
30using SinkStreamPtr = std::unique_ptr<SinkStream>; 30using SinkStreamPtr = std::unique_ptr<SinkStream>;
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp
index 7ab87c0c9..ad9e2915c 100644
--- a/src/audio_core/stream.cpp
+++ b/src/audio_core/stream.cpp
@@ -32,10 +32,6 @@ u32 Stream::GetNumChannels() const {
32 return {}; 32 return {};
33} 33}
34 34
35u32 Stream::GetSampleSize() const {
36 return GetNumChannels() * 2;
37}
38
39Stream::Stream(u32 sample_rate, Format format, ReleaseCallback&& release_callback, 35Stream::Stream(u32 sample_rate, Format format, ReleaseCallback&& release_callback,
40 SinkStream& sink_stream, std::string&& name_) 36 SinkStream& sink_stream, std::string&& name_)
41 : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)}, 37 : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)},
@@ -55,17 +51,15 @@ void Stream::Stop() {
55} 51}
56 52
57s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const { 53s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const {
58 const size_t num_samples{buffer.GetData().size() / GetSampleSize()}; 54 const size_t num_samples{buffer.GetSamples().size() / GetNumChannels()};
59 return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate); 55 return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate);
60} 56}
61 57
62static std::vector<s16> GetVolumeAdjustedSamples(const std::vector<u8>& data) { 58static void VolumeAdjustSamples(std::vector<s16>& samples) {
63 std::vector<s16> samples(data.size() / sizeof(s16));
64 std::memcpy(samples.data(), data.data(), data.size());
65 const float volume{std::clamp(Settings::values.volume, 0.0f, 1.0f)}; 59 const float volume{std::clamp(Settings::values.volume, 0.0f, 1.0f)};
66 60
67 if (volume == 1.0f) { 61 if (volume == 1.0f) {
68 return samples; 62 return;
69 } 63 }
70 64
71 // Implementation of a volume slider with a dynamic range of 60 dB 65 // Implementation of a volume slider with a dynamic range of 60 dB
@@ -73,8 +67,6 @@ static std::vector<s16> GetVolumeAdjustedSamples(const std::vector<u8>& data) {
73 for (auto& sample : samples) { 67 for (auto& sample : samples) {
74 sample = static_cast<s16>(sample * volume_scale_factor); 68 sample = static_cast<s16>(sample * volume_scale_factor);
75 } 69 }
76
77 return samples;
78} 70}
79 71
80void Stream::PlayNextBuffer() { 72void Stream::PlayNextBuffer() {
@@ -96,9 +88,8 @@ void Stream::PlayNextBuffer() {
96 active_buffer = queued_buffers.front(); 88 active_buffer = queued_buffers.front();
97 queued_buffers.pop(); 89 queued_buffers.pop();
98 90
99 const size_t sample_count{active_buffer->GetData().size() / GetSampleSize()}; 91 VolumeAdjustSamples(active_buffer->Samples());
100 sink_stream.EnqueueSamples( 92 sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples());
101 GetNumChannels(), GetVolumeAdjustedSamples(active_buffer->GetData()).data(), sample_count);
102 93
103 CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {}); 94 CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {});
104} 95}
diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h
index 00f991733..049b92ca9 100644
--- a/src/audio_core/stream.h
+++ b/src/audio_core/stream.h
@@ -69,9 +69,6 @@ public:
69 /// Gets the number of channels 69 /// Gets the number of channels
70 u32 GetNumChannels() const; 70 u32 GetNumChannels() const;
71 71
72 /// Gets the sample size in bytes
73 u32 GetSampleSize() const;
74
75private: 72private:
76 /// Current state of the stream 73 /// Current state of the stream
77 enum class State { 74 enum class State {
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index f4a557634..108a7c6eb 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -113,10 +113,10 @@ private:
113 std::memcpy(&audio_buffer, input_buffer.data(), sizeof(AudioBuffer)); 113 std::memcpy(&audio_buffer, input_buffer.data(), sizeof(AudioBuffer));
114 const u64 tag{rp.Pop<u64>()}; 114 const u64 tag{rp.Pop<u64>()};
115 115
116 std::vector<u8> data(audio_buffer.buffer_size); 116 std::vector<s16> samples(audio_buffer.buffer_size / sizeof(s16));
117 Memory::ReadBlock(audio_buffer.buffer, data.data(), data.size()); 117 Memory::ReadBlock(audio_buffer.buffer, samples.data(), audio_buffer.buffer_size);
118 118
119 if (!audio_core.QueueBuffer(stream, tag, std::move(data))) { 119 if (!audio_core.QueueBuffer(stream, tag, std::move(samples))) {
120 IPC::ResponseBuilder rb{ctx, 2}; 120 IPC::ResponseBuilder rb{ctx, 2};
121 rb.Push(ResultCode(ErrorModule::Audio, ErrCodes::BufferCountExceeded)); 121 rb.Push(ResultCode(ErrorModule::Audio, ErrCodes::BufferCountExceeded));
122 } 122 }