int main()
{
- u8 *framebuf;
- u32 *sharedmem = NULL, sharedmem_size = 0x30000;
- u8 *audiobuf;
- u32 audiobuf_size = 0x100000, audiobuf_pos = 0;
- u8 control=0x40;
- u32 audio_initialized = 0;
-
gfxInitDefault();
consoleInit(GFX_BOTTOM, NULL);
- if(csndInit()==0)
+ bool initialized = true;
+
+ u32 micbuf_size = 0x30000;
+ u32 micbuf_pos = 0;
+ u8* micbuf = memalign(micbuf_size, 0x1000);
+
+ printf("Initializing CSND...\n");
+ if(R_FAILED(csndInit()))
{
- printf("Init success\n");
- audio_initialized = 1;
- }
+ initialized = false;
+ printf("Could not initialize CSND.\n");
+ } else printf("CSND initialized.\n");
+
+ printf("Initializing MIC...\n");
+ if(R_FAILED(micInit(micbuf, micbuf_size)))
+ {
+ initialized = false;
+ printf("Could not initialize MIC.\n");
+ } else printf("MIC initialized.\n");
+
+ u32 micbuf_datasize = micGetSampleDataSize();
- sharedmem = (u32*)memalign(0x1000, sharedmem_size);
- audiobuf = linearAlloc(audiobuf_size);
+ u32 audiobuf_size = 0x100000;
+ u32 audiobuf_pos = 0;
+ u8* audiobuf = linearAlloc(audiobuf_size);
- MIC_Initialize(sharedmem, sharedmem_size, control, 0, 3, 1, 1);//See mic.h.
+ if(initialized) printf("Hold A to record, release to play.\n");
+ printf("Press START to exit.\n");
while(aptMainLoop())
{
if (kDown & KEY_START)
break; // break in order to return to hbmenu
- if(audio_initialized)
+ if(initialized)
{
- framebuf = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL);
-
if(kDown & KEY_A)
{
audiobuf_pos = 0;
- printf("Stopping audio playback\n");
- CSND_SetPlayState(0x8, 0);//Stop audio playback.
- CSND_UpdateInfo(0);
+ micbuf_pos = 0;
- MIC_SetRecording(1);
+ printf("Stopping audio playback...\n");
+ CSND_SetPlayState(0x8, 0);
+ if(R_FAILED(CSND_UpdateInfo(0))) printf("Failed to stop audio playback.\n");
- memset(framebuf, 0x20, 0x46500);
- printf("Now recording\n");
+ printf("Starting sampling...\n");
+ if(R_SUCCEEDED(MICU_SetPower(true)) && R_SUCCEEDED(MICU_StartSampling(MICU_ENCODING_PCM16_SIGNED, MICU_SAMPLE_RATE_16360, 0, micbuf_datasize, true))) printf("Now recording.\n");
+ else printf("Failed to start sampling.\n");
}
if((hidKeysHeld() & KEY_A) && audiobuf_pos < audiobuf_size)
{
- audiobuf_pos+= MIC_ReadAudioData(&audiobuf[audiobuf_pos], audiobuf_size-audiobuf_pos, 1);
- if(audiobuf_pos > audiobuf_size)audiobuf_pos = audiobuf_size;
-
- memset(framebuf, 0x60, 0x46500);
+ u32 micbuf_readpos = micbuf_pos;
+ micbuf_pos = micGetLastSampleOffset();
+ while(audiobuf_pos < audiobuf_size && micbuf_readpos != micbuf_pos)
+ {
+ audiobuf[audiobuf_pos] = micbuf[micbuf_readpos];
+ audiobuf_pos++;
+ micbuf_readpos = (micbuf_readpos + 1) % micbuf_datasize;
+ }
}
if(hidKeysUp() & KEY_A)
{
- printf("Playing the recorded sample\n");
- MIC_SetRecording(0);
- GSPGPU_FlushDataCache(NULL, audiobuf, audiobuf_pos);
- csndPlaySound(0x8, SOUND_ONE_SHOT | SOUND_FORMAT_16BIT, 16000, 1.0, 0.0, (u32*)audiobuf, NULL, audiobuf_pos);
-
- memset(framebuf, 0xe0, 0x46500);
-
- gfxFlushBuffers();
- gfxSwapBuffers();
+ printf("Stoping sampling...\n");
+ if(R_FAILED(MICU_StopSampling()) || R_FAILED(MICU_SetPower(false))) printf("Failed to stop sampling.\n");
- framebuf = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL);
- memset(framebuf, 0xe0, 0x46500);
+ printf("Starting audio playback...\n");
+ if(R_SUCCEEDED(GSPGPU_FlushDataCache(audiobuf, audiobuf_pos)) && R_SUCCEEDED(csndPlaySound(0x8, SOUND_ONE_SHOT | SOUND_FORMAT_16BIT, 16360, 1.0, 0.0, (u32*)audiobuf, NULL, audiobuf_pos))) printf("Now playing.\n");
+ else printf("Failed to start playback.\n");
}
}
gfxSwapBuffers();
}
- MIC_Shutdown();
-
- if(audio_initialized)csndExit();
-
- free(sharedmem);
linearFree(audiobuf);
+ micExit();
+ free(micbuf);
+
+ csndExit();
gfxExit();
return 0;
}
*/
#pragma once
-//See also: http://3dbrew.org/wiki/MIC_Services
+/// Microphone audio encodings.
+typedef enum
+{
+ MICU_ENCODING_PCM8 = 0, ///< Unsigned 8-bit PCM.
+ MICU_ENCODING_PCM16 = 1, ///< Unsigned 16-bit PCM.
+ MICU_ENCODING_PCM8_SIGNED = 2, ///< Signed 8-bit PCM.
+ MICU_ENCODING_PCM16_SIGNED = 3, ///< Signed 16-bit PCM.
+} MICU_Encoding;
+
+/// Microphone audio sampling rates.
+typedef enum
+{
+ MICU_SAMPLE_RATE_32730 = 0, ///< 32730 Hz
+ MICU_SAMPLE_RATE_16360 = 1, ///< 16360 Hz
+ MICU_SAMPLE_RATE_10910 = 2, ///< 10910 Hz
+ MICU_SAMPLE_RATE_8180 = 3, ///< 8180 Hz
+} MICU_SampleRate;
/**
* @brief Initializes MIC.
- * @param sharedmem Shared memory block to use. Must be 0x1000-bytes aligned.
- * @param sharedmem_size Size of the shared memory block to use. (audiodata size + 4, aligned to 0x1000-bytes)
- * @param control Control value. Bits 0-6 = Amplification.
- * @param unk0 Unknown. Typically 3.
- * @param unk1 Unknown. Typically 1.
- * @param unk2 Unknown. Typically 1.
+ * @param size Shared memory buffer to write audio data to. Must be aligned to 0x1000 bytes.
+ * @param handle Size of the shared memory buffer.
*/
-Result MIC_Initialize(u32 *sharedmem, u32 sharedmem_size, u8 control, u8 recording, u8 unk0, u8 unk1, u8 unk2);
+Result micInit(u8* buffer, u32 bufferSize);
-/// Shuts down MIC.
-Result MIC_Shutdown(void);
+/// Exits MIC.
+void micExit(void);
/**
- * @brief Gets the current shared memory offset.
- * @return The current shared memory offset.
+ * @brief Gets the size of the sample data area within the shared memory buffer.
+ * @return The sample data's size.
*/
-u32 MIC_GetSharedMemOffsetValue(void);
+u32 micGetSampleDataSize(void);
/**
- * @brief Reads MIC audio data.
- * @param outbuf Buffer to write audio data to.
- * @param readsize Size of the buffer to write to.
- * @param waitforevent Whether to wait for the MIC service to signal that audio data is ready. (non-zero = wait)
- * @return Actual number of bytes read.
+ * @brief Gets the offset within the shared memory buffer of the last sample written.
+ * @return The last sample's offset.
*/
-u32 MIC_ReadAudioData(u8 *outbuf, u32 readsize, u32 waitforevent);
+u32 micGetLastSampleOffset(void);
/**
- * @brief Maps MIC's shared memory.
- * @param handle Handle of the shared memory.
+ * @brief Maps MIC shared memory.
* @param size Size of the shared memory.
+ * @param handle Handle of the shared memory.
*/
-Result MIC_MapSharedMem(Handle handle, u32 size);
+Result MICU_MapSharedMem(u32 size, Handle handle);
-/// Unmaps MIC's shardd memory.
-Result MIC_UnmapSharedMem(void);
+/// Unmaps MIC shared memory.
+Result MICU_UnmapSharedMem(void);
/**
- * @brief Initializes MIC.
- * @param unk0 Unknown.
- * @param unk1 Unknown.
- * @param sharedmem_baseoffset Base offset of shared memory.
- * @param sharedmem_endoffset End offset of shared memory.
- * @param unk2 Unknown.
+ * @brief Begins sampling microphone input.
+ * @param encoding Encoding of outputted audio.
+ * @param sampleRate Sample rate of outputted audio.
+ * @param sharedMemAudioOffset Offset to write audio data to in the shared memory buffer.
+ * @param sharedMemAudioSize Size of audio data to write to the shared memory buffer. This should be at most "bufferSize - 4".
+ * @param loop Whether to loop back to the beginning of the buffer when the end is reached.
*/
-Result MIC_cmd3_Initialize(u8 unk0, u8 unk1, u32 sharedmem_baseoffset, u32 sharedmem_endoffset, u8 unk2);
+Result MICU_StartSampling(MICU_Encoding encoding, MICU_SampleRate sampleRate, u32 offset, u32 size, bool loop);
-/// Unknown MIC command.
-Result MIC_cmd5(void);
+/**
+ * @brief Adjusts the configuration of the current sampling session.
+ * @param sampleRate Sample rate of outputted audio.
+ */
+Result MICU_AdjustSampling(MICU_SampleRate sampleRate);
+
+/// Stops sampling microphone input.
+Result MICU_StopSampling(void);
/**
- * @brief Gets CNT bit 15 from MIC.
- * @param out Pointer to output the bit to.
+ * @brief Gets whether microphone input is currently being sampled.
+ * @param sampling Pointer to output the sampling state to.
*/
-Result MIC_GetCNTBit15(u8 *out);
+Result MICU_IsSampling(bool* sampling);
/**
- * @brief Gets the event handle signaled by MIC when data is ready.
+ * @brief Gets an event handle triggered when the shared memory buffer is full.
* @param handle Pointer to output the event handle to.
*/
-Result MIC_GetEventHandle(Handle *handle);
+Result MICU_GetEventHandle(Handle* handle);
+
+/**
+ * @brief Sets the microphone's gain.
+ * @param gain Gain to set.
+ */
+Result MICU_SetGain(u8 gain);
/**
- * Sets the control value.
- * @note Bits 0-6 = Amplification.
- * @param value Control value to set.
+ * @brief Gets the microphone's gain.
+ * @param gain Pointer to output the current gain to.
*/
-Result MIC_SetControl(u8 value);
+Result MICU_GetGain(u8* gain);
/**
- * Gets the control value.
- * @note Bits 0-6 = Amplification.
- * @param value Pointer to output the control value to.
+ * @brief Sets whether the microphone is powered on.
+ * @param power Whether the microphone is powered on.
*/
-Result MIC_GetControl(u8 *value);
+Result MICU_SetPower(bool power);
/**
- * Sets whether the microphone is recording.
- * @param value Whether the microphone is recording.
+ * @brief Gets whether the microphone is powered on.
+ * @param power Pointer to output the power state to.
*/
-Result MIC_SetRecording(u8 value);
+Result MICU_GetPower(bool* power);
/**
- * Gets whether the microphone is recording.
- * @param value Pointer to output whether the microphone is recording to.
+ * @brief Sets whether to clamp microphone input.
+ * @param clamp Whether to clamp microphone input.
*/
-Result MIC_IsRecoding(u8 *value);
+Result MICU_SetClamp(bool clamp);
+/**
+ * @brief Gets whether to clamp microphone input.
+ * @param clamp Pointer to output the clamp state to.
+ */
+Result MICU_GetClamp(bool* clamp);
+
+/**
+ * @brief Sets whether to allow sampling when the shell is closed.
+ * @param allowShellClosed Whether to allow sampling when the shell is closed.
+ */
+Result MICU_SetAllowShellClosed(bool allowShellClosed);
#include <stdlib.h>
-#include <string.h>
#include <3ds/types.h>
#include <3ds/svc.h>
#include <3ds/srv.h>
#include <3ds/services/mic.h>
#include <3ds/ipc.h>
+#include <3ds/synchronization.h>
+#include <3ds/result.h>
-//See also: http://3dbrew.org/wiki/MIC_Services
+static Handle micHandle;
+static int micRefCount;
-Handle MIC_handle;
+static u8* micSharedMem;
+static u32 micSharedMemSize;
+static Handle micSharedMemHandle;
-static u8 *MIC_sharedmem;
-static u32 MIC_sharedmem_size;
-static u32 *MIC_sharedmem_offsetfield, MIC_sharedmem_offsetfield_location;
-static Handle MIC_sharedmem_handle;
-static Handle MIC_event;
-
-static u32 MIC_prev_endpos, MIC_cur_endpos;
-
-Result MIC_Initialize(u32 *sharedmem, u32 sharedmem_size, u8 control, u8 recording, u8 unk0, u8 unk1, u8 unk2)
+Result micInit(u8* buffer, u32 bufferSize)
{
- Result ret=0;
-
- MIC_sharedmem = (u8*)sharedmem;
- MIC_sharedmem_size = sharedmem_size;
- MIC_sharedmem_offsetfield_location = MIC_sharedmem_size - 4;
- MIC_sharedmem_offsetfield = (u32*)&MIC_sharedmem[MIC_sharedmem_offsetfield_location];
- MIC_event = 0;
- MIC_prev_endpos = 0;
- MIC_cur_endpos = 0;
-
- ret = srvGetServiceHandle(&MIC_handle, "mic:u");
- if(ret!=0)return ret;
+ Result ret = 0;
- ret = svcCreateMemoryBlock(&MIC_sharedmem_handle, (u32)MIC_sharedmem, MIC_sharedmem_size, 3, 3);
- if(ret!=0)return ret;
+ if (AtomicPostIncrement(&micRefCount)) return 0;
- ret = MIC_SetControl(control);
- if(ret!=0)return ret;
+ ret = srvGetServiceHandle(&micHandle, "mic:u");
+ if (R_FAILED(ret)) goto end;
- ret = MIC_MapSharedMem(MIC_sharedmem_handle, sharedmem_size);
- if(ret!=0)return ret;
+ micSharedMem = buffer;
+ micSharedMemSize = bufferSize;
- ret = MIC_SetRecording(recording);
- if(ret!=0)return ret;
+ ret = svcCreateMemoryBlock(&micSharedMemHandle, (u32) micSharedMem, micSharedMemSize, MEMPERM_READ | MEMPERM_WRITE, MEMPERM_READ | MEMPERM_WRITE);
+ if (R_FAILED(ret)) goto end;
- ret = MIC_cmd3_Initialize(unk0, unk1, 0, MIC_sharedmem_size-4, unk2);
- if(ret!=0)return ret;
-
- ret = MIC_GetEventHandle(&MIC_event);
- if(ret!=0)return ret;
- svcClearEvent(MIC_event);
-
- return 0;
+ ret = MICU_MapSharedMem(micSharedMemSize, micSharedMemHandle);
+end:
+ if (R_FAILED(ret)) micExit();
+ return ret;
}
-Result MIC_Shutdown(void)
+void micExit(void)
{
- Result ret=0;
-
- MIC_cmd5();
- MIC_SetRecording(0);
+ if (AtomicDecrement(&micRefCount)) return;
- ret = MIC_UnmapSharedMem();
- if(ret!=0)return ret;
-
- MIC_cmd5();
-
- ret = svcCloseHandle(MIC_sharedmem_handle);
- if(ret!=0)return ret;
-
- ret = svcCloseHandle(MIC_event);
- if(ret!=0)return ret;
-
- ret = svcCloseHandle(MIC_handle);
- if(ret!=0)return ret;
+ if (micSharedMemHandle)
+ {
+ MICU_UnmapSharedMem();
+ svcCloseHandle(micSharedMemHandle);
+ micSharedMemHandle = 0;
+ }
- MIC_sharedmem_offsetfield = NULL;
- MIC_sharedmem = NULL;
- MIC_sharedmem_size = 0;
- MIC_handle = 0;
- MIC_event = 0;
+ if(micHandle)
+ {
+ svcCloseHandle(micHandle);
+ micHandle = 0;
+ }
- return 0;
+ micSharedMem = NULL;
+ micSharedMemSize = 0;
}
-u32 MIC_GetSharedMemOffsetValue(void)
+u32 micGetSampleDataSize(void)
{
- u32 pos = 0;
-
- if(MIC_sharedmem_offsetfield==NULL)return pos;
- pos = *MIC_sharedmem_offsetfield;
- if(pos > MIC_sharedmem_offsetfield_location)pos = MIC_sharedmem_offsetfield_location;
-
- return pos;
+ return micSharedMemSize - 4;
}
-u32 MIC_ReadAudioData(u8 *outbuf, u32 readsize, u32 waitforevent)
+u32 micGetLastSampleOffset(void)
{
- u32 pos = 0, bufpos = 0;
-
- if(waitforevent)
- {
- svcClearEvent(MIC_event);
- svcWaitSynchronization(MIC_event, U64_MAX);
- }
-
- MIC_prev_endpos = MIC_cur_endpos;
- MIC_cur_endpos = MIC_GetSharedMemOffsetValue();
- pos = MIC_prev_endpos;
-
- while(pos != MIC_cur_endpos)
- {
- if(pos >= MIC_sharedmem_offsetfield_location)pos = 0;
- if(bufpos>=readsize)break;
-
- outbuf[bufpos] = MIC_sharedmem[pos];
- bufpos++;
- pos++;
- }
-
- return bufpos;
+ if(micSharedMem) return *(u32*) &micSharedMem[micGetSampleDataSize()];
+ return 0;
}
-Result MIC_MapSharedMem(Handle handle, u32 size)
+Result MICU_MapSharedMem(u32 size, Handle handle)
{
- Result ret=0;
- u32 *cmdbuf = getThreadCommandBuffer();
-
+ Result ret = 0;
+ u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x1,1,2); // 0x10042
cmdbuf[1] = size;
cmdbuf[2] = IPC_Desc_SharedHandles(1);
cmdbuf[3] = handle;
- if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
-
- return (Result)cmdbuf[1];
+ if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
+ return cmdbuf[1];
}
-Result MIC_UnmapSharedMem(void)
+Result MICU_UnmapSharedMem(void)
{
- Result ret=0;
- u32 *cmdbuf = getThreadCommandBuffer();
-
+ Result ret = 0;
+ u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x2,0,0); // 0x20000
- if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
-
- return (Result)cmdbuf[1];
+ if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
+ return cmdbuf[1];
}
-Result MIC_cmd3_Initialize(u8 unk0, u8 unk1, u32 sharedmem_baseoffset, u32 sharedmem_endoffset, u8 unk2)
+Result MICU_StartSampling(MICU_Encoding encoding, MICU_SampleRate sampleRate, u32 offset, u32 size, bool loop)
{
- Result ret=0;
- u32 *cmdbuf = getThreadCommandBuffer();
-
+ Result ret = 0;
+ u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x3,5,0); // 0x30140
- cmdbuf[1] = unk0;
- cmdbuf[2] = unk1;
- cmdbuf[3] = sharedmem_baseoffset;
- cmdbuf[4] = sharedmem_endoffset;
- cmdbuf[5] = unk2;
+ cmdbuf[1] = encoding;
+ cmdbuf[2] = sampleRate;
+ cmdbuf[3] = offset;
+ cmdbuf[4] = size;
+ cmdbuf[5] = loop;
+
+ if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
+ return cmdbuf[1];
+}
- if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
+Result MICU_AdjustSampling(MICU_SampleRate sampleRate)
+{
+ Result ret = 0;
+ u32* cmdbuf = getThreadCommandBuffer();
+ cmdbuf[0] = IPC_MakeHeader(0x4,1,0); // 0x40040
+ cmdbuf[1] = sampleRate;
- return (Result)cmdbuf[1];
+ if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
+ return cmdbuf[1];
}
-Result MIC_cmd5(void)
+Result MICU_StopSampling(void)
{
- Result ret=0;
- u32 *cmdbuf = getThreadCommandBuffer();
-
+ Result ret = 0;
+ u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x5,0,0); // 0x50000
- if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
-
- return (Result)cmdbuf[1];
+ if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
+ return cmdbuf[1];
}
-Result MIC_GetCNTBit15(u8 *out)
+Result MICU_IsSampling(bool* sampling)
{
- Result ret=0;
- u32 *cmdbuf = getThreadCommandBuffer();
-
+ Result ret = 0;
+ u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x6,0,0); // 0x60000
- if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
-
- if(out)*out = cmdbuf[2];
-
- return (Result)cmdbuf[1];
+ if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
+ if (sampling) *sampling = cmdbuf[2] & 0xFF;
+ return cmdbuf[1];
}
-Result MIC_GetEventHandle(Handle *handle)
+Result MICU_GetEventHandle(Handle* handle)
{
- Result ret=0;
- u32 *cmdbuf = getThreadCommandBuffer();
-
- if(MIC_event)
- {
- *handle = MIC_event;
- return 0;
- }
-
+ Result ret = 0;
+ u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x7,0,0); // 0x70000
- if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
-
- if(handle)*handle = cmdbuf[3];
-
- return (Result)cmdbuf[1];
+ if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
+ if (handle) *handle = cmdbuf[3];
+ return cmdbuf[1];
}
-Result MIC_SetControl(u8 value)
+Result MICU_SetGain(u8 gain)
{
- Result ret=0;
- u32 *cmdbuf = getThreadCommandBuffer();
-
+ Result ret = 0;
+ u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x8,1,0); // 0x80040
- cmdbuf[1] = value;
+ cmdbuf[1] = gain;
- if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
-
- return (Result)cmdbuf[1];
+ if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
+ return cmdbuf[1];
}
-Result MIC_GetControl(u8 *value)
+Result MICU_GetGain(u8* gain)
{
- Result ret=0;
- u32 *cmdbuf = getThreadCommandBuffer();
-
+ Result ret = 0;
+ u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x9,0,0); // 0x90000
- if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
-
- if(value)*value = cmdbuf[2];
-
- return (Result)cmdbuf[1];
+ if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
+ if (gain) *gain = cmdbuf[2] & 0xFF;
+ return cmdbuf[1];
}
-Result MIC_SetRecording(u8 value)
+Result MICU_SetPower(bool power)
{
- Result ret=0;
- u32 *cmdbuf = getThreadCommandBuffer();
-
+ Result ret = 0;
+ u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0xA,1,0); // 0xA0040
- cmdbuf[1] = value;
+ cmdbuf[1] = power;
- if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
+ if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
+ return cmdbuf[1];
+}
- if(value==1)MIC_cur_endpos = MIC_GetSharedMemOffsetValue();
+Result MICU_GetPower(bool* power)
+{
+ Result ret = 0;
+ u32* cmdbuf = getThreadCommandBuffer();
+ cmdbuf[0] = IPC_MakeHeader(0xB,0,0); // 0xB0000
- return (Result)cmdbuf[1];
+ if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
+ if (power) *power = cmdbuf[2] & 0xFF;
+ return cmdbuf[1];
}
-Result MIC_IsRecoding(u8 *value)
+Result MICU_SetClamp(bool clamp)
{
- Result ret=0;
- u32 *cmdbuf = getThreadCommandBuffer();
+ Result ret = 0;
+ u32* cmdbuf = getThreadCommandBuffer();
+ cmdbuf[0] = IPC_MakeHeader(0xD,1,0); // 0xD0040
+ cmdbuf[1] = clamp;
- cmdbuf[0] = IPC_MakeHeader(0xB,0,0); // 0xB0000
-
- if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
+ if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
+ return cmdbuf[1];
+}
- if(value)*value = cmdbuf[2];
+Result MICU_GetClamp(bool* clamp)
+{
+ Result ret = 0;
+ u32* cmdbuf = getThreadCommandBuffer();
+ cmdbuf[0] = IPC_MakeHeader(0xE,0,0); // 0xE0000
- return (Result)cmdbuf[1];
+ if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
+ if (clamp) *clamp = cmdbuf[2] & 0xFF;
+ return cmdbuf[1];
}
+Result MICU_SetAllowShellClosed(bool allowShellClosed)
+{
+ Result ret = 0;
+ u32* cmdbuf = getThreadCommandBuffer();
+ cmdbuf[0] = IPC_MakeHeader(0xF,1,0); // 0xF0040
+ cmdbuf[1] = allowShellClosed;
+
+ if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
+ return cmdbuf[1];
+}