summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Lioncash2019-07-19 03:56:21 -0400
committerGravatar Lioncash2019-07-19 07:55:27 -0400
commit16730c4c4351133c9a27d0b34c5aeb54ac65e9a6 (patch)
tree4e5a6890207e0ae77c6f4f127e75d68f2be797f9
parentservice/audren_u: Move revision testing code out of AudRenU (diff)
downloadyuzu-16730c4c4351133c9a27d0b34c5aeb54ac65e9a6.tar.gz
yuzu-16730c4c4351133c9a27d0b34c5aeb54ac65e9a6.tar.xz
yuzu-16730c4c4351133c9a27d0b34c5aeb54ac65e9a6.zip
service/audren_u: Handle audio USB output revision queries in ListAudioDeviceName()
Audio devices use the supplied revision information in order to determine if USB audio output is able to be supported. In this case, we can only really handle using this revision information in ListAudioDeviceName(), where it checks if USB audio output is supported before supplying it as a device name. A few other scenarios exist where the revision info is checked, such as: - Early exiting from SetAudioDeviceOutputVolume if USB audio is attempted to be set when that device is unsupported. - Early exiting and returning 0.0f in GetAudioDeviceOutputVolume when USB output volume is queried and it's an unsupported device. - Falling back to AHUB headphones in GetActiveAudioDeviceName when the device type is USB output, but is unsupported based off the revision info. In order for these changes to also be implemented, a few other changes to the interface need to be made. Given we now properly handle everything about ListAudioDeviceName(), we no longer need to describe it as a stubbed function.
-rw-r--r--src/core/hle/service/audio/audren_u.cpp60
-rw-r--r--src/core/hle/service/audio/audren_u.h1
2 files changed, 45 insertions, 16 deletions
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 8a7bf8a79..5b0b7f17e 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -160,7 +160,8 @@ private:
160 160
161class IAudioDevice final : public ServiceFramework<IAudioDevice> { 161class IAudioDevice final : public ServiceFramework<IAudioDevice> {
162public: 162public:
163 explicit IAudioDevice(Core::System& system) : 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"},
@@ -196,25 +197,40 @@ private:
196 "AudioTvOutput", 197 "AudioTvOutput",
197 "AudioUsbDeviceOutput", 198 "AudioUsbDeviceOutput",
198 }}; 199 }};
200 enum class DeviceType {
201 AHUBHeadphones,
202 AHUBSpeakers,
203 HDA,
204 USBOutput,
205 };
199 206
200 void ListAudioDeviceName(Kernel::HLERequestContext& ctx) { 207 void ListAudioDeviceName(Kernel::HLERequestContext& ctx) {
201 LOG_WARNING(Service_Audio, "(STUBBED) called"); 208 LOG_DEBUG(Service_Audio, "called");
202 209
203 const std::size_t num_names_requested = ctx.GetWriteBufferSize() / sizeof(AudioDeviceName); 210 const bool usb_output_supported =
204 const std::size_t num_to_copy = std::min(num_names_requested, audio_device_names.size()); 211 IsFeatureSupported(AudioFeatures::AudioUSBDeviceOutput, revision);
205 std::vector<AudioDeviceName> name_buffer(num_to_copy); 212 const std::size_t count = ctx.GetWriteBufferSize() / sizeof(AudioDeviceName);
206 213
207 for (std::size_t i = 0; i < num_to_copy; i++) { 214 std::vector<AudioDeviceName> name_buffer;
208 const auto& device_name = audio_device_names[i]; 215 name_buffer.reserve(audio_device_names.size());
209 216
210 device_name.copy(name_buffer[i].data(), device_name.size()); 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());
211 } 227 }
212 228
213 ctx.WriteBuffer(name_buffer); 229 ctx.WriteBuffer(name_buffer);
214 230
215 IPC::ResponseBuilder rb{ctx, 3}; 231 IPC::ResponseBuilder rb{ctx, 3};
216 rb.Push(RESULT_SUCCESS); 232 rb.Push(RESULT_SUCCESS);
217 rb.Push(static_cast<u32>(num_to_copy)); 233 rb.Push(static_cast<u32>(name_buffer.size()));
218 } 234 }
219 235
220 void SetAudioDeviceOutputVolume(Kernel::HLERequestContext& ctx) { 236 void SetAudioDeviceOutputVolume(Kernel::HLERequestContext& ctx) {
@@ -271,6 +287,7 @@ private:
271 rb.PushCopyObjects(audio_output_device_switch_event.readable); 287 rb.PushCopyObjects(audio_output_device_switch_event.readable);
272 } 288 }
273 289
290 u32_le revision = 0;
274 Kernel::EventPair buffer_event; 291 Kernel::EventPair buffer_event;
275 Kernel::EventPair audio_output_device_switch_event; 292 Kernel::EventPair audio_output_device_switch_event;
276 293
@@ -597,12 +614,16 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
597} 614}
598 615
599void AudRenU::GetAudioDeviceService(Kernel::HLERequestContext& ctx) { 616void AudRenU::GetAudioDeviceService(Kernel::HLERequestContext& ctx) {
600 LOG_DEBUG(Service_Audio, "called"); 617 IPC::RequestParser rp{ctx};
618 const u64 aruid = rp.Pop<u64>();
601 619
602 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 620 LOG_DEBUG(Service_Audio, "called. aruid={:016X}", aruid);
603 621
622 // Revisionless variant of GetAudioDeviceServiceWithRevisionInfo that
623 // always assumes the initial release revision (REV1).
624 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
604 rb.Push(RESULT_SUCCESS); 625 rb.Push(RESULT_SUCCESS);
605 rb.PushIpcInterface<IAudioDevice>(system); 626 rb.PushIpcInterface<IAudioDevice>(system, Common::MakeMagic('R', 'E', 'V', '1'));
606} 627}
607 628
608void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) { 629void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) {
@@ -612,14 +633,19 @@ void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) {
612} 633}
613 634
614void AudRenU::GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx) { 635void AudRenU::GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx) {
615 LOG_WARNING(Service_Audio, "(STUBBED) called"); 636 struct Parameters {
637 u32 revision;
638 u64 aruid;
639 };
616 640
617 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 641 IPC::RequestParser rp{ctx};
642 const auto [revision, aruid] = rp.PopRaw<Parameters>();
618 643
619 // TODO(ogniK): Figure out what is different based on the current revision 644 LOG_DEBUG(Service_Audio, "called. revision={:08X}, aruid={:016X}", revision, aruid);
620 645
646 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
621 rb.Push(RESULT_SUCCESS); 647 rb.Push(RESULT_SUCCESS);
622 rb.PushIpcInterface<IAudioDevice>(system); 648 rb.PushIpcInterface<IAudioDevice>(system, revision);
623} 649}
624 650
625void AudRenU::OpenAudioRendererImpl(Kernel::HLERequestContext& ctx) { 651void AudRenU::OpenAudioRendererImpl(Kernel::HLERequestContext& ctx) {
@@ -636,6 +662,8 @@ bool IsFeatureSupported(AudioFeatures feature, u32_le revision) {
636 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');
637 663
638 switch (feature) { 664 switch (feature) {
665 case AudioFeatures::AudioUSBDeviceOutput:
666 return version_num >= 4U;
639 case AudioFeatures::Splitter: 667 case AudioFeatures::Splitter:
640 return version_num >= 2U; 668 return version_num >= 2U;
641 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 0f3aad501..4e0ccc792 100644
--- a/src/core/hle/service/audio/audren_u.h
+++ b/src/core/hle/service/audio/audren_u.h
@@ -36,6 +36,7 @@ private:
36 36
37// Describes a particular audio feature that may be supported in a particular revision. 37// Describes a particular audio feature that may be supported in a particular revision.
38enum class AudioFeatures : u32 { 38enum class AudioFeatures : u32 {
39 AudioUSBDeviceOutput,
39 Splitter, 40 Splitter,
40 PerformanceMetricsVersion2, 41 PerformanceMetricsVersion2,
41 VariadicCommandBuffer, 42 VariadicCommandBuffer,