summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/logging/backend.cpp1
-rw-r--r--src/common/logging/log.h1
-rw-r--r--src/core/hle/service/mic_u.cpp322
-rw-r--r--src/core/hle/service/mic_u.h1
4 files changed, 309 insertions, 16 deletions
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 88209081d..7fd397fe5 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -43,6 +43,7 @@ namespace Log {
43 SUB(Service, AM) \ 43 SUB(Service, AM) \
44 SUB(Service, PTM) \ 44 SUB(Service, PTM) \
45 SUB(Service, LDR) \ 45 SUB(Service, LDR) \
46 SUB(Service, MIC) \
46 SUB(Service, NDM) \ 47 SUB(Service, NDM) \
47 SUB(Service, NIM) \ 48 SUB(Service, NIM) \
48 SUB(Service, NWM) \ 49 SUB(Service, NWM) \
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index 8d3a2d03e..8011534b8 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -60,6 +60,7 @@ enum class Class : ClassType {
60 Service_AM, ///< The AM (Application manager) service 60 Service_AM, ///< The AM (Application manager) service
61 Service_PTM, ///< The PTM (Power status & misc.) service 61 Service_PTM, ///< The PTM (Power status & misc.) service
62 Service_LDR, ///< The LDR (3ds dll loader) service 62 Service_LDR, ///< The LDR (3ds dll loader) service
63 Service_MIC, ///< The MIC (microphone) service
63 Service_NDM, ///< The NDM (Network daemon manager) service 64 Service_NDM, ///< The NDM (Network daemon manager) service
64 Service_NIM, ///< The NIM (Network interface manager) service 65 Service_NIM, ///< The NIM (Network interface manager) service
65 Service_NWM, ///< The NWM (Network wlan manager) service 66 Service_NWM, ///< The NWM (Network wlan manager) service
diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp
index edd1ea97b..563341504 100644
--- a/src/core/hle/service/mic_u.cpp
+++ b/src/core/hle/service/mic_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/kernel/event.h"
7#include "core/hle/kernel/shared_memory.h"
5#include "core/hle/service/mic_u.h" 8#include "core/hle/service/mic_u.h"
6 9
7//////////////////////////////////////////////////////////////////////////////////////////////////// 10////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -9,23 +12,298 @@
9 12
10namespace MIC_U { 13namespace MIC_U {
11 14
15enum class Encoding : u8 {
16 PCM8 = 0,
17 PCM16 = 1,
18 PCM8Signed = 2,
19 PCM16Signed = 3,
20};
21
22enum class SampleRate : u8 {
23 SampleRate32730 = 0,
24 SampleRate16360 = 1,
25 SampleRate10910 = 2,
26 SampleRate8180 = 3
27};
28
29static Kernel::SharedPtr<Kernel::Event> buffer_full_event;
30static Kernel::SharedPtr<Kernel::SharedMemory> shared_memory;
31static u8 mic_gain = 0;
32static bool mic_power = false;
33static bool is_sampling = false;
34static bool allow_shell_closed;
35static bool clamp = false;
36static Encoding encoding;
37static SampleRate sample_rate;
38static s32 audio_buffer_offset;
39static u32 audio_buffer_size;
40static bool audio_buffer_loop;
41
42/**
43 * MIC::MapSharedMem service function
44 * Inputs:
45 * 0 : Header Code[0x00010042]
46 * 1 : Shared-mem size
47 * 2 : CopyHandleDesc
48 * 3 : Shared-mem handle
49 * Outputs:
50 * 1 : Result of function, 0 on success, otherwise error code
51 */
52static void MapSharedMem(Service::Interface* self) {
53 u32* cmd_buff = Kernel::GetCommandBuffer();
54 u32 size = cmd_buff[1];
55 Handle mem_handle = cmd_buff[3];
56 shared_memory = Kernel::g_handle_table.Get<Kernel::SharedMemory>(mem_handle);
57 if (shared_memory) {
58 shared_memory->name = "MIC_U:shared_memory";
59 }
60 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
61 LOG_WARNING(Service_MIC, "called, size=0x%X, mem_handle=0x%08X", size, mem_handle);
62}
63
64/**
65 * MIC::UnmapSharedMem service function
66 * Inputs:
67 * 0 : Header Code[0x00020000]
68 * Outputs:
69 * 1 : Result of function, 0 on success, otherwise error code
70 */
71static void UnmapSharedMem(Service::Interface* self) {
72 u32* cmd_buff = Kernel::GetCommandBuffer();
73
74 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
75 LOG_WARNING(Service_MIC, "called");
76}
77
78/**
79 * MIC::StartSampling service function
80 * Inputs:
81 * 0 : Header Code[0x00030140]
82 * 1 : Encoding
83 * 2 : SampleRate
84 * 3 : Base offset for audio data in sharedmem
85 * 4 : Size of the audio data in sharedmem
86 * 5 : Loop at end of buffer
87 * Outputs:
88 * 1 : Result of function, 0 on success, otherwise error code
89 */
90static void StartSampling(Service::Interface* self) {
91 u32* cmd_buff = Kernel::GetCommandBuffer();
92
93 encoding = static_cast<Encoding>(cmd_buff[1] & 0xFF);
94 sample_rate = static_cast<SampleRate>(cmd_buff[2] & 0xFF);
95 audio_buffer_offset = cmd_buff[3];
96 audio_buffer_size = cmd_buff[4];
97 audio_buffer_loop = static_cast<bool>(cmd_buff[5] & 0xFF);
98
99 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
100 is_sampling = true;
101 LOG_WARNING(Service_MIC, "(STUBBED) called, encoding=%u, sample_rate=%u, "
102 "audio_buffer_offset=%d, audio_buffer_size=%u, audio_buffer_loop=%u",
103 encoding, sample_rate, audio_buffer_offset, audio_buffer_size, audio_buffer_loop);
104}
105
106/**
107 * MIC::AdjustSampling service function
108 * Inputs:
109 * 0 : Header Code[0x00040040]
110 * 1 : SampleRate
111 * Outputs:
112 * 1 : Result of function, 0 on success, otherwise error code
113 */
114static void AdjustSampling(Service::Interface* self) {
115 u32* cmd_buff = Kernel::GetCommandBuffer();
116 sample_rate = static_cast<SampleRate>(cmd_buff[1] & 0xFF);
117 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
118 LOG_WARNING(Service_MIC, "(STUBBED) called, sample_rate=%u", sample_rate);
119}
120
121/**
122 * MIC::StopSampling service function
123 * Inputs:
124 * 0 : Header Code[0x00050000]
125 * Outputs:
126 * 1 : Result of function, 0 on success, otherwise error code
127 */
128static void StopSampling(Service::Interface* self) {
129 u32* cmd_buff = Kernel::GetCommandBuffer();
130 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
131 is_sampling = false;
132 LOG_WARNING(Service_MIC, "(STUBBED) called");
133}
134
135/**
136 * MIC::IsSampling service function
137 * Inputs:
138 * 0 : Header Code[0x00060000]
139 * Outputs:
140 * 1 : Result of function, 0 on success, otherwise error code
141 * 2 : 0 = sampling, non-zero = sampling
142 */
143static void IsSampling(Service::Interface* self) {
144 u32* cmd_buff = Kernel::GetCommandBuffer();
145 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
146 cmd_buff[2] = is_sampling;
147 LOG_WARNING(Service_MIC, "(STUBBED) called");
148}
149
150/**
151 * MIC::GetBufferFullEvent service function
152 * Inputs:
153 * 0 : Header Code[0x00070000]
154 * Outputs:
155 * 1 : Result of function, 0 on success, otherwise error code
156 * 3 : Event handle
157 */
158static void GetBufferFullEvent(Service::Interface* self) {
159 u32* cmd_buff = Kernel::GetCommandBuffer();
160 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
161 cmd_buff[3] = Kernel::g_handle_table.Create(buffer_full_event).MoveFrom();
162 LOG_WARNING(Service_MIC, "(STUBBED) called");
163}
164
165/**
166 * MIC::SetGain service function
167 * Inputs:
168 * 0 : Header Code[0x00080040]
169 * 1 : Gain
170 * Outputs:
171 * 1 : Result of function, 0 on success, otherwise error code
172 */
173static void SetGain(Service::Interface* self) {
174 u32* cmd_buff = Kernel::GetCommandBuffer();
175 mic_gain = cmd_buff[1] & 0xFF;
176 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
177 LOG_WARNING(Service_MIC, "(STUBBED) called, mic_gain=%u", mic_gain);
178}
179
180/**
181 * MIC::GetGain service function
182 * Inputs:
183 * 0 : Header Code[0x00090000]
184 * Outputs:
185 * 1 : Result of function, 0 on success, otherwise error code
186 * 2 : Gain
187 */
188static void GetGain(Service::Interface* self) {
189 u32* cmd_buff = Kernel::GetCommandBuffer();
190 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
191 cmd_buff[2] = mic_gain;
192 LOG_WARNING(Service_MIC, "(STUBBED) called");
193}
194
195/**
196 * MIC::SetPower service function
197 * Inputs:
198 * 0 : Header Code[0x000A0040]
199 * 1 : Power (0 = off, 1 = on)
200 * Outputs:
201 * 1 : Result of function, 0 on success, otherwise error code
202 */
203static void SetPower(Service::Interface* self) {
204 u32* cmd_buff = Kernel::GetCommandBuffer();
205 mic_power = static_cast<bool>(cmd_buff[1] & 0xFF);
206 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
207 LOG_WARNING(Service_MIC, "(STUBBED) called, mic_power=%u", mic_power);
208}
209
210/**
211 * MIC::GetPower service function
212 * Inputs:
213 * 0 : Header Code[0x000B0000]
214 * Outputs:
215 * 1 : Result of function, 0 on success, otherwise error code
216 * 2 : Power
217 */
218static void GetPower(Service::Interface* self) {
219 u32* cmd_buff = Kernel::GetCommandBuffer();
220 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
221 cmd_buff[2] = mic_power;
222 LOG_WARNING(Service_MIC, "(STUBBED) called");
223}
224
225/**
226 * MIC::SetIirFilterMic service function
227 * Inputs:
228 * 0 : Header Code[0x000C0042]
229 * 1 : Size
230 * 2 : (Size << 4) | 0xA
231 * 3 : Pointer to IIR Filter Data
232 * Outputs:
233 * 1 : Result of function, 0 on success, otherwise error code
234 */
235static void SetIirFilterMic(Service::Interface* self) {
236 u32* cmd_buff = Kernel::GetCommandBuffer();
237
238 u32 size = cmd_buff[1];
239 VAddr buffer = cmd_buff[3];
240
241 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
242 LOG_WARNING(Service_MIC, "(STUBBED) called, size=0x%X, buffer=0x%08X", size, buffer);
243}
244
245/**
246 * MIC::SetClamp service function
247 * Inputs:
248 * 0 : Header Code[0x000D0040]
249 * 1 : Clamp (0 = don't clamp, non-zero = clamp)
250 * Outputs:
251 * 1 : Result of function, 0 on success, otherwise error code
252 */
253static void SetClamp(Service::Interface* self) {
254 u32* cmd_buff = Kernel::GetCommandBuffer();
255 clamp = static_cast<bool>(cmd_buff[1] & 0xFF);
256 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
257 LOG_WARNING(Service_MIC, "(STUBBED) called, clamp=%u", clamp);
258}
259
260/**
261 * MIC::GetClamp service function
262 * Inputs:
263 * 0 : Header Code[0x000E0000]
264 * Outputs:
265 * 1 : Result of function, 0 on success, otherwise error code
266 * 2 : Clamp (0 = don't clamp, non-zero = clamp)
267 */
268static void GetClamp(Service::Interface* self) {
269 u32* cmd_buff = Kernel::GetCommandBuffer();
270 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
271 cmd_buff[2] = clamp;
272 LOG_WARNING(Service_MIC, "(STUBBED) called");
273}
274
275/**
276 * MIC::SetAllowShellClosed service function
277 * Inputs:
278 * 0 : Header Code[0x000D0040]
279 * 1 : Sampling allowed while shell closed (0 = disallow, non-zero = allow)
280 * Outputs:
281 * 1 : Result of function, 0 on success, otherwise error code
282 */
283static void SetAllowShellClosed(Service::Interface* self) {
284 u32* cmd_buff = Kernel::GetCommandBuffer();
285 allow_shell_closed = static_cast<bool>(cmd_buff[1] & 0xFF);
286 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
287 LOG_WARNING(Service_MIC, "(STUBBED) called, allow_shell_closed=%u", allow_shell_closed);
288}
289
12const Interface::FunctionInfo FunctionTable[] = { 290const Interface::FunctionInfo FunctionTable[] = {
13 {0x00010042, nullptr, "MapSharedMem"}, 291 {0x00010042, MapSharedMem, "MapSharedMem"},
14 {0x00020000, nullptr, "UnmapSharedMem"}, 292 {0x00020000, UnmapSharedMem, "UnmapSharedMem"},
15 {0x00030140, nullptr, "Initialize"}, 293 {0x00030140, StartSampling, "StartSampling"},
16 {0x00040040, nullptr, "AdjustSampling"}, 294 {0x00040040, AdjustSampling, "AdjustSampling"},
17 {0x00050000, nullptr, "StopSampling"}, 295 {0x00050000, StopSampling, "StopSampling"},
18 {0x00060000, nullptr, "IsSampling"}, 296 {0x00060000, IsSampling, "IsSampling"},
19 {0x00070000, nullptr, "GetEventHandle"}, 297 {0x00070000, GetBufferFullEvent, "GetBufferFullEvent"},
20 {0x00080040, nullptr, "SetGain"}, 298 {0x00080040, SetGain, "SetGain"},
21 {0x00090000, nullptr, "GetGain"}, 299 {0x00090000, GetGain, "GetGain"},
22 {0x000A0040, nullptr, "SetPower"}, 300 {0x000A0040, SetPower, "SetPower"},
23 {0x000B0000, nullptr, "GetPower"}, 301 {0x000B0000, GetPower, "GetPower"},
24 {0x000C0042, nullptr, "size"}, 302 {0x000C0042, SetIirFilterMic, "SetIirFilterMic"},
25 {0x000D0040, nullptr, "SetClamp"}, 303 {0x000D0040, SetClamp, "SetClamp"},
26 {0x000E0000, nullptr, "GetClamp"}, 304 {0x000E0000, GetClamp, "GetClamp"},
27 {0x000F0040, nullptr, "SetAllowShellClosed"}, 305 {0x000F0040, SetAllowShellClosed, "SetAllowShellClosed"},
28 {0x00100040, nullptr, "unknown_input2"}, 306 {0x00100040, nullptr, "SetClientSDKVersion"},
29}; 307};
30 308
31//////////////////////////////////////////////////////////////////////////////////////////////////// 309////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -33,6 +311,18 @@ const Interface::FunctionInfo FunctionTable[] = {
33 311
34Interface::Interface() { 312Interface::Interface() {
35 Register(FunctionTable); 313 Register(FunctionTable);
314 shared_memory = nullptr;
315 buffer_full_event =
316 Kernel::Event::Create(Kernel::ResetType::OneShot, "MIC_U::buffer_full_event");
317 mic_gain = 0;
318 mic_power = false;
319 is_sampling = false;
320 clamp = false;
321}
322
323Interface::~Interface() {
324 shared_memory = nullptr;
325 buffer_full_event = nullptr;
36} 326}
37 327
38} // namespace 328} // namespace
diff --git a/src/core/hle/service/mic_u.h b/src/core/hle/service/mic_u.h
index dc795d14c..1cff7390e 100644
--- a/src/core/hle/service/mic_u.h
+++ b/src/core/hle/service/mic_u.h
@@ -16,6 +16,7 @@ namespace MIC_U {
16class Interface : public Service::Interface { 16class Interface : public Service::Interface {
17public: 17public:
18 Interface(); 18 Interface();
19 ~Interface();
19 20
20 std::string GetPortName() const override { 21 std::string GetPortName() const override {
21 return "mic:u"; 22 return "mic:u";