From 7186882bfe502799f7578e7ee6010b4c8956bed4 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 2 Aug 2018 18:27:22 -0400 Subject: audio_core: Streams need unique names for CoreTiming. --- src/audio_core/audio_out.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/audio_core/audio_out.cpp') diff --git a/src/audio_core/audio_out.cpp b/src/audio_core/audio_out.cpp index 3dfdf61f9c..5cf665c229 100644 --- a/src/audio_core/audio_out.cpp +++ b/src/audio_core/audio_out.cpp @@ -27,16 +27,16 @@ static Stream::Format ChannelsToStreamFormat(u32 num_channels) { return {}; } -StreamPtr AudioOut::OpenStream(u32 sample_rate, u32 num_channels, +StreamPtr AudioOut::OpenStream(u32 sample_rate, u32 num_channels, std::string&& name, Stream::ReleaseCallback&& release_callback) { if (!sink) { const SinkDetails& sink_details = GetSinkDetails(Settings::values.sink_id); sink = sink_details.factory(Settings::values.audio_device_id); } - return std::make_shared(sample_rate, ChannelsToStreamFormat(num_channels), - std::move(release_callback), - sink->AcquireSinkStream(sample_rate, num_channels)); + return std::make_shared( + sample_rate, ChannelsToStreamFormat(num_channels), std::move(release_callback), + sink->AcquireSinkStream(sample_rate, num_channels), std::move(name)); } std::vector AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count) { -- cgit v1.2.3 From 97647e60f238bf735f41ea8015ce075468eb7c57 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 2 Aug 2018 18:54:25 -0400 Subject: audio_core: Sinks need unique names as well. --- src/audio_core/audio_out.cpp | 2 +- src/audio_core/cubeb_sink.cpp | 11 ++++++----- src/audio_core/cubeb_sink.h | 3 ++- src/audio_core/null_sink.h | 3 ++- src/audio_core/sink.h | 4 +++- 5 files changed, 14 insertions(+), 9 deletions(-) (limited to 'src/audio_core/audio_out.cpp') diff --git a/src/audio_core/audio_out.cpp b/src/audio_core/audio_out.cpp index 5cf665c229..eb9db755a6 100644 --- a/src/audio_core/audio_out.cpp +++ b/src/audio_core/audio_out.cpp @@ -36,7 +36,7 @@ StreamPtr AudioOut::OpenStream(u32 sample_rate, u32 num_channels, std::string&& return std::make_shared( sample_rate, ChannelsToStreamFormat(num_channels), std::move(release_callback), - sink->AcquireSinkStream(sample_rate, num_channels), std::move(name)); + sink->AcquireSinkStream(sample_rate, num_channels, name), std::move(name)); } std::vector AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count) { diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp index 34ae5b0623..cf48399891 100644 --- a/src/audio_core/cubeb_sink.cpp +++ b/src/audio_core/cubeb_sink.cpp @@ -13,7 +13,7 @@ namespace AudioCore { class SinkStreamImpl final : public SinkStream { public: - SinkStreamImpl(cubeb* ctx, cubeb_devid output_device) : ctx{ctx} { + SinkStreamImpl(cubeb* ctx, cubeb_devid output_device, const std::string& name) : ctx{ctx} { cubeb_stream_params params; params.rate = 48000; params.channels = GetNumChannels(); @@ -25,8 +25,8 @@ public: LOG_CRITICAL(Audio_Sink, "Error getting minimum latency"); } - if (cubeb_stream_init(ctx, &stream_backend, "yuzu Audio Output", nullptr, nullptr, - output_device, ¶ms, std::max(512u, minimum_latency), + if (cubeb_stream_init(ctx, &stream_backend, name.c_str(), nullptr, nullptr, output_device, + ¶ms, std::max(512u, minimum_latency), &SinkStreamImpl::DataCallback, &SinkStreamImpl::StateCallback, this) != CUBEB_OK) { LOG_CRITICAL(Audio_Sink, "Error initializing cubeb stream"); @@ -129,8 +129,9 @@ CubebSink::~CubebSink() { cubeb_destroy(ctx); } -SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels) { - sink_streams.push_back(std::make_unique(ctx, output_device)); +SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels, + const std::string& name) { + sink_streams.push_back(std::make_unique(ctx, output_device, name)); return *sink_streams.back(); } diff --git a/src/audio_core/cubeb_sink.h b/src/audio_core/cubeb_sink.h index d07113f1fa..59cbf05e9c 100644 --- a/src/audio_core/cubeb_sink.h +++ b/src/audio_core/cubeb_sink.h @@ -18,7 +18,8 @@ public: explicit CubebSink(std::string device_id); ~CubebSink() override; - SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels) override; + SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels, + const std::string& name) override; private: cubeb* ctx{}; diff --git a/src/audio_core/null_sink.h b/src/audio_core/null_sink.h index 2e04438f78..66041ea3f8 100644 --- a/src/audio_core/null_sink.h +++ b/src/audio_core/null_sink.h @@ -13,7 +13,8 @@ public: explicit NullSink(std::string){}; ~NullSink() override = default; - SinkStream& AcquireSinkStream(u32 /*sample_rate*/, u32 /*num_channels*/) override { + SinkStream& AcquireSinkStream(u32 /*sample_rate*/, u32 /*num_channels*/, + const std::string& /*name*/) override { return null_sink_stream; } diff --git a/src/audio_core/sink.h b/src/audio_core/sink.h index d1bb98c3d9..95c7b2b6ec 100644 --- a/src/audio_core/sink.h +++ b/src/audio_core/sink.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include "audio_core/sink_stream.h" #include "common/common_types.h" @@ -21,7 +22,8 @@ constexpr char auto_device_name[] = "auto"; class Sink { public: virtual ~Sink() = default; - virtual SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels) = 0; + virtual SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels, + const std::string& name) = 0; }; using SinkPtr = std::unique_ptr; -- cgit v1.2.3 From 600e4bbeac6430f27356e32d2905feb0d98fdd66 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 4 Aug 2018 00:03:12 -0400 Subject: audio_core: Use s16 where possible for audio samples. --- src/audio_core/audio_out.cpp | 2 +- src/audio_core/audio_out.h | 2 +- src/audio_core/buffer.h | 13 +++++++++---- src/audio_core/cubeb_sink.cpp | 11 +++++------ src/audio_core/null_sink.h | 3 +-- src/audio_core/sink_stream.h | 4 ++-- src/audio_core/stream.cpp | 19 +++++-------------- src/audio_core/stream.h | 3 --- src/core/hle/service/audio/audout_u.cpp | 6 +++--- 9 files changed, 27 insertions(+), 36 deletions(-) (limited to 'src/audio_core/audio_out.cpp') diff --git a/src/audio_core/audio_out.cpp b/src/audio_core/audio_out.cpp index eb9db755a6..12632a95c5 100644 --- a/src/audio_core/audio_out.cpp +++ b/src/audio_core/audio_out.cpp @@ -51,7 +51,7 @@ void AudioOut::StopStream(StreamPtr stream) { stream->Stop(); } -bool AudioOut::QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector&& data) { +bool AudioOut::QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector&& data) { return stream->QueueBuffer(std::make_shared(tag, std::move(data))); } diff --git a/src/audio_core/audio_out.h b/src/audio_core/audio_out.h index d564ff91ae..39b7e656b2 100644 --- a/src/audio_core/audio_out.h +++ b/src/audio_core/audio_out.h @@ -34,7 +34,7 @@ public: void StopStream(StreamPtr stream); /// Queues a buffer into the specified audio stream, returns true on success - bool QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector&& data); + bool QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector&& data); private: SinkPtr sink; diff --git a/src/audio_core/buffer.h b/src/audio_core/buffer.h index 4bf5fd58a7..a323b23ec9 100644 --- a/src/audio_core/buffer.h +++ b/src/audio_core/buffer.h @@ -18,11 +18,16 @@ class Buffer { public: using Tag = u64; - Buffer(Tag tag, std::vector&& data) : tag{tag}, data{std::move(data)} {} + Buffer(Tag tag, std::vector&& samples) : tag{tag}, samples{std::move(samples)} {} /// Returns the raw audio data for the buffer - const std::vector& GetData() const { - return data; + std::vector& Samples() { + return samples; + } + + /// Returns the raw audio data for the buffer + const std::vector& GetSamples() const { + return samples; } /// Returns the buffer tag, this is provided by the game to the audout service @@ -32,7 +37,7 @@ public: private: Tag tag; - std::vector data; + std::vector samples; }; using BufferPtr = std::shared_ptr; diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp index 0b0e9a0535..1501ef1f48 100644 --- a/src/audio_core/cubeb_sink.cpp +++ b/src/audio_core/cubeb_sink.cpp @@ -61,25 +61,24 @@ public: cubeb_stream_destroy(stream_backend); } - void EnqueueSamples(u32 num_channels, const s16* samples, size_t sample_count) override { + void EnqueueSamples(u32 num_channels, const std::vector& samples) override { if (!ctx) { return; } - queue.reserve(queue.size() + sample_count * GetNumChannels()); + queue.reserve(queue.size() + samples.size() * GetNumChannels()); if (is_6_channel) { // Downsample 6 channels to 2 - const size_t sample_count_copy_size = sample_count * num_channels * 2; + const size_t sample_count_copy_size = samples.size() * 2; queue.reserve(sample_count_copy_size); - for (size_t i = 0; i < sample_count * num_channels; i += num_channels) { + for (size_t i = 0; i < samples.size(); i += num_channels) { queue.push_back(samples[i]); queue.push_back(samples[i + 1]); } } else { // Copy as-is - std::copy(samples, samples + sample_count * GetNumChannels(), - std::back_inserter(queue)); + std::copy(samples.begin(), samples.end(), std::back_inserter(queue)); } } diff --git a/src/audio_core/null_sink.h b/src/audio_core/null_sink.h index 66041ea3f8..f235d93e56 100644 --- a/src/audio_core/null_sink.h +++ b/src/audio_core/null_sink.h @@ -20,8 +20,7 @@ public: private: struct NullSinkStreamImpl final : SinkStream { - void EnqueueSamples(u32 /*num_channels*/, const s16* /*samples*/, - size_t /*sample_count*/) override {} + void EnqueueSamples(u32 /*num_channels*/, const std::vector& /*samples*/) override {} } null_sink_stream; }; diff --git a/src/audio_core/sink_stream.h b/src/audio_core/sink_stream.h index e7a3f01b0c..41b6736d88 100644 --- a/src/audio_core/sink_stream.h +++ b/src/audio_core/sink_stream.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include "common/common_types.h" @@ -22,9 +23,8 @@ public: * Feed stereo samples to sink. * @param num_channels Number of channels used. * @param samples Samples in interleaved stereo PCM16 format. - * @param sample_count Number of samples. */ - virtual void EnqueueSamples(u32 num_channels, const s16* samples, size_t sample_count) = 0; + virtual void EnqueueSamples(u32 num_channels, const std::vector& samples) = 0; }; using SinkStreamPtr = std::unique_ptr; diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp index 7ab87c0c9d..ad9e2915ce 100644 --- a/src/audio_core/stream.cpp +++ b/src/audio_core/stream.cpp @@ -32,10 +32,6 @@ u32 Stream::GetNumChannels() const { return {}; } -u32 Stream::GetSampleSize() const { - return GetNumChannels() * 2; -} - Stream::Stream(u32 sample_rate, Format format, ReleaseCallback&& release_callback, SinkStream& sink_stream, std::string&& name_) : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)}, @@ -55,17 +51,15 @@ void Stream::Stop() { } s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const { - const size_t num_samples{buffer.GetData().size() / GetSampleSize()}; + const size_t num_samples{buffer.GetSamples().size() / GetNumChannels()}; return CoreTiming::usToCycles((static_cast(num_samples) * 1000000) / sample_rate); } -static std::vector GetVolumeAdjustedSamples(const std::vector& data) { - std::vector samples(data.size() / sizeof(s16)); - std::memcpy(samples.data(), data.data(), data.size()); +static void VolumeAdjustSamples(std::vector& samples) { const float volume{std::clamp(Settings::values.volume, 0.0f, 1.0f)}; if (volume == 1.0f) { - return samples; + return; } // Implementation of a volume slider with a dynamic range of 60 dB @@ -73,8 +67,6 @@ static std::vector GetVolumeAdjustedSamples(const std::vector& data) { for (auto& sample : samples) { sample = static_cast(sample * volume_scale_factor); } - - return samples; } void Stream::PlayNextBuffer() { @@ -96,9 +88,8 @@ void Stream::PlayNextBuffer() { active_buffer = queued_buffers.front(); queued_buffers.pop(); - const size_t sample_count{active_buffer->GetData().size() / GetSampleSize()}; - sink_stream.EnqueueSamples( - GetNumChannels(), GetVolumeAdjustedSamples(active_buffer->GetData()).data(), sample_count); + VolumeAdjustSamples(active_buffer->Samples()); + sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples()); CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {}); } diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h index 00f991733b..049b92ca92 100644 --- a/src/audio_core/stream.h +++ b/src/audio_core/stream.h @@ -69,9 +69,6 @@ public: /// Gets the number of channels u32 GetNumChannels() const; - /// Gets the sample size in bytes - u32 GetSampleSize() const; - private: /// Current state of the stream enum class State { diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index f4a5576343..108a7c6eba 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -113,10 +113,10 @@ private: std::memcpy(&audio_buffer, input_buffer.data(), sizeof(AudioBuffer)); const u64 tag{rp.Pop()}; - std::vector data(audio_buffer.buffer_size); - Memory::ReadBlock(audio_buffer.buffer, data.data(), data.size()); + std::vector samples(audio_buffer.buffer_size / sizeof(s16)); + Memory::ReadBlock(audio_buffer.buffer, samples.data(), audio_buffer.buffer_size); - if (!audio_core.QueueBuffer(stream, tag, std::move(data))) { + if (!audio_core.QueueBuffer(stream, tag, std::move(samples))) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultCode(ErrorModule::Audio, ErrCodes::BufferCountExceeded)); } -- cgit v1.2.3