summaryrefslogtreecommitdiff
path: root/arm7/lib
diff options
context:
space:
mode:
Diffstat (limited to 'arm7/lib')
-rw-r--r--arm7/lib/include/SND.h4
-rw-r--r--arm7/lib/include/SND_channel.h4
-rw-r--r--arm7/lib/include/SND_command.h2
-rw-r--r--arm7/lib/include/SND_exChannel.h1
-rw-r--r--arm7/lib/include/SND_main.h2
-rw-r--r--arm7/lib/include/SND_seq.h17
-rw-r--r--arm7/lib/include/SND_wave.h2
-rw-r--r--arm7/lib/include/SND_work.h4
-rw-r--r--arm7/lib/src/SND_command.c302
-rw-r--r--arm7/lib/src/SND_lockChannel.c2
-rw-r--r--arm7/lib/src/SND_wave.c4
-rw-r--r--arm7/lib/src/SND_work.c4
12 files changed, 337 insertions, 11 deletions
diff --git a/arm7/lib/include/SND.h b/arm7/lib/include/SND.h
index b471ac72..c417ab0e 100644
--- a/arm7/lib/include/SND.h
+++ b/arm7/lib/include/SND.h
@@ -4,8 +4,6 @@
#include "nitro/types.h"
void SND_Enable(void);
-void SND_SetOutputSelector(u8 leftOutputFrom, u8 rightOutputFrom, u8 outputCh1ToMixer, u8 outputCh3ToMixer);
-void SND_SetMasterVolume(u8 vol);
-void SND_StopChannel(s32 idx, BOOL hold);
+void SND_SetOutputSelector(int leftOutputFrom, int rightOutputFrom, int outputCh1ToMixer, int outputCh3ToMixer);
#endif //GUARD_SND_H
diff --git a/arm7/lib/include/SND_channel.h b/arm7/lib/include/SND_channel.h
index ea179968..8b74b579 100644
--- a/arm7/lib/include/SND_channel.h
+++ b/arm7/lib/include/SND_channel.h
@@ -5,6 +5,8 @@
#include "SND_exChannel.h"
+void SNDi_SetSurroundDecay(int decay);
+
void SND_SetupChannelPcm(
s32 chnIdx,
const void *data,
@@ -41,6 +43,8 @@ void SND_SetChannelVolume(s32 chnIdx, s32 volume, s32 volumeDiv);
void SND_SetChannelPan(s32 chnIdx, s32 pan);
void SND_SetChannelTimer(s32 chnIdx, s32 timer);
+u32 SND_GetChannelControl(int idx);
+
// TODO move this function to SND_exChannel.c
u16 CalcDecayCoeff(int value);
diff --git a/arm7/lib/include/SND_command.h b/arm7/lib/include/SND_command.h
index ea5452b9..c22cd459 100644
--- a/arm7/lib/include/SND_command.h
+++ b/arm7/lib/include/SND_command.h
@@ -1,6 +1,8 @@
#ifndef GUARD_SND_COMMAND_H
#define GUARD_SND_COMMAND_H
+#include "nitro/SND_command_shared.h"
+
void SND_CommandInit(void);
void SND_CommandProc(void);
diff --git a/arm7/lib/include/SND_exChannel.h b/arm7/lib/include/SND_exChannel.h
index fcc3a548..038a1a49 100644
--- a/arm7/lib/include/SND_exChannel.h
+++ b/arm7/lib/include/SND_exChannel.h
@@ -22,6 +22,7 @@ BOOL SND_IsExChannelActive(struct SNDExChannel *chn);
struct SNDExChannel *SND_AllocExChannel(u32 channelMask, int priority, u32 flags, SNDExChannelCallback callback, void *callbackUserData);
void SND_FreeExChannel(struct SNDExChannel *chn);
BOOL SND_IsChannelActive(s32 idx);
+void SND_InvalidateWave(const void *start, const void *end);
// TODO internal functions, move these so exChannel
int ExChannelSweepUpdate(struct SNDExChannel *chn, BOOL step);
diff --git a/arm7/lib/include/SND_main.h b/arm7/lib/include/SND_main.h
index eba3ff44..fc72ae33 100644
--- a/arm7/lib/include/SND_main.h
+++ b/arm7/lib/include/SND_main.h
@@ -12,5 +12,7 @@ u32 SND_WaitForIntervalTimer(void);
void SND_SendWakeupMessage(void);
void SNDi_LockMutex(void);
void SNDi_UnlockMutex(void);
+void SND_SetMasterVolume(int vol);
+void SND_SetMasterPan(int pan);
#endif //GUARD_SND_MAIN_H
diff --git a/arm7/lib/include/SND_seq.h b/arm7/lib/include/SND_seq.h
index 642cff3e..25b63a35 100644
--- a/arm7/lib/include/SND_seq.h
+++ b/arm7/lib/include/SND_seq.h
@@ -1,7 +1,24 @@
#ifndef GUARD_SND_SEQ_H
#define GUARD_SND_SEQ_H
+#include "nitro/types.h"
+
+#include "nitro/SND_bank_shared.h"
+
void SND_SeqInit(void);
void SND_SeqMain(BOOL update);
+void SND_StartSeq(int player, const void *seq, u32 offset, struct SNDBankData *bank);
+void SND_StopSeq(int player);
+void SND_PrepareSeq(int player, const void *seq, u32 offset, struct SNDBankData *bank);
+void SND_StartPreparedSeq(int player);
+void SND_PauseSeq(int player, BOOL pause);
+void SND_SkipSeq(int player, u32 tick);
+void SNDi_SetPlayerParam(int player, u32 offset, u32 data, int size);
+void SNDi_SetTrackParam(int player, u32 trackMask, u32 offset, u32 data, int size);
+void SND_SetTrackMute(int player, u32 trackMask, BOOL mute);
+void SND_SetTrackAllocatableChannel(int player, u32 trackMask, u32 channelMask);
+void SND_InvalidateSeq(const void *start, const void *end);
+void SND_InvalidateBank(const void *start, const void *end);
+
#endif //GUARD_SND_SEQ_H
diff --git a/arm7/lib/include/SND_wave.h b/arm7/lib/include/SND_wave.h
index e1ae93fe..fd76b1a5 100644
--- a/arm7/lib/include/SND_wave.h
+++ b/arm7/lib/include/SND_wave.h
@@ -1,6 +1,6 @@
#ifndef GUARD_SND_WAVE_H
#define GUARD_SND_WAVE_H
-void SND_InvalidateWave(void *begin, void *end);
+void SND_InvalidateWave(const void *begin, const void *end);
#endif //GUARD_SND_WAVE_H
diff --git a/arm7/lib/include/SND_work.h b/arm7/lib/include/SND_work.h
index 49933fc7..0125a52d 100644
--- a/arm7/lib/include/SND_work.h
+++ b/arm7/lib/include/SND_work.h
@@ -6,8 +6,8 @@
extern struct SNDWork SNDi_Work;
extern struct SNDSharedWork *SNDi_SharedWork;
-void SND_SetPlayerLocalVariable(u32 player, u32 var, s16 value);
-void SND_SetPlayerGlobalVariable(u32 var, s16 value);
+void SND_SetPlayerLocalVariable(int player, int var, s16 value);
+void SND_SetPlayerGlobalVariable(int var, s16 value);
void SND_UpdateSharedWork(void);
#endif //GUARD_SND_WORK_H
diff --git a/arm7/lib/src/SND_command.c b/arm7/lib/src/SND_command.c
new file mode 100644
index 00000000..fc059c89
--- /dev/null
+++ b/arm7/lib/src/SND_command.c
@@ -0,0 +1,302 @@
+#include "SND_command.h"
+
+#include "registers.h"
+#include "mmap.h"
+
+#include "MI_memory.h"
+#include "PXI_fifo.h"
+#include "OS_message.h"
+#include "OS_system.h"
+#include "SND.h"
+#include "SND_alarm.h"
+#include "SND_capture.h"
+#include "SND_channel.h"
+#include "SND_exChannel.h"
+#include "SND_lockChannel.h"
+#include "SND_main.h"
+#include "SND_seq.h"
+#include "SND_work.h"
+
+#define SND_MSG_ARRAY_SIZE 8
+
+static OSMessage sMsgArray[SND_MSG_ARRAY_SIZE];
+static struct OSMessageQueue sMsgQueue;
+
+static void InitPXI(void);
+static void StartTimer(u32 channelMask, u32 captureMask, u32 alarmMask, s32 unused);
+static void StopTimer(u32 channelMask, u32 captureMask, u32 alarmMask, s32 hold);
+static void SetChannelTimer(u32 channelMask, int timer);
+static void SetChannelVolume(u32 channelMask, int vol, int shift);
+static void SetChannelPan(u32 channelMask, int pan);
+static void ReadDriverInfo(struct SNDDriverInfo *driverInfo);
+
+void SND_CommandInit(void) {
+ OS_InitMessageQueue(&sMsgQueue, sMsgArray, SND_MSG_ARRAY_SIZE);
+ InitPXI();
+ SNDi_SharedWork = NULL;
+}
+
+void SND_CommandProc(void) {
+ struct SNDCommand cmd;
+ struct SNDCommand *cmd_ptr;
+ OSMessage msg;
+
+ while (OS_ReceiveMessage(&sMsgQueue, &msg, 0)) {
+ // casting it directly below doesn't appear to match
+ cmd_ptr = (struct SNDCommand *)msg;
+
+ while (cmd_ptr) {
+ cmd = *cmd_ptr;
+
+ switch (cmd.id) {
+ case SND_CMD_START_SEQ:
+ SND_StartSeq((int)cmd.arg[0], (const void *)cmd.arg[1], cmd.arg[2], (struct SNDBankData *)cmd.arg[3]);
+ break;
+ case SND_CMD_STOP_SEQ:
+ SND_StopSeq((int)cmd.arg[0]);
+ break;
+ case SND_CMD_PREPARE_SEQ:
+ SND_PrepareSeq((int)cmd.arg[0], (const void *)cmd.arg[1], cmd.arg[2], (struct SNDBankData *)cmd.arg[3]);
+ break;
+ case SND_CMD_START_PREPARED_SEQ:
+ SND_StartPreparedSeq((int)cmd.arg[0]);
+ break;
+ case SND_CMD_PAUSE_SEQ:
+ SND_PauseSeq((int)cmd.arg[0], (BOOL)cmd.arg[1]);
+ break;
+ case SND_CMD_SKIP_SEQ:
+ SND_SkipSeq((int)cmd.arg[0], cmd.arg[1]);
+ break;
+ case SND_CMD_PLAYER_PARAM:
+ SNDi_SetPlayerParam((int)cmd.arg[0], cmd.arg[1], cmd.arg[2], (int)cmd.arg[3]);
+ break;
+ case SND_CMD_TRACK_PARAM:
+ SNDi_SetTrackParam((int)cmd.arg[0] & 0xFFFFFF, cmd.arg[1], cmd.arg[2], cmd.arg[3], (u8)(cmd.arg[0] >> 24));
+ break;
+ case SND_CMD_MUTE_TRACK:
+ SND_SetTrackMute((int)cmd.arg[0], cmd.arg[1], (BOOL)cmd.arg[2]);
+ break;
+ case SND_CMD_ALLOCATABLE_CHANNEL:
+ SND_SetTrackAllocatableChannel((int)cmd.arg[0], cmd.arg[1], cmd.arg[2]);
+ break;
+ case SND_CMD_PLAYER_LOCAL_VAR:
+ SND_SetPlayerLocalVariable((int)cmd.arg[0], (int)cmd.arg[1], (s16)cmd.arg[2]);
+ break;
+ case SND_CMD_PLAYER_GLOBAL_VAR:
+ SND_SetPlayerGlobalVariable((int)cmd.arg[0], (s16)cmd.arg[1]);
+ break;
+ case SND_CMD_START_TIMER:
+ StartTimer(cmd.arg[0], cmd.arg[1], cmd.arg[2], (int)cmd.arg[3]);
+ break;
+ case SND_CMD_STOP_TIMER:
+ StopTimer(cmd.arg[0], cmd.arg[1], cmd.arg[2], (int)cmd.arg[3]);
+ break;
+ case SND_CMD_SETUP_CAPTURE:
+ SND_SetupCapture(
+ (int)(cmd.arg[2] >> 31u) & 1,
+ (int)(cmd.arg[2] >> 30u) & 1,
+ (void *)cmd.arg[0],
+ (int)cmd.arg[1],
+ (BOOL)(cmd.arg[2] >> 29u) & 1,
+ (int)(cmd.arg[2] >> 28u) & 1,
+ (int)(cmd.arg[2] >> 27u) & 1
+ );
+ break;
+ case SND_CMD_SETUP_ALARM:
+ SND_SetupAlarm(
+ (int)cmd.arg[0],
+ cmd.arg[1],
+ cmd.arg[2],
+ cmd.arg[3]
+ );
+ break;
+ case SND_CMD_CHANNEL_TIMER:
+ SetChannelTimer(cmd.arg[0], (int)cmd.arg[1]);
+ break;
+ case SND_CMD_CHANNEL_VOLUME:
+ SetChannelVolume(cmd.arg[0], (int)cmd.arg[1], (int)cmd.arg[2]);
+ break;
+ case SND_CMD_CHANNEL_PAN:
+ SetChannelPan(cmd.arg[0], (int)cmd.arg[1]);
+ break;
+ case SND_CMD_SETUP_CHANNEL_PCM:
+ SND_SetupChannelPcm(
+ (int)cmd.arg[0] & 0xFFFF,
+ (void *)(cmd.arg[1] & 0x7FFFFFFu),
+ (int)(cmd.arg[3] >> 24u) & 0x3,
+ (int)(cmd.arg[3] >> 26u) & 0x3,
+ (int)cmd.arg[3] & 0xFFFF,
+ (int)cmd.arg[2] & 0x3FFFFF,
+ (int)(cmd.arg[2] >> 24u) & 0x7F,
+ (int)(cmd.arg[2] >> 22u) & 0x3,
+ (int)(cmd.arg[0] >> 16u) & 0xFFFF,
+ (int)(cmd.arg[3] >> 16u) & 0x7F
+ );
+ break;
+ case SND_CMD_SETUP_CHANNEL_PSG:
+ SND_SetupChannelPsg(
+ (int)cmd.arg[0],
+ (int)cmd.arg[3],
+ (int)cmd.arg[1] & 0x7F,
+ (int)(cmd.arg[1] >> 8u) & 0x3,
+ (int)(cmd.arg[2] >> 8u) & 0xFFFF,
+ (int)cmd.arg[2] & 0x7F
+ );
+ break;
+ case SND_CMD_SETUP_CHANNEL_NOISE:
+ SND_SetupChannelNoise(
+ (int)cmd.arg[0],
+ (int)cmd.arg[1] & 0x7F,
+ (int)(cmd.arg[1] >> 8u) & 0x3,
+ (int)(cmd.arg[2] >> 8u) & 0xFFFF,
+ (int)cmd.arg[2] & 0x7F
+ );
+ break;
+ case SND_CMD_SURROUND_DECAY:
+ SNDi_SetSurroundDecay((int)cmd.arg[0]);
+ break;
+ case SND_CMD_MASTER_VOLUME:
+ SND_SetMasterVolume((int)cmd.arg[0]);
+ break;
+ case SND_CMD_MASTER_PAN:
+ SND_SetMasterPan((int)cmd.arg[0]);
+ break;
+ case SND_CMD_OUTPUT_SELECTOR:
+ SND_SetOutputSelector((int)cmd.arg[0], (int)cmd.arg[1], (int)cmd.arg[2], (int)cmd.arg[3]);
+ break;
+ case SND_CMD_LOCK_CHANNEL:
+ SND_LockChannel(cmd.arg[0], cmd.arg[1]);
+ break;
+ case SND_CMD_UNLOCK_CHANNEL:
+ SND_UnlockChannel(cmd.arg[0], cmd.arg[1]);
+ break;
+ case SND_CMD_STOP_UNLOCKED_CHANNEL:
+ SND_StopUnlockedChannel(cmd.arg[0], cmd.arg[1]);
+ break;
+ case SND_CMD_INVALIDATE_SEQ:
+ SND_InvalidateSeq((void *)cmd.arg[0], (void *)cmd.arg[1]);
+ break;
+ case SND_CMD_INVALIDATE_BANK:
+ SND_InvalidateBank((void *)cmd.arg[0], (void *)cmd.arg[1]);
+ break;
+ case SND_CMD_INVALIDATE_WAVE:
+ SND_InvalidateWave((void *)cmd.arg[0], (void *)cmd.arg[1]);
+ break;
+ case SND_CMD_SET_SHARED_WORK:
+ SNDi_SharedWork = (struct SNDSharedWork *)cmd.arg[0];
+ break;
+ case SND_CMD_READ_DRIVER_INFO:
+ ReadDriverInfo((struct SNDDriverInfo *)cmd.arg[0]);
+ break;
+ } // end switch
+
+ cmd_ptr = cmd.llNext;
+ } // end loop over command linked list
+
+ SNDi_SharedWork->finishedCommandTag++;
+ } // end loop over receive message
+}
+
+static void PxiFifoCallback(PXIFifoTag tag, u32 data, BOOL error) {
+ (void)tag;
+ (void)error;
+
+ OSIntrMode intrMode = OS_DisableInterrupts();
+
+ if (data >= HW_MAIN_MEM) {
+ (void)OS_SendMessage(&sMsgQueue, (OSMessage)data, 0);
+ } else {
+ if (data == 0)
+ SND_SendWakeupMessage();
+ }
+
+ (void)OS_RestoreInterrupts(intrMode);
+}
+
+static void InitPXI(void) {
+ PXI_SetFifoRecvCallback(PXI_FIFO_TAG_SOUND, PxiFifoCallback);
+}
+
+static void SetChannelTimer(u32 channelMask, int timer) {
+ for (int i = 0; i < SND_CHANNEL_COUNT && channelMask != 0; i++, channelMask >>= 1) {
+ if (channelMask & 1)
+ SND_SetChannelTimer(i, timer);
+ }
+}
+
+static void SetChannelVolume(u32 channelMask, int vol, int shift) {
+ for (int i = 0; i < SND_CHANNEL_COUNT && channelMask != 0; i++, channelMask >>= 1) {
+ if (channelMask & 1)
+ SND_SetChannelVolume(i, vol, shift);
+ }
+}
+
+static void SetChannelPan(u32 channelMask, int pan) {
+ for (int i = 0; i < SND_CHANNEL_COUNT && channelMask != 0; i++, channelMask >>= 1) {
+ if (channelMask & 1)
+ SND_SetChannelPan(i, pan);
+ }
+}
+
+static void StartTimer(u32 channelMask, u32 captureMask, u32 alarmMask, s32 unused) {
+ (void)unused;
+
+ OSIntrMode intrMode = OS_DisableInterrupts();
+
+ for (int i = 0; i < SND_CHANNEL_COUNT && channelMask != 0; i++, channelMask >>= 1) {
+ if (channelMask & 1)
+ reg_SOUNDxCNT_STAT(i) |= 0x80;
+ }
+
+ if (captureMask & 1) {
+ if (captureMask & 2) {
+ *(vu16 *)&reg_SNDCAPxCNT(0) |= 0x8080;
+ } else {
+ reg_SNDCAPxCNT(0) |= 0x80;
+ }
+ } else if (captureMask & 2) {
+ reg_SNDCAPxCNT(1) |= 0x80;
+ }
+
+ for (int i = 0; i < SND_ALARM_COUNT && alarmMask != 0; i++, alarmMask >>= 1) {
+ if (alarmMask & 1)
+ SND_StartAlarm(i);
+ }
+
+ (void)OS_RestoreInterrupts(intrMode);
+ SND_UpdateSharedWork();
+}
+
+static void StopTimer(u32 channelMask, u32 captureMask, u32 alarmMask, s32 hold) {
+ OSIntrMode intrMode = OS_DisableInterrupts();
+
+ for (int i = 0; i < SND_ALARM_COUNT && alarmMask != 0; i++, alarmMask >>= 1) {
+ if (alarmMask & 1)
+ SND_StopAlarm(i);
+ }
+
+ for (int i = 0; i < SND_CHANNEL_COUNT && channelMask != 0; i++, channelMask >>= 1) {
+ if (channelMask & 1)
+ SND_StopChannel(i, hold);
+ }
+
+ if (captureMask & 1)
+ reg_SNDCAPxCNT(0) = 0;
+ if (captureMask & 2)
+ reg_SNDCAPxCNT(1) = 0;
+
+ (void)OS_RestoreInterrupts(intrMode);
+ SND_UpdateSharedWork();
+}
+
+static void ReadDriverInfo(struct SNDDriverInfo *driverInfo) {
+ MI_CpuCopy32(&SNDi_Work, driverInfo, sizeof(SNDi_Work));
+
+ driverInfo->workPtr = &SNDi_Work;
+
+ for (int i = 0; i < SND_CHANNEL_COUNT; i++) {
+ driverInfo->channelControls[i] = SND_GetChannelControl(i);
+ }
+
+ driverInfo->lockedChannels = SND_GetLockedChannel(0);
+}
diff --git a/arm7/lib/src/SND_lockChannel.c b/arm7/lib/src/SND_lockChannel.c
index 608ed67a..871cf716 100644
--- a/arm7/lib/src/SND_lockChannel.c
+++ b/arm7/lib/src/SND_lockChannel.c
@@ -2,7 +2,7 @@
#include "SND_work.h"
#include "SND_exChannel.h"
-#include "SND.h"
+#include "SND_channel.h"
// TODO make these vars static after merging this file with exChannel
u32 sLockedChannelMask;
diff --git a/arm7/lib/src/SND_wave.c b/arm7/lib/src/SND_wave.c
index 75d84e5f..21c48dc8 100644
--- a/arm7/lib/src/SND_wave.c
+++ b/arm7/lib/src/SND_wave.c
@@ -1,9 +1,9 @@
#include "SND_wave.h"
-#include "SND.h"
+#include "SND_channel.h"
#include "SND_work.h"
-void SND_InvalidateWave(void *start, void *end) {
+void SND_InvalidateWave(const void *start, const void *end) {
for (u8 i = 0; i < SND_CHANNEL_COUNT; i++) {
struct SNDExChannel *chn = &SNDi_Work.channels[i];
diff --git a/arm7/lib/src/SND_work.c b/arm7/lib/src/SND_work.c
index 4b23056d..3f0d10f0 100644
--- a/arm7/lib/src/SND_work.c
+++ b/arm7/lib/src/SND_work.c
@@ -6,11 +6,11 @@
struct SNDWork SNDi_Work;
struct SNDSharedWork *SNDi_SharedWork;
-void SND_SetPlayerLocalVariable(u32 player, u32 var, s16 value) {
+void SND_SetPlayerLocalVariable(int player, int var, s16 value) {
SNDi_SharedWork->players[player].localVars[var] = value;
}
-void SND_SetPlayerGlobalVariable(u32 var, s16 value) {
+void SND_SetPlayerGlobalVariable(int var, s16 value) {
SNDi_SharedWork->globalVars[var] = value;
}