diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/audio/audin_u.cpp | 69 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audin_u.h | 29 |
2 files changed, 93 insertions, 5 deletions
diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp index d7f1d348d..bce7e61dd 100644 --- a/src/core/hle/service/audio/audin_u.cpp +++ b/src/core/hle/service/audio/audin_u.cpp | |||
| @@ -2,6 +2,9 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/logging/log.h" | ||
| 6 | #include "core/hle/ipc_helpers.h" | ||
| 7 | #include "core/hle/kernel/hle_ipc.h" | ||
| 5 | #include "core/hle/service/audio/audin_u.h" | 8 | #include "core/hle/service/audio/audin_u.h" |
| 6 | 9 | ||
| 7 | namespace Service::Audio { | 10 | namespace Service::Audio { |
| @@ -36,11 +39,12 @@ public: | |||
| 36 | AudInU::AudInU() : ServiceFramework("audin:u") { | 39 | AudInU::AudInU() : ServiceFramework("audin:u") { |
| 37 | // clang-format off | 40 | // clang-format off |
| 38 | static const FunctionInfo functions[] = { | 41 | static const FunctionInfo functions[] = { |
| 39 | {0, nullptr, "ListAudioIns"}, | 42 | {0, &AudInU::ListAudioIns, "ListAudioIns"}, |
| 40 | {1, nullptr, "OpenAudioIn"}, | 43 | {1, &AudInU::OpenAudioIn, "OpenAudioIn"}, |
| 41 | {2, nullptr, "Unknown"}, | 44 | {2, &AudInU::ListAudioIns, "ListAudioInsAuto"}, |
| 42 | {3, nullptr, "OpenAudioInAuto"}, | 45 | {3, &AudInU::OpenAudioIn, "OpenAudioInAuto"}, |
| 43 | {4, nullptr, "ListAudioInsAuto"}, | 46 | {4, &AudInU::ListAudioInsAutoFiltered, "ListAudioInsAutoFiltered"}, |
| 47 | {5, &AudInU::OpenAudioInProtocolSpecified, "OpenAudioInProtocolSpecified"}, | ||
| 44 | }; | 48 | }; |
| 45 | // clang-format on | 49 | // clang-format on |
| 46 | 50 | ||
| @@ -49,4 +53,59 @@ AudInU::AudInU() : ServiceFramework("audin:u") { | |||
| 49 | 53 | ||
| 50 | AudInU::~AudInU() = default; | 54 | AudInU::~AudInU() = default; |
| 51 | 55 | ||
| 56 | void AudInU::ListAudioIns(Kernel::HLERequestContext& ctx) { | ||
| 57 | LOG_DEBUG(Service_Audio, "called"); | ||
| 58 | const std::size_t count = ctx.GetWriteBufferSize() / sizeof(AudioInDeviceName); | ||
| 59 | |||
| 60 | std::vector<AudioInDeviceName> device_names; | ||
| 61 | const std::size_t device_count = std::min(count, audio_device_names.size()); | ||
| 62 | |||
| 63 | for (std::size_t i = 0; i < device_count; i++) { | ||
| 64 | const auto& device_name = audio_device_names[i]; | ||
| 65 | auto& entry = device_names.emplace_back(); | ||
| 66 | device_name.copy(entry.data(), device_name.size()); | ||
| 67 | } | ||
| 68 | |||
| 69 | ctx.WriteBuffer(device_names); | ||
| 70 | |||
| 71 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 72 | rb.Push(RESULT_SUCCESS); | ||
| 73 | rb.Push(static_cast<u32>(device_names.size())); | ||
| 74 | } | ||
| 75 | |||
| 76 | void AudInU::ListAudioInsAutoFiltered(Kernel::HLERequestContext& ctx) { | ||
| 77 | LOG_DEBUG(Service_Audio, "called"); | ||
| 78 | const u32 device_count = 0; | ||
| 79 | |||
| 80 | // Since we don't actually use any other audio input devices, we return 0 devices. Filtered | ||
| 81 | // device listing just omits the default input device | ||
| 82 | |||
| 83 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 84 | rb.Push(RESULT_SUCCESS); | ||
| 85 | rb.Push(static_cast<u32>(device_count)); | ||
| 86 | } | ||
| 87 | |||
| 88 | void AudInU::OpenInOutImpl(Kernel::HLERequestContext& ctx) { | ||
| 89 | AudInOutParams params{}; | ||
| 90 | params.channel_count = 2; | ||
| 91 | params.sample_format = SampleFormat::PCM16; | ||
| 92 | params.sample_rate = 48000; | ||
| 93 | params.state = State::Started; | ||
| 94 | |||
| 95 | IPC::ResponseBuilder rb{ctx, 6, 0, 1}; | ||
| 96 | rb.Push(RESULT_SUCCESS); | ||
| 97 | rb.PushRaw<AudInOutParams>(params); | ||
| 98 | rb.PushIpcInterface<IAudioIn>(); | ||
| 99 | } | ||
| 100 | |||
| 101 | void AudInU::OpenAudioIn(Kernel::HLERequestContext& ctx) { | ||
| 102 | LOG_WARNING(Service_Audio, "called"); | ||
| 103 | OpenInOutImpl(ctx); | ||
| 104 | } | ||
| 105 | |||
| 106 | void AudInU::OpenAudioInProtocolSpecified(Kernel::HLERequestContext& ctx) { | ||
| 107 | LOG_WARNING(Service_Audio, "called"); | ||
| 108 | OpenInOutImpl(ctx); | ||
| 109 | } | ||
| 110 | |||
| 52 | } // namespace Service::Audio | 111 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audin_u.h b/src/core/hle/service/audio/audin_u.h index 0538b9560..a599f4a64 100644 --- a/src/core/hle/service/audio/audin_u.h +++ b/src/core/hle/service/audio/audin_u.h | |||
| @@ -16,6 +16,35 @@ class AudInU final : public ServiceFramework<AudInU> { | |||
| 16 | public: | 16 | public: |
| 17 | explicit AudInU(); | 17 | explicit AudInU(); |
| 18 | ~AudInU() override; | 18 | ~AudInU() override; |
| 19 | |||
| 20 | private: | ||
| 21 | enum class SampleFormat : u32_le { | ||
| 22 | PCM16 = 2, | ||
| 23 | }; | ||
| 24 | |||
| 25 | enum class State : u32_le { | ||
| 26 | Started = 0, | ||
| 27 | Stopped = 1, | ||
| 28 | }; | ||
| 29 | |||
| 30 | struct AudInOutParams { | ||
| 31 | u32_le sample_rate{}; | ||
| 32 | u32_le channel_count{}; | ||
| 33 | SampleFormat sample_format{}; | ||
| 34 | State state{}; | ||
| 35 | }; | ||
| 36 | static_assert(sizeof(AudInOutParams) == 0x10, "AudInOutParams is an invalid size"); | ||
| 37 | |||
| 38 | using AudioInDeviceName = std::array<char, 256>; | ||
| 39 | static constexpr std::array<std::string_view, 1> audio_device_names{{ | ||
| 40 | "BuiltInHeadset", | ||
| 41 | }}; | ||
| 42 | |||
| 43 | void ListAudioIns(Kernel::HLERequestContext& ctx); | ||
| 44 | void ListAudioInsAutoFiltered(Kernel::HLERequestContext& ctx); | ||
| 45 | void OpenInOutImpl(Kernel::HLERequestContext& ctx); | ||
| 46 | void OpenAudioIn(Kernel::HLERequestContext& ctx); | ||
| 47 | void OpenAudioInProtocolSpecified(Kernel::HLERequestContext& ctx); | ||
| 19 | }; | 48 | }; |
| 20 | 49 | ||
| 21 | } // namespace Service::Audio | 50 | } // namespace Service::Audio |