diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/audio/audren_u.cpp | 60 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audren_u.h | 1 |
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 | ||
| 161 | class IAudioDevice final : public ServiceFramework<IAudioDevice> { | 161 | class IAudioDevice final : public ServiceFramework<IAudioDevice> { |
| 162 | public: | 162 | public: |
| 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 | ||
| 599 | void AudRenU::GetAudioDeviceService(Kernel::HLERequestContext& ctx) { | 616 | void 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 | ||
| 608 | void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) { | 629 | void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) { |
| @@ -612,14 +633,19 @@ void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) { | |||
| 612 | } | 633 | } |
| 613 | 634 | ||
| 614 | void AudRenU::GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx) { | 635 | void 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 | ||
| 625 | void AudRenU::OpenAudioRendererImpl(Kernel::HLERequestContext& ctx) { | 651 | void 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. |
| 38 | enum class AudioFeatures : u32 { | 38 | enum class AudioFeatures : u32 { |
| 39 | AudioUSBDeviceOutput, | ||
| 39 | Splitter, | 40 | Splitter, |
| 40 | PerformanceMetricsVersion2, | 41 | PerformanceMetricsVersion2, |
| 41 | VariadicCommandBuffer, | 42 | VariadicCommandBuffer, |