My Project
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules
mic.c
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <string.h>
3 #include <3ds.h>
4 
5 //See also: http://3dbrew.org/wiki/MIC_Services
6 
8 
9 static u8 *MIC_sharedmem;
10 static u32 MIC_sharedmem_size;
11 static u32 *MIC_sharedmem_offsetfield, MIC_sharedmem_offsetfield_location;
12 static Handle MIC_sharedmem_handle;
13 static Handle MIC_event;
14 
15 static u32 MIC_prev_endpos, MIC_cur_endpos;
16 
17 Result MIC_Initialize(u32 *sharedmem, u32 sharedmem_size, u8 control, u8 recording, u8 unk0, u8 unk1, u8 unk2)
18 {
19  Result ret=0;
20 
21  MIC_sharedmem = (u8*)sharedmem;
22  MIC_sharedmem_size = sharedmem_size;
23  MIC_sharedmem_offsetfield_location = MIC_sharedmem_size - 4;
24  MIC_sharedmem_offsetfield = (u32*)&MIC_sharedmem[MIC_sharedmem_offsetfield_location];
25  MIC_event = 0;
26  MIC_prev_endpos = 0;
27  MIC_cur_endpos = 0;
28 
29  ret = srvGetServiceHandle(&MIC_handle, "mic:u");
30  if(ret!=0)return ret;
31 
32  ret = svcCreateMemoryBlock(&MIC_sharedmem_handle, (u32)MIC_sharedmem, MIC_sharedmem_size, 3, 3);
33  if(ret!=0)return ret;
34 
35  ret = MIC_SetControl(control);
36  if(ret!=0)return ret;
37 
38  ret = MIC_MapSharedMem(MIC_sharedmem_handle, sharedmem_size);
39  if(ret!=0)return ret;
40 
41  ret = MIC_SetRecording(recording);
42  if(ret!=0)return ret;
43 
44  ret = MIC_cmd3_Initialize(unk0, unk1, 0, MIC_sharedmem_size-4, unk2);
45  if(ret!=0)return ret;
46 
47  ret = MIC_GetEventHandle(&MIC_event);
48  if(ret!=0)return ret;
49  svcClearEvent(MIC_event);
50 
51  return 0;
52 }
53 
55 {
56  Result ret=0;
57 
58  MIC_cmd5();
60 
61  ret = MIC_UnmapSharedMem();
62  if(ret!=0)return ret;
63 
64  MIC_cmd5();
65 
66  ret = svcUnmapMemoryBlock(MIC_sharedmem_handle, (u32)MIC_sharedmem);
67  if(ret!=0)return ret;
68 
69  ret = svcCloseHandle(MIC_sharedmem_handle);
70  if(ret!=0)return ret;
71 
72  ret = svcCloseHandle(MIC_event);
73  if(ret!=0)return ret;
74 
76  if(ret!=0)return ret;
77 
78  MIC_sharedmem_offsetfield = NULL;
79  MIC_sharedmem = NULL;
80  MIC_sharedmem_size = 0;
81  MIC_handle = 0;
82  MIC_event = 0;
83 
84  return 0;
85 }
86 
88 {
89  u32 pos = 0;
90 
91  if(MIC_sharedmem_offsetfield==NULL)return pos;
92  pos = *MIC_sharedmem_offsetfield;
93  if(pos > MIC_sharedmem_offsetfield_location)pos = MIC_sharedmem_offsetfield_location;
94 
95  return pos;
96 }
97 
98 u32 MIC_ReadAudioData(u8 *outbuf, u32 readsize, u32 waitforevent)
99 {
100  u32 pos = 0, bufpos = 0;
101 
102  if(waitforevent)
103  {
104  svcClearEvent(MIC_event);
105  svcWaitSynchronization(MIC_event, U64_MAX);
106  }
107 
108  MIC_prev_endpos = MIC_cur_endpos;
109  MIC_cur_endpos = MIC_GetSharedMemOffsetValue();
110  pos = MIC_prev_endpos;
111 
112  while(pos != MIC_cur_endpos)
113  {
114  if(pos >= MIC_sharedmem_offsetfield_location)pos = 0;
115  if(bufpos>=readsize)break;
116 
117  outbuf[bufpos] = MIC_sharedmem[pos];
118  bufpos++;
119  pos++;
120  }
121 
122  return bufpos;
123 }
124 
126 {
127  Result ret=0;
128  u32 *cmdbuf = getThreadCommandBuffer();
129 
130  cmdbuf[0] = 0x00010042;
131  cmdbuf[1] = size;
132  cmdbuf[2] = 0;
133  cmdbuf[3] = handle;
134 
135  if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
136 
137  return (Result)cmdbuf[1];
138 }
139 
141 {
142  Result ret=0;
143  u32 *cmdbuf = getThreadCommandBuffer();
144 
145  cmdbuf[0] = 0x00020000;
146 
147  if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
148 
149  return (Result)cmdbuf[1];
150 }
151 
152 Result MIC_cmd3_Initialize(u8 unk0, u8 unk1, u32 sharedmem_baseoffset, u32 sharedmem_endoffset, u8 unk2)
153 {
154  Result ret=0;
155  u32 *cmdbuf = getThreadCommandBuffer();
156 
157  cmdbuf[0] = 0x00030140;
158  cmdbuf[1] = unk0;
159  cmdbuf[2] = unk1;
160  cmdbuf[3] = sharedmem_baseoffset;
161  cmdbuf[4] = sharedmem_endoffset;
162  cmdbuf[5] = unk2;
163 
164  if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
165 
166  return (Result)cmdbuf[1];
167 }
168 
170 {
171  Result ret=0;
172  u32 *cmdbuf = getThreadCommandBuffer();
173 
174  cmdbuf[0] = 0x00050000;
175 
176  if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
177 
178  return (Result)cmdbuf[1];
179 }
180 
182 {
183  Result ret=0;
184  u32 *cmdbuf = getThreadCommandBuffer();
185 
186  cmdbuf[0] = 0x00060000;
187 
188  if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
189 
190  if(out)*out = cmdbuf[2];
191 
192  return (Result)cmdbuf[1];
193 }
194 
196 {
197  Result ret=0;
198  u32 *cmdbuf = getThreadCommandBuffer();
199 
200  if(MIC_event)
201  {
202  *handle = MIC_event;
203  return 0;
204  }
205 
206  cmdbuf[0] = 0x00070000;
207 
208  if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
209 
210  if(handle)*handle = cmdbuf[2];
211 
212  return (Result)cmdbuf[1];
213 }
214 
216 {
217  Result ret=0;
218  u32 *cmdbuf = getThreadCommandBuffer();
219 
220  cmdbuf[0] = 0x00080040;
221  cmdbuf[1] = value;
222 
223  if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
224 
225  return (Result)cmdbuf[1];
226 }
227 
229 {
230  Result ret=0;
231  u32 *cmdbuf = getThreadCommandBuffer();
232 
233  cmdbuf[0] = 0x00090000;
234 
235  if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
236 
237  if(value)*value = cmdbuf[2];
238 
239  return (Result)cmdbuf[1];
240 }
241 
243 {
244  Result ret=0;
245  u32 *cmdbuf = getThreadCommandBuffer();
246 
247  cmdbuf[0] = 0x000A0040;
248  cmdbuf[1] = value;
249 
250  if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
251 
252  if(value==1)MIC_cur_endpos = MIC_GetSharedMemOffsetValue();
253 
254  return (Result)cmdbuf[1];
255 }
256 
258 {
259  Result ret=0;
260  u32 *cmdbuf = getThreadCommandBuffer();
261 
262  cmdbuf[0] = 0x000B0000;
263 
264  if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
265 
266  if(value)*value = cmdbuf[2];
267 
268  return (Result)cmdbuf[1];
269 }
270 
s32 svcClearEvent(Handle handle)
s32 Result
Definition: types.h:42
s32 svcCloseHandle(Handle handle)
s32 svcWaitSynchronization(Handle handle, s64 nanoseconds)
Result srvGetServiceHandle(Handle *out, const char *name)
Definition: srv.c:109
Result MIC_UnmapSharedMem()
Definition: mic.c:140
u32 MIC_GetSharedMemOffsetValue()
Definition: mic.c:87
u32 Handle
Definition: types.h:41
Result MIC_cmd5()
Definition: mic.c:169
s32 svcUnmapMemoryBlock(Handle memblock, u32 addr)
#define U64_MAX
Definition: types.h:12
u32 * getThreadCommandBuffer(void)
uint8_t u8
Definition: types.h:21
uint32_t u32
Definition: types.h:23
Result MIC_GetControl(u8 *value)
Definition: mic.c:228
Result MIC_MapSharedMem(Handle handle, u32 size)
Definition: mic.c:125
u32 MIC_ReadAudioData(u8 *outbuf, u32 readsize, u32 waitforevent)
Definition: mic.c:98
Result MIC_Initialize(u32 *sharedmem, u32 sharedmem_size, u8 control, u8 recording, u8 unk0, u8 unk1, u8 unk2)
Definition: mic.c:17
Handle MIC_handle
Definition: mic.c:7
Result MIC_SetRecording(u8 value)
Definition: mic.c:242
Result MIC_GetCNTBit15(u8 *out)
Definition: mic.c:181
Result MIC_GetEventHandle(Handle *handle)
Definition: mic.c:195
s32 svcSendSyncRequest(Handle session)
Result MIC_Shutdown()
Definition: mic.c:54
Result MIC_cmd3_Initialize(u8 unk0, u8 unk1, u32 sharedmem_baseoffset, u32 sharedmem_endoffset, u8 unk2)
Definition: mic.c:152
Result MIC_SetControl(u8 value)
Definition: mic.c:215
s32 svcCreateMemoryBlock(Handle *memblock, u32 addr, u32 size, MemPerm my_perm, MemPerm other_perm)
Result MIC_IsRecoding(u8 *value)
Definition: mic.c:257