move snd_bank to c

This commit is contained in:
Seth Barberee
2026-06-24 20:39:00 -07:00
parent dbe51b3466
commit a651a286b5
11 changed files with 994 additions and 461 deletions

View File

@@ -0,0 +1,133 @@
.include "asm/macros.inc"
.include "include/fx_vec.inc"
.text
arm_func_start FX_Atan2Idx
FX_Atan2Idx: ; 0x02075EC8
stmdb sp!, {r4, lr}
cmp r0, #0
ble _02075F5C
cmp r1, #0
ble _02075F14
cmp r1, r0
ble _02075EF4
mov r2, r0
mov r4, #0
mov r0, #1
b _0207600C
_02075EF4:
bge _02075F0C
mov r2, r1
mov r1, r0
mov r4, #0x4000
mov r0, #0
b _0207600C
_02075F0C:
mov r0, #0x2000
ldmia sp!, {r4, pc}
_02075F14:
bge _02075F54
rsb r1, r1, #0
cmp r1, r0
bge _02075F38
mov r2, r1
mov r1, r0
mov r4, #0x4000
mov r0, #1
b _0207600C
_02075F38:
ble _02075F4C
mov r2, r0
mov r4, #0x8000
mov r0, #0
b _0207600C
_02075F4C:
mov r0, #0x6000
ldmia sp!, {r4, pc}
_02075F54:
mov r0, #0x4000
ldmia sp!, {r4, pc}
_02075F5C:
bge _02075FFC
cmp r1, #0
rsb r0, r0, #0
bge _02075FB0
rsb r1, r1, #0
cmp r1, r0
ble _02075F8C
mov r4, #0x8000
mov r2, r0
rsb r4, r4, #0
mov r0, #1
b _0207600C
_02075F8C:
bge _02075FA8
mov r4, #0x4000
mov r2, r1
mov r1, r0
rsb r4, r4, #0
mov r0, #0
b _0207600C
_02075FA8:
mov r0, #0xa000
ldmia sp!, {r4, pc}
_02075FB0:
cmp r1, #0
ble _02075FF4
cmp r1, r0
bge _02075FD8
mov r4, #0x4000
mov r2, r1
mov r1, r0
rsb r4, r4, #0
mov r0, #1
b _0207600C
_02075FD8:
ble _02075FEC
mov r4, #0
mov r2, r0
mov r0, r4
b _0207600C
_02075FEC:
mov r0, #0xe000
ldmia sp!, {r4, pc}
_02075FF4:
mov r0, #0xc000
ldmia sp!, {r4, pc}
_02075FFC:
cmp r1, #0
movge r0, #0
movlt r0, #0x8000
ldmia sp!, {r4, pc}
_0207600C:
cmp r1, #0
moveq r0, #0
ldmeqia sp!, {r4, pc}
cmp r0, #0
mov r0, r2
beq _02076048
bl FX_Div
mov r1, r0, asr #5
ldr r0, _0207606C ; =FX_AtanIdxTable_
mov r1, r1, lsl #1
ldrsh r0, [r0, r1]
add r0, r4, r0
mov r0, r0, lsl #0x10
mov r0, r0, lsr #0x10
ldmia sp!, {r4, pc}
_02076048:
bl FX_Div
mov r1, r0, asr #5
ldr r0, _0207606C ; =FX_AtanIdxTable_
mov r1, r1, lsl #1
ldrsh r0, [r0, r1]
sub r0, r4, r0
mov r0, r0, lsl #0x10
mov r0, r0, lsr #0x10
ldmia sp!, {r4, pc}
.align 2, 0
_0207606C: .word FX_AtanIdxTable_
arm_func_end FX_Atan2Idx

9
lib/NitroSDK/asm/fx_fx.s Normal file
View File

@@ -0,0 +1,9 @@
.include "asm/macros.inc"
.text
arm_func_start FX_Init
FX_Init: ; 0x02076070
bx lr
arm_func_end FX_Init

View File

@@ -173,134 +173,3 @@ _02075EC0: .word 0x040002B0
_02075EC4: .word 0x040002B4
arm_func_end VEC_Distance
arm_func_start FX_Atan2Idx
FX_Atan2Idx: ; 0x02075EC8
stmdb sp!, {r4, lr}
cmp r0, #0
ble _02075F5C
cmp r1, #0
ble _02075F14
cmp r1, r0
ble _02075EF4
mov r2, r0
mov r4, #0
mov r0, #1
b _0207600C
_02075EF4:
bge _02075F0C
mov r2, r1
mov r1, r0
mov r4, #0x4000
mov r0, #0
b _0207600C
_02075F0C:
mov r0, #0x2000
ldmia sp!, {r4, pc}
_02075F14:
bge _02075F54
rsb r1, r1, #0
cmp r1, r0
bge _02075F38
mov r2, r1
mov r1, r0
mov r4, #0x4000
mov r0, #1
b _0207600C
_02075F38:
ble _02075F4C
mov r2, r0
mov r4, #0x8000
mov r0, #0
b _0207600C
_02075F4C:
mov r0, #0x6000
ldmia sp!, {r4, pc}
_02075F54:
mov r0, #0x4000
ldmia sp!, {r4, pc}
_02075F5C:
bge _02075FFC
cmp r1, #0
rsb r0, r0, #0
bge _02075FB0
rsb r1, r1, #0
cmp r1, r0
ble _02075F8C
mov r4, #0x8000
mov r2, r0
rsb r4, r4, #0
mov r0, #1
b _0207600C
_02075F8C:
bge _02075FA8
mov r4, #0x4000
mov r2, r1
mov r1, r0
rsb r4, r4, #0
mov r0, #0
b _0207600C
_02075FA8:
mov r0, #0xa000
ldmia sp!, {r4, pc}
_02075FB0:
cmp r1, #0
ble _02075FF4
cmp r1, r0
bge _02075FD8
mov r4, #0x4000
mov r2, r1
mov r1, r0
rsb r4, r4, #0
mov r0, #1
b _0207600C
_02075FD8:
ble _02075FEC
mov r4, #0
mov r2, r0
mov r0, r4
b _0207600C
_02075FEC:
mov r0, #0xe000
ldmia sp!, {r4, pc}
_02075FF4:
mov r0, #0xc000
ldmia sp!, {r4, pc}
_02075FFC:
cmp r1, #0
movge r0, #0
movlt r0, #0x8000
ldmia sp!, {r4, pc}
_0207600C:
cmp r1, #0
moveq r0, #0
ldmeqia sp!, {r4, pc}
cmp r0, #0
mov r0, r2
beq _02076048
bl FX_Div
mov r1, r0, asr #5
ldr r0, _0207606C ; =FX_AtanIdxTable_
mov r1, r1, lsl #1
ldrsh r0, [r0, r1]
add r0, r4, r0
mov r0, r0, lsl #0x10
mov r0, r0, lsr #0x10
ldmia sp!, {r4, pc}
_02076048:
bl FX_Div
mov r1, r0, asr #5
ldr r0, _0207606C ; =FX_AtanIdxTable_
mov r1, r1, lsl #1
ldrsh r0, [r0, r1]
sub r0, r4, r0
mov r0, r0, lsl #0x10
mov r0, r0, lsr #0x10
ldmia sp!, {r4, pc}
.align 2, 0
_0207606C: .word FX_AtanIdxTable_
arm_func_end FX_Atan2Idx
arm_func_start FX_Init
FX_Init: ; 0x02076070
bx lr
arm_func_end FX_Init

