summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2019-08-18 09:08:25 -0400
committerGravatar GitHub2019-08-18 09:08:25 -0400
commitef584f1a3a1dc8c10b6fb624265ae81fc1078c3a (patch)
tree41e9fa35694d70a91a9f0cf04f4c8533271e52cc /src
parentMerge pull request #2778 from ReinUsesLisp/nop (diff)
parentservice/audren_u: Handle audio USB output revision queries in ListAudioDevice... (diff)
downloadyuzu-ef584f1a3a1dc8c10b6fb624265ae81fc1078c3a.tar.gz
yuzu-ef584f1a3a1dc8c10b6fb624265ae81fc1078c3a.tar.xz
yuzu-ef584f1a3a1dc8c10b6fb624265ae81fc1078c3a.zip
Merge pull request #2747 from lioncash/audio
service/audren_u: Unstub ListAudioDeviceName
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/audio/audio.cpp6
-rw-r--r--src/core/hle/service/audio/audio.h6
-rw-r--r--src/core/hle/service/audio/audout_u.cpp36
-rw-r--r--src/core/hle/service/audio/audout_u.h12
-rw-r--r--src/core/hle/service/audio/audren_u.cpp200
-rw-r--r--src/core/hle/service/audio/audren_u.h25
-rw-r--r--src/core/hle/service/service.cpp2
7 files changed, 179 insertions, 108 deletions
diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp
index 128df7db5..1781bec83 100644
--- a/src/core/hle/service/audio/audio.cpp
+++ b/src/core/hle/service/audio/audio.cpp
@@ -19,16 +19,16 @@
19 19
20namespace Service::Audio { 20namespace Service::Audio {
21 21
22void InstallInterfaces(SM::ServiceManager& service_manager) { 22void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
23 std::make_shared<AudCtl>()->InstallAsService(service_manager); 23 std::make_shared<AudCtl>()->InstallAsService(service_manager);
24 std::make_shared<AudOutA>()->InstallAsService(service_manager); 24 std::make_shared<AudOutA>()->InstallAsService(service_manager);
25 std::make_shared<AudOutU>()->InstallAsService(service_manager); 25 std::make_shared<AudOutU>(system)->InstallAsService(service_manager);
26 std::make_shared<AudInA>()->InstallAsService(service_manager); 26 std::make_shared<AudInA>()->InstallAsService(service_manager);
27 std::make_shared<AudInU>()->InstallAsService(service_manager); 27 std::make_shared<AudInU>()->InstallAsService(service_manager);
28 std::make_shared<AudRecA>()->InstallAsService(service_manager); 28 std::make_shared<AudRecA>()->InstallAsService(service_manager);
29 std::make_shared<AudRecU>()->InstallAsService(service_manager); 29 std::make_shared<AudRecU>()->InstallAsService(service_manager);
30 std::make_shared<AudRenA>()->InstallAsService(service_manager); 30 std::make_shared<AudRenA>()->InstallAsService(service_manager);
31 std::make_shared<AudRenU>()->InstallAsService(service_manager); 31 std::make_shared<AudRenU>(system)->InstallAsService(service_manager);
32 std::make_shared<CodecCtl>()->InstallAsService(service_manager); 32 std::make_shared<CodecCtl>()->InstallAsService(service_manager);
33 std::make_shared<HwOpus>()->InstallAsService(service_manager); 33 std::make_shared<HwOpus>()->InstallAsService(service_manager);
34 34
diff --git a/src/core/hle/service/audio/audio.h b/src/core/hle/service/audio/audio.h
index f5bd3bf5f..b6d13912e 100644
--- a/src/core/hle/service/audio/audio.h
+++ b/src/core/hle/service/audio/audio.h
@@ -4,6 +4,10 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
@@ -11,6 +15,6 @@ class ServiceManager;
11namespace Service::Audio { 15namespace Service::Audio {
12 16
13/// Registers all Audio services with the specified service manager. 17/// Registers all Audio services with the specified service manager.
14void InstallInterfaces(SM::ServiceManager& service_manager); 18void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
15 19
16} // namespace Service::Audio 20} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 7db6eb08d..fb84a8f13 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -40,8 +40,8 @@ enum class AudioState : u32 {
40 40
41class IAudioOut final : public ServiceFramework<IAudioOut> { 41class IAudioOut final : public ServiceFramework<IAudioOut> {
42public: 42public:
43 IAudioOut(AudoutParams audio_params, AudioCore::AudioOut& audio_core, std::string&& device_name, 43 IAudioOut(Core::System& system, AudoutParams audio_params, AudioCore::AudioOut& audio_core,
44 std::string&& unique_name) 44 std::string&& device_name, std::string&& unique_name)
45 : ServiceFramework("IAudioOut"), audio_core(audio_core), 45 : ServiceFramework("IAudioOut"), audio_core(audio_core),
46 device_name(std::move(device_name)), audio_params(audio_params) { 46 device_name(std::move(device_name)), audio_params(audio_params) {
47 // clang-format off 47 // clang-format off
@@ -65,7 +65,6 @@ public:
65 RegisterHandlers(functions); 65 RegisterHandlers(functions);
66 66
67 // This is the event handle used to check if the audio buffer was released 67 // This is the event handle used to check if the audio buffer was released
68 auto& system = Core::System::GetInstance();
69 buffer_event = Kernel::WritableEvent::CreateEventPair( 68 buffer_event = Kernel::WritableEvent::CreateEventPair(
70 system.Kernel(), Kernel::ResetType::Manual, "IAudioOutBufferReleased"); 69 system.Kernel(), Kernel::ResetType::Manual, "IAudioOutBufferReleased");
71 70
@@ -212,6 +211,22 @@ private:
212 Kernel::EventPair buffer_event; 211 Kernel::EventPair buffer_event;
213}; 212};
214 213
214AudOutU::AudOutU(Core::System& system_) : ServiceFramework("audout:u"), system{system_} {
215 // clang-format off
216 static const FunctionInfo functions[] = {
217 {0, &AudOutU::ListAudioOutsImpl, "ListAudioOuts"},
218 {1, &AudOutU::OpenAudioOutImpl, "OpenAudioOut"},
219 {2, &AudOutU::ListAudioOutsImpl, "ListAudioOutsAuto"},
220 {3, &AudOutU::OpenAudioOutImpl, "OpenAudioOutAuto"},
221 };
222 // clang-format on
223
224 RegisterHandlers(functions);
225 audio_core = std::make_unique<AudioCore::AudioOut>();
226}
227
228AudOutU::~AudOutU() = default;
229
215void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) { 230void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) {
216 LOG_DEBUG(Service_Audio, "called"); 231 LOG_DEBUG(Service_Audio, "called");
217 232
@@ -248,7 +263,7 @@ void AudOutU::OpenAudioOutImpl(Kernel::HLERequestContext& ctx) {
248 263
249 std::string unique_name{fmt::format("{}-{}", device_name, audio_out_interfaces.size())}; 264 std::string unique_name{fmt::format("{}-{}", device_name, audio_out_interfaces.size())};
250 auto audio_out_interface = std::make_shared<IAudioOut>( 265 auto audio_out_interface = std::make_shared<IAudioOut>(
251 params, *audio_core, std::move(device_name), std::move(unique_name)); 266 system, params, *audio_core, std::move(device_name), std::move(unique_name));
252 267
253 IPC::ResponseBuilder rb{ctx, 6, 0, 1}; 268 IPC::ResponseBuilder rb{ctx, 6, 0, 1};
254 rb.Push(RESULT_SUCCESS); 269 rb.Push(RESULT_SUCCESS);
@@ -256,20 +271,9 @@ void AudOutU::OpenAudioOutImpl(Kernel::HLERequestContext& ctx) {
256 rb.Push<u32>(params.channel_count); 271 rb.Push<u32>(params.channel_count);
257 rb.Push<u32>(static_cast<u32>(AudioCore::Codec::PcmFormat::Int16)); 272 rb.Push<u32>(static_cast<u32>(AudioCore::Codec::PcmFormat::Int16));
258 rb.Push<u32>(static_cast<u32>(AudioState::Stopped)); 273 rb.Push<u32>(static_cast<u32>(AudioState::Stopped));
259 rb.PushIpcInterface<Audio::IAudioOut>(audio_out_interface); 274 rb.PushIpcInterface<IAudioOut>(audio_out_interface);
260 275
261 audio_out_interfaces.push_back(std::move(audio_out_interface)); 276 audio_out_interfaces.push_back(std::move(audio_out_interface));
262} 277}
263 278
264AudOutU::AudOutU() : ServiceFramework("audout:u") {
265 static const FunctionInfo functions[] = {{0, &AudOutU::ListAudioOutsImpl, "ListAudioOuts"},
266 {1, &AudOutU::OpenAudioOutImpl, "OpenAudioOut"},
267 {2, &AudOutU::ListAudioOutsImpl, "ListAudioOutsAuto"},
268 {3, &AudOutU::OpenAudioOutImpl, "OpenAudioOutAuto"}};
269 RegisterHandlers(functions);
270 audio_core = std::make_unique<AudioCore::AudioOut>();
271}
272
273AudOutU::~AudOutU() = default;
274
275} // namespace Service::Audio 279} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audout_u.h b/src/core/hle/service/audio/audout_u.h
index aed4c43b2..c9f532ccd 100644
--- a/src/core/hle/service/audio/audout_u.h
+++ b/src/core/hle/service/audio/audout_u.h
@@ -11,6 +11,10 @@ namespace AudioCore {
11class AudioOut; 11class AudioOut;
12} 12}
13 13
14namespace Core {
15class System;
16}
17
14namespace Kernel { 18namespace Kernel {
15class HLERequestContext; 19class HLERequestContext;
16} 20}
@@ -21,15 +25,17 @@ class IAudioOut;
21 25
22class AudOutU final : public ServiceFramework<AudOutU> { 26class AudOutU final : public ServiceFramework<AudOutU> {
23public: 27public:
24 AudOutU(); 28 explicit AudOutU(Core::System& system_);
25 ~AudOutU() override; 29 ~AudOutU() override;
26 30
27private: 31private:
32 void ListAudioOutsImpl(Kernel::HLERequestContext& ctx);
33 void OpenAudioOutImpl(Kernel::HLERequestContext& ctx);
34
28 std::vector<std::shared_ptr<IAudioOut>> audio_out_interfaces; 35 std::vector<std::shared_ptr<IAudioOut>> audio_out_interfaces;
29 std::unique_ptr<AudioCore::AudioOut> audio_core; 36 std::unique_ptr<AudioCore::AudioOut> audio_core;
30 37
31 void ListAudioOutsImpl(Kernel::HLERequestContext& ctx); 38 Core::System& system;
32 void OpenAudioOutImpl(Kernel::HLERequestContext& ctx);
33}; 39};
34 40
35} // namespace Service::Audio 41} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 679299f68..5b0b7f17e 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -5,6 +5,7 @@
5#include <algorithm> 5#include <algorithm>
6#include <array> 6#include <array>
7#include <memory> 7#include <memory>
8#include <string_view>
8 9
9#include "audio_core/audio_renderer.h" 10#include "audio_core/audio_renderer.h"
10#include "common/alignment.h" 11#include "common/alignment.h"
@@ -25,7 +26,7 @@ namespace Service::Audio {
25 26
26class IAudioRenderer final : public ServiceFramework<IAudioRenderer> { 27class IAudioRenderer final : public ServiceFramework<IAudioRenderer> {
27public: 28public:
28 explicit IAudioRenderer(AudioCore::AudioRendererParameter audren_params, 29 explicit IAudioRenderer(Core::System& system, AudioCore::AudioRendererParameter audren_params,
29 const std::size_t instance_number) 30 const std::size_t instance_number)
30 : ServiceFramework("IAudioRenderer") { 31 : ServiceFramework("IAudioRenderer") {
31 // clang-format off 32 // clang-format off
@@ -46,7 +47,6 @@ public:
46 // clang-format on 47 // clang-format on
47 RegisterHandlers(functions); 48 RegisterHandlers(functions);
48 49
49 auto& system = Core::System::GetInstance();
50 system_event = Kernel::WritableEvent::CreateEventPair( 50 system_event = Kernel::WritableEvent::CreateEventPair(
51 system.Kernel(), Kernel::ResetType::Manual, "IAudioRenderer:SystemEvent"); 51 system.Kernel(), Kernel::ResetType::Manual, "IAudioRenderer:SystemEvent");
52 renderer = std::make_unique<AudioCore::AudioRenderer>( 52 renderer = std::make_unique<AudioCore::AudioRenderer>(
@@ -160,7 +160,8 @@ private:
160 160
161class IAudioDevice final : public ServiceFramework<IAudioDevice> { 161class IAudioDevice final : public ServiceFramework<IAudioDevice> {
162public: 162public:
163 IAudioDevice() : ServiceFramework("IAudioDevice") { 163 explicit IAudioDevice(Core::System& system, u32_le revision_num)
164 : ServiceFramework("IAudioDevice"), revision{revision_num} {
164 static const FunctionInfo functions[] = { 165 static const FunctionInfo functions[] = {
165 {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"}, 166 {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"},
166 {1, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolume"}, 167 {1, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolume"},
@@ -178,7 +179,7 @@ public:
178 }; 179 };
179 RegisterHandlers(functions); 180 RegisterHandlers(functions);
180 181
181 auto& kernel = Core::System::GetInstance().Kernel(); 182 auto& kernel = system.Kernel();
182 buffer_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic, 183 buffer_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
183 "IAudioOutBufferReleasedEvent"); 184 "IAudioOutBufferReleasedEvent");
184 185
@@ -189,15 +190,47 @@ public:
189 } 190 }
190 191
191private: 192private:
193 using AudioDeviceName = std::array<char, 256>;
194 static constexpr std::array<std::string_view, 4> audio_device_names{{
195 "AudioStereoJackOutput",
196 "AudioBuiltInSpeakerOutput",
197 "AudioTvOutput",
198 "AudioUsbDeviceOutput",
199 }};
200 enum class DeviceType {
201 AHUBHeadphones,
202 AHUBSpeakers,
203 HDA,
204 USBOutput,
205 };
206
192 void ListAudioDeviceName(Kernel::HLERequestContext& ctx) { 207 void ListAudioDeviceName(Kernel::HLERequestContext& ctx) {
193 LOG_WARNING(Service_Audio, "(STUBBED) called"); 208 LOG_DEBUG(Service_Audio, "called");
194 209
195 constexpr std::array<char, 15> audio_interface{{"AudioInterface"}}; 210 const bool usb_output_supported =
196 ctx.WriteBuffer(audio_interface); 211 IsFeatureSupported(AudioFeatures::AudioUSBDeviceOutput, revision);
212 const std::size_t count = ctx.GetWriteBufferSize() / sizeof(AudioDeviceName);
213
214 std::vector<AudioDeviceName> name_buffer;
215 name_buffer.reserve(audio_device_names.size());
216
217 for (std::size_t i = 0; i < count && i < audio_device_names.size(); i++) {
218 const auto type = static_cast<DeviceType>(i);
219
220 if (!usb_output_supported && type == DeviceType::USBOutput) {
221 continue;
222 }
223
224 const auto& device_name = audio_device_names[i];
225 auto& entry = name_buffer.emplace_back();
226 device_name.copy(entry.data(), device_name.size());
227 }
228
229 ctx.WriteBuffer(name_buffer);
197 230
198 IPC::ResponseBuilder rb{ctx, 3}; 231 IPC::ResponseBuilder rb{ctx, 3};
199 rb.Push(RESULT_SUCCESS); 232 rb.Push(RESULT_SUCCESS);
200 rb.Push<u32>(1); 233 rb.Push(static_cast<u32>(name_buffer.size()));
201 } 234 }
202 235
203 void SetAudioDeviceOutputVolume(Kernel::HLERequestContext& ctx) { 236 void SetAudioDeviceOutputVolume(Kernel::HLERequestContext& ctx) {
@@ -216,12 +249,16 @@ private:
216 void GetActiveAudioDeviceName(Kernel::HLERequestContext& ctx) { 249 void GetActiveAudioDeviceName(Kernel::HLERequestContext& ctx) {
217 LOG_WARNING(Service_Audio, "(STUBBED) called"); 250 LOG_WARNING(Service_Audio, "(STUBBED) called");
218 251
219 constexpr std::array<char, 12> audio_interface{{"AudioDevice"}}; 252 // Currently set to always be TV audio output.
220 ctx.WriteBuffer(audio_interface); 253 const auto& device_name = audio_device_names[2];
221 254
222 IPC::ResponseBuilder rb{ctx, 3}; 255 AudioDeviceName out_device_name{};
256 device_name.copy(out_device_name.data(), device_name.size());
257
258 ctx.WriteBuffer(out_device_name);
259
260 IPC::ResponseBuilder rb{ctx, 2};
223 rb.Push(RESULT_SUCCESS); 261 rb.Push(RESULT_SUCCESS);
224 rb.Push<u32>(1);
225 } 262 }
226 263
227 void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) { 264 void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) {
@@ -250,12 +287,13 @@ private:
250 rb.PushCopyObjects(audio_output_device_switch_event.readable); 287 rb.PushCopyObjects(audio_output_device_switch_event.readable);
251 } 288 }
252 289
290 u32_le revision = 0;
253 Kernel::EventPair buffer_event; 291 Kernel::EventPair buffer_event;
254 Kernel::EventPair audio_output_device_switch_event; 292 Kernel::EventPair audio_output_device_switch_event;
255 293
256}; // namespace Audio 294}; // namespace Audio
257 295
258AudRenU::AudRenU() : ServiceFramework("audren:u") { 296AudRenU::AudRenU(Core::System& system_) : ServiceFramework("audren:u"), system{system_} {
259 // clang-format off 297 // clang-format off
260 static const FunctionInfo functions[] = { 298 static const FunctionInfo functions[] = {
261 {0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"}, 299 {0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"},
@@ -328,7 +366,7 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
328 }; 366 };
329 367
330 // Calculates the portion of the size related to the mix data (and the sorting thereof). 368 // Calculates the portion of the size related to the mix data (and the sorting thereof).
331 const auto calculate_mix_info_size = [this](const AudioCore::AudioRendererParameter& params) { 369 const auto calculate_mix_info_size = [](const AudioCore::AudioRendererParameter& params) {
332 // The size of the mixing info data structure. 370 // The size of the mixing info data structure.
333 constexpr u64 mix_info_size = 0x940; 371 constexpr u64 mix_info_size = 0x940;
334 372
@@ -400,7 +438,7 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
400 438
401 // Calculates the part of the size related to the splitter context. 439 // Calculates the part of the size related to the splitter context.
402 const auto calculate_splitter_context_size = 440 const auto calculate_splitter_context_size =
403 [this](const AudioCore::AudioRendererParameter& params) -> u64 { 441 [](const AudioCore::AudioRendererParameter& params) -> u64 {
404 if (!IsFeatureSupported(AudioFeatures::Splitter, params.revision)) { 442 if (!IsFeatureSupported(AudioFeatures::Splitter, params.revision)) {
405 return 0; 443 return 0;
406 } 444 }
@@ -447,7 +485,7 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
447 }; 485 };
448 486
449 // Calculates the part of the size related to performance statistics. 487 // Calculates the part of the size related to performance statistics.
450 const auto calculate_perf_size = [this](const AudioCore::AudioRendererParameter& params) { 488 const auto calculate_perf_size = [](const AudioCore::AudioRendererParameter& params) {
451 // Extra size value appended to the end of the calculation. 489 // Extra size value appended to the end of the calculation.
452 constexpr u64 appended = 128; 490 constexpr u64 appended = 128;
453 491
@@ -474,78 +512,76 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
474 }; 512 };
475 513
476 // Calculates the part of the size that relates to the audio command buffer. 514 // Calculates the part of the size that relates to the audio command buffer.
477 const auto calculate_command_buffer_size = 515 const auto calculate_command_buffer_size = [](const AudioCore::AudioRendererParameter& params) {
478 [this](const AudioCore::AudioRendererParameter& params) { 516 constexpr u64 alignment = (buffer_alignment_size - 1) * 2;
479 constexpr u64 alignment = (buffer_alignment_size - 1) * 2;
480 517
481 if (!IsFeatureSupported(AudioFeatures::VariadicCommandBuffer, params.revision)) { 518 if (!IsFeatureSupported(AudioFeatures::VariadicCommandBuffer, params.revision)) {
482 constexpr u64 command_buffer_size = 0x18000; 519 constexpr u64 command_buffer_size = 0x18000;
483 520
484 return command_buffer_size + alignment; 521 return command_buffer_size + alignment;
485 } 522 }
486 523
487 // When the variadic command buffer is supported, this means 524 // When the variadic command buffer is supported, this means
488 // the command generator for the audio renderer can issue commands 525 // the command generator for the audio renderer can issue commands
489 // that are (as one would expect), variable in size. So what we need to do 526 // that are (as one would expect), variable in size. So what we need to do
490 // is determine the maximum possible size for a few command data structures 527 // is determine the maximum possible size for a few command data structures
491 // then multiply them by the amount of present commands indicated by the given 528 // then multiply them by the amount of present commands indicated by the given
492 // respective audio parameters. 529 // respective audio parameters.
493 530
494 constexpr u64 max_biquad_filters = 2; 531 constexpr u64 max_biquad_filters = 2;
495 constexpr u64 max_mix_buffers = 24; 532 constexpr u64 max_mix_buffers = 24;
496 533
497 constexpr u64 biquad_filter_command_size = 0x2C; 534 constexpr u64 biquad_filter_command_size = 0x2C;
498 535
499 constexpr u64 depop_mix_command_size = 0x24; 536 constexpr u64 depop_mix_command_size = 0x24;
500 constexpr u64 depop_setup_command_size = 0x50; 537 constexpr u64 depop_setup_command_size = 0x50;
501 538
502 constexpr u64 effect_command_max_size = 0x540; 539 constexpr u64 effect_command_max_size = 0x540;
503 540
504 constexpr u64 mix_command_size = 0x1C; 541 constexpr u64 mix_command_size = 0x1C;
505 constexpr u64 mix_ramp_command_size = 0x24; 542 constexpr u64 mix_ramp_command_size = 0x24;
506 constexpr u64 mix_ramp_grouped_command_size = 0x13C; 543 constexpr u64 mix_ramp_grouped_command_size = 0x13C;
507 544
508 constexpr u64 perf_command_size = 0x28; 545 constexpr u64 perf_command_size = 0x28;
509 546
510 constexpr u64 sink_command_size = 0x130; 547 constexpr u64 sink_command_size = 0x130;
511 548
512 constexpr u64 submix_command_max_size = 549 constexpr u64 submix_command_max_size =
513 depop_mix_command_size + (mix_command_size * max_mix_buffers) * max_mix_buffers; 550 depop_mix_command_size + (mix_command_size * max_mix_buffers) * max_mix_buffers;
514 551
515 constexpr u64 volume_command_size = 0x1C; 552 constexpr u64 volume_command_size = 0x1C;
516 constexpr u64 volume_ramp_command_size = 0x20; 553 constexpr u64 volume_ramp_command_size = 0x20;
517 554
518 constexpr u64 voice_biquad_filter_command_size = 555 constexpr u64 voice_biquad_filter_command_size =
519 biquad_filter_command_size * max_biquad_filters; 556 biquad_filter_command_size * max_biquad_filters;
520 constexpr u64 voice_data_command_size = 0x9C; 557 constexpr u64 voice_data_command_size = 0x9C;
521 const u64 voice_command_max_size = 558 const u64 voice_command_max_size =
522 (params.splitter_count * depop_setup_command_size) + 559 (params.splitter_count * depop_setup_command_size) +
523 (voice_data_command_size + voice_biquad_filter_command_size + 560 (voice_data_command_size + voice_biquad_filter_command_size + volume_ramp_command_size +
524 volume_ramp_command_size + mix_ramp_grouped_command_size); 561 mix_ramp_grouped_command_size);
525 562
526 // Now calculate the individual elements that comprise the size and add them together. 563 // Now calculate the individual elements that comprise the size and add them together.
527 const u64 effect_commands_size = params.effect_count * effect_command_max_size; 564 const u64 effect_commands_size = params.effect_count * effect_command_max_size;
528 565
529 const u64 final_mix_commands_size = 566 const u64 final_mix_commands_size =
530 depop_mix_command_size + volume_command_size * max_mix_buffers; 567 depop_mix_command_size + volume_command_size * max_mix_buffers;
531 568
532 const u64 perf_commands_size = 569 const u64 perf_commands_size =
533 perf_command_size * 570 perf_command_size * (CalculateNumPerformanceEntries(params) + max_perf_detail_entries);
534 (CalculateNumPerformanceEntries(params) + max_perf_detail_entries);
535 571
536 const u64 sink_commands_size = params.sink_count * sink_command_size; 572 const u64 sink_commands_size = params.sink_count * sink_command_size;
537 573
538 const u64 splitter_commands_size = 574 const u64 splitter_commands_size =
539 params.num_splitter_send_channels * max_mix_buffers * mix_ramp_command_size; 575 params.num_splitter_send_channels * max_mix_buffers * mix_ramp_command_size;
540 576
541 const u64 submix_commands_size = params.submix_count * submix_command_max_size; 577 const u64 submix_commands_size = params.submix_count * submix_command_max_size;
542 578
543 const u64 voice_commands_size = params.voice_count * voice_command_max_size; 579 const u64 voice_commands_size = params.voice_count * voice_command_max_size;
544 580
545 return effect_commands_size + final_mix_commands_size + perf_commands_size + 581 return effect_commands_size + final_mix_commands_size + perf_commands_size +
546 sink_commands_size + splitter_commands_size + submix_commands_size + 582 sink_commands_size + splitter_commands_size + submix_commands_size +
547 voice_commands_size + alignment; 583 voice_commands_size + alignment;
548 }; 584 };
549 585
550 IPC::RequestParser rp{ctx}; 586 IPC::RequestParser rp{ctx};
551 const auto params = rp.PopRaw<AudioCore::AudioRendererParameter>(); 587 const auto params = rp.PopRaw<AudioCore::AudioRendererParameter>();
@@ -578,12 +614,16 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
578} 614}
579 615
580void AudRenU::GetAudioDeviceService(Kernel::HLERequestContext& ctx) { 616void AudRenU::GetAudioDeviceService(Kernel::HLERequestContext& ctx) {
581 LOG_DEBUG(Service_Audio, "called"); 617 IPC::RequestParser rp{ctx};
618 const u64 aruid = rp.Pop<u64>();
582 619
583 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 620 LOG_DEBUG(Service_Audio, "called. aruid={:016X}", aruid);
584 621
622 // Revisionless variant of GetAudioDeviceServiceWithRevisionInfo that
623 // always assumes the initial release revision (REV1).
624 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
585 rb.Push(RESULT_SUCCESS); 625 rb.Push(RESULT_SUCCESS);
586 rb.PushIpcInterface<Audio::IAudioDevice>(); 626 rb.PushIpcInterface<IAudioDevice>(system, Common::MakeMagic('R', 'E', 'V', '1'));
587} 627}
588 628
589void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) { 629void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) {
@@ -593,13 +633,19 @@ void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) {
593} 633}
594 634
595void AudRenU::GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx) { 635void AudRenU::GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx) {
596 LOG_WARNING(Service_Audio, "(STUBBED) called"); 636 struct Parameters {
637 u32 revision;
638 u64 aruid;
639 };
597 640
598 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 641 IPC::RequestParser rp{ctx};
642 const auto [revision, aruid] = rp.PopRaw<Parameters>();
643
644 LOG_DEBUG(Service_Audio, "called. revision={:08X}, aruid={:016X}", revision, aruid);
599 645
646 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
600 rb.Push(RESULT_SUCCESS); 647 rb.Push(RESULT_SUCCESS);
601 rb.PushIpcInterface<Audio::IAudioDevice>(); // TODO(ogniK): Figure out what is different 648 rb.PushIpcInterface<IAudioDevice>(system, revision);
602 // based on the current revision
603} 649}
604 650
605void AudRenU::OpenAudioRendererImpl(Kernel::HLERequestContext& ctx) { 651void AudRenU::OpenAudioRendererImpl(Kernel::HLERequestContext& ctx) {
@@ -608,14 +654,16 @@ void AudRenU::OpenAudioRendererImpl(Kernel::HLERequestContext& ctx) {
608 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 654 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
609 655
610 rb.Push(RESULT_SUCCESS); 656 rb.Push(RESULT_SUCCESS);
611 rb.PushIpcInterface<IAudioRenderer>(params, audren_instance_count++); 657 rb.PushIpcInterface<IAudioRenderer>(system, params, audren_instance_count++);
612} 658}
613 659
614bool AudRenU::IsFeatureSupported(AudioFeatures feature, u32_le revision) const { 660bool IsFeatureSupported(AudioFeatures feature, u32_le revision) {
615 // Byte swap 661 // Byte swap
616 const u32_be version_num = revision - Common::MakeMagic('R', 'E', 'V', '0'); 662 const u32_be version_num = revision - Common::MakeMagic('R', 'E', 'V', '0');
617 663
618 switch (feature) { 664 switch (feature) {
665 case AudioFeatures::AudioUSBDeviceOutput:
666 return version_num >= 4U;
619 case AudioFeatures::Splitter: 667 case AudioFeatures::Splitter:
620 return version_num >= 2U; 668 return version_num >= 2U;
621 case AudioFeatures::PerformanceMetricsVersion2: 669 case AudioFeatures::PerformanceMetricsVersion2:
diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h
index 49f2733cf..4e0ccc792 100644
--- a/src/core/hle/service/audio/audren_u.h
+++ b/src/core/hle/service/audio/audren_u.h
@@ -6,6 +6,10 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Kernel { 13namespace Kernel {
10class HLERequestContext; 14class HLERequestContext;
11} 15}
@@ -14,7 +18,7 @@ namespace Service::Audio {
14 18
15class AudRenU final : public ServiceFramework<AudRenU> { 19class AudRenU final : public ServiceFramework<AudRenU> {
16public: 20public:
17 explicit AudRenU(); 21 explicit AudRenU(Core::System& system_);
18 ~AudRenU() override; 22 ~AudRenU() override;
19 23
20private: 24private:
@@ -26,14 +30,19 @@ private:
26 30
27 void OpenAudioRendererImpl(Kernel::HLERequestContext& ctx); 31 void OpenAudioRendererImpl(Kernel::HLERequestContext& ctx);
28 32
29 enum class AudioFeatures : u32 {
30 Splitter,
31 PerformanceMetricsVersion2,
32 VariadicCommandBuffer,
33 };
34
35 bool IsFeatureSupported(AudioFeatures feature, u32_le revision) const;
36 std::size_t audren_instance_count = 0; 33 std::size_t audren_instance_count = 0;
34 Core::System& system;
37}; 35};
38 36
37// Describes a particular audio feature that may be supported in a particular revision.
38enum class AudioFeatures : u32 {
39 AudioUSBDeviceOutput,
40 Splitter,
41 PerformanceMetricsVersion2,
42 VariadicCommandBuffer,
43};
44
45// Tests if a particular audio feature is supported with a given audio revision.
46bool IsFeatureSupported(AudioFeatures feature, u32_le revision);
47
39} // namespace Service::Audio 48} // namespace Service::Audio
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 2daa1ae49..3a0f8c3f6 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -206,7 +206,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system) {
206 AM::InstallInterfaces(*sm, nv_flinger, system); 206 AM::InstallInterfaces(*sm, nv_flinger, system);
207 AOC::InstallInterfaces(*sm); 207 AOC::InstallInterfaces(*sm);
208 APM::InstallInterfaces(system); 208 APM::InstallInterfaces(system);
209 Audio::InstallInterfaces(*sm); 209 Audio::InstallInterfaces(*sm, system);
210 BCAT::InstallInterfaces(*sm); 210 BCAT::InstallInterfaces(*sm);
211 BPC::InstallInterfaces(*sm); 211 BPC::InstallInterfaces(*sm);
212 BtDrv::InstallInterfaces(*sm); 212 BtDrv::InstallInterfaces(*sm);