diff options
| author | 2019-08-18 09:08:25 -0400 | |
|---|---|---|
| committer | 2019-08-18 09:08:25 -0400 | |
| commit | ef584f1a3a1dc8c10b6fb624265ae81fc1078c3a (patch) | |
| tree | 41e9fa35694d70a91a9f0cf04f4c8533271e52cc /src | |
| parent | Merge pull request #2778 from ReinUsesLisp/nop (diff) | |
| parent | service/audren_u: Handle audio USB output revision queries in ListAudioDevice... (diff) | |
| download | yuzu-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.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audio.h | 6 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audout_u.cpp | 36 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audout_u.h | 12 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audren_u.cpp | 200 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audren_u.h | 25 | ||||
| -rw-r--r-- | src/core/hle/service/service.cpp | 2 |
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 | ||
| 20 | namespace Service::Audio { | 20 | namespace Service::Audio { |
| 21 | 21 | ||
| 22 | void InstallInterfaces(SM::ServiceManager& service_manager) { | 22 | void 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 | ||
| 7 | namespace Core { | ||
| 8 | class System; | ||
| 9 | } | ||
| 10 | |||
| 7 | namespace Service::SM { | 11 | namespace Service::SM { |
| 8 | class ServiceManager; | 12 | class ServiceManager; |
| 9 | } | 13 | } |
| @@ -11,6 +15,6 @@ class ServiceManager; | |||
| 11 | namespace Service::Audio { | 15 | namespace Service::Audio { |
| 12 | 16 | ||
| 13 | /// Registers all Audio services with the specified service manager. | 17 | /// Registers all Audio services with the specified service manager. |
| 14 | void InstallInterfaces(SM::ServiceManager& service_manager); | 18 | void 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 | ||
| 41 | class IAudioOut final : public ServiceFramework<IAudioOut> { | 41 | class IAudioOut final : public ServiceFramework<IAudioOut> { |
| 42 | public: | 42 | public: |
| 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 | ||
| 214 | AudOutU::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 | |||
| 228 | AudOutU::~AudOutU() = default; | ||
| 229 | |||
| 215 | void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) { | 230 | void 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 | ||
| 264 | AudOutU::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 | |||
| 273 | AudOutU::~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 { | |||
| 11 | class AudioOut; | 11 | class AudioOut; |
| 12 | } | 12 | } |
| 13 | 13 | ||
| 14 | namespace Core { | ||
| 15 | class System; | ||
| 16 | } | ||
| 17 | |||
| 14 | namespace Kernel { | 18 | namespace Kernel { |
| 15 | class HLERequestContext; | 19 | class HLERequestContext; |
| 16 | } | 20 | } |
| @@ -21,15 +25,17 @@ class IAudioOut; | |||
| 21 | 25 | ||
| 22 | class AudOutU final : public ServiceFramework<AudOutU> { | 26 | class AudOutU final : public ServiceFramework<AudOutU> { |
| 23 | public: | 27 | public: |
| 24 | AudOutU(); | 28 | explicit AudOutU(Core::System& system_); |
| 25 | ~AudOutU() override; | 29 | ~AudOutU() override; |
| 26 | 30 | ||
| 27 | private: | 31 | private: |
| 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 | ||
| 26 | class IAudioRenderer final : public ServiceFramework<IAudioRenderer> { | 27 | class IAudioRenderer final : public ServiceFramework<IAudioRenderer> { |
| 27 | public: | 28 | public: |
| 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 | ||
| 161 | class IAudioDevice final : public ServiceFramework<IAudioDevice> { | 161 | class IAudioDevice final : public ServiceFramework<IAudioDevice> { |
| 162 | public: | 162 | public: |
| 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 | ||
| 191 | private: | 192 | private: |
| 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 | ||
| 258 | AudRenU::AudRenU() : ServiceFramework("audren:u") { | 296 | AudRenU::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 | ||
| 580 | void AudRenU::GetAudioDeviceService(Kernel::HLERequestContext& ctx) { | 616 | void 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 | ||
| 589 | void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) { | 629 | void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) { |
| @@ -593,13 +633,19 @@ void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) { | |||
| 593 | } | 633 | } |
| 594 | 634 | ||
| 595 | void AudRenU::GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx) { | 635 | void 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 | ||
| 605 | void AudRenU::OpenAudioRendererImpl(Kernel::HLERequestContext& ctx) { | 651 | void 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 | ||
| 614 | bool AudRenU::IsFeatureSupported(AudioFeatures feature, u32_le revision) const { | 660 | bool 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 | ||
| 9 | namespace Core { | ||
| 10 | class System; | ||
| 11 | } | ||
| 12 | |||
| 9 | namespace Kernel { | 13 | namespace Kernel { |
| 10 | class HLERequestContext; | 14 | class HLERequestContext; |
| 11 | } | 15 | } |
| @@ -14,7 +18,7 @@ namespace Service::Audio { | |||
| 14 | 18 | ||
| 15 | class AudRenU final : public ServiceFramework<AudRenU> { | 19 | class AudRenU final : public ServiceFramework<AudRenU> { |
| 16 | public: | 20 | public: |
| 17 | explicit AudRenU(); | 21 | explicit AudRenU(Core::System& system_); |
| 18 | ~AudRenU() override; | 22 | ~AudRenU() override; |
| 19 | 23 | ||
| 20 | private: | 24 | private: |
| @@ -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. | ||
| 38 | enum 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. | ||
| 46 | bool 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); |