View File

@@ -1,316 +0,0 @@
.include "asm/macros.inc"
.include "include/nitro.inc"
.text
arm_func_start Snd_AssignWaveArc
Snd_AssignWaveArc: ; 0x0207D5B0
stmdb sp!, {r4, r5, r6, lr}
mov r6, r0
mov r5, r1
mov r4, r2
bl Sndi_LockMutex
add r3, r6, r5, lsl #3
ldr r2, [r3, #0x18]
cmp r2, #0
beq _0207D640
cmp r4, r2
bne _0207D5E4
bl Sndi_UnlockMutex
ldmia sp!, {r4, r5, r6, pc}
_0207D5E4:
add r1, r6, #0x18
ldr r0, [r2, #0x18]
add ip, r1, r5, lsl #3
cmp ip, r0
bne _0207D610
ldr r0, [r3, #0x1c]
mov r1, #0x3c
str r0, [r2, #0x18]
ldr r0, [r3, #0x18]
bl DC_StoreRange
b _0207D640
_0207D610:
cmp r0, #0
beq _0207D62C
_0207D618:
ldr r1, [r0, #4]
cmp ip, r1
movne r0, r1
cmpne r1, #0
bne _0207D618
_0207D62C:
add r1, r6, r5, lsl #3
ldr r2, [r1, #0x1c]
mov r1, #8
str r2, [r0, #4]
bl DC_StoreRange
_0207D640:
add r0, r6, #0x18
ldr r1, [r4, #0x18]
add r0, r0, r5, lsl #3
str r0, [r4, #0x18]
add r0, r6, r5, lsl #3
str r1, [r0, #0x1c]
str r4, [r0, #0x18]
bl Sndi_UnlockMutex
mov r0, r6
mov r1, #0x3c
bl DC_StoreRange
mov r0, r4
mov r1, #0x3c
bl DC_StoreRange
ldmia sp!, {r4, r5, r6, pc}
arm_func_end Snd_AssignWaveArc
arm_func_start Snd_DestroyBank
Snd_DestroyBank: ; 0x0207D67C
stmdb sp!, {r4, r5, r6, r7, r8, lr}
mov r7, r0
bl Sndi_LockMutex
add r5, r7, #0x18
mov r6, #0
mov r8, #8
mov r4, #0x3c
_0207D698:
add r1, r7, r6, lsl #3
ldr r0, [r1, #0x18]
cmp r0, #0
beq _0207D6FC
ldr r3, [r0, #0x18]
cmp r5, r3
bne _0207D6C8
ldr r2, [r1, #0x1c]
mov r1, r4
str r2, [r0, #0x18]
bl DC_StoreRange
b _0207D6FC
_0207D6C8:
cmp r3, #0
beq _0207D6E4
_0207D6D0:
ldr r0, [r3, #4]
cmp r5, r0
movne r3, r0
cmpne r0, #0
bne _0207D6D0
_0207D6E4:
add r0, r7, r6, lsl #3
ldr r2, [r0, #0x1c]
mov r0, r3
mov r1, r8
str r2, [r3, #4]
bl DC_StoreRange
_0207D6FC:
add r6, r6, #1
cmp r6, #4
add r5, r5, #8
blt _0207D698
bl Sndi_UnlockMutex
ldmia sp!, {r4, r5, r6, r7, r8, pc}
arm_func_end Snd_DestroyBank
arm_func_start Snd_DestroyWaveArc
Snd_DestroyWaveArc: ; 0x0207D714
stmdb sp!, {r4, r5, r6, lr}
mov r4, r0
bl Sndi_LockMutex
ldr r0, [r4, #0x18]
cmp r0, #0
beq _0207D754
mov r5, #0
mov r4, #8
_0207D734:
ldr r6, [r0, #4]
mov r1, r4
str r5, [r0]
str r5, [r0, #4]
bl DC_StoreRange
mov r0, r6
cmp r6, #0
bne _0207D734
_0207D754:
bl Sndi_UnlockMutex
ldmia sp!, {r4, r5, r6, pc}
arm_func_end Snd_DestroyWaveArc
arm_func_start Snd_GetFirstInstDataPos
Snd_GetFirstInstDataPos: ; 0x0207D75C
sub sp, sp, #8
mov r1, #0
str r1, [r0]
str r1, [sp]
str r1, [sp, #4]
str r1, [r0, #4]
add sp, sp, #8
bx lr
arm_func_end Snd_GetFirstInstDataPos
arm_func_start Snd_GetNextInstData
Snd_GetNextInstData: ; 0x0207D77C
stmdb sp!, {r3, r4, r5, lr}
ldr r4, [r2]
ldr r3, [r0, #0x38]
cmp r4, r3
bhs _0207D924
mov ip, #0
_0207D794:
add r3, r0, r4, lsl #2
ldr r4, [r3, #0x3c]
and r3, r4, #0xff
strb r4, [r1]
cmp r3, #0x10
mov r4, r4, lsr #8
bgt _0207D7DC
cmp r3, #0x10
bge _0207D828
cmp r3, #5
addls pc, pc, r3, lsl #2
b _0207D908
_0207D7C4: ; jump table
b _0207D908 ; case 0
b _0207D7E8 ; case 1
b _0207D7E8 ; case 2
b _0207D7E8 ; case 3
b _0207D7E8 ; case 4
b _0207D7E8 ; case 5
_0207D7DC:
cmp r3, #0x11
beq _0207D89C
b _0207D908
_0207D7E8:
add r5, r0, r4
ldrh r4, [r0, r4]
ldrh r3, [r5, #2]
mov r0, #1
strh r4, [r1, #2]
strh r3, [r1, #4]
ldrh r4, [r5, #4]
ldrh r3, [r5, #6]
strh r4, [r1, #6]
strh r3, [r1, #8]
ldrh r3, [r5, #8]
strh r3, [r1, #0xa]
ldr r1, [r2]
add r1, r1, #1
str r1, [r2]
ldmia sp!, {r3, r4, r5, pc}
_0207D828:
add r5, r0, r4
b _0207D87C
_0207D830:
mov r0, #0xc
mla ip, lr, r0, r5
ldrh r4, [ip, #2]
ldrh r3, [ip, #4]
mov r0, #1
strh r4, [r1]
strh r3, [r1, #2]
ldrh r4, [ip, #6]
ldrh r3, [ip, #8]
strh r4, [r1, #4]
strh r3, [r1, #6]
ldrh r4, [ip, #0xa]
ldrh r3, [ip, #0xc]
strh r4, [r1, #8]
strh r3, [r1, #0xa]
ldr r1, [r2, #4]
add r1, r1, #1
str r1, [r2, #4]
ldmia sp!, {r3, r4, r5, pc}
_0207D87C:
ldrb r4, [r5, #1]
ldrb r3, [r5]
ldr lr, [r2, #4]
sub r3, r4, r3
add r3, r3, #1
cmp lr, r3
blo _0207D830
b _0207D908
_0207D89C:
add r4, r0, r4
b _0207D8FC
_0207D8A4:
ldrb lr, [r4, r3]
cmp lr, #0
beq _0207D908
mov r0, #0xc
mla lr, r3, r0, r4
ldrh ip, [lr, #8]
ldrh r3, [lr, #0xa]
mov r0, #1
strh ip, [r1]
strh r3, [r1, #2]
ldrh ip, [lr, #0xc]
ldrh r3, [lr, #0xe]
strh ip, [r1, #4]
strh r3, [r1, #6]
ldrh ip, [lr, #0x10]
ldrh r3, [lr, #0x12]
strh ip, [r1, #8]
strh r3, [r1, #0xa]
ldr r1, [r2, #4]
add r1, r1, #1
str r1, [r2, #4]
ldmia sp!, {r3, r4, r5, pc}
_0207D8FC:
ldr r3, [r2, #4]
cmp r3, #8
blo _0207D8A4
_0207D908:
ldr r3, [r2]
add r3, r3, #1
stmia r2, {r3, ip}
ldr r4, [r2]
ldr r3, [r0, #0x38]
cmp r4, r3
blo _0207D794
_0207D924:
mov r0, #0
ldmia sp!, {r3, r4, r5, pc}
arm_func_end Snd_GetNextInstData
arm_func_start Snd_GetWaveDataCount
Snd_GetWaveDataCount: ; 0x0207D92C
ldr r0, [r0, #0x38]
bx lr
arm_func_end Snd_GetWaveDataCount
arm_func_start Snd_SetWaveDataAddress
Snd_SetWaveDataAddress: ; 0x0207D934
stmdb sp!, {r4, r5, r6, lr}
mov r6, r0
mov r5, r1
mov r4, r2
bl Sndi_LockMutex
add r0, r6, #0x3c
add r2, r6, r5, lsl #2
add r0, r0, r5, lsl #2
mov r1, #4
str r4, [r2, #0x3c]
bl DC_StoreRange
bl Sndi_UnlockMutex
ldmia sp!, {r4, r5, r6, pc}
arm_func_end Snd_SetWaveDataAddress
arm_func_start Snd_GetWaveDataAddress
Snd_GetWaveDataAddress: ; 0x0207D968
stmdb sp!, {r3, r4, r5, lr}
mov r5, r0
mov r4, r1
bl Sndi_LockMutex
add r0, r5, r4, lsl #2
ldr r4, [r0, #0x3c]
cmp r4, #0
beq _0207D994
cmp r4, #0x2000000
addlo r4, r5, r4
b _0207D998
_0207D994:
mov r4, #0
_0207D998:
bl Sndi_UnlockMutex
mov r0, r4
ldmia sp!, {r3, r4, r5, pc}
arm_func_end Snd_GetWaveDataAddress

View File

@@ -0,0 +1,502 @@
#include <nitro.h>
static u8 MI_ReadByte (const void * address)
{
return *(u8 *)address;
}
#ifdef _MSC_VER
#pragma warning(disable : 4018)
#pragma warning(disable : 4311)
#pragma warning(disable : 4312)
#endif
static const SNDWaveData * GetWaveData(const SNDBankData * bank, int waveArcNo, int waveIndex);
void Snd_AssignWaveArc (SNDBankData * bank, int index, SNDWaveArc * waveArc)
{
SNDWaveArcLink * next;
SNDWaveArcLink * prev;
SDK_NULL_ASSERT(bank);
SDK_NULL_ASSERT(waveArc);
#ifdef SDK_ARM9
SDK_ASSERTMSG(((u32)bank & 0x1f) == 0, "bank address must be aligned 32 bytes boundary.");
SDK_ASSERTMSG(((u32)waveArc & 0x1f) == 0, "waveArc address must be aligned 32 bytes boundary.");
#endif
SDK_MINMAX_ASSERT(index, 0, SND_BANK_TO_WAVEARC_MAX - 1);
Sndi_LockMutex();
if (bank->waveArcLink[index].waveArc != NULL) {
if (waveArc == bank->waveArcLink[index].waveArc) {
Sndi_UnlockMutex();
return;
}
if (&bank->waveArcLink[index] == bank->waveArcLink[index].waveArc->topLink) {
bank->waveArcLink[index].waveArc->topLink = bank->waveArcLink[index].next;
#ifdef SDK_ARM9
DC_StoreRange(bank->waveArcLink[index].waveArc, sizeof(SNDWaveArc));
#endif
} else {
prev = bank->waveArcLink[index].waveArc->topLink;
while (prev != NULL) {
if (&bank->waveArcLink[index] == prev->next)
break;
prev = prev->next;
}
SDK_NULL_ASSERT(prev);
prev->next = bank->waveArcLink[index].next;
#ifdef SDK_ARM9
DC_StoreRange(prev, sizeof(SNDWaveArcLink));
#endif
}
}
next = waveArc->topLink;
waveArc->topLink = &bank->waveArcLink[index];
bank->waveArcLink[index].next = next;
bank->waveArcLink[index].waveArc = waveArc;
Sndi_UnlockMutex();
#ifdef SDK_ARM9
DC_StoreRange(bank, sizeof(SNDBankData));
DC_StoreRange(waveArc, sizeof(SNDWaveArc));
#endif
}
void Snd_DestroyBank (SNDBankData * bank)
{
SNDWaveArc * waveArc;
SNDWaveArcLink * prev;
int i;
SDK_NULL_ASSERT(bank);
#ifdef SDK_ARM9
SDK_ASSERTMSG(((u32)bank & 0x1f) == 0, "bank address must be aligned 32 bytes boundary.");
#endif
Sndi_LockMutex();
for (i = 0; i < SND_BANK_TO_WAVEARC_MAX; i++) {
waveArc = bank->waveArcLink[i].waveArc;
if (waveArc == NULL)
continue;
if (&bank->waveArcLink[i] == waveArc->topLink) {
waveArc->topLink = bank->waveArcLink[i].next;
#ifdef SDK_ARM9
DC_StoreRange(waveArc, sizeof(SNDWaveArc));
#endif
} else {
prev = waveArc->topLink;
while (prev != NULL) {
if (&bank->waveArcLink[i] == prev->next)
break;
prev = prev->next;
}
SDK_NULL_ASSERT(prev);
prev->next = bank->waveArcLink[i].next;
#ifdef SDK_ARM9
DC_StoreRange(prev, sizeof(SNDWaveArcLink));
#endif
}
}
Sndi_UnlockMutex();
}
void Snd_DestroyWaveArc (SNDWaveArc * waveArc)
{
SNDWaveArcLink * link;
SNDWaveArcLink * next;
SDK_NULL_ASSERT(waveArc);
#ifdef SDK_ARM9
SDK_ASSERTMSG(((u32)waveArc & 0x1f) == 0, "waveArc address must be aligned 32 bytes boundary.");
#endif
Sndi_LockMutex();
link = waveArc->topLink;
while (link != NULL) {
next = link->next;
link->waveArc = NULL;
link->next = NULL;
#ifdef SDK_ARM9
DC_StoreRange(link, sizeof(SNDWaveArcLink));
#endif
link = next;
}
Sndi_UnlockMutex();
}
// BOOL Snd_ReadInstData (const SNDBankData * bank, int prgNo, int key, SNDInstData * inst)
// {
// u32 instOffset;
//
// SDK_NULL_ASSERT(bank);
// SDK_NULL_ASSERT(inst);
//
// if (prgNo < 0)
// return FALSE;
//
// #ifdef SDK_FROM_TOOL
// if (bank->fileHeader.signature[0] == 'S' &&
// bank->fileHeader.signature[1] == 'B' &&
// bank->fileHeader.signature[2] == 'C' && bank->fileHeader.signature[3] == 'B') {
// const SNDBankDataCallback * bankcb = (const SNDBankDataCallback *)bank;
// return bankcb->readInstDataFunc(bankcb, prgNo, key, inst);
// }
// #endif
//
// Sndi_LockMutex();
//
// if (prgNo >= bank->instCount) {
// Sndi_UnlockMutex();
// return FALSE;
// }
//
// instOffset = bank->instOffset[prgNo];
// inst->type = (u8)(instOffset & 0xff);
// instOffset >>= 8;
//
// switch (inst->type) {
// case SND_INST_PCM:
// case SND_INST_PSG:
// case SND_INST_NOISE:
// case SND_INST_DIRECTPCM:
// case SND_INST_NULL:
// {
// const SNDInstParam * param = (const SNDInstParam *)((u8 *)bank + instOffset);
//
// inst->param = *param;
// break;
// }
// case SND_INST_DRUM_SET:
// {
// const SNDDrumSet * drumSet = (const SNDDrumSet *)((u8 *)bank + instOffset);
// u8 min = MI_ReadByte(&drumSet->min);
// u8 max = MI_ReadByte(&drumSet->max);
//
// if (key < min || key > max) {
// Sndi_UnlockMutex();
// return FALSE;
// }
//
// *inst = drumSet->instOffset[key - min];
// break;
// }
// case SND_INST_KEY_SPLIT:
// {
// int index = 0;
// const SNDKeySplit * keySplit = (const SNDKeySplit *)((u8 *)bank + instOffset);
//
// while (key > MI_ReadByte(&keySplit->key[index])) {
// index++;
// if (index >= SND_INST_KEYSPLIT_MAX) {
// Sndi_UnlockMutex();
// return FALSE;
// }
// }
//
// *inst = keySplit->instOffset[index];
// break;
// }
// case SND_INST_INVALID:
// default:
// Sndi_UnlockMutex();
// return FALSE;
// }
//
// Sndi_UnlockMutex();
// return TRUE;
// }
// BOOL Snd_WriteInstData (SNDBankData * bank, int prgNo, int key, const struct SNDInstData * inst)
// {
// u32 instOffset;
// u8 type;
//
// SDK_NULL_ASSERT(bank);
// SDK_NULL_ASSERT(inst);
//
// if (prgNo < 0)
// return FALSE;
//
// Sndi_LockMutex();
//
// if (prgNo >= bank->instCount) {
// Sndi_UnlockMutex();
// return FALSE;
// }
//
// instOffset = bank->instOffset[prgNo];
// type = (u8)(instOffset & 0xff);
// instOffset >>= 8;
//
// switch (type) {
// case SND_INST_PCM:
// case SND_INST_PSG:
// case SND_INST_NOISE:
// case SND_INST_DIRECTPCM:
// case SND_INST_NULL:
// {
// SNDInstParam * param = (SNDInstParam *)((u8 *)bank + instOffset);
//
// bank->instOffset[prgNo] = (instOffset << 8) | inst->type;
// *param = inst->param;
// break;
// }
// case SND_INST_DRUM_SET:
// {
// SNDDrumSet * drumSet = (SNDDrumSet *)((u8 *)bank + instOffset);
// u8 min = MI_ReadByte(&drumSet->min);
// u8 max = MI_ReadByte(&drumSet->max);
//
// if (key < min || key > max) {
// Sndi_UnlockMutex();
// return FALSE;
// }
//
// drumSet->instOffset[key - min] = *inst;
// break;
// }
// case SND_INST_KEY_SPLIT:
// {
// int index = 0;
// SNDKeySplit * keySplit = (SNDKeySplit *)((u8 *)bank + instOffset);
//
// while (key > MI_ReadByte(&keySplit->key[index])) {
// index++;
// if (index >= SND_INST_KEYSPLIT_MAX) {
// Sndi_UnlockMutex();
// return FALSE;
// }
// }
//
// keySplit->instOffset[index] = *inst;
// break;
// }
// case SND_INST_INVALID:
// default:
// Sndi_UnlockMutex();
// return FALSE;
// }
//
// Sndi_UnlockMutex();
//
// #ifdef SDK_ARM9
// DC_StoreRange(bank, bank->fileHeader.fileSize);
// #endif
//
// return TRUE;
// }
SNDInstPos Snd_GetFirstInstDataPos (const SNDBankData * bank)
{
SNDInstPos pos;
SDK_NULL_ASSERT(bank);
(void)bank;
pos.prgNo = 0;
pos.index = 0;
return pos;
}
BOOL Snd_GetNextInstData (const SNDBankData * bank, SNDInstData * inst, SNDInstPos * pos)
{
SDK_NULL_ASSERT(bank);
SDK_NULL_ASSERT(inst);
SDK_NULL_ASSERT(pos);
for (; pos->prgNo < bank->instCount; pos->prgNo++, pos->index = 0) {
u32 instOffset = bank->instOffset[pos->prgNo];
inst->type = (u8)(instOffset & 0xff);
instOffset >>= 8;
switch (inst->type) {
case SND_INST_PCM:
case SND_INST_PSG:
case SND_INST_NOISE:
case SND_INST_DIRECTPCM:
case SND_INST_NULL:
{
const SNDInstParam * param = (const SNDInstParam *)((u8 *)bank + instOffset);
inst->param = *param;
pos->prgNo++;
return TRUE;
}
case SND_INST_DRUM_SET:
{
const SNDDrumSet * drumSet = (const SNDDrumSet *)((u8 *)bank + instOffset);
for (; pos->index < drumSet->max - drumSet->min + 1; pos->index++) {
*inst = drumSet->instOffset[pos->index];
pos->index++;
return TRUE;
}
break;
}
case SND_INST_KEY_SPLIT:
{
const SNDKeySplit * keySplit = (const SNDKeySplit *)((u8 *)bank + instOffset);
for (; pos->index < SND_INST_KEYSPLIT_MAX; pos->index++) {
if (keySplit->key[pos->index] == 0)
break;
*inst = keySplit->instOffset[pos->index];
pos->index++;
return TRUE;
}
break;
}
default:
break;
}
}
return FALSE;
}
u32 Snd_GetWaveDataCount (const struct SNDWaveArc * waveArc)
{
SDK_NULL_ASSERT(waveArc);
return waveArc->waveCount;
}
void Snd_SetWaveDataAddress (SNDWaveArc * waveArc, int index, const SNDWaveData * address)
{
SDK_NULL_ASSERT(waveArc);
SDK_MINMAX_ASSERT(index, 0, waveArc->waveCount);
SDK_ASSERT(address == NULL || address >= (void *)HW_MAIN_MEM);
Sndi_LockMutex();
waveArc->waveOffset[index] = (u32)address;
#ifdef SDK_ARM9
DC_StoreRange(&waveArc->waveOffset[index], sizeof(u32));
#endif
Sndi_UnlockMutex();
}
const SNDWaveData * Snd_GetWaveDataAddress (const SNDWaveArc * waveArc, int index)
{
const SNDWaveData * wave;
u32 offset;
SDK_NULL_ASSERT(waveArc);
SDK_MINMAX_ASSERT(index, 0, waveArc->waveCount);
Sndi_LockMutex();
offset = waveArc->waveOffset[index];
if (offset != 0) {
if (offset < HW_MAIN_MEM)
wave = (const SNDWaveData *)((u8 *)waveArc + offset);
else
wave = (const SNDWaveData *)offset;
} else {
wave = NULL;
}
Sndi_UnlockMutex();
return wave;
}
#ifdef SDK_ARM7
BOOL Snd_NoteOn (SNDExChannel * ch_p, int key, int velocity, s32 length, const SNDBankData * bank, const SNDInstData * inst)
{
const SNDWaveData * wave_data;
int release;
BOOL result;
SDK_NULL_ASSERT(ch_p);
SDK_MINMAX_ASSERT(key, 0, 127);
SDK_MINMAX_ASSERT(velocity, 0, 127);
SDK_NULL_ASSERT(inst);
release = inst->param.release;
if (inst->param.release == SND_BANK_DISABLE_RELEASE) {
length = -1;
release = 0;
}
switch (inst->type) {
case SND_INST_PCM:
case SND_INST_DIRECTPCM:
if (inst->type == SND_INST_PCM) {
wave_data = GetWaveData(bank, inst->param.wave[1], inst->param.wave[0]);
} else {
wave_data = (const SNDWaveData *)(inst->param.wave[1] << 16 | inst->param.wave[0]);
}
if (wave_data != NULL) {
result = Snd_StartExChannelPcm(ch_p, &wave_data->param, wave_data->samples, length);
} else {
result = FALSE;
}
break;
case SND_INST_PSG:
result = Snd_StartExChannelPsg(ch_p, (SNDDuty)inst->param.wave[0], length);
break;
case SND_INST_NOISE:
result = Snd_StartExChannelNoise(ch_p, length);
break;
default:
result = FALSE;
break;
}
if (!result)
return FALSE;
ch_p->key = (u8)key;
ch_p->original_key = inst->param.original_key;
ch_p->velocity = (u8)velocity;
Snd_SetExChannelAttack(ch_p, inst->param.attack);
Snd_SetExChannelDecay(ch_p, inst->param.decay);
Snd_SetExChannelSustain(ch_p, inst->param.sustain);
Snd_SetExChannelRelease(ch_p, release);
ch_p->init_pan = (s8)(inst->param.pan - 64);
return TRUE;
}
#endif
#ifdef SDK_ARM7
static const SNDWaveData * GetWaveData (const SNDBankData * bank, int waveArcNo, int waveIndex)
{
const SNDWaveArc * arc;
SDK_MINMAX_ASSERT(waveArcNo, 0, SND_BANK_TO_WAVEARC_MAX - 1);
arc = bank->waveArcLink[waveArcNo].waveArc;
if (arc == NULL)
return NULL;
if (waveIndex >= arc->waveCount)
return NULL;
return Snd_GetWaveDataAddress(arc, waveIndex);
}
#endif

View File

@@ -3,5 +3,6 @@
#include <nitro/snd/common/main.h>
#include <nitro/snd/common/util.h>
#include <nitro/snd/common/bank.h>
#endif //NITRO_SND_H_

View File

@@ -0,0 +1,130 @@
#ifndef NITRO_SND_COMMON_BANK_H_
#define NITRO_SND_COMMON_BANK_H_
#include <nitro/snd/common/exchannel.h>
#include <nitro/snd/common/data.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SND_INST_KEYSPLIT_MAX 8
#define SND_BANK_TO_WAVEARC_MAX 4
#define SND_BANK_DISABLE_RELEASE 255
struct SNDWaveArc;
struct SNDExChannel;
typedef enum SNDInstType {
SND_INST_INVALID = 0,
SND_INST_PCM = 0x01,
SND_INST_PSG,
SND_INST_NOISE,
SND_INST_DIRECTPCM,
SND_INST_NULL,
SND_INST_DRUM_SET = 0x10,
SND_INST_KEY_SPLIT
} SNDInstType;
#ifdef _MSC_VER
#pragma warning( disable : 4200 )
#endif
typedef struct SNDWaveArcLink {
struct SNDWaveArc * waveArc;
struct SNDWaveArcLink * next;
} SNDWaveArcLink;
typedef struct SNDWaveArc {
struct SNDBinaryFileHeader fileHeader;
struct SNDBinaryBlockHeader blockHeader;
struct SNDWaveArcLink * topLink;
u32 reserved[7];
u32 waveCount;
u32 waveOffset[0];
} SNDWaveArc;
typedef struct SNDWaveData {
struct SNDWaveParam param;
u8 samples[0];
} SNDWaveData;
typedef struct SNDBankData {
struct SNDBinaryFileHeader fileHeader;
struct SNDBinaryBlockHeader blockHeader;
struct SNDWaveArcLink waveArcLink[SND_BANK_TO_WAVEARC_MAX];
u32 instCount;
u32 instOffset[0];
} SNDBankData;
typedef struct SNDInstParam {
u16 wave[2];
u8 original_key;
u8 attack;
u8 decay;
u8 sustain;
u8 release;
u8 pan;
} SNDInstParam;
typedef struct SNDInstData {
u8 type;
u8 padding_;
struct SNDInstParam param;
} SNDInstData;
typedef struct SNDKeySplit {
u8 key[SND_INST_KEYSPLIT_MAX];
struct SNDInstData instOffset[0];
} SNDKeySplit;
typedef struct SNDDrumSet {
u8 min;
u8 max;
struct SNDInstData instOffset[0];
} SNDDrumSet;
typedef struct SNDInstPos {
u32 prgNo;
u32 index;
} SNDInstPos;
#if defined(SDK_WIN32) || defined(SDK_FROM_TOOL)
struct SNDBankDataCallback;
typedef BOOL (__stdcall * SNDReadInstDataFunc)(const struct SNDBankDataCallback * bank, int prgNo, int key, struct SNDInstData * inst);
typedef struct SNDBankDataCallback {
struct SNDBinaryFileHeader fileHeader;
struct SNDBinaryBlockHeader blockHeader;
void * arg;
SNDReadInstDataFunc readInstDataFunc;
} SNDBankDataCallback;
#endif
#ifdef _MSC_VER
#pragma warning(default : 4200)
#endif
void Snd_AssignWaveArc(struct SNDBankData * bank, int index, struct SNDWaveArc * waveArc);
void Snd_DestroyBank(struct SNDBankData * bank);
void Snd_DestroyWaveArc(struct SNDWaveArc * waveArc);
BOOL Snd_ReadInstData(const struct SNDBankData * bank, int prgNo, int key, struct SNDInstData * inst);
BOOL Snd_WriteInstData(struct SNDBankData * bank, int prgNo, int key, const struct SNDInstData * inst);
struct SNDInstPos Snd_GetFirstInstDataPos(const struct SNDBankData * bank);
BOOL Snd_GetNextInstData(const struct SNDBankData * bank, struct SNDInstData * inst, struct SNDInstPos * pos);
u32 Snd_GetWaveDataCount(const struct SNDWaveArc * waveArc);
void Snd_SetWaveDataAddress(struct SNDWaveArc * waveArc, int index, const SNDWaveData * address);
const SNDWaveData * Snd_GetWaveDataAddress(const struct SNDWaveArc * waveArc, int index);
#ifdef SDK_ARM7
BOOL Snd_NoteOn(struct SNDExChannel * ch_p, int key, int velocity, s32 length, const struct SNDBankData * bank, const struct SNDInstData * inst);
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -144,7 +144,7 @@ typedef enum {
#ifdef SDK_ARM7
#if !(defined(SDK_WIN32) || defined(SDK_FROM_TOOL))
static inline void SND_StartChannel (int chNo)
static inline void Snd_StartChannel (int chNo)
{
SDK_MINMAX_ASSERT(chNo, SND_CHANNEL_MIN, SND_CHANNEL_MAX);
@@ -152,34 +152,34 @@ typedef enum {
|= REG_SND_SOUND0CNT_8_E_MASK;
}
#else
void SND_StartChannel(int chNo);
void Snd_StartChannel(int chNo);
#endif
#endif
#ifdef SDK_ARM7
void SND_SetupChannelPcm(int chNo,
void Snd_SetupChannelPcm(int chNo,
const void * dataaddr,
SNDWaveFormat format,
SNDChannelLoop loop,
int loopStart,
int loopLen, int volume, SNDChannelDataShift shift, int timer, int pan);
void SND_SetupChannelPsg(int chNo,
void Snd_SetupChannelPsg(int chNo,
SNDDuty duty,
int volume, SNDChannelDataShift shift, int timer, int pan);
void SND_SetupChannelNoise(int chNo, int volume, SNDChannelDataShift shift, int timer, int pan);
void SND_StopChannel(int chNo, s32 flags);
void SND_SetChannelVolume(int chNo, int volume, SNDChannelDataShift shift);
void SND_SetChannelTimer(int chNo, int timer);
void SND_SetChannelPan(int chNo, int pan);
BOOL SND_IsChannelActive(int chNo);
void SND_SetMasterPan(int pan);
u32 SND_GetChannelControl(int chNo);
void Snd_SetupChannelNoise(int chNo, int volume, SNDChannelDataShift shift, int timer, int pan);
void Snd_StopChannel(int chNo, s32 flags);
void Snd_SetChannelVolume(int chNo, int volume, SNDChannelDataShift shift);
void Snd_SetChannelTimer(int chNo, int timer);
void Snd_SetChannelPan(int chNo, int pan);
BOOL Snd_IsChannelActive(int chNo);
void Snd_SetMasterPan(int pan);
u32 Snd_GetChannelControl(int chNo);
#endif
#ifdef SDK_ARM7
void SNDi_SetSurroundDecay(int decay);
void Sndi_SetSurroundDecay(int decay);
#endif
#ifdef __cplusplus

View File

@@ -0,0 +1,28 @@
#ifndef NITRO_SND_COMMON_DATA_H_
#define NITRO_SND_COMMON_DATA_H_
#include <nitro/types.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct SNDBinaryFileHeader {
char signature[4];
u16 byteOrder;
u16 version;
u32 fileSize;
u16 headerSize;
u16 dataBlocks;
} SNDBinaryFileHeader;
typedef struct SNDBinaryBlockHeader {
u32 kind;
u32 size;
} SNDBinaryBlockHeader;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,175 @@
#ifndef NITRO_SND_COMMON_EX_CHANNEL_H_
#define NITRO_SND_COMMON_EX_CHANNEL_H_
#include <nitro/types.h>
#include <nitro/snd/common/channel.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SND_EX_CHANNEL_PRIO_HIGHEST 255
#define SND_EX_CHANNEL_PRIO_LOWEST 1
#define SND_EX_CHANNEL_RELEASE_PRIO 1
#define SND_EX_CHANNEL_STOP_PRIO 0
#define SND_EX_CHANNEL_USER_PAN_MIN -128
#define SND_EX_CHANNEL_USER_PAN_MAX 127
#define SND_EX_CHANNEL_ENV_DECAY_SHIFT 7
#define SND_EX_CHANNEL_UPDATE_START (0x01 << 0)
#define SND_EX_CHANNEL_UPDATE_STOP (0x01 << 1)
#define SND_EX_CHANNEL_UPDATE_TIMER (0x01 << 2)
#define SND_EX_CHANNEL_UPDATE_VOLUME (0x01 << 3)
#define SND_EX_CHANNEL_UPDATE_PAN (0x01 << 4)
#define SND_LOCK_IMPLIED_ALLOC_CHANNEL (1 << 0)
struct SNDExChannel;
typedef enum SNDExChannelType {
SND_EX_CHANNEL_PCM,
SND_EX_CHANNEL_PSG,
SND_EX_CHANNEL_NOISE
} SNDExChannelType;
typedef enum SNDExChannelCallbackStatus {
SND_EX_CHANNEL_CALLBACK_DROP,
SND_EX_CHANNEL_CALLBACK_FINISH
} SNDExChannelCallbackStatus;
typedef enum SNDEnvStatus {
SND_ENV_ATTACK,
SND_ENV_DECAY,
SND_ENV_SUSTAIN,
SND_ENV_RELEASE
} SNDEnvStatus;
typedef enum SNDLfoTarget {
SND_LFO_PITCH,
SND_LFO_VOLUME,
SND_LFO_PAN
} SNDLfoTarget;
typedef void (*SNDExChannelCallback) (struct SNDExChannel * ch_p, SNDExChannelCallbackStatus status, void * userData);
#if !(defined(SDK_WIN32) || defined(SDK_FROM_TOOL))
typedef struct SNDWaveParam {
u8 format;
u8 loopflag;
u16 rate;
u16 timer;
u16 loopstart;
u32 looplen;
} SNDWaveParam;
#else
typedef struct SNDWaveParam {
u8 format;
u8 loopflag;
u16 rate;
u16 timer;
u32 loopstart;
u32 looplen;
} SNDWaveParam;
#endif
typedef struct SNDLfoParam {
u8 target;
u8 speed;
u8 depth;
u8 range;
u16 delay;
} SNDLfoParam;
typedef struct SNDLfo {
struct SNDLfoParam param;
u16 delay_counter;
u16 counter;
} SNDLfo;
typedef struct SNDExChannel {
u8 myNo;
u8 type;
u8 env_status;
u8 active_flag : 1;
u8 start_flag : 1;
u8 auto_sweep : 1;
u8 sync_flag : 5;
u8 pan_range;
u8 original_key;
s16 user_decay2;
u8 key;
u8 velocity;
s8 init_pan;
s8 user_pan;
s16 user_decay;
s16 user_pitch;
s32 env_decay;
s32 sweep_counter;
s32 sweep_length;
u8 attack;
u8 sustain;
u16 decay;
u16 release;
u8 prio;
u8 pan;
u16 volume;
u16 timer;
struct SNDLfo lfo;
s16 sweep_pitch;
s32 length;
struct SNDWaveParam wave;
union {
const void * data;
SNDDuty duty;
};
SNDExChannelCallback callback;
void * callback_data;
struct SNDExChannel * nextLink;
} SNDExChannel;
#ifdef SDK_ARM7
void Snd_ExChannelInit(void);
void Snd_ExChannelMain(BOOL doPeriodicProc);
void Snd_UpdateExChannel(void);
struct SNDExChannel * Snd_AllocExChannel(u32 chBitMask,
int prio,
BOOL strongRequest,
SNDExChannelCallback callback, void * callbackData);
void Snd_FreeExChannel(struct SNDExChannel * ch_p);
BOOL Snd_StartExChannelPcm(SNDExChannel * ch_p, const struct SNDWaveParam * wave, const void * data, s32 length);
BOOL Snd_StartExChannelPsg(struct SNDExChannel * ch_p, SNDDuty duty, s32 length);
BOOL Snd_StartExChannelNoise(struct SNDExChannel * ch_p, s32 length);
void Snd_ReleaseExChannel(struct SNDExChannel * ch_p);
BOOL Snd_IsExChannelActive(struct SNDExChannel * ch_p);
void Snd_InvalidateWave(const void * start, const void * end);
s32 Snd_UpdateExChannelEnvelope(SNDExChannel * ch_p, BOOL doPeriodicProc);
void Snd_SetExChannelAttack(struct SNDExChannel * ch_p, int attack);
void Snd_SetExChannelDecay(struct SNDExChannel * ch_p, int decay);
void Snd_SetExChannelSustain(struct SNDExChannel * ch_p, int sustain);
void Snd_SetExChannelRelease(struct SNDExChannel * ch_p, int release);
void Snd_InitLfoParam(SNDLfoParam * lfo);
void Snd_StartLfo(SNDLfo * lfo);
void Snd_UpdateLfo(SNDLfo * lfo);
s32 Snd_GetLfoValue(SNDLfo * lfo);
void Snd_LockChannel(u32 chBitMask, u32 flags);
void Snd_UnlockChannel(u32 chBitMask, u32 flags);
void Snd_StopUnlockedChannel(u32 chBitMask, u32 flags);
u32 Snd_GetLockedChannel(u32 flags);
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -227,6 +227,8 @@ Static main
Object lib/NitroSDK/asm/mtx.o
Object lib/NitroSDK/asm/fx_cp.o
Object lib/NitroSDK/asm/fx_vec.o
Object lib/NitroSDK/asm/fx_atanidx.o
Object lib/NitroSDK/asm/fx_fx.o
Object lib/NitroSDK/asm/gx.o
Object lib/NitroSDK/asm/gxstate.o
Object lib/NitroSDK/asm/gx_vramcnt.o
@@ -276,7 +278,7 @@ Static main
Object lib/NitroSDK/asm/snd_alarm.o
Object lib/NitroSDK/asm/snd_work.o
Object lib/NitroSDK/src/snd/snd_util.o
Object lib/NitroSDK/asm/snd_bank.o
Object lib/NitroSDK/src/snd/snd_bank.o
Object lib/NitroSDK/src/pxi_init.o
Object lib/NitroSDK/asm/pxi_fifo.o
Object lib/NitroSDK/asm/fs_command.o