//ADPCM Encoding support from latest libctru revision
void CSND_SetAdpcmState(u32 channel, int block, int sample, int index){
u32 cmdparams[0x18>>2];
memset(cmdparams, 0, 0x18);
cmdparams[0] = channel & 0x1f;
cmdparams[1] = sample & 0xFFFF;
cmdparams[2] = index & 0x7F;
CSND_writesharedmem_cmdtype0(block ? 0xC : 0xB, (u8*)&cmdparams);
}
void CSND_ChnSetAdpcmReload(u32 channel, bool reload){
u32 cmdparams[0x18>>2];
memset(cmdparams, 0, 0x18);
cmdparams[0] = channel & 0x1f;
cmdparams[1] = reload ? 1 : 0;
CSND_writesharedmem_cmdtype0(0xD, (u8*)&cmdparams);
}
Result ADPCM_PlaySound(u32 chn, u32 looping, u32 encoding, u32 samplerate, void* data0, void* data1, u32 size, u32 l_vol, u32 r_vol){
u32 paddr0 = 0, paddr1 = 0;
if (data0) paddr0 = osConvertVirtToPhys((u32)data0);
if (data1) paddr1 = osConvertVirtToPhys((u32)data1);
if (data0 && encoding == CSND_ENCODING_IMA_ADPCM){
int adpcmSample = ((s16*)data0)[-2];
int adpcmIndex = ((u8*)data0)[-2];
CSND_SetAdpcmState(chn, 0, adpcmSample, adpcmIndex);
}
CSND_sharedmemtype0_cmde(chn, looping, encoding, samplerate, 2, 0, paddr0, paddr1, size);
if(looping){
if(paddr1>paddr0)size-= (u32)paddr1 - (u32)paddr0;
CSND_sharedmemtype0_cmd3(chn, paddr1, size);
}
CSND_sharedmemtype0_cmd8(chn, samplerate);
u32 cmdparams[0x18>>2];
memset(cmdparams, 0, 0x18);
cmdparams[0] = chn & 0x1f;
cmdparams[1] = l_vol | (r_vol<<16);
CSND_writesharedmem_cmdtype0(0x9, (u8*)&cmdparams);
CSND_ChnSetAdpcmReload(chn, true);
return CSND_processtype0cmds();
}