Merge pull request #205 from Steveice10/great-refactor
Rewrite MIC service code, clean up microphone example.
This commit is contained in:
commit
7440ca7901
@ -6,26 +6,37 @@
|
|||||||
|
|
||||||
int main()
|
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();
|
gfxInitDefault();
|
||||||
consoleInit(GFX_BOTTOM, NULL);
|
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");
|
initialized = false;
|
||||||
audio_initialized = 1;
|
printf("Could not initialize CSND.\n");
|
||||||
}
|
} else printf("CSND initialized.\n");
|
||||||
|
|
||||||
sharedmem = (u32*)memalign(0x1000, sharedmem_size);
|
printf("Initializing MIC...\n");
|
||||||
audiobuf = linearAlloc(audiobuf_size);
|
if(R_FAILED(micInit(micbuf, micbuf_size)))
|
||||||
|
{
|
||||||
|
initialized = false;
|
||||||
|
printf("Could not initialize MIC.\n");
|
||||||
|
} else printf("MIC initialized.\n");
|
||||||
|
|
||||||
MIC_Initialize(sharedmem, sharedmem_size, control, 0, 3, 1, 1);//See mic.h.
|
u32 micbuf_datasize = micGetSampleDataSize();
|
||||||
|
|
||||||
|
u32 audiobuf_size = 0x100000;
|
||||||
|
u32 audiobuf_pos = 0;
|
||||||
|
u8* audiobuf = linearAlloc(audiobuf_size);
|
||||||
|
|
||||||
|
if(initialized) printf("Hold A to record, release to play.\n");
|
||||||
|
printf("Press START to exit.\n");
|
||||||
|
|
||||||
while(aptMainLoop())
|
while(aptMainLoop())
|
||||||
{
|
{
|
||||||
@ -36,45 +47,42 @@ int main()
|
|||||||
if (kDown & KEY_START)
|
if (kDown & KEY_START)
|
||||||
break; // break in order to return to hbmenu
|
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)
|
if(kDown & KEY_A)
|
||||||
{
|
{
|
||||||
audiobuf_pos = 0;
|
audiobuf_pos = 0;
|
||||||
printf("Stopping audio playback\n");
|
micbuf_pos = 0;
|
||||||
CSND_SetPlayState(0x8, 0);//Stop audio playback.
|
|
||||||
CSND_UpdateInfo(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("Starting sampling...\n");
|
||||||
printf("Now recording\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)
|
if((hidKeysHeld() & KEY_A) && audiobuf_pos < audiobuf_size)
|
||||||
{
|
{
|
||||||
audiobuf_pos+= MIC_ReadAudioData(&audiobuf[audiobuf_pos], audiobuf_size-audiobuf_pos, 1);
|
u32 micbuf_readpos = micbuf_pos;
|
||||||
if(audiobuf_pos > audiobuf_size)audiobuf_pos = audiobuf_size;
|
micbuf_pos = micGetLastSampleOffset();
|
||||||
|
while(audiobuf_pos < audiobuf_size && micbuf_readpos != micbuf_pos)
|
||||||
memset(framebuf, 0x60, 0x46500);
|
{
|
||||||
|
audiobuf[audiobuf_pos] = micbuf[micbuf_readpos];
|
||||||
|
audiobuf_pos++;
|
||||||
|
micbuf_readpos = (micbuf_readpos + 1) % micbuf_datasize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hidKeysUp() & KEY_A)
|
if(hidKeysUp() & KEY_A)
|
||||||
{
|
{
|
||||||
printf("Playing the recorded sample\n");
|
printf("Stoping sampling...\n");
|
||||||
MIC_SetRecording(0);
|
if(R_FAILED(MICU_StopSampling()) || R_FAILED(MICU_SetPower(false))) printf("Failed to stop sampling.\n");
|
||||||
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);
|
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");
|
||||||
gfxFlushBuffers();
|
else printf("Failed to start playback.\n");
|
||||||
gfxSwapBuffers();
|
|
||||||
|
|
||||||
framebuf = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL);
|
|
||||||
memset(framebuf, 0xe0, 0x46500);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,13 +90,12 @@ int main()
|
|||||||
gfxSwapBuffers();
|
gfxSwapBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
MIC_Shutdown();
|
|
||||||
|
|
||||||
if(audio_initialized)csndExit();
|
|
||||||
|
|
||||||
free(sharedmem);
|
|
||||||
linearFree(audiobuf);
|
linearFree(audiobuf);
|
||||||
|
|
||||||
|
micExit();
|
||||||
|
free(micbuf);
|
||||||
|
|
||||||
|
csndExit();
|
||||||
gfxExit();
|
gfxExit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -4,95 +4,125 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#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.
|
* @brief Initializes MIC.
|
||||||
* @param sharedmem Shared memory block to use. Must be 0x1000-bytes aligned.
|
* @param size Shared memory buffer to write audio data to. Must be aligned to 0x1000 bytes.
|
||||||
* @param sharedmem_size Size of the shared memory block to use. (audiodata size + 4, aligned to 0x1000-bytes)
|
* @param handle Size of the shared memory buffer.
|
||||||
* @param control Control value. Bits 0-6 = Amplification.
|
|
||||||
* @param unk0 Unknown. Typically 3.
|
|
||||||
* @param unk1 Unknown. Typically 1.
|
|
||||||
* @param unk2 Unknown. Typically 1.
|
|
||||||
*/
|
*/
|
||||||
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.
|
/// Exits MIC.
|
||||||
Result MIC_Shutdown(void);
|
void micExit(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the current shared memory offset.
|
* @brief Gets the size of the sample data area within the shared memory buffer.
|
||||||
* @return The current shared memory offset.
|
* @return The sample data's size.
|
||||||
*/
|
*/
|
||||||
u32 MIC_GetSharedMemOffsetValue(void);
|
u32 micGetSampleDataSize(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads MIC audio data.
|
* @brief Gets the offset within the shared memory buffer of the last sample written.
|
||||||
* @param outbuf Buffer to write audio data to.
|
* @return The last sample's offset.
|
||||||
* @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.
|
|
||||||
*/
|
*/
|
||||||
u32 MIC_ReadAudioData(u8 *outbuf, u32 readsize, u32 waitforevent);
|
u32 micGetLastSampleOffset(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Maps MIC's shared memory.
|
* @brief Maps MIC shared memory.
|
||||||
* @param handle Handle of the shared memory.
|
|
||||||
* @param size Size of the 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.
|
/// Unmaps MIC shared memory.
|
||||||
Result MIC_UnmapSharedMem(void);
|
Result MICU_UnmapSharedMem(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes MIC.
|
* @brief Begins sampling microphone input.
|
||||||
* @param unk0 Unknown.
|
* @param encoding Encoding of outputted audio.
|
||||||
* @param unk1 Unknown.
|
* @param sampleRate Sample rate of outputted audio.
|
||||||
* @param sharedmem_baseoffset Base offset of shared memory.
|
* @param sharedMemAudioOffset Offset to write audio data to in the shared memory buffer.
|
||||||
* @param sharedmem_endoffset End offset of shared memory.
|
* @param sharedMemAudioSize Size of audio data to write to the shared memory buffer. This should be at most "bufferSize - 4".
|
||||||
* @param unk2 Unknown.
|
* @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 Gets CNT bit 15 from MIC.
|
* @brief Adjusts the configuration of the current sampling session.
|
||||||
* @param out Pointer to output the bit to.
|
* @param sampleRate Sample rate of outputted audio.
|
||||||
*/
|
*/
|
||||||
Result MIC_GetCNTBit15(u8 *out);
|
Result MICU_AdjustSampling(MICU_SampleRate sampleRate);
|
||||||
|
|
||||||
|
/// Stops sampling microphone input.
|
||||||
|
Result MICU_StopSampling(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the event handle signaled by MIC when data is ready.
|
* @brief Gets whether microphone input is currently being sampled.
|
||||||
|
* @param sampling Pointer to output the sampling state to.
|
||||||
|
*/
|
||||||
|
Result MICU_IsSampling(bool* sampling);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets an event handle triggered when the shared memory buffer is full.
|
||||||
* @param handle Pointer to output the event handle to.
|
* @param handle Pointer to output the event handle to.
|
||||||
*/
|
*/
|
||||||
Result MIC_GetEventHandle(Handle *handle);
|
Result MICU_GetEventHandle(Handle* handle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the control value.
|
* @brief Sets the microphone's gain.
|
||||||
* @note Bits 0-6 = Amplification.
|
* @param gain Gain to set.
|
||||||
* @param value Control value to set.
|
|
||||||
*/
|
*/
|
||||||
Result MIC_SetControl(u8 value);
|
Result MICU_SetGain(u8 gain);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the control value.
|
* @brief Gets the microphone's gain.
|
||||||
* @note Bits 0-6 = Amplification.
|
* @param gain Pointer to output the current gain to.
|
||||||
* @param value Pointer to output the control value to.
|
|
||||||
*/
|
*/
|
||||||
Result MIC_GetControl(u8 *value);
|
Result MICU_GetGain(u8* gain);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether the microphone is recording.
|
* @brief Sets whether the microphone is powered on.
|
||||||
* @param value Whether the microphone is recording.
|
* @param power Whether the microphone is powered on.
|
||||||
*/
|
*/
|
||||||
Result MIC_SetRecording(u8 value);
|
Result MICU_SetPower(bool power);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets whether the microphone is recording.
|
* @brief Gets whether the microphone is powered on.
|
||||||
* @param value Pointer to output whether the microphone is recording to.
|
* @param power Pointer to output the power state to.
|
||||||
*/
|
*/
|
||||||
Result MIC_IsRecoding(u8 *value);
|
Result MICU_GetPower(bool* power);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets whether to clamp microphone input.
|
||||||
|
* @param clamp Whether to clamp microphone input.
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
@ -1,271 +1,226 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
|
||||||
#include <3ds/types.h>
|
#include <3ds/types.h>
|
||||||
#include <3ds/svc.h>
|
#include <3ds/svc.h>
|
||||||
#include <3ds/srv.h>
|
#include <3ds/srv.h>
|
||||||
#include <3ds/services/mic.h>
|
#include <3ds/services/mic.h>
|
||||||
#include <3ds/ipc.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;
|
Result micInit(u8* buffer, u32 bufferSize)
|
||||||
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 ret=0;
|
Result ret = 0;
|
||||||
|
|
||||||
MIC_sharedmem = (u8*)sharedmem;
|
if (AtomicPostIncrement(&micRefCount)) return 0;
|
||||||
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");
|
ret = srvGetServiceHandle(&micHandle, "mic:u");
|
||||||
if(ret!=0)return ret;
|
if (R_FAILED(ret)) goto end;
|
||||||
|
|
||||||
ret = svcCreateMemoryBlock(&MIC_sharedmem_handle, (u32)MIC_sharedmem, MIC_sharedmem_size, 3, 3);
|
micSharedMem = buffer;
|
||||||
if(ret!=0)return ret;
|
micSharedMemSize = bufferSize;
|
||||||
|
|
||||||
ret = MIC_SetControl(control);
|
ret = svcCreateMemoryBlock(&micSharedMemHandle, (u32) micSharedMem, micSharedMemSize, MEMPERM_READ | MEMPERM_WRITE, MEMPERM_READ | MEMPERM_WRITE);
|
||||||
if(ret!=0)return ret;
|
if (R_FAILED(ret)) goto end;
|
||||||
|
|
||||||
ret = MIC_MapSharedMem(MIC_sharedmem_handle, sharedmem_size);
|
ret = MICU_MapSharedMem(micSharedMemSize, micSharedMemHandle);
|
||||||
if(ret!=0)return ret;
|
end:
|
||||||
|
if (R_FAILED(ret)) micExit();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
ret = MIC_SetRecording(recording);
|
void micExit(void)
|
||||||
if(ret!=0)return ret;
|
{
|
||||||
|
if (AtomicDecrement(&micRefCount)) return;
|
||||||
|
|
||||||
ret = MIC_cmd3_Initialize(unk0, unk1, 0, MIC_sharedmem_size-4, unk2);
|
if (micSharedMemHandle)
|
||||||
if(ret!=0)return ret;
|
{
|
||||||
|
MICU_UnmapSharedMem();
|
||||||
|
svcCloseHandle(micSharedMemHandle);
|
||||||
|
micSharedMemHandle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
ret = MIC_GetEventHandle(&MIC_event);
|
if(micHandle)
|
||||||
if(ret!=0)return ret;
|
{
|
||||||
svcClearEvent(MIC_event);
|
svcCloseHandle(micHandle);
|
||||||
|
micHandle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
micSharedMem = NULL;
|
||||||
|
micSharedMemSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 micGetSampleDataSize(void)
|
||||||
|
{
|
||||||
|
return micSharedMemSize - 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 micGetLastSampleOffset(void)
|
||||||
|
{
|
||||||
|
if(micSharedMem) return *(u32*) &micSharedMem[micGetSampleDataSize()];
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result MIC_Shutdown(void)
|
Result MICU_MapSharedMem(u32 size, Handle handle)
|
||||||
{
|
{
|
||||||
Result ret=0;
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
MIC_cmd5();
|
|
||||||
MIC_SetRecording(0);
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
MIC_sharedmem_offsetfield = NULL;
|
|
||||||
MIC_sharedmem = NULL;
|
|
||||||
MIC_sharedmem_size = 0;
|
|
||||||
MIC_handle = 0;
|
|
||||||
MIC_event = 0;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 MIC_GetSharedMemOffsetValue(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 MIC_ReadAudioData(u8 *outbuf, u32 readsize, u32 waitforevent)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result MIC_MapSharedMem(Handle handle, u32 size)
|
|
||||||
{
|
|
||||||
Result ret=0;
|
|
||||||
u32 *cmdbuf = getThreadCommandBuffer();
|
|
||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x1,1,2); // 0x10042
|
cmdbuf[0] = IPC_MakeHeader(0x1,1,2); // 0x10042
|
||||||
cmdbuf[1] = size;
|
cmdbuf[1] = size;
|
||||||
cmdbuf[2] = IPC_Desc_SharedHandles(1);
|
cmdbuf[2] = IPC_Desc_SharedHandles(1);
|
||||||
cmdbuf[3] = handle;
|
cmdbuf[3] = handle;
|
||||||
|
|
||||||
if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
|
if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
|
||||||
|
return cmdbuf[1];
|
||||||
return (Result)cmdbuf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result MIC_UnmapSharedMem(void)
|
Result MICU_UnmapSharedMem(void)
|
||||||
{
|
{
|
||||||
Result ret=0;
|
Result ret = 0;
|
||||||
u32 *cmdbuf = getThreadCommandBuffer();
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x2,0,0); // 0x20000
|
cmdbuf[0] = IPC_MakeHeader(0x2,0,0); // 0x20000
|
||||||
|
|
||||||
if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
|
if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
|
||||||
|
return cmdbuf[1];
|
||||||
return (Result)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;
|
Result ret = 0;
|
||||||
u32 *cmdbuf = getThreadCommandBuffer();
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x3,5,0); // 0x30140
|
cmdbuf[0] = IPC_MakeHeader(0x3,5,0); // 0x30140
|
||||||
cmdbuf[1] = unk0;
|
cmdbuf[1] = encoding;
|
||||||
cmdbuf[2] = unk1;
|
cmdbuf[2] = sampleRate;
|
||||||
cmdbuf[3] = sharedmem_baseoffset;
|
cmdbuf[3] = offset;
|
||||||
cmdbuf[4] = sharedmem_endoffset;
|
cmdbuf[4] = size;
|
||||||
cmdbuf[5] = unk2;
|
cmdbuf[5] = loop;
|
||||||
|
|
||||||
if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
|
if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
|
||||||
|
return cmdbuf[1];
|
||||||
return (Result)cmdbuf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result MIC_cmd5(void)
|
Result MICU_AdjustSampling(MICU_SampleRate sampleRate)
|
||||||
{
|
{
|
||||||
Result ret=0;
|
Result ret = 0;
|
||||||
u32 *cmdbuf = getThreadCommandBuffer();
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0x4,1,0); // 0x40040
|
||||||
|
cmdbuf[1] = sampleRate;
|
||||||
|
|
||||||
|
if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Result MICU_StopSampling(void)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x5,0,0); // 0x50000
|
cmdbuf[0] = IPC_MakeHeader(0x5,0,0); // 0x50000
|
||||||
|
|
||||||
if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
|
if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
|
||||||
|
return cmdbuf[1];
|
||||||
return (Result)cmdbuf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result MIC_GetCNTBit15(u8 *out)
|
Result MICU_IsSampling(bool* sampling)
|
||||||
{
|
{
|
||||||
Result ret=0;
|
Result ret = 0;
|
||||||
u32 *cmdbuf = getThreadCommandBuffer();
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x6,0,0); // 0x60000
|
cmdbuf[0] = IPC_MakeHeader(0x6,0,0); // 0x60000
|
||||||
|
|
||||||
if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
|
if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
|
||||||
|
if (sampling) *sampling = cmdbuf[2] & 0xFF;
|
||||||
if(out)*out = cmdbuf[2];
|
return cmdbuf[1];
|
||||||
|
|
||||||
return (Result)cmdbuf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result MIC_GetEventHandle(Handle *handle)
|
Result MICU_GetEventHandle(Handle* handle)
|
||||||
{
|
{
|
||||||
Result ret=0;
|
Result ret = 0;
|
||||||
u32 *cmdbuf = getThreadCommandBuffer();
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
|
||||||
if(MIC_event)
|
|
||||||
{
|
|
||||||
*handle = MIC_event;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x7,0,0); // 0x70000
|
cmdbuf[0] = IPC_MakeHeader(0x7,0,0); // 0x70000
|
||||||
|
|
||||||
if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
|
if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
|
||||||
|
if (handle) *handle = cmdbuf[3];
|
||||||
if(handle)*handle = cmdbuf[3];
|
return cmdbuf[1];
|
||||||
|
|
||||||
return (Result)cmdbuf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result MIC_SetControl(u8 value)
|
Result MICU_SetGain(u8 gain)
|
||||||
{
|
{
|
||||||
Result ret=0;
|
Result ret = 0;
|
||||||
u32 *cmdbuf = getThreadCommandBuffer();
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x8,1,0); // 0x80040
|
cmdbuf[0] = IPC_MakeHeader(0x8,1,0); // 0x80040
|
||||||
cmdbuf[1] = value;
|
cmdbuf[1] = gain;
|
||||||
|
|
||||||
if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
|
if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
|
||||||
|
return cmdbuf[1];
|
||||||
return (Result)cmdbuf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result MIC_GetControl(u8 *value)
|
Result MICU_GetGain(u8* gain)
|
||||||
{
|
{
|
||||||
Result ret=0;
|
Result ret = 0;
|
||||||
u32 *cmdbuf = getThreadCommandBuffer();
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x9,0,0); // 0x90000
|
cmdbuf[0] = IPC_MakeHeader(0x9,0,0); // 0x90000
|
||||||
|
|
||||||
if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
|
if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
|
||||||
|
if (gain) *gain = cmdbuf[2] & 0xFF;
|
||||||
if(value)*value = cmdbuf[2];
|
return cmdbuf[1];
|
||||||
|
|
||||||
return (Result)cmdbuf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result MIC_SetRecording(u8 value)
|
Result MICU_SetPower(bool power)
|
||||||
{
|
{
|
||||||
Result ret=0;
|
Result ret = 0;
|
||||||
u32 *cmdbuf = getThreadCommandBuffer();
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0xA,1,0); // 0xA0040
|
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();
|
|
||||||
|
|
||||||
return (Result)cmdbuf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result MIC_IsRecoding(u8 *value)
|
Result MICU_GetPower(bool* power)
|
||||||
{
|
{
|
||||||
Result ret=0;
|
Result ret = 0;
|
||||||
u32 *cmdbuf = getThreadCommandBuffer();
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0xB,0,0); // 0xB0000
|
cmdbuf[0] = IPC_MakeHeader(0xB,0,0); // 0xB0000
|
||||||
|
|
||||||
if((ret = svcSendSyncRequest(MIC_handle))!=0)return ret;
|
if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
|
||||||
|
if (power) *power = cmdbuf[2] & 0xFF;
|
||||||
if(value)*value = cmdbuf[2];
|
return cmdbuf[1];
|
||||||
|
|
||||||
return (Result)cmdbuf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result MICU_SetClamp(bool clamp)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0xD,1,0); // 0xD0040
|
||||||
|
cmdbuf[1] = clamp;
|
||||||
|
|
||||||
|
if (R_FAILED(ret = svcSendSyncRequest(micHandle))) return ret;
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Result MICU_GetClamp(bool* clamp)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0xE,0,0); // 0xE0000
|
||||||
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user