Partially fix csndChnGetState() and csndChnIsPlaying()
This commit is contained in:
parent
c042ff5a6c
commit
59009d531d
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <3ds/types.h>
|
#include <3ds/types.h>
|
||||||
|
|
||||||
|
#define CSND_NUM_CHANNELS 32
|
||||||
#define CSND_SHAREDMEM_DEFAULT 0x10004000
|
#define CSND_SHAREDMEM_DEFAULT 0x10004000
|
||||||
|
|
||||||
#define CSND_TIMER(n) (0x3FEC3FC / ((u32)(n)))
|
#define CSND_TIMER(n) (0x3FEC3FC / ((u32)(n)))
|
||||||
@ -18,8 +18,27 @@ typedef enum{
|
|||||||
CSND_ENCODING_PSG, // Similar to DS?
|
CSND_ENCODING_PSG, // Similar to DS?
|
||||||
} CSND_ENCODING;
|
} CSND_ENCODING;
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
u32 value[3];
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u8 active;
|
||||||
|
u8 _pad1;
|
||||||
|
u16 _pad2;
|
||||||
|
s16 adpcmSample;
|
||||||
|
u8 adpcmIndex;
|
||||||
|
u8 _pad3;
|
||||||
|
u32 samplePAddr;
|
||||||
|
};
|
||||||
|
} CSND_ChnInfo;
|
||||||
|
|
||||||
// See here regarding CSND shared-mem commands, etc: http://3dbrew.org/wiki/CSND_Shared_Memory
|
// See here regarding CSND shared-mem commands, etc: http://3dbrew.org/wiki/CSND_Shared_Memory
|
||||||
|
|
||||||
|
extern vu32* csndSharedMem;
|
||||||
|
extern u32 csndSharedMemSize;
|
||||||
|
extern u32 csndChannels; // Bitmask of channels that are allowed for usage
|
||||||
|
|
||||||
Result csndInit(void);
|
Result csndInit(void);
|
||||||
Result csndExit(void);
|
Result csndExit(void);
|
||||||
|
|
||||||
@ -37,5 +56,7 @@ Result CSND_UpdateChnInfo(bool waitDone);
|
|||||||
|
|
||||||
Result csndChnPlaySound(u32 channel, u32 looping, u32 encoding, u32 samplerate, u32 *vaddr0, u32 *vaddr1, u32 totalbytesize, u32 unk0, u32 unk1);
|
Result csndChnPlaySound(u32 channel, u32 looping, u32 encoding, u32 samplerate, u32 *vaddr0, u32 *vaddr1, u32 totalbytesize, u32 unk0, u32 unk1);
|
||||||
|
|
||||||
Result csndChnGetState(u32 entryindex, u32 *out);
|
CSND_ChnInfo* csndChnGetInfo(u32 channel); // Requires previous CSND_UpdateChnInfo()
|
||||||
Result csndChnIsPlaying(u32 entryindex, u8 *status);
|
|
||||||
|
Result csndChnGetState(u32 channel, u32 *out);
|
||||||
|
Result csndChnIsPlaying(u32 channel, u8 *status);
|
||||||
|
@ -8,12 +8,15 @@
|
|||||||
|
|
||||||
// See here regarding CSND shared-mem commands, etc: http://3dbrew.org/wiki/CSND_Shared_Memory
|
// See here regarding CSND shared-mem commands, etc: http://3dbrew.org/wiki/CSND_Shared_Memory
|
||||||
|
|
||||||
|
vu32* csndSharedMem = NULL;
|
||||||
|
u32 csndSharedMemSize;
|
||||||
|
u32 csndChannels = 0;
|
||||||
|
|
||||||
static Handle csndHandle = 0;
|
static Handle csndHandle = 0;
|
||||||
static Handle csndMutex = 0;
|
static Handle csndMutex = 0;
|
||||||
static Handle csndSharedMemBlock = 0;
|
static Handle csndSharedMemBlock = 0;
|
||||||
static vu32* csndSharedMem = NULL;
|
|
||||||
static u32 csndBitmask = 0;
|
|
||||||
|
|
||||||
|
static u8 csndChnIdx[CSND_NUM_CHANNELS];
|
||||||
static u32 csndCmdBlockSize = 0x2000;
|
static u32 csndCmdBlockSize = 0x2000;
|
||||||
static u32 csndCmdStartOff = 0;
|
static u32 csndCmdStartOff = 0;
|
||||||
static u32 csndCmdCurOff = 0;
|
static u32 csndCmdCurOff = 0;
|
||||||
@ -50,7 +53,7 @@ static Result CSND_Shutdown()
|
|||||||
return (Result)cmdbuf[1];
|
return (Result)cmdbuf[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result CSND_GetBitmask(u32* bitmask)
|
static Result CSND_AcquireSoundChannels(u32* channelMask)
|
||||||
{
|
{
|
||||||
Result ret=0;
|
Result ret=0;
|
||||||
u32 *cmdbuf = getThreadCommandBuffer();
|
u32 *cmdbuf = getThreadCommandBuffer();
|
||||||
@ -59,7 +62,19 @@ static Result CSND_GetBitmask(u32* bitmask)
|
|||||||
|
|
||||||
if((ret = svcSendSyncRequest(csndHandle))!=0)return ret;
|
if((ret = svcSendSyncRequest(csndHandle))!=0)return ret;
|
||||||
|
|
||||||
*bitmask = cmdbuf[2];
|
*channelMask = cmdbuf[2];
|
||||||
|
|
||||||
|
return (Result)cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static Result CSND_ReleaseSoundChannels(void)
|
||||||
|
{
|
||||||
|
Result ret=0;
|
||||||
|
u32 *cmdbuf = getThreadCommandBuffer();
|
||||||
|
|
||||||
|
cmdbuf[0] = 0x00060000;
|
||||||
|
|
||||||
|
if((ret = svcSendSyncRequest(csndHandle))!=0)return ret;
|
||||||
|
|
||||||
return (Result)cmdbuf[1];
|
return (Result)cmdbuf[1];
|
||||||
}
|
}
|
||||||
@ -74,19 +89,32 @@ Result csndInit(void)
|
|||||||
ret = srvGetServiceHandle(&csndHandle, "csnd:SND");
|
ret = srvGetServiceHandle(&csndHandle, "csnd:SND");
|
||||||
if (ret != 0) return ret;
|
if (ret != 0) return ret;
|
||||||
|
|
||||||
u32 sharedMemSize = csndCmdBlockSize+0x114;
|
u32 offset0 = csndCmdBlockSize;
|
||||||
|
u32 offset1 = offset0 + 8;
|
||||||
|
u32 offset2 = offset1 + 32*sizeof(CSND_ChnInfo);
|
||||||
|
u32 offset3 = offset2 + 0x10;
|
||||||
|
csndSharedMemSize = offset3 + 0x3C;
|
||||||
|
|
||||||
ret = CSND_Initialize(sharedMemSize, csndCmdBlockSize, csndCmdBlockSize+8, csndCmdBlockSize+0xc8, csndCmdBlockSize+0xd8);
|
ret = CSND_Initialize(csndSharedMemSize, offset0, offset1, offset2, offset3);
|
||||||
if (ret != 0) return ret;
|
if (ret != 0) return ret;
|
||||||
|
|
||||||
ret = svcMapMemoryBlock(csndSharedMemBlock, (u32)csndSharedMem, 3, 0x10000000);
|
ret = svcMapMemoryBlock(csndSharedMemBlock, (u32)csndSharedMem, 3, 0x10000000);
|
||||||
if (ret != 0) return ret;
|
if (ret != 0) return ret;
|
||||||
|
|
||||||
memset((void*)csndSharedMem, 0, sharedMemSize);
|
memset((void*)csndSharedMem, 0, csndSharedMemSize);
|
||||||
|
|
||||||
ret = CSND_GetBitmask(&csndBitmask);
|
ret = CSND_AcquireSoundChannels(&csndChannels);
|
||||||
if (ret != 0) return ret;
|
if (ret != 0) return ret;
|
||||||
|
|
||||||
|
// Build index table
|
||||||
|
int i, j = 0;
|
||||||
|
for (i = 0; i < CSND_NUM_CHANNELS; i ++)
|
||||||
|
{
|
||||||
|
csndChnIdx[i] = j;
|
||||||
|
if (csndChannels & BIT(i))
|
||||||
|
j ++;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +122,9 @@ Result csndExit(void)
|
|||||||
{
|
{
|
||||||
Result ret;
|
Result ret;
|
||||||
|
|
||||||
|
ret = CSND_ReleaseSoundChannels();
|
||||||
|
if (ret != 0) return ret;
|
||||||
|
|
||||||
svcUnmapMemoryBlock(csndSharedMemBlock, (u32)csndSharedMem);
|
svcUnmapMemoryBlock(csndSharedMemBlock, (u32)csndSharedMem);
|
||||||
svcCloseHandle(csndSharedMemBlock);
|
svcCloseHandle(csndSharedMemBlock);
|
||||||
|
|
||||||
@ -265,6 +296,9 @@ Result CSND_UpdateChnInfo(bool waitDone)
|
|||||||
|
|
||||||
Result csndChnPlaySound(u32 channel, u32 looping, u32 encoding, u32 samplerate, u32 *vaddr0, u32 *vaddr1, u32 totalbytesize, u32 unk0, u32 unk1)
|
Result csndChnPlaySound(u32 channel, u32 looping, u32 encoding, u32 samplerate, u32 *vaddr0, u32 *vaddr1, u32 totalbytesize, u32 unk0, u32 unk1)
|
||||||
{
|
{
|
||||||
|
if (!(csndChannels & BIT(channel)))
|
||||||
|
return 1;
|
||||||
|
|
||||||
u32 physaddr0 = 0;
|
u32 physaddr0 = 0;
|
||||||
u32 physaddr1 = 0;
|
u32 physaddr1 = 0;
|
||||||
|
|
||||||
@ -283,28 +317,34 @@ Result csndChnPlaySound(u32 channel, u32 looping, u32 encoding, u32 samplerate,
|
|||||||
return CSND_UpdateChnInfo(false);
|
return CSND_UpdateChnInfo(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result csndChnGetState(u32 entryindex, u32 *out)
|
CSND_ChnInfo* csndChnGetInfo(u32 channel)
|
||||||
|
{
|
||||||
|
channel = csndChnIdx[channel];
|
||||||
|
return (CSND_ChnInfo*)(&csndSharedMem[(csndCmdBlockSize+8 + channel*0xc) >> 2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result csndChnGetState(u32 channel, u32 *out)
|
||||||
{
|
{
|
||||||
Result ret = 0;
|
Result ret = 0;
|
||||||
|
channel = csndChnIdx[channel];
|
||||||
|
|
||||||
if((ret = CSND_UpdateChnInfo(true)) != 0)return ret;
|
if((ret = CSND_UpdateChnInfo(true)) != 0)return ret;
|
||||||
|
|
||||||
memcpy(out, (const void*)&csndSharedMem[(csndCmdBlockSize+8 + entryindex*0xc) >> 2], 0xc);
|
memcpy(out, (const void*)&csndSharedMem[(csndCmdBlockSize+8 + channel*0xc) >> 2], 0xc);
|
||||||
//out[2] -= 0x0c000000;
|
//out[2] -= 0x0c000000;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result csndChnIsPlaying(u32 entryindex, u8 *status)
|
Result csndChnIsPlaying(u32 channel, u8 *status)
|
||||||
{
|
{
|
||||||
Result ret;
|
Result ret;
|
||||||
struct CSND_CHANNEL_STATUS entry;
|
struct CSND_CHANNEL_STATUS entry;
|
||||||
|
|
||||||
ret = csndChnGetState(entryindex, entry);
|
ret = csndChnGetState(channel, entry);
|
||||||
if(ret!=0)return ret;
|
if(ret!=0)return ret;
|
||||||
|
|
||||||
*status = entry.state;
|
*status = entry.state;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user