Merge pull request #129 from HarbourMasters/modding+

Audio implementation
This commit is contained in:
MegaMech
2024-12-04 11:20:38 -07:00
committed by GitHub
71 changed files with 2694 additions and 379 deletions
+34
View File
@@ -115,4 +115,38 @@
// Hey, you're very good. See you next time!
#define SOUND_CREDITS_FAREWELL SOUND_ARG_LOAD(0x49, 0x00, 0x80, 0x26)
enum MusicSeq {
MUSIC_SEQ_UNKNOWN = -1,
MUSIC_SEQ_00,
MUSIC_SEQ_TITLE_SCREEN,
MUSIC_SEQ_MAIN_MENU,
MUSIC_SEQ_RACEWAYS_WARIO_STADIUM,
MUSIC_SEQ_MOO_MOO_FARM_YOSHI_VALLEY,
MUSIC_SEQ_CHOCO_MOUNTAIN,
MUSIC_SEQ_KOOPA_TROOPA_BEACH,
MUSIC_SEQ_BANSHEE_BOARDWALK,
MUSIC_SEQ_FRAPPE_SNOWLAND,
MUSIC_SEQ_BOWSERS_CASTLE,
MUSIC_SEQ_KALIMARI_DESERT,
MUSIC_SEQ_START_GRID_GP_VS,
MUSIC_SEQ_FINAL_LAP_FANFARE,
MUSIC_SEQ_FINISH_1ST_PLACE,
MUSIC_SEQ_FINISH_2ND_4TH_PLACE,
MUSIC_SEQ_FINISH_5TH_8TH_PLACE,
MUSIC_SEQ_16,
MUSIC_SEQ_STAR_JINGLE,
MUSIC_SEQ_RAINBOW_ROAD,
MUSIC_SEQ_DK_JUNGLE,
MUSIC_SEQ_GAME_OVER,
MUSIC_SEQ_TOADS_TURNPIKE,
MUSIC_SEQ_START_GIRD_TIME_ATTACK,
MUSIC_SEQ_VS_BATTLE_RESULTS,
MUSIC_SEQ_LOSING_RESULTS,
MUSIC_SEQ_BATTLE_ARENAS,
MUSIC_SEQ_AWARD_CEREMONY_BUILDUP,
MUSIC_SEQ_AWARD_CEREMONY_1ST_3RD,
MUSIC_SEQ_STAFF_ROLL,
MUSIC_SEQ_AWARD_CEREMONY_4TH_8TH,
};
#endif // SOUNDS_H
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#include <thread>
#include <condition_variable>
static struct {
std::thread thread;
std::condition_variable cv_to_thread, cv_from_thread;
std::mutex mutex;
bool running;
bool processing;
} audio;
+1 -1
View File
@@ -12,7 +12,7 @@ void sequence_channel_process_sound(struct SequenceChannel* seqChannel, s32 reca
s32 i;
if (seqChannel->changes.as_bitfields.volume || recalculateVolume) {
channelVolume = seqChannel->volume * seqChannel->volumeScale * seqChannel->seqPlayer->appliedFadeVolume;
channelVolume = (seqChannel->volume * (seqChannel->volumeScale * seqChannel->seqPlayer->fadeVolume)) * seqChannel->seqPlayer->gameVolume;
if (seqChannel->seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_SOFTEN) != 0) {
channelVolume = seqChannel->seqPlayer->muteVolumeScale * channelVolume;
}
+18 -13
View File
@@ -92,7 +92,7 @@ f32 D_800EA120[] = { 0.0f, 0.0f, 0.0f, 0.0f };
f32 D_800EA130[] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
f32 D_800EA150 = 1.4f;
u8 D_800EA154[] = { 2, 2, 88, 90, 3, 48, 88, 48 };
u16 D_800EA15C = 0;
u16 gCurrentMusicSeq = 0;
u16 D_800EA160 = 0;
u8 D_800EA164 = 0;
s8 D_800EA168 = 0;
@@ -565,7 +565,7 @@ void func_800C2474(void) {
D_800EA16C = 0;
func_800CBBB8(0xF2000000U, 0);
D_800EA16C = 0;
D_800EA15C = 0;
gCurrentMusicSeq = 0;
D_800EA160 = 0;
D_800EA164 = 0;
D_800EA178 = 1.0f;
@@ -1253,7 +1253,7 @@ void func_800C4398(void) {
u8 soundIndex;
u8 var_a3;
struct Sound* var_a2;
u8 var_t2;
u8 var_t2 = 0;
u32 var_t3;
var_a2 = &sSoundRequests[sNumProcessedSoundRequests];
@@ -2834,9 +2834,9 @@ void play_sound2(s32 soundBits) {
play_sound(soundBits, &D_800EA1C8, 4, &D_800EA1D4, &D_800EA1D4, &D_800EA1DC);
}
void func_800C8EAC(u16 arg0) {
void play_sequence(u16 arg0) {
func_800C3448(arg0 | 0x10000);
D_800EA15C = arg0;
gCurrentMusicSeq = arg0;
}
void func_800C8EF8(u16 arg0) {
@@ -3284,7 +3284,7 @@ void func_800CA49C(u8 arg0) {
func_800C3448(0x100100FF); // 0x19000000
func_800C3448(0x110100FF);
func_800C8EF8(0xC);
func_800C3448(D_800EA15C | 0xC1500000);
func_800C3448(gCurrentMusicSeq | 0xC1500000);
func_800C3448(0xC130017D);
}
D_8018FC08 = D_8018FC08 + 1;
@@ -3334,20 +3334,20 @@ void func_800CA730(u8 arg0) {
if (D_8018FC08 != 0) {
if (((u32) (gSequencePlayers[1].enabled)) == 0) {
func_800C3608(1, 5);
func_800C8EAC(D_800EA15C);
play_sequence(gCurrentMusicSeq);
func_800C3448(0xB001307DU);
} else if ((func_800C3508(1) == 0xC) || (func_800C357C(0x0101000C) == 0)) {
func_800C3448(0xC1F00000U);
func_800C3448(D_800EA15C | 0xC1500000);
func_800C3448(gCurrentMusicSeq | 0xC1500000);
func_800C3448(0xC130017DU);
} else {
func_800C3448(0x110100FFU);
func_800C8EAC(D_800EA15C);
play_sequence(gCurrentMusicSeq);
func_800C3448(0xB001307DU);
}
} else {
func_800C3448(0x110100FFU);
func_800C8EAC(D_800EA15C);
play_sequence(gCurrentMusicSeq);
}
}
D_800EA164 = 0;
@@ -3512,11 +3512,11 @@ void func_800CB14C() {
if (D_800EA174 != 0) {
D_800EA174++;
if (D_800EA174 == 3) {
func_800C8EAC(0x001AU);
play_sequence(MUSIC_SEQ_AWARD_CEREMONY_BUILDUP);
func_800C3448(0x4000007F);
}
if (D_800EA174 == 0x012C) {
func_800C8EAC(0x001BU);
play_sequence(MUSIC_SEQ_AWARD_CEREMONY_1ST_3RD);
func_800C3448(0x4000007F);
func_800C8EF8(0x001DU);
func_800C3448(0x41000000);
@@ -3541,12 +3541,17 @@ void func_800CB14C() {
func_800C3448(0x110100FF);
}
if (D_800EA174 == 0x04CE) {
func_800C8EAC(0x0014U);
play_sequence(MUSIC_SEQ_GAME_OVER);
func_800C3448(0x4000007F);
}
}
}
void audio_set_player_volume(u8 player, f32 volume) {
gSequencePlayers[player].gameVolume = volume;
gSequencePlayers[player].recalculateVolume = 1;
}
// run audio?
void func_800CB2C4() {
func_800C1F8C();
+4 -2
View File
@@ -271,7 +271,7 @@ void func_800C8AE4(void);
void func_800C8C7C(u8);
void func_800C8CCC(void);
void play_sound2(s32);
void func_800C8EAC(u16);
void play_sequence(u16);
void func_800C8EF8(u16);
void func_800C8F44(u8);
void func_800C8F80(u8, u32);
@@ -322,6 +322,8 @@ void func_800CB14C(void);
void func_800CB2C4(void);
void func_800CBC24(void);
extern void audio_set_player_volume(u8 player, f32 volume);
// This is some from other file, its definitely not part of audio's data/bss
extern s8 D_801657E5;
@@ -399,7 +401,7 @@ extern f32 D_800EA120[4];
extern f32 D_800EA130[8];
extern f32 D_800EA150; // = 1.4f;
extern u8 D_800EA154[];
extern u16 D_800EA15C;
extern u16 gCurrentMusicSeq;
extern u16 D_800EA160;
extern u8 D_800EA164;
extern s8 D_800EA168;
+2
View File
@@ -663,6 +663,7 @@ void audio_reset_session(void) {
for (var_s5 = 0; var_s5 < 4; var_s5++) {
gSynthesisReverbs[var_s5].useReverb = 0;
}
gNumSynthesisReverbs = temp_s6->numReverbs;
for (var_s5 = 0; var_s5 < gNumSynthesisReverbs; var_s5++) {
reverb = &gSynthesisReverbs[var_s5];
@@ -695,6 +696,7 @@ void audio_reset_session(void) {
}
}
}
func_800BB030(gMaxSimultaneousNotes);
osWritebackDCacheAll();
}
+2 -2
View File
@@ -12,8 +12,8 @@
#define SOUND_LOAD_STATUS_4 4
#define SOUND_LOAD_STATUS_5 5
#define IS_BANK_LOAD_COMPLETE(bankId) (gBankLoadStatus[bankId] >= SOUND_LOAD_STATUS_COMPLETE)
#define IS_SEQ_LOAD_COMPLETE(seqId) (gSeqLoadStatus[seqId] >= SOUND_LOAD_STATUS_COMPLETE)
#define IS_BANK_LOAD_COMPLETE(bankId) GameEngine_IsBankLoaded(bankId)
#define IS_SEQ_LOAD_COMPLETE(seqId) GameEngine_IsSequenceLoaded(seqId)
struct SoundAllocPool {
u8* start;
+9 -24
View File
@@ -3,6 +3,7 @@
#include <libultraship.h>
#include "common_structs.h"
#include "port/resource/type/AudioSequence.h"
#define SEQUENCE_PLAYERS 4
#define SEQUENCE_CHANNELS 48
@@ -121,13 +122,13 @@ struct AdpcmLoop {
u32 end;
u32 count;
u32 pad;
s16 state[16]; // only exists if count != 0. 8-byte aligned
s16* state; // only exists if count != 0. 8-byte aligned
};
struct AdpcmBook {
s32 order;
s32 npredictors;
s16 book[1]; // size 8 * order * npredictors. 8-byte aligned
s16* book; // size 8 * order * npredictors. 8-byte aligned
};
struct AudioBankSample {
@@ -169,7 +170,7 @@ struct AudioBank {
}; // dynamic size
struct CtlEntry {
u8 unused;
u8 bankId;
u8 numInstruments;
u8 numDrums;
struct Instrument** instruments;
@@ -227,6 +228,7 @@ struct SequencePlayer {
/*0x130, 0x13C*/ u8* bankDmaCurrMemAddr;
/*0x138, 0x140*/ uintptr_t bankDmaCurrDevAddr;
/*0x13C, 0x144*/ size_t bankDmaRemaining;
f32 gameVolume;
}; // size = 0x140, 0x148 on EU, 0x14C on SH
struct AdsrSettings {
@@ -556,13 +558,14 @@ struct AudioBufferParametersEU {
* The version of that function in MK64 is significantly different
* from its SM64 counterpart
* Or we just have a poor understanding of this part of the system.
**/
struct EuAudioCmd {
union {
#if IS_BIG_ENDIAN
struct {
u8 op;
u8 arg1;
u8 bankId;
u8 arg2;
u8 arg3;
} s;
@@ -570,7 +573,7 @@ struct EuAudioCmd {
struct {
u8 arg3;
u8 arg2;
u8 arg1;
u8 bankId;
u8 op;
} s;
#endif
@@ -595,25 +598,7 @@ struct EuAudioCmd {
#endif
} u2;
};
**/
struct EuAudioCmd {
union {
struct {
u8 op;
u8 bankId;
u8 arg2;
u8 arg3;
} s;
u32 first;
} u;
union {
s32 as_s32;
u32 as_u32;
f32 as_f32;
u8 as_u8;
s8 as_s8;
} u2;
};
extern void create_next_audio_buffer(s16* samples, u32 num_samples);
#endif // AUDIO_INTERNAL_H
+35 -110
View File
@@ -5,10 +5,12 @@
#include "audio/data.h"
#include "audio/heap.h"
#include "audio/internal.h"
#include "audio/external.h"
#include "audio/playback.h"
#include "audio/synthesis.h"
#include "audio/seqplayer.h"
#include "audio/port_eu.h"
#include "port/Engine.h"
#include "buffers/gfx_output_buffer.h"
#include <string.h>
@@ -598,58 +600,19 @@ void* sequence_dma_async(s32 seqId, s32 arg1, struct SequencePlayer* seqPlayer)
return ptr;
}
u8 get_missing_bank(u32 seqId, s32* nonNullCount, s32* nullCount) {
void* temp;
u32 bankId;
u16 offset;
u8 i;
u8 ret;
*nullCount = 0;
*nonNullCount = 0;
offset = ((u16*) gAlBankSets)[seqId];
for (i = gAlBankSets[offset++], ret = 0; i != 0; i--) {
bankId = gAlBankSets[offset++];
if (IS_BANK_LOAD_COMPLETE(bankId) == true) {
temp = get_bank_or_seq(1, 2, bankId);
} else {
temp = NULL;
}
if (temp == NULL) {
(*nullCount)++;
ret = bankId;
} else {
(*nonNullCount)++;
}
}
return ret;
uint8_t* load_sequence_immediate(s32 seqId, s32 arg1) {
return GameEngine_LoadSequence(seqId)->data;
}
struct AudioBank* load_banks_immediate(s32 seqId, u8* outDefaultBank) {
void* ret;
struct CtlEntry* load_banks_immediate(s32 seqId, u8 *outDefaultBank) {
u32 bankId;
u16 offset;
u8 i;
offset = ((u16*) gAlBankSets)[seqId];
for (i = gAlBankSets[offset++]; i != 0; i--) {
bankId = gAlBankSets[offset++];
if (IS_BANK_LOAD_COMPLETE(bankId) == true) {
ret = get_bank_or_seq(1, 2, bankId);
} else {
ret = NULL;
}
if (ret == NULL) {
ret = bank_load_immediate(bankId, 2);
}
struct AudioSequenceData *seqData = GameEngine_LoadSequence(seqId);
struct CtlEntry *output;
for(size_t i = 0; i < seqData->bankCount; i++) {
output = GameEngine_LoadBank(bankId = seqData->banks[i]);
}
*outDefaultBank = bankId;
return ret;
return output;
}
void preload_sequence(u32 seqId, u8 preloadMask) {
@@ -660,9 +623,9 @@ void preload_sequence(u32 seqId, u8 preloadMask) {
return;
}
if (gSeqFileHeader->seqArray[seqId].len == 0) {
seqId = (u32) gSeqFileHeader->seqArray[seqId].offset;
}
// if (gSeqFileHeader->seqArray[seqId].len == 0) {
// seqId = (u32) gSeqFileHeader->seqArray[seqId].offset;
// }
gAudioLoadLock = AUDIO_LOCK_LOADING;
if (preloadMask & PRELOAD_BANKS) {
@@ -671,8 +634,8 @@ void preload_sequence(u32 seqId, u8 preloadMask) {
if (preloadMask & PRELOAD_SEQUENCE) {
//! @bug should be IS_SEQ_LOAD_COMPLETE
if (IS_BANK_LOAD_COMPLETE(seqId) == true) {
sequenceData = get_bank_or_seq(0, 2, seqId);
if (IS_SEQ_LOAD_COMPLETE(seqId) == true) {
sequenceData = load_sequence_immediate(seqId, 2);
} else {
sequenceData = NULL;
}
@@ -696,63 +659,32 @@ void load_sequence(u32 player, u32 seqId, s32 loadAsync) {
}
void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) {
void* sequenceData;
struct SequencePlayer* seqPlayer = &gSequencePlayers[player];
UNUSED u32 padding[2];
struct SequencePlayer *seqPlayer = &gSequencePlayers[player];
if (seqId >= gSequenceCount) {
return;
}
if (gSeqFileHeader->seqArray[seqId].len == 0) {
seqId = (u32) gSeqFileHeader->seqArray[seqId].offset;
sequence_player_disable(seqPlayer);
struct CtlEntry* bank = load_banks_immediate(seqId, &seqPlayer->defaultBank[0]);
if (bank == NULL) {
return;
}
sequence_player_disable(seqPlayer);
if (loadAsync) {
s32 numMissingBanks = 0;
s32 dummy = 0;
s32 bankId = get_missing_bank(seqId, &dummy, &numMissingBanks);
if (numMissingBanks == 1) {
if (bank_load_async(bankId, 2, seqPlayer) == NULL) {
return;
}
/**
* @bug This should set the last bank (i.e. the first in the JSON)
* as default, not the missing one. This code path never gets
* taken, though -- all sequence loading is synchronous.
*/
seqPlayer->defaultBank[0] = bankId;
} else {
if (load_banks_immediate(seqId, &seqPlayer->defaultBank[0]) == NULL) {
return;
}
}
} else if (load_banks_immediate(seqId, &seqPlayer->defaultBank[0]) == NULL) {
eu_stubbed_printf_2("Seq %d:Default Load Id is %d\n", seqId, seqPlayer->defaultBank[0]);
eu_stubbed_printf_0("Seq Loading Start\n");
uint8_t* sequenceData = load_sequence_immediate(seqId, 2);
if (sequenceData == NULL) {
return;
}
seqPlayer->seqId = seqId;
sequenceData = get_bank_or_seq(0, 2, seqId);
if (sequenceData == NULL) {
if (seqPlayer->seqDmaInProgress) {
return;
}
if (loadAsync) {
sequenceData = sequence_dma_async(seqId, 2, seqPlayer);
} else {
sequenceData = sequence_dma_immediate(seqId, 2);
}
if (sequenceData == NULL) {
return;
}
}
init_sequence_player(player);
seqPlayer->scriptState.depth = 0;
seqPlayer->delay = 0;
seqPlayer->enabled = true;
seqPlayer->enabled = 1;
seqPlayer->seqData = sequenceData;
seqPlayer->scriptState.pc = sequenceData;
}
@@ -801,21 +733,8 @@ void audio_init(void) {
#endif
// UTODO: Which is the correct one?
switch (0) { /* irregular */
case 0:
D_803B7178 = 20.03042f;
gRefreshRate = 0x00000032;
break;
case 2:
D_803B7178 = 16.546f;
gRefreshRate = 0x0000003C;
break;
case 1:
default:
D_803B7178 = 16.713f;
gRefreshRate = 0x0000003C;
break;
}
D_803B7178 = 16.713f;
gRefreshRate = 60;
port_eu_init();
for (i = 0; i < NUMAIBUFFERS; i++) {
gAiBufferLengths[i] = 0xa0;
@@ -845,6 +764,7 @@ void audio_init(void) {
gAudioResetPresetIdToLoad = 0;
gAudioResetStatus = one;
audio_shut_down_and_reset_step();
gSequenceCount = GameEngine_GetSequenceCount();
#ifdef TARGET_N64
gSeqFileHeader = (ALSeqFile*) sp60;
test = &_sequencesSegmentRomStart;
@@ -884,6 +804,11 @@ void audio_init(void) {
sound_alloc_pool_init(&gUnkPool1.pool, soundAlloc(&gAudioInitPool, (u32) D_800EA5D8), (u32) D_800EA5D8);
init_sequence_players();
gAudioLoadLock = 0x76557364;
audio_set_player_volume(SEQ_PLAYER_LEVEL, CVarGetFloat("gMainMusicVolume", 1.0f));
audio_set_player_volume(SEQ_PLAYER_ENV, CVarGetFloat("gEnvironmentVolume", 1.0f));
audio_set_player_volume(SEQ_PLAYER_SFX, CVarGetFloat("gSFXMusicVolume", 1.0f));
}
#else
#ifdef VERSION_EU
+1 -2
View File
@@ -39,8 +39,7 @@ struct AudioBank* bank_load_immediate(s32, s32);
struct AudioBank* bank_load_async(s32, s32, struct SequencePlayer*);
void* sequence_dma_immediate(s32, s32);
void* sequence_dma_async(s32, s32, struct SequencePlayer*);
u8 get_missing_bank(u32 seqId, s32* nonNullCount, s32* nullCount);
struct AudioBank* load_banks_immediate(s32, u8*);
struct CtlEntry* load_banks_immediate(s32, u8*);
void preload_sequence(u32, u8);
void load_sequence(u32, u32, s32);
void load_sequence_internal(u32, u32, s32);
+537 -48
View File
@@ -1,7 +1,13 @@
#include <libultraship.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "mixer.h"
#pragma GCC optimize("unroll-loops")
#ifndef __clang__
#pragma GCC optimize ("unroll-loops")
#endif
#define ROUND_UP_64(v) (((v) + 63) & ~63)
#define ROUND_UP_32(v) (((v) + 31) & ~31)
@@ -9,78 +15,561 @@
#define ROUND_UP_8(v) (((v) + 7) & ~7)
#define ROUND_DOWN_16(v) ((v) & ~0xf)
#ifdef NEW_AUDIO_UCODE
#define BUF_SIZE 2880
#define BUF_U8(a) (rspa.buf.as_u8 + ((a) - 0x450))
#define BUF_S16(a) (rspa.buf.as_s16 + ((a) - 0x450) / sizeof(int16_t))
#else
#define BUF_SIZE 2512
//#define DMEM_BUF_SIZE (0x1000 - 0x0330 - 0x10 - 0x40)
#define DMEM_BUF_SIZE 0x17D0
#define BUF_U8(a) (rspa.buf.as_u8 + (a))
#define BUF_S16(a) (rspa.buf.as_s16 + (a) / sizeof(int16_t))
#endif
static struct {
uint16_t in;
uint16_t out;
uint16_t nbytes;
#ifdef NEW_AUDIO_UCODE
uint16_t vol[2];
uint16_t rate[2];
uint16_t vol_wet;
uint16_t rate_wet;
#else
int16_t vol[2];
uint16_t dry_right;
uint16_t wet_left;
uint16_t wet_right;
int16_t target[2];
int32_t rate[2];
int16_t vol_dry;
int16_t vol_wet;
#endif
ADPCM_STATE* adpcm_loop_state;
ADPCM_STATE *adpcm_loop_state;
int16_t adpcm_table[8][2][8];
#ifdef NEW_AUDIO_UCODE
uint16_t filter_count;
int16_t filter[8];
#endif
union {
int16_t as_s16[BUF_SIZE / sizeof(int16_t)];
uint8_t as_u8[BUF_SIZE];
int16_t as_s16[DMEM_BUF_SIZE / sizeof(int16_t)];
uint8_t as_u8[DMEM_BUF_SIZE];
} buf;
} rspa;
void aDownsampleHalfImpl(uint16_t n_samples, uint16_t in_addr, uint16_t out_addr) {
int16_t* in = BUF_S16(in_addr);
int16_t* out = BUF_S16(out_addr);
int n = ROUND_UP_8(n_samples);
static int16_t resample_table[64][4] = {
{0x0c39, 0x66ad, 0x0d46, 0xffdf}, {0x0b39, 0x6696, 0x0e5f, 0xffd8},
{0x0a44, 0x6669, 0x0f83, 0xffd0}, {0x095a, 0x6626, 0x10b4, 0xffc8},
{0x087d, 0x65cd, 0x11f0, 0xffbf}, {0x07ab, 0x655e, 0x1338, 0xffb6},
{0x06e4, 0x64d9, 0x148c, 0xffac}, {0x0628, 0x643f, 0x15eb, 0xffa1},
{0x0577, 0x638f, 0x1756, 0xff96}, {0x04d1, 0x62cb, 0x18cb, 0xff8a},
{0x0435, 0x61f3, 0x1a4c, 0xff7e}, {0x03a4, 0x6106, 0x1bd7, 0xff71},
{0x031c, 0x6007, 0x1d6c, 0xff64}, {0x029f, 0x5ef5, 0x1f0b, 0xff56},
{0x022a, 0x5dd0, 0x20b3, 0xff48}, {0x01be, 0x5c9a, 0x2264, 0xff3a},
{0x015b, 0x5b53, 0x241e, 0xff2c}, {0x0101, 0x59fc, 0x25e0, 0xff1e},
{0x00ae, 0x5896, 0x27a9, 0xff10}, {0x0063, 0x5720, 0x297a, 0xff02},
{0x001f, 0x559d, 0x2b50, 0xfef4}, {0xffe2, 0x540d, 0x2d2c, 0xfee8},
{0xffac, 0x5270, 0x2f0d, 0xfedb}, {0xff7c, 0x50c7, 0x30f3, 0xfed0},
{0xff53, 0x4f14, 0x32dc, 0xfec6}, {0xff2e, 0x4d57, 0x34c8, 0xfebd},
{0xff0f, 0x4b91, 0x36b6, 0xfeb6}, {0xfef5, 0x49c2, 0x38a5, 0xfeb0},
{0xfedf, 0x47ed, 0x3a95, 0xfeac}, {0xfece, 0x4611, 0x3c85, 0xfeab},
{0xfec0, 0x4430, 0x3e74, 0xfeac}, {0xfeb6, 0x424a, 0x4060, 0xfeaf},
{0xfeaf, 0x4060, 0x424a, 0xfeb6}, {0xfeac, 0x3e74, 0x4430, 0xfec0},
{0xfeab, 0x3c85, 0x4611, 0xfece}, {0xfeac, 0x3a95, 0x47ed, 0xfedf},
{0xfeb0, 0x38a5, 0x49c2, 0xfef5}, {0xfeb6, 0x36b6, 0x4b91, 0xff0f},
{0xfebd, 0x34c8, 0x4d57, 0xff2e}, {0xfec6, 0x32dc, 0x4f14, 0xff53},
{0xfed0, 0x30f3, 0x50c7, 0xff7c}, {0xfedb, 0x2f0d, 0x5270, 0xffac},
{0xfee8, 0x2d2c, 0x540d, 0xffe2}, {0xfef4, 0x2b50, 0x559d, 0x001f},
{0xff02, 0x297a, 0x5720, 0x0063}, {0xff10, 0x27a9, 0x5896, 0x00ae},
{0xff1e, 0x25e0, 0x59fc, 0x0101}, {0xff2c, 0x241e, 0x5b53, 0x015b},
{0xff3a, 0x2264, 0x5c9a, 0x01be}, {0xff48, 0x20b3, 0x5dd0, 0x022a},
{0xff56, 0x1f0b, 0x5ef5, 0x029f}, {0xff64, 0x1d6c, 0x6007, 0x031c},
{0xff71, 0x1bd7, 0x6106, 0x03a4}, {0xff7e, 0x1a4c, 0x61f3, 0x0435},
{0xff8a, 0x18cb, 0x62cb, 0x04d1}, {0xff96, 0x1756, 0x638f, 0x0577},
{0xffa1, 0x15eb, 0x643f, 0x0628}, {0xffac, 0x148c, 0x64d9, 0x06e4},
{0xffb6, 0x1338, 0x655e, 0x07ab}, {0xffbf, 0x11f0, 0x65cd, 0x087d},
{0xffc8, 0x10b4, 0x6626, 0x095a}, {0xffd0, 0x0f83, 0x6669, 0x0a44},
{0xffd8, 0x0e5f, 0x6696, 0x0b39}, {0xffdf, 0x0d46, 0x66ad, 0x0c39}
};
static inline int16_t clamp16(int32_t v) {
if (v < -0x8000) {
return -0x8000;
} else if (v > 0x7fff) {
return 0x7fff;
}
return (int16_t)v;
}
static inline int32_t clamp32(int64_t v) {
if (v < -0x7fffffff - 1) {
return -0x7fffffff - 1;
} else if (v > 0x7fffffff) {
return 0x7fffffff;
}
return (int32_t)v;
}
void aClearBufferImpl(uint16_t addr, int nbytes) {
nbytes = ROUND_UP_16(nbytes);
memset(BUF_U8(addr), 0, nbytes);
}
void aLoadBufferImpl(const void *source_addr, uint16_t dest_addr, uint16_t nbytes) {
#if __SANITIZE_ADDRESS__
for (size_t i = 0; i < ROUND_DOWN_16(nbytes); i++) {
BUF_U8(dest_addr)[i] = ((const unsigned char*)source_addr)[i];
}
#else
memcpy(BUF_U8(dest_addr), source_addr, ROUND_DOWN_16(nbytes));
#endif
}
void aSaveBufferImpl(uint16_t source_addr, int16_t *dest_addr, uint16_t nbytes) {
//printf("source_addr: %x\n dest_addr; %x\n nbytes: %d\n", source_addr, dest_addr, nbytes);
//if (nbytes > 704) {nbytes = 704;}
memcpy(dest_addr, BUF_S16(source_addr), ROUND_DOWN_16(nbytes));
}
void aLoadADPCMImpl(int num_entries_times_16, const int16_t *book_source_addr) {
memcpy(rspa.adpcm_table, book_source_addr, num_entries_times_16);
}
void aSetBufferImpl(uint8_t flags, uint16_t in, uint16_t out, uint16_t nbytes) {
rspa.in = in;
rspa.out = out;
rspa.nbytes = nbytes;
}
void aInterleaveImpl(uint16_t left, uint16_t right) {
int count = ROUND_UP_16(rspa.nbytes) / sizeof(int16_t) / 8;
int16_t *l = BUF_S16(left);
int16_t *r = BUF_S16(right);
int16_t *d = BUF_S16(rspa.out);
while (count > 0) {
int16_t l0 = *l++;
int16_t l1 = *l++;
int16_t l2 = *l++;
int16_t l3 = *l++;
int16_t l4 = *l++;
int16_t l5 = *l++;
int16_t l6 = *l++;
int16_t l7 = *l++;
int16_t r0 = *r++;
int16_t r1 = *r++;
int16_t r2 = *r++;
int16_t r3 = *r++;
int16_t r4 = *r++;
int16_t r5 = *r++;
int16_t r6 = *r++;
int16_t r7 = *r++;
*d++ = l0;
*d++ = r0;
*d++ = l1;
*d++ = r1;
*d++ = l2;
*d++ = r2;
*d++ = l3;
*d++ = r3;
*d++ = l4;
*d++ = r4;
*d++ = l5;
*d++ = r5;
*d++ = l6;
*d++ = r6;
*d++ = l7;
*d++ = r7;
--count;
}
}
void aDMEMMoveImpl(uint16_t in_addr, uint16_t out_addr, int nbytes) {
nbytes = ROUND_UP_16(nbytes);
memmove(BUF_U8(out_addr), BUF_U8(in_addr), nbytes);
}
void aSetLoopImpl(ADPCM_STATE *adpcm_loop_state) {
rspa.adpcm_loop_state = adpcm_loop_state;
}
void aADPCMdecImpl(uint8_t flags, ADPCM_STATE state) {
uint8_t *in = BUF_U8(rspa.in);
int16_t *out = BUF_S16(rspa.out);
int nbytes = ROUND_UP_32(rspa.nbytes);
if (flags & A_INIT) {
memset(out, 0, 16 * sizeof(int16_t));
} else if (flags & A_LOOP) {
memcpy(out, rspa.adpcm_loop_state, 16 * sizeof(int16_t));
} else {
memcpy(out, state, 16 * sizeof(int16_t));
}
out += 16;
while (nbytes > 0) {
int shift = *in >> 4; // should be in 0..12 or 0..14
int table_index = *in++ & 0xf; // should be in 0..7
int16_t (*tbl)[8] = rspa.adpcm_table[table_index];
int i;
for (i = 0; i < 2; i++) {
int16_t ins[8];
int16_t prev1 = out[-1];
int16_t prev2 = out[-2];
int j, k;
for (j = 0; j < 4; j++) {
ins[j * 2] = (((*in >> 4) << 28) >> 28) << shift;
ins[j * 2 + 1] = (((*in++ & 0xf) << 28) >> 28) << shift;
}
for (j = 0; j < 8; j++) {
int32_t acc = tbl[0][j] * prev2 + tbl[1][j] * prev1 + (ins[j] << 11);
for (k = 0; k < j; k++) {
acc += tbl[1][((j - k) - 1)] * ins[k];
}
acc >>= 11;
*out++ = clamp16(acc);
}
}
nbytes -= 16 * sizeof(int16_t);
}
memcpy(state, out - 16, 16 * sizeof(int16_t));
}
void aResampleImpl(uint8_t flags, uint16_t pitch, RESAMPLE_STATE state) {
int16_t tmp[32];
int16_t *in_initial = BUF_S16(rspa.in);
int16_t *in = in_initial;
int16_t *out = BUF_S16(rspa.out);
int nbytes = ROUND_UP_16(rspa.nbytes);
uint32_t pitch_accumulator;
int i;
int16_t *tbl;
int32_t sample;
if (flags & A_INIT) {
memset(tmp, 0, 5 * sizeof(int16_t));
} else {
memcpy(tmp, state, 16 * sizeof(int16_t));
}
if (flags & 2) {
memcpy(in - 8, tmp + 8, 8 * sizeof(int16_t));
in -= tmp[5] / sizeof(int16_t);
}
in -= 4;
pitch_accumulator = (uint16_t)tmp[4];
memcpy(in, tmp, 4 * sizeof(int16_t));
do {
*out++ = *in++;
in++;
*out++ = *in++;
in++;
*out++ = *in++;
in++;
*out++ = *in++;
in++;
*out++ = *in++;
in++;
*out++ = *in++;
in++;
*out++ = *in++;
in++;
*out++ = *in++;
in++;
for (i = 0; i < 8; i++) {
tbl = resample_table[pitch_accumulator * 64 >> 16];
sample = ((in[0] * tbl[0] + 0x4000) >> 15) +
((in[1] * tbl[1] + 0x4000) >> 15) +
((in[2] * tbl[2] + 0x4000) >> 15) +
((in[3] * tbl[3] + 0x4000) >> 15);
*out++ = clamp16(sample);
pitch_accumulator += (pitch << 1);
in += pitch_accumulator >> 16;
pitch_accumulator %= 0x10000;
}
nbytes -= 8 * sizeof(int16_t);
} while (nbytes > 0);
state[4] = (int16_t)pitch_accumulator;
memcpy(state, in, 4 * sizeof(int16_t));
i = (in - in_initial + 4) & 7;
in -= i;
if (i != 0) {
i = -8 - i;
}
state[5] = i;
memcpy(state + 8, in, 8 * sizeof(int16_t));
}
void aEnvSetup1Impl(uint8_t initial_vol_wet, uint16_t rate_wet, uint16_t rate_left, uint16_t rate_right) {
rspa.vol_wet = (uint16_t)(initial_vol_wet << 8);
rspa.rate_wet = 0;
rspa.rate[0] = rate_left;
rspa.rate[1] = rate_right;
}
void aEnvSetup2Impl(uint16_t initial_vol_left, uint16_t initial_vol_right) {
rspa.vol[0] = initial_vol_left;
rspa.vol[1] = initial_vol_right;
}
void aEnvMixerImpl(uint16_t in_addr, uint16_t n_samples, bool swap_reverb,
bool neg_left, bool neg_right,
uint16_t dry_left_addr, uint16_t dry_right_addr,
uint16_t wet_left_addr, uint16_t wet_right_addr)
{
swap_reverb = false;
int16_t *in = BUF_S16(in_addr);
int16_t *dry[2] = {BUF_S16(dry_left_addr), BUF_S16(dry_right_addr)};
int16_t *wet[2] = {BUF_S16(wet_left_addr), BUF_S16(wet_right_addr)};
int16_t negs[2] = {neg_left ? -1 : 0, neg_right ? -1 : 0};
int swapped[2] = {swap_reverb ? 1 : 0, swap_reverb ? 0 : 1};
int n = ROUND_UP_16(n_samples);
uint16_t vols[2] = {rspa.vol[0], rspa.vol[1]};
uint16_t rates[2] = {rspa.rate[0], rspa.rate[1]};
uint16_t vol_wet = rspa.vol_wet;
uint16_t rate_wet = rspa.rate_wet;
do {
for (int i = 0; i < 8; i++) {
int16_t samples[2] = {*in, *in}; in++;
for (int j = 0; j < 2; j++) {
samples[j] = (samples[j] * vols[j] >> 16) ^ negs[j];
*dry[j] = clamp16(*dry[j] + samples[j]); dry[j]++;
*wet[j] = clamp16(*wet[j] + (samples[swapped[j]] * vol_wet >> 16)); wet[j]++;
}
}
vols[0] += rates[0];
vols[1] += rates[1];
vol_wet += rate_wet;
n -= 8;
} while (n > 0);
}
void aMixImpl(int16_t gain, uint16_t in_addr, uint16_t out_addr, uint16_t count) {
int nbytes = ROUND_UP_32(ROUND_DOWN_16(count));
int16_t *in = BUF_S16(in_addr);
int16_t *out = BUF_S16(out_addr);
int i;
int32_t sample;
if (gain == -0x8000) {
while (nbytes > 0) {
for (i = 0; i < 16; i++) {
sample = *out - *in++;
*out++ = clamp16(sample);
}
nbytes -= 16 * sizeof(int16_t);
}
}
while (nbytes > 0) {
for (i = 0; i < 16; i++) {
sample = ((*out * 0x7fff + *in++ * gain) + 0x4000) >> 15;
*out++ = clamp16(sample);
}
nbytes -= 16 * sizeof(int16_t);
}
}
void aS8DecImpl(uint8_t flags, ADPCM_STATE state) {
uint8_t *in = BUF_U8(rspa.in);
int16_t *out = BUF_S16(rspa.out);
int nbytes = ROUND_UP_32(rspa.nbytes);
if (flags & A_INIT) {
memset(out, 0, 16 * sizeof(int16_t));
} else if (flags & A_LOOP) {
memcpy(out, rspa.adpcm_loop_state, 16 * sizeof(int16_t));
} else {
memcpy(out, state, 16 * sizeof(int16_t));
}
out += 16;
while (nbytes > 0) {
*out++ = (int16_t)(*in++ << 8);
*out++ = (int16_t)(*in++ << 8);
*out++ = (int16_t)(*in++ << 8);
*out++ = (int16_t)(*in++ << 8);
*out++ = (int16_t)(*in++ << 8);
*out++ = (int16_t)(*in++ << 8);
*out++ = (int16_t)(*in++ << 8);
*out++ = (int16_t)(*in++ << 8);
*out++ = (int16_t)(*in++ << 8);
*out++ = (int16_t)(*in++ << 8);
*out++ = (int16_t)(*in++ << 8);
*out++ = (int16_t)(*in++ << 8);
*out++ = (int16_t)(*in++ << 8);
*out++ = (int16_t)(*in++ << 8);
*out++ = (int16_t)(*in++ << 8);
*out++ = (int16_t)(*in++ << 8);
nbytes -= 16 * sizeof(int16_t);
}
memcpy(state, out - 16, 16 * sizeof(int16_t));
}
void aAddMixerImpl(uint16_t count, uint16_t in_addr, uint16_t out_addr) {
int16_t *in = BUF_S16(in_addr);
int16_t *out = BUF_S16(out_addr);
int nbytes = ROUND_UP_64(ROUND_DOWN_16(count));
do {
*out = clamp16(*out + *in++); out++;
*out = clamp16(*out + *in++); out++;
*out = clamp16(*out + *in++); out++;
*out = clamp16(*out + *in++); out++;
*out = clamp16(*out + *in++); out++;
*out = clamp16(*out + *in++); out++;
*out = clamp16(*out + *in++); out++;
*out = clamp16(*out + *in++); out++;
*out = clamp16(*out + *in++); out++;
*out = clamp16(*out + *in++); out++;
*out = clamp16(*out + *in++); out++;
*out = clamp16(*out + *in++); out++;
*out = clamp16(*out + *in++); out++;
*out = clamp16(*out + *in++); out++;
*out = clamp16(*out + *in++); out++;
*out = clamp16(*out + *in++); out++;
nbytes -= 16 * sizeof(int16_t);
} while (nbytes > 0);
}
void aDuplicateImpl(uint16_t count, uint16_t in_addr, uint16_t out_addr) {
uint8_t* in = BUF_U8(in_addr);
uint8_t *out = BUF_U8(out_addr);
uint8_t tmp[128];
memcpy(tmp, in, 128);
do {
memcpy(out, tmp, 128);
out += 128;
} while (count-- > 0);
}
void aDMEMMove2Impl(uint8_t t, uint16_t in_addr, uint16_t out_addr, uint16_t count) {
uint8_t *in = BUF_U8(in_addr);
uint8_t *out = BUF_U8(out_addr);
int nbytes = ROUND_UP_32(count);
do {
memmove(out, in, nbytes);
in += nbytes;
out += nbytes;
} while (t-- > 0);
}
void aResampleZohImpl(uint16_t pitch, uint16_t start_fract) {
int16_t *in = BUF_S16(rspa.in);
int16_t *out = BUF_S16(rspa.out);
int nbytes = ROUND_UP_8(rspa.nbytes);
uint32_t pos = start_fract;
uint32_t pitch_add = pitch << 2;
do {
*out++ = in[pos >> 17]; pos += pitch_add;
*out++ = in[pos >> 17]; pos += pitch_add;
*out++ = in[pos >> 17]; pos += pitch_add;
*out++ = in[pos >> 17]; pos += pitch_add;
nbytes -= 4 * sizeof(int16_t);
} while (nbytes > 0);
}
void aDownsampleHalfImpl(uint16_t n_samples, uint16_t in_addr, uint16_t out_addr) {
int16_t *in = BUF_S16(in_addr);
int16_t *out = BUF_S16(out_addr);
int n = ROUND_UP_8(n_samples);
do {
*out++ = *in++; in++;
*out++ = *in++; in++;
*out++ = *in++; in++;
*out++ = *in++; in++;
*out++ = *in++; in++;
*out++ = *in++; in++;
*out++ = *in++; in++;
*out++ = *in++; in++;
n -= 8;
} while (n > 0);
}
void aInterlImpl(uint16_t in_addr, uint16_t out_addr, uint16_t n_samples) {
int16_t *in = BUF_S16(in_addr);
int16_t *out = BUF_S16(out_addr);
int n = ROUND_UP_8(n_samples);
do {
*out++ = *in++; in++;
*out++ = *in++; in++;
*out++ = *in++; in++;
*out++ = *in++; in++;
*out++ = *in++; in++;
*out++ = *in++; in++;
*out++ = *in++; in++;
*out++ = *in++; in++;
n -= 8;
} while (n > 0);
}
void aFilterImpl(uint8_t flags, uint16_t count_or_buf, int16_t *state_or_filter) {
if (flags > A_INIT) {
rspa.filter_count = ROUND_UP_16(count_or_buf);
memcpy(rspa.filter, state_or_filter, sizeof(rspa.filter));
} else {
int16_t tmp[16], tmp2[8];
int count = rspa.filter_count;
int16_t *buf = BUF_S16(count_or_buf);
if (flags == A_INIT) {
#ifndef __clang__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmemset-elt-size"
#endif
memset(tmp, 0, 8 * sizeof(int16_t));
#ifndef __clang__
#pragma GCC diagnostic pop
#endif
memset(tmp2, 0, 8 * sizeof(int16_t));
} else {
memcpy(tmp, state_or_filter, 8 * sizeof(int16_t));
memcpy(tmp2, state_or_filter + 8, 8 * sizeof(int16_t));
}
for (int i = 0; i < 8; i++) {
rspa.filter[i] = (tmp2[i] + rspa.filter[i]) / 2;
}
do {
memcpy(tmp + 8, buf, 8 * sizeof(int16_t));
for (int i = 0; i < 8; i++) {
int64_t sample = 0x4000; // round term
for (int j = 0; j < 8; j++) {
sample += tmp[i + j] * rspa.filter[7 - j];
}
buf[i] = clamp16((int32_t)(sample >> 15));
}
memcpy(tmp, tmp + 8, 8 * sizeof(int16_t));
buf += 8;
count -= 8 * sizeof(int16_t);
} while (count > 0);
memcpy(state_or_filter, tmp, 8 * sizeof(int16_t));
memcpy(state_or_filter + 8, rspa.filter, 8 * sizeof(int16_t));
}
}
void aHiLoGainImpl(uint8_t g, uint16_t count, uint16_t addr) {
int16_t *samples = BUF_S16(addr);
int nbytes = ROUND_UP_32(count);
do {
*samples = clamp16((*samples * g) >> 4); samples++;
*samples = clamp16((*samples * g) >> 4); samples++;
*samples = clamp16((*samples * g) >> 4); samples++;
*samples = clamp16((*samples * g) >> 4); samples++;
*samples = clamp16((*samples * g) >> 4); samples++;
*samples = clamp16((*samples * g) >> 4); samples++;
*samples = clamp16((*samples * g) >> 4); samples++;
*samples = clamp16((*samples * g) >> 4); samples++;
nbytes -= 8;
} while (nbytes > 0);
}
void aUnkCmd3Impl(uint16_t a, uint16_t b, uint16_t c) {
}
void aUnkCmd19Impl(uint8_t f, uint16_t count, uint16_t out_addr, uint16_t in_addr) {
int nbytes = ROUND_UP_64(count);
int16_t *in = BUF_S16(in_addr + f);
int16_t *out = BUF_S16(out_addr);
int16_t tbl[32];
memcpy(tbl, in, 32 * sizeof(int16_t));
do {
for (int i = 0; i < 32; i++) {
out[i] = clamp16(out[i] * tbl[i]);
}
out += 32;
nbytes -= 32 * sizeof(int16_t);
} while (nbytes > 0);
}
+90 -7
View File
@@ -1,11 +1,94 @@
#ifndef MIXER_H
#define MIXER_H
#pragma once
#include <libultraship.h>
void aDownsampleHalfImpl(uint16_t n_samples, uint16_t in_addr, uint16_t out_addr);
#include <stdbool.h>
#include <stdint.h>
#include "libultraship/libultra/abi.h"
#undef aSegment
#undef aClearBuffer
#undef aSetBuffer
#undef aLoadBuffer
#undef aSaveBuffer
#undef aDMEMMove
#undef aMix
#undef aEnvMixer
#undef aResample
#undef aInterleave
#undef aSetVolume
#undef aSetVolume32
#undef aSetLoop
#undef aLoadADPCM
#undef aADPCMdec
#undef aS8Dec
#undef aAddMixer
#undef aDuplicate
#undef aDMEMMove2
#undef aResampleZoh
#undef aDownsampleHalf
#define aDownsampleHalf(pkt, nSamples, i, o) aDownsampleHalfImpl(nSamples, i, o)
#undef aEnvSetup1
#undef aEnvSetup2
#undef aFilter
#undef aHiLoGain
#undef aInterl
#undef aUnkCmd3
#undef aUnkCmd19
#endif
void aClearBufferImpl(uint16_t addr, int nbytes);
void aLoadBufferImpl(const void* source_addr, uint16_t dest_addr, uint16_t nbytes);
void aSaveBufferImpl(uint16_t source_addr, int16_t* dest_addr, uint16_t nbytes);
void aLoadADPCMImpl(int num_entries_times_16, const int16_t* book_source_addr);
void aSetBufferImpl(uint8_t flags, uint16_t in, uint16_t out, uint16_t nbytes);
void aInterleaveImpl(uint16_t left, uint16_t right);
void aDMEMMoveImpl(uint16_t in_addr, uint16_t out_addr, int nbytes);
void aSetLoopImpl(ADPCM_STATE* adpcm_loop_state);
void aADPCMdecImpl(uint8_t flags, ADPCM_STATE state);
void aResampleImpl(uint8_t flags, uint16_t pitch, RESAMPLE_STATE state);
void aEnvSetup1Impl(uint8_t initial_vol_wet, uint16_t rate_wet, uint16_t rate_left, uint16_t rate_right);
void aEnvSetup2Impl(uint16_t initial_vol_left, uint16_t initial_vol_right);
void aEnvMixerImpl(uint16_t in_addr, uint16_t n_samples, bool swap_reverb,
bool neg_left, bool neg_right,
uint16_t dry_left_addr, uint16_t dry_right_addr,
uint16_t wet_left_addr, uint16_t wet_right_addr);
void aMixImpl(int16_t gain, uint16_t in_addr, uint16_t out_addr, uint16_t count);
void aS8DecImpl(uint8_t flags, ADPCM_STATE state);
void aAddMixerImpl(uint16_t count, uint16_t in_addr, uint16_t out_addr);
void aDuplicateImpl(uint16_t count, uint16_t in_addr, uint16_t out_addr);
void aDMEMMove2Impl(uint8_t t, uint16_t in_addr, uint16_t out_addr, uint16_t count);
void aDownsampleHalfImpl(uint16_t n_samples, uint16_t in_addr, uint16_t out_addr);
void aResampleZohImpl(uint16_t pitch, uint16_t start_fract);
void aInterlImpl(uint16_t in_addr, uint16_t out_addr, uint16_t n_samples);
void aFilterImpl(uint8_t flags, uint16_t count_or_buf, int16_t* state_or_filter);
void aHiLoGainImpl(uint8_t g, uint16_t count, uint16_t addr);
void aUnkCmd3Impl(uint16_t a, uint16_t b, uint16_t c);
void aUnkCmd19Impl(uint8_t f, uint16_t count, uint16_t out_addr, uint16_t in_addr);
#define aSegment(pkt, s, b) \
do { \
} while (0)
#define aClearBuffer(pkt, d, c) aClearBufferImpl(d, c)
#define aLoadBuffer(pkt, s, d, c) aLoadBufferImpl(s, d, c)
#define aSaveBuffer(pkt, s, d, c) aSaveBufferImpl(s, d, c)
#define aLoadADPCM(pkt, c, d) aLoadADPCMImpl(c, d)
#define aSetBuffer(pkt, f, i, o, c) aSetBufferImpl(f, i, o, c)
#define aInterleave(pkt, o, l, r, c) aInterleaveImpl(l, r)
#define aDMEMMove(pkt, i, o, c) aDMEMMoveImpl(i, o, c)
#define aSetLoop(pkt, a) aSetLoopImpl(a)
#define aADPCMdec(pkt, f, s) aADPCMdecImpl(f, s)
#define aResample(pkt, f, p, s) aResampleImpl(f, p, s)
#define aEnvSetup1(pkt, initialVolReverb, rampReverb, rampLeft, rampRight) \
aEnvSetup1Impl(initialVolReverb, rampReverb, rampLeft, rampRight)
#define aEnvSetup2(pkt, initialVolLeft, initialVolRight) aEnvSetup2Impl(initialVolLeft, initialVolRight)
#define aEnvMixer(pkt, inBuf, nSamples, swapReverb, negLeft, negRight, dryLeft, dryRight, wetLeft, wetRight) \
aEnvMixerImpl(inBuf, nSamples, swapReverb, negLeft, negRight, dryLeft, dryRight, wetLeft, wetRight)
#define aMix(pkt, g, i, o, c) aMixImpl(g, i, o, c)
#define aS8Dec(pkt, f, s) aS8DecImpl(f, s)
#define aAddMixer(pkt, s, d, c) aAddMixerImpl(s, d, c)
#define aDuplicate(pkt, s, d, c) aDuplicateImpl(s, d, c)
#define aDMEMMove2(pkt, t, i, o, c) aDMEMMove2Impl(t, i, o, c)
#define aResampleZoh(pkt, pitch, startFract) aResampleZohImpl(pitch, startFract)
#define aInterl(pkt, dmemi, dmemo, count) aInterlImpl(dmemi, dmemo, count)
#define aFilter(pkt, f, countOrBuf, addr) aFilterImpl(f, countOrBuf, addr)
#define aDownsampleHalf(pkt, nSamples, i, o) aDownsampleHalfImpl(nSamples, i, o)
#define aHiLoGain(pkt, g, buflen, i, a4) aHiLoGainImpl(g, buflen, i)
#define aUnkCmd3(pkt, a1, a2, a3) aUnkCmd3Impl(a1, a2, a3)
#define aUnkCmd19(pkt, a1, a2, a3, a4) aUnkCmd19Impl(a1, a2, a3, a4)
+13 -9
View File
@@ -9,6 +9,7 @@
#include "audio/effects.h"
#include "audio/data.h"
#include "audio/seqplayer.h"
#include "port/Engine.h"
void note_set_vel_pan_reverb(struct Note* note, f32 velocity, u8 pan, u8 reverbVol) {
struct NoteSubEu* sub = &note->noteSubEu;
@@ -70,6 +71,10 @@ void note_set_vel_pan_reverb(struct Note* note, f32 velocity, u8 pan, u8 reverbV
velocity = 1.0f;
}
float master_vol = CVarGetFloat("gGameMasterVolume", 1.0f);
volLeft *= master_vol;
volRight *= master_vol;
sub->targetVolLeft = ((s32) (velocity * volLeft * 4095.999f));
sub->targetVolRight = ((s32) (velocity * volRight * 4095.999f));
@@ -136,13 +141,15 @@ struct Instrument* get_instrument_inner(s32 bankId, s32 instId) {
return NULL;
}
if (instId >= gCtlEntries[bankId].numInstruments) {
struct CtlEntry* bank = GameEngine_LoadBank(bankId);
if (instId >= bank->numInstruments) {
stubbed_printf("Audio: voiceman: progNo. overflow %d,%d\n", instId, gCtlEntries[bankId].numInstruments);
gAudioErrorFlags = ((bankId << 8) + instId) + 0x3000000;
return NULL;
}
inst = gCtlEntries[bankId].instruments[instId];
inst = bank->instruments[instId];
if (inst == NULL) {
stubbed_printf("Audio: voiceman: progNo. undefined %d,%d\n", bankId, instId);
gAudioErrorFlags = ((bankId << 8) + instId) + 0x1000000;
@@ -160,18 +167,15 @@ struct Drum* get_drum(s32 bankId, s32 drumId) {
return NULL;
}
if (drumId >= gCtlEntries[bankId].numDrums) {
struct CtlEntry* bank = GameEngine_LoadBank(bankId);
if (drumId >= bank->numDrums) {
stubbed_printf("Audio: voiceman: Percussion Overflow %d,%d\n", drumId, gCtlEntries[bankId].numDrums);
gAudioErrorFlags = ((bankId << 8) + drumId) + 0x4000000;
return NULL;
}
if ((uintptr_t) gCtlEntries[bankId].drums < 0x80000000U) {
stubbed_printf("Audio: voiceman: Percussion table pointer (bank %d) is irregular.\n");
return NULL;
}
drum = gCtlEntries[bankId].drums[drumId];
drum = bank->drums[drumId];
if (drum == NULL) {
stubbed_printf("Audio: voiceman: Percpointer NULL %d,%d\n", bankId, drumId);
gAudioErrorFlags = ((bankId << 8) + drumId) + 0x5000000;
+43 -9
View File
@@ -46,6 +46,40 @@ s32 D_800EA4A4 = 0;
char port_eu_unused_string7[] = "Undefined Port Command %d\n";
void create_next_audio_buffer(s16* samples, u32 num_samples) {
static s32 gMaxAbiCmdCnt = 128;
s32 abiCmdCount;
OSMesg specId;
OSMesg msg;
gAudioFrameCount++;
gCurrAiBufferIndex %= 3;
gCurrAudioFrameDmaCount = 0;
if (osRecvMesg(D_800EA3B0, &specId, 0) != -1) {
gAudioResetPresetIdToLoad = specId.data8;
gAudioResetStatus = 5;
}
if (gAudioResetStatus != 0) {
if (audio_shut_down_and_reset_step() == 0) {
if (gAudioResetStatus == 0) {
osSendMesg(D_800EA3B4, OS_MESG_8(gAudioResetPresetIdToLoad), OS_MESG_NOBLOCK);
}
return;
}
}
if (osRecvMesg(D_800EA3AC, &msg, 0) != -1) {
func_800CBCB0(msg.data32);
}
gAudioCmd = gAudioCmdBuffers[gAudioTaskIndex];
gAudioCmd = synthesis_execute((Acmd*) gAudioCmd, &abiCmdCount, samples, num_samples);
gAudioRandom = osGetCount() * (gAudioRandom + gAudioFrameCount);
}
struct SPTask* create_next_audio_frame_task(void) {
u32 samplesRemainingInAI;
s32 writtenCmds;
@@ -126,7 +160,7 @@ struct SPTask* create_next_audio_frame_task(void) {
gAiBufferLengths[index] = gAudioBufferParameters.maxAiBufferLength;
}
if (osRecvMesg(D_800EA3AC, &sp54, 0) != -1) {
func_800CBCB0((u32) sp54.data16);
func_800CBCB0(sp54.data32);
}
gAudioCmd = synthesis_execute((Acmd*) gAudioCmd, &writtenCmds, currAiBuffer, gAiBufferLengths[index]);
gAudioRandom = osGetCount() * (gAudioRandom + gAudioFrameCount);
@@ -266,26 +300,26 @@ void func_800CBBE8(u32 arg0, s8 arg1) {
}
//! @todo clenanup, something's weird with the variables. D_800EA4A4 is probably EuAudioCmd bc of the + 0x100
#if 1
void func_800CBC24(void) {
s32 temp_t6;
s32 test;
OSMesg thing;
temp_t6 = D_800EA3A0[0] - D_800EA3A4[0];
test = (u8) temp_t6;
test = (test + 0x100) & 0xFF;
do {
} while (0);
if (D_800EA4A4 < test) {
D_800EA4A4 = test;
}
OSMesg audioMesg;
audioMesg.ptr = ((D_800EA3A0[0] & 0xFF) | ((D_800EA3A4[0] & 0xFF) << 8));
thing = audioMesg;
osSendMesg(D_800EA3AC, thing, 0);
osSendMesg(D_800EA3AC, OS_MESG_32(((D_800EA3A0[0] & 0xFF) | ((D_800EA3A4[0] & 0xFF) << 8))), 0);
D_800EA3A4[0] = D_800EA3A0[0];
}
#else
void func_800CBC24(void) {
osSendMesg(D_800EA3AC, OS_MESG_32(((D_800EA3A0[0] & 0xff) << 8 | (D_800EA3A4[0] & 0xff))), OS_MESG_NOBLOCK);
D_800EA3A4[0] = D_800EA3A0[0];
}
#endif
void func_800CBCB0(u32 arg0) {
struct EuAudioCmd* cmd;
+24 -17
View File
@@ -9,6 +9,7 @@
#include "audio/effects.h"
#include "audio/playback.h"
#include "audio/external.h"
#include "port/Engine.h"
/**
* Given that (almost) all of these are format strings, it is highly likely
@@ -248,11 +249,11 @@ void sequence_player_disable(struct SequencePlayer* seqPlayer) {
seqPlayer->enabled = false;
if (IS_SEQ_LOAD_COMPLETE(seqPlayer->seqId) && gSeqLoadStatus[seqPlayer->seqId] != 5) {
gSeqLoadStatus[seqPlayer->seqId] = SOUND_LOAD_STATUS_DISCARDABLE;
GameEngine_UnloadSequence(seqPlayer->seqId);
}
if (IS_BANK_LOAD_COMPLETE(seqPlayer->defaultBank[0]) && gBankLoadStatus[seqPlayer->defaultBank[0]] != 5) {
gBankLoadStatus[seqPlayer->defaultBank[0]] = 4;
GameEngine_UnloadBank(seqPlayer->defaultBank[0]);
}
// (Note that if this is called from alloc_bank_or_seq, the side will get swapped
@@ -732,11 +733,14 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer* layer) {
if (seqChannel) {}
}
u8 get_instrument(struct SequenceChannel* seqChannel, u8 instId, struct Instrument** instOut,
struct AdsrSettings* adsr) {
struct Instrument* inst;
inst = get_instrument_inner(seqChannel->bankId, instId);
if (inst == NULL) {
u8 get_instrument(struct SequenceChannel *seqChannel, u8 instId, struct Instrument **instOut, struct AdsrSettings *adsr) {
struct CtlEntry *bank = GameEngine_LoadBank(seqChannel->bankId);
if(instId >= bank->numInstruments) {
*instOut = NULL;
return 0;
}
struct Instrument* inst = bank->instruments[instId];
if(inst == NULL) {
*instOut = NULL;
return 0;
}
@@ -905,14 +909,14 @@ void sequence_channel_process_script(struct SequenceChannel* seqChannel) {
}
break;
case 0xEB:
case 0xEB: {
cmd = m64_read_u8(state);
sp38 = ((u16*) gAlBankSets)[seqPlayer->seqId];
loBits = *(sp38 + gAlBankSets);
cmd = gAlBankSets[(((s32) sp38) + loBits) - cmd];
if (get_bank_or_seq(1, 2, cmd) != NULL) {
struct AudioSequenceData *sequence = GameEngine_LoadSequence(seqPlayer->seqId);
cmd = sequence->banks[cmd];
if(IS_BANK_LOAD_COMPLETE(cmd)) {
seqChannel->bankId = cmd;
}
}
case 0xC1:
set_instrument(seqChannel, m64_read_u8(state));
@@ -1003,15 +1007,15 @@ void sequence_channel_process_script(struct SequenceChannel* seqChannel) {
seqChannel->reverbVol = m64_read_u8(state);
break;
case 0xC6:
case 0xC6: {
cmd = m64_read_u8(state);
sp5A = ((u16*) gAlBankSets)[seqPlayer->seqId];
loBits = *(sp5A + gAlBankSets);
cmd = gAlBankSets[(sp5A + loBits) - cmd];
if (get_bank_or_seq(1, 2, cmd) != NULL) {
struct AudioSequenceData *sequence = GameEngine_LoadSequence(seqPlayer->seqId);
cmd = sequence->banks[cmd];
if(IS_BANK_LOAD_COMPLETE(cmd)) {
seqChannel->bankId = cmd;
}
break;
}
case 0xC7:
cmd = m64_read_u8(state);
@@ -1210,6 +1214,9 @@ void sequence_player_process_sequence(struct SequencePlayer* seqPlayer) {
if (seqPlayer->enabled == false) {
return;
}
GameEngine_LoadSequence(seqPlayer->seqId);
GameEngine_LoadBank(seqPlayer->defaultBank[0]);
if (seqPlayer->bankDmaInProgress == true) {
if (osRecvMesg(&seqPlayer->bankDmaMesgQueue, NULL, 0) == -1) {
+6 -8
View File
@@ -7,7 +7,7 @@
#include "audio/load.h"
#include "audio/seqplayer.h"
#include "audio/internal.h"
// #include "audio/external.h"
#include "port/Engine.h"
#include <libultra/abi.h>
#define aSetLoadBufferPair(pkt, c, off) \
@@ -161,8 +161,7 @@ Acmd* synthesis_execute(Acmd* acmd, s32* writtenCmds, s16* aiBuf, s32 bufLen) {
process_sequences(i - 1);
synthesis_load_note_subs_eu(gAudioBufferParameters.updatesPerFrame - i);
}
// UTODO: Stubbed
// aSegment(cmd++, 0, 0);
aSegment(cmd++, 0, 0);
aiBufPtr = (u32*) aiBuf;
for (i = gAudioBufferParameters.updatesPerFrame; i > 0; i--) {
if (i == 1) {
@@ -325,7 +324,7 @@ Acmd* synthesis_do_one_audio_update(s16* aiBuf, s32 bufLen, Acmd* acmd, s32 upda
temp = bufLen * 2;
aSetBuffer(acmd++, 0, 0, DMEM_ADDR_TEMP, temp);
// UTODO: Stubbed
// aInterleave(acmd++, DMEM_ADDR_LEFT_CH, DMEM_ADDR_RIGHT_CH);
aInterleave(acmd++, 0, DMEM_ADDR_LEFT_CH, DMEM_ADDR_RIGHT_CH, 0);
aSaveBuffer(acmd++, DMEM_ADDR_TEMP, VIRTUAL_TO_PHYSICAL2(aiBuf), temp * 2);
return acmd;
}
@@ -344,7 +343,7 @@ Acmd* synthesis_process_note(s32 noteIndex, struct NoteSubEu* noteSubEu, struct
u16 resamplingRateFixedPoint;
s32 nSamplesToLoad;
s32 spFC;
s32 spFC = 0;
UNUSED s32 pad2[2];
s32 loopInfo_2;
@@ -613,8 +612,7 @@ Acmd* load_wave_samples(Acmd* acmd, struct NoteSubEu* noteSubEu, struct NoteSynt
s32 nSamplesToLoad) {
s32 a3;
s32 repeats;
// UTODO: Stubbed
// aLoadBuffer(acmd++, VIRTUAL_TO_PHYSICAL2(noteSubEu->sound.samples), 0x1A0, 128);
aLoadBuffer(acmd++, VIRTUAL_TO_PHYSICAL2(noteSubEu->sound.samples), 0x1A0, 128);
synthesisState->samplePosInt &= 0x3f;
a3 = 64 - synthesisState->samplePosInt;
@@ -622,7 +620,7 @@ Acmd* load_wave_samples(Acmd* acmd, struct NoteSubEu* noteSubEu, struct NoteSynt
repeats = (nSamplesToLoad - a3 + 63) / 64;
if (repeats != 0) {
// UTODO: Stubbed
// aDMEMMove2(acmd++, repeats, 0x1A0, 0x1A0 + 128, 128);
aDMEMMove2(acmd++, repeats, 0x1A0, 0x1A0 + 128, 128);
}
}
return acmd;
+1
View File
@@ -20,6 +20,7 @@
#define DMEM_ADDR_WET_LEFT_CH 0x840
#define DMEM_ADDR_WET_RIGHT_CH 0x9C0
/*
Its not clear what values these macros should have. Neither version seem to
line up for MK64. Maybe each game has unique values for these? I don't know
+2
View File
@@ -6,6 +6,7 @@
#include "objects.h"
#include "path_spawn_metadata.h"
#include "waypoints.h"
#include "sounds.h"
typedef struct {
RGB8 TopRight;
@@ -44,6 +45,7 @@ typedef struct {
s32 MinimapFinishlineX;
s32 MinimapFinishlineY;
SkyboxColours Skybox;
enum MusicSeq Sequence;
} CProperties;
#endif // __ENGINE_H__
+1
View File
@@ -67,6 +67,7 @@ class World {
int32_t MinimapFinishlineX;
int32_t MinimapFinishlineY;
SkyboxColours Skybox;
MusicSeq Sequence;
} Properties;
typedef struct {
+1
View File
@@ -101,6 +101,7 @@ BansheeBoardwalk::BansheeBoardwalk() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {0, 0, 0};
Props.Sequence = MusicSeq::MUSIC_SEQ_BANSHEE_BOARDWALK;
}
void BansheeBoardwalk::Load() {
+1
View File
@@ -96,6 +96,7 @@ BigDonut::BigDonut() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {0, 0, 0};
Props.Sequence = MusicSeq::MUSIC_SEQ_BATTLE_ARENAS;
}
void BigDonut::Load() {
+1
View File
@@ -99,6 +99,7 @@ BlockFort::BlockFort() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {216, 232, 248};
Props.Sequence = MusicSeq::MUSIC_SEQ_CHOCO_MOUNTAIN;
}
void BlockFort::Load() {
+1
View File
@@ -101,6 +101,7 @@ BowsersCastle::BowsersCastle() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {0, 0, 0};
Props.Sequence = MusicSeq::MUSIC_SEQ_BOWSERS_CASTLE;
}
void BowsersCastle::Load() {
+1
View File
@@ -101,6 +101,7 @@ ChocoMountain::ChocoMountain() {
Props.Skybox.FloorBottomRight = {255, 255, 255};
Props.Skybox.FloorBottomLeft = {255, 255, 255};
Props.Skybox.FloorTopLeft = {255, 255, 255};
Props.Sequence = MusicSeq::MUSIC_SEQ_CHOCO_MOUNTAIN;
}
void ChocoMountain::Load() {
+1
View File
@@ -73,6 +73,7 @@ Course::Course() {
Props.CloudList = NULL;
Props.MinimapFinishlineX = 0;
Props.MinimapFinishlineY = 0;
Props.Sequence = MusicSeq::MUSIC_SEQ_UNKNOWN;
}
void Course::Load(Vtx* vtx, Gfx* gfx) {
+1
View File
@@ -75,6 +75,7 @@ public:
int32_t MinimapFinishlineX;
int32_t MinimapFinishlineY;
SkyboxColours Skybox;
MusicSeq Sequence;
} Properties;
Properties Props;
+1
View File
@@ -104,6 +104,7 @@ DKJungle::DKJungle() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {22, 145, 22};
Props.Sequence = MusicSeq::MUSIC_SEQ_DK_JUNGLE;
}
void DKJungle::Load() {
+1
View File
@@ -99,6 +99,7 @@ DoubleDeck::DoubleDeck() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {255, 224, 240};
Props.Sequence = MusicSeq::MUSIC_SEQ_CHOCO_MOUNTAIN;
}
void DoubleDeck::Load() {
+1
View File
@@ -102,6 +102,7 @@ FrappeSnowland::FrappeSnowland() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {0, 99, 164};
Props.Sequence = MusicSeq::MUSIC_SEQ_FRAPPE_SNOWLAND;
}
void FrappeSnowland::Load() {
+1
View File
@@ -102,6 +102,7 @@ KalimariDesert::KalimariDesert() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {255, 192, 0};
Props.Sequence = MusicSeq::MUSIC_SEQ_KALIMARI_DESERT;
}
void KalimariDesert::Load() {
+1
View File
@@ -102,6 +102,7 @@ KoopaTroopaBeach::KoopaTroopaBeach() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {48, 152, 120};
Props.Sequence = MusicSeq::MUSIC_SEQ_KOOPA_TROOPA_BEACH;
}
void KoopaTroopaBeach::Load() {
+1
View File
@@ -105,6 +105,7 @@ LuigiRaceway::LuigiRaceway() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {216, 232, 248};
Props.Sequence = MusicSeq::MUSIC_SEQ_RACEWAYS_WARIO_STADIUM;
}
void LuigiRaceway::Load() {
+1
View File
@@ -102,6 +102,7 @@ MarioRaceway::MarioRaceway() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {0, 0, 0};
Props.Sequence = MusicSeq::MUSIC_SEQ_RACEWAYS_WARIO_STADIUM;
}
void MarioRaceway::Load() {
+1
View File
@@ -102,6 +102,7 @@ MooMooFarm::MooMooFarm() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {255, 184, 99};
Props.Sequence = MusicSeq::MUSIC_SEQ_MOO_MOO_FARM_YOSHI_VALLEY;
}
void MooMooFarm::Load() {
+1
View File
@@ -96,6 +96,7 @@ PodiumCeremony::PodiumCeremony() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {255, 224, 240};
Props.Sequence = MusicSeq::MUSIC_SEQ_UNKNOWN;
}
void PodiumCeremony::Load() {
+1
View File
@@ -99,6 +99,7 @@ RainbowRoad::RainbowRoad() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {0, 0, 0};
Props.Sequence = MusicSeq::MUSIC_SEQ_RAINBOW_ROAD;
}
void RainbowRoad::Load() {
+1
View File
@@ -100,6 +100,7 @@ RoyalRaceway::RoyalRaceway() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {255, 224, 240};
Props.Sequence = MusicSeq::MUSIC_SEQ_RACEWAYS_WARIO_STADIUM;
}
void RoyalRaceway::Load() {
+1
View File
@@ -100,6 +100,7 @@ SherbetLand::SherbetLand() {
Props.Skybox.FloorBottomRight = {128, 184, 248};
Props.Skybox.FloorBottomLeft = {128, 184, 248};
Props.Skybox.FloorTopLeft = {216, 232, 248};
Props.Sequence = MusicSeq::MUSIC_SEQ_FRAPPE_SNOWLAND;
}
void SherbetLand::Load() {
+1
View File
@@ -99,6 +99,7 @@ Skyscraper::Skyscraper() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {0, 0, 0};
Props.Sequence = MusicSeq::MUSIC_SEQ_BATTLE_ARENAS;
}
void Skyscraper::Load() {
+1
View File
@@ -112,6 +112,7 @@ TestCourse::TestCourse() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {0, 0, 0};
Props.Sequence = MusicSeq::MUSIC_SEQ_RACEWAYS_WARIO_STADIUM;
}
void TestCourse::Load() {
+1
View File
@@ -104,6 +104,7 @@ ToadsTurnpike::ToadsTurnpike() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {209, 65, 23};
Props.Sequence = MusicSeq::MUSIC_SEQ_TOADS_TURNPIKE;
}
void ToadsTurnpike::Load() {
+1
View File
@@ -103,6 +103,7 @@ WarioStadium::WarioStadium() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {0, 0, 0};
Props.Sequence = MusicSeq::MUSIC_SEQ_RACEWAYS_WARIO_STADIUM;
}
void WarioStadium::Load() {
+1
View File
@@ -100,6 +100,7 @@ YoshiValley::YoshiValley() {
Props.Skybox.FloorBottomRight = {0, 0, 0};
Props.Skybox.FloorBottomLeft = {0, 0, 0};
Props.Skybox.FloorTopLeft = {95, 40, 15};
Props.Sequence = MusicSeq::MUSIC_SEQ_MOO_MOO_FARM_YOSHI_VALLEY;
}
void YoshiValley::Load() {
+1 -1
View File
@@ -1239,7 +1239,7 @@ void thread5_game_loop(void) {
}
void thread5_iteration(void) {
// func_800CB2C4();
func_800CB2C4();
calculate_delta_time();
#ifdef TARGET_N64
while (true) {
+6 -6
View File
@@ -60,7 +60,7 @@ s8 D_8018EE0C;
struct_8018EE10_entry D_8018EE10[2];
/** Data **/
s32 gMenuSelection = START_MENU;
s32 gMenuSelection = LOGO_INTRO_MENU;
s32 D_800E86A4 = 0;
s8 gCharacterSelections[4] = { MARIO, LUIGI, YOSHI, TOAD };
@@ -1851,7 +1851,7 @@ void func_800B3F74(s32 menuSelection) {
}
D_8018EDF1 = D_800F2BE0[gPlayerCount - 1];
func_800CA008(0, 0);
func_800C8EAC(1);
play_sequence(MUSIC_SEQ_TITLE_SCREEN);
D_8018EDFC = 0;
break;
}
@@ -1868,13 +1868,13 @@ void func_800B3F74(s32 menuSelection) {
func_800CB2C4();
gGamestate = 0;
gGamestateNext = 0;
func_800C8EAC(2);
play_sequence(MUSIC_SEQ_MAIN_MENU);
}
switch (D_8018EDE0) {
case 0: {
gMainMenuSelectionDepth = PLAYER_NUM_SELECTION;
func_800C8EAC(2);
play_sequence(MUSIC_SEQ_MAIN_MENU);
gPlayerCount = 1;
if (gScreenModeSelection >= NUM_SCREEN_MODES || gScreenModeSelection < 0) {
gScreenModeSelection = SCREEN_MODE_1P;
@@ -1926,7 +1926,7 @@ void func_800B3F74(s32 menuSelection) {
func_800CB2C4();
gGamestate = 0;
gGamestateNext = 0;
func_800C8EAC(2);
play_sequence(MUSIC_SEQ_MAIN_MENU);
for (i = 0; i < ARRAY_COUNT(D_8018EDE8); i++) {
D_8018EDE8[i] = false;
}
@@ -1966,7 +1966,7 @@ void func_800B3F74(s32 menuSelection) {
func_800CB2C4();
gGamestate = 0;
gGamestateNext = 0;
func_800C8EAC(2);
play_sequence(MUSIC_SEQ_MAIN_MENU);
}
play_sound2(SOUND_MENU_SELECT_MAP);
D_8018EE0A = 0;
+193 -18
View File
@@ -5,6 +5,9 @@
#include "libultraship/src/Context.h"
#include "resource/type/ResourceType.h"
#include "resource/importers/GenericArrayFactory.h"
#include "resource/importers/AudioBankFactory.h"
#include "resource/importers/AudioSampleFactory.h"
#include "resource/importers/AudioSequenceFactory.h"
#include "resource/importers/Vec3fFactory.h"
#include "resource/importers/Vec3sFactory.h"
#include "resource/importers/KartAIFactory.h"
@@ -31,6 +34,8 @@ float gInterpolationStep = 0.0f;
#include <BlobFactory.h>
#include <VertexFactory.h>
#include <LightFactory.h>
#include "audio/internal.h"
#include "audio/GameAudio.h"
}
GameEngine* GameEngine::Instance;
@@ -57,7 +62,7 @@ GameEngine::GameEngine() {
}
}
this->context = Ship::Context::CreateInstance("Spaghettify", "skart64", "spaghettify.cfg.json", OTRFiles, {}, 3);
this->context = Ship::Context::CreateInstance("Spaghettify", "skart64", "spaghettify.cfg.json", OTRFiles, {}, 3, { 26800, 512, 1100 });
auto wnd = std::dynamic_pointer_cast<Fast::Fast3dWindow>(Ship::Context::GetInstance()->GetWindow());
@@ -65,21 +70,33 @@ GameEngine::GameEngine() {
this->context->InitGfxDebugger();
auto loader = context->GetResourceManager()->GetResourceLoader();
loader->RegisterResourceFactory(std::make_shared<SM64::AudioBankFactoryV0>(), RESOURCE_FORMAT_BINARY,
"AudioBank", static_cast<uint32_t>(SF64::ResourceType::Bank), 0);
loader->RegisterResourceFactory(std::make_shared<SM64::AudioSampleFactoryV0>(), RESOURCE_FORMAT_BINARY,
"AudioSample", static_cast<uint32_t>(SF64::ResourceType::Sample), 0);
loader->RegisterResourceFactory(std::make_shared<SM64::AudioSequenceFactoryV0>(), RESOURCE_FORMAT_BINARY,
"AudioSequence", static_cast<uint32_t>(SF64::ResourceType::Sequence), 0);
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryVec3fV0>(), RESOURCE_FORMAT_BINARY,
"Vec3f", static_cast<uint32_t>(SF64::ResourceType::Vec3f), 0);
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryVec3sV0>(), RESOURCE_FORMAT_BINARY,
"Vec3s", static_cast<uint32_t>(SF64::ResourceType::Vec3s), 0);
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryGenericArrayV0>(),
RESOURCE_FORMAT_BINARY, "GenericArray",
static_cast<uint32_t>(SF64::ResourceType::GenericArray), 0);
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryGenericArrayV0>(), RESOURCE_FORMAT_BINARY,
"GenericArray", static_cast<uint32_t>(SF64::ResourceType::GenericArray), 0);
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryTextureV0>(), RESOURCE_FORMAT_BINARY,
"Texture", static_cast<uint32_t>(LUS::ResourceType::Texture), 0);
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryTextureV1>(), RESOURCE_FORMAT_BINARY,
"Texture", static_cast<uint32_t>(LUS::ResourceType::Texture), 1);
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryVertexV0>(), RESOURCE_FORMAT_BINARY,
"Vertex", static_cast<uint32_t>(LUS::ResourceType::Vertex), 0);
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryXMLVertexV0>(), RESOURCE_FORMAT_XML,
"Vertex", static_cast<uint32_t>(LUS::ResourceType::Vertex), 0);
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryDisplayListV0>(), RESOURCE_FORMAT_BINARY,
"DisplayList", static_cast<uint32_t>(LUS::ResourceType::DisplayList), 0);
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryXMLDisplayListV0>(), RESOURCE_FORMAT_XML,
"DisplayList", static_cast<uint32_t>(LUS::ResourceType::DisplayList), 0);
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryMatrixV0>(), RESOURCE_FORMAT_BINARY,
"Matrix", static_cast<uint32_t>(LUS::ResourceType::Matrix), 0);
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryBlobV0>(), RESOURCE_FORMAT_BINARY,
@@ -92,29 +109,27 @@ GameEngine::GameEngine() {
"KartAI", static_cast<uint32_t>(MK64::ResourceType::KartAI), 0);
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryCourseVtxV0>(), RESOURCE_FORMAT_BINARY,
"CourseVtx", static_cast<uint32_t>(MK64::ResourceType::CourseVertex), 0);
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryTrackSectionsV0>(),
RESOURCE_FORMAT_BINARY, "TrackSections",
static_cast<uint32_t>(MK64::ResourceType::TrackSection), 0);
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryTrackWaypointsV0>(),
RESOURCE_FORMAT_BINARY, "Waypoints",
static_cast<uint32_t>(MK64::ResourceType::Waypoints), 0);
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryActorSpawnDataV0>(),
RESOURCE_FORMAT_BINARY, "SpawnData",
static_cast<uint32_t>(MK64::ResourceType::SpawnData), 0);
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryUnkActorSpawnDataV0>(),
RESOURCE_FORMAT_BINARY, "UnkSpawnData",
static_cast<uint32_t>(MK64::ResourceType::UnkSpawnData), 0);
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryTrackSectionsV0>(), RESOURCE_FORMAT_BINARY,
"TrackSections", static_cast<uint32_t>(MK64::ResourceType::TrackSection), 0);
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryTrackWaypointsV0>(), RESOURCE_FORMAT_BINARY,
"Waypoints", static_cast<uint32_t>(MK64::ResourceType::Waypoints), 0);
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryActorSpawnDataV0>(), RESOURCE_FORMAT_BINARY,
"SpawnData", static_cast<uint32_t>(MK64::ResourceType::SpawnData), 0);
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryUnkActorSpawnDataV0>(), RESOURCE_FORMAT_BINARY,
"UnkSpawnData", static_cast<uint32_t>(MK64::ResourceType::UnkSpawnData), 0);
}
void GameEngine::Create() {
const auto instance = Instance = new GameEngine();
instance->AudioInit();
GameUI::SetupGuiElements();
#if defined(__SWITCH__) || defined(__WIIU__)
CVarRegisterInteger("gControlNav", 1); // always enable controller nav on switch/wii u
#endif
}
void GameEngine::Destroy() {
void GameEngine::Destroy(){
AudioExit();
}
bool ShouldClearTextureCacheAtEndOfFrame = false;
@@ -161,6 +176,106 @@ void GameEngine::ProcessGfxCommands(Gfx* commands) {
}
}
// Audio
void GameEngine::HandleAudioThread(){
while (audio.running) {
{
std::unique_lock<std::mutex> Lock(audio.mutex);
while (!audio.processing && audio.running) {
audio.cv_to_thread.wait(Lock);
}
if (!audio.running) {
break;
}
}
std::unique_lock<std::mutex> Lock(audio.mutex);
int samples_left = AudioPlayerBuffered();
u32 num_audio_samples = samples_left < AudioPlayerGetDesiredBuffered() ? SAMPLES_HIGH : SAMPLES_LOW;
s16 audio_buffer[SAMPLES_PER_FRAME];
for (int i = 0; i < NUM_AUDIO_CHANNELS; i++) {
create_next_audio_buffer(audio_buffer + i * (num_audio_samples * 2), num_audio_samples);
}
AudioPlayerPlayFrame((u8 *) audio_buffer, 2 * num_audio_samples * 4);
audio.processing = false;
audio.cv_from_thread.notify_one();
}
}
void GameEngine::StartAudioFrame(){
{
std::unique_lock<std::mutex> Lock(audio.mutex);
audio.processing = true;
}
audio.cv_to_thread.notify_one();
}
void GameEngine::EndAudioFrame(){
{
std::unique_lock<std::mutex> Lock(audio.mutex);
while (audio.processing) {
audio.cv_from_thread.wait(Lock);
}
}
}
void GameEngine::AudioInit() {
const auto resourceMgr = Ship::Context::GetInstance()->GetResourceManager();
resourceMgr->LoadDirectory("sound");
const auto banksFiles = resourceMgr->GetArchiveManager()->ListFiles("sound/banks/*");
const auto sequences_files = resourceMgr->GetArchiveManager()->ListFiles("sound/sequences/*");
Instance->sequenceTable.resize(512);
Instance->audioSequenceTable.resize(512);
Instance->banksTable.resize(512);
for(auto& bank : *banksFiles){
auto path = "__OTR__" + bank;
const auto ctl = static_cast<CtlEntry *>(ResourceGetDataByName(path.c_str()));
this->bankMapTable[bank] = ctl->bankId;
SPDLOG_INFO("Loaded bank: {}", bank);
}
for(auto& sequence : *sequences_files){
auto path = "__OTR__" + sequence;
auto seq = static_cast<AudioSequenceData *>(ResourceGetDataByName(path.c_str()));
Instance->sequenceTable[seq->id] = path;
SPDLOG_INFO("Loaded sequence: {}", sequence);
}
if (!audio.running) {
audio.running = true;
audio.thread = std::thread(HandleAudioThread);
SPDLOG_INFO("Audio thread started");
}
}
void GameEngine::AudioExit() {
{
std::unique_lock lock(audio.mutex);
audio.running = false;
}
audio.cv_to_thread.notify_all();
// Wait until the audio thread quit
audio.thread.join();
}
uint8_t GameEngine::GetBankIdByName(const std::string& name) {
if(Instance->bankMapTable.contains(name)){
return Instance->bankMapTable[name];
}
return 0;
}
// End
extern "C" uint32_t GameEngine_GetSampleRate() {
auto player = Ship::Context::GetInstance()->GetAudio()->GetAudioPlayer();
if (player == nullptr) {
@@ -178,7 +293,67 @@ extern "C" uint32_t GameEngine_GetSamplesPerFrame() {
return SAMPLES_PER_FRAME;
}
// End
extern "C" CtlEntry* GameEngine_LoadBank(const uint8_t bankId) {
const auto engine = GameEngine::Instance;
if(bankId >= engine->bankMapTable.size()){
return nullptr;
}
if(engine->banksTable[bankId] != nullptr){
return engine->banksTable[bankId];
}
for(auto& bank : engine->bankMapTable){
if(bank.second == bankId){
const auto ctl = static_cast<CtlEntry *>(ResourceGetDataByName(("__OTR__" + bank.first).c_str()));
engine->banksTable[bankId] = ctl;
return ctl;
}
}
return nullptr;
}
extern "C" uint8_t GameEngine_IsBankLoaded(const uint8_t bankId) {
const auto engine = GameEngine::Instance;
GameEngine_LoadBank(bankId);
return engine->banksTable[bankId] != nullptr;
}
extern "C" void GameEngine_UnloadBank(const uint8_t bankId) {
const auto engine = GameEngine::Instance;
engine->banksTable[bankId] = nullptr;
}
extern "C" AudioSequenceData* GameEngine_LoadSequence(const uint8_t seqId) {
auto engine = GameEngine::Instance;
if(engine->sequenceTable[seqId].empty()){
return nullptr;
}
if(engine->audioSequenceTable[seqId] != nullptr){
return engine->audioSequenceTable[seqId];
}
auto sequences = static_cast<AudioSequenceData *>(ResourceGetDataByName(engine->sequenceTable[seqId].c_str()));
engine->audioSequenceTable[seqId] = sequences;
return sequences;
}
extern "C" uint32_t GameEngine_GetSequenceCount(){
auto engine = GameEngine::Instance;
return engine->sequenceTable.size();
}
extern "C" uint8_t GameEngine_IsSequenceLoaded(const uint8_t seqId) {
return GameEngine_LoadSequence(seqId) != nullptr;
}
extern "C" void GameEngine_UnloadSequence(const uint8_t seqId) {
const auto engine = GameEngine::Instance;
engine->audioSequenceTable[seqId] = nullptr;
}
extern "C" float GameEngine_GetAspectRatio() {
return gfx_current_dimensions.aspect_ratio;
+27 -2
View File
@@ -10,25 +10,41 @@
#include <Fast3D/gfx_pc.h>
#include "libultraship/src/Context.h"
#define SAMPLES_HIGH 544
#define SAMPLES_LOW 528
#define SAMPLES_HIGH 448
#define SAMPLES_LOW 432
#define AUDIO_FRAMES_PER_UPDATE 2
#define NUM_AUDIO_CHANNELS 2
#define SAMPLES_PER_FRAME (SAMPLES_HIGH * NUM_AUDIO_CHANNELS * 2)
struct CtlEntry;
struct AudioBankSample;
struct AudioSequenceData;
class GameEngine {
public:
static GameEngine* Instance;
std::shared_ptr<Ship::Context> context;
std::vector<CtlEntry*> banksTable;
std::vector<std::string> sequenceTable;
std::vector<AudioSequenceData*> audioSequenceTable;
std::unordered_map<std::string, uint8_t> bankMapTable;
GameEngine();
static void Create();
void AudioInit();
static void HandleAudioThread();
static void StartAudioFrame();
static void EndAudioFrame();
static void AudioExit();
void StartFrame() const;
static void RunCommands(Gfx* Commands);
void ProcessFrame(void (*run_one_game_iter)()) const;
static void Destroy();
static void ProcessGfxCommands(Gfx* commands);
static uint8_t GetBankIdByName(const std::string& name);
float OTRGetAspectRatio(void);
float OTRGetDimensionFromLeftEdge(float v);
float OTRGetDimensionFromRightEdge(float v);
@@ -39,7 +55,16 @@ class GameEngine {
};
#else
void GameEngine_ProcessGfxCommands(Gfx* commands);
uint32_t GameEngine_GetSampleRate();
uint32_t GameEngine_GetSamplesPerFrame();
float GameEngine_GetAspectRatio();
struct CtlEntry* GameEngine_LoadBank(uint8_t bankId);
uint8_t GameEngine_IsBankLoaded(uint8_t bankId);
void GameEngine_UnloadBank(uint8_t bankId);
struct AudioSequenceData* GameEngine_LoadSequence(uint8_t seqId);
uint32_t GameEngine_GetSequenceCount();
uint8_t GameEngine_IsSequenceLoaded(uint8_t seqId);
void GameEngine_UnloadSequence(uint8_t seqId);
uint8_t GameEngine_OTRSigCheck(char* imgData);
float OTRGetAspectRatio(void);
float OTRGetDimensionFromLeftEdge(float v);
+8 -9
View File
@@ -701,13 +701,13 @@ extern "C" {
}
void push_frame() {
// GameEngine::StartAudioFrame();
GameEngine::Instance->StartFrame();
thread5_iteration();
GameEngine::StartAudioFrame();
GameEngine::Instance->StartFrame();
thread5_iteration();
GameEngine::EndAudioFrame();
// thread5_game_loop();
// Graphics_ThreadUpdate();w
// Timer_Update();
// GameEngine::EndAudioFrame();
}
#ifdef _WIN32
@@ -716,13 +716,12 @@ int SDL_main(int argc, char** argv) {
#if defined(__cplusplus) && defined(PLATFORM_IOS)
extern "C"
#endif
int
main(int argc, char* argv[]) {
int main(int argc, char* argv[]) {
#endif
//load_wasm();
//load_wasm();
GameEngine::Create();
// audio_init();
// sound_init();
audio_init();
sound_init();
CustomEngineInit();
thread5_game_loop();
@@ -0,0 +1,96 @@
#include "AudioBankFactory.h"
#include "../type/AudioBank.h"
#include "spdlog/spdlog.h"
#include "resourcebridge.h"
#include "ResourceUtil.h"
std::shared_ptr<Ship::IResource> SM64::AudioBankFactoryV0::ReadResource(std::shared_ptr<Ship::File> file) {
if (!FileHasValidFormatAndReader(file)) {
return nullptr;
}
std::shared_ptr<AudioBank> bank = std::make_shared<AudioBank>(file->InitData);
auto reader = std::get<std::shared_ptr<Ship::BinaryReader>>(file->Reader);
uint8_t bankId = reader->ReadUInt32();
uint32_t instrumentCount = reader->ReadUInt32();
for(size_t i = 0; i < instrumentCount; i++){
auto* instrument = new Instrument();
bool valid = reader->ReadUByte();
if(!valid){
bank->instruments.push_back(nullptr);
continue;
}
instrument->loaded = 1;
instrument->releaseRate = reader->ReadUByte();
instrument->normalRangeLo = reader->ReadUByte();
instrument->normalRangeHi = reader->ReadUByte();
uint32_t envelopeSize = reader->ReadUInt32();
if(envelopeSize != 0){
instrument->envelope = new AdsrEnvelope[envelopeSize];
for(size_t j = 0; j < envelopeSize; j++){
instrument->envelope[j].delay = BSWAP16(reader->ReadInt16());
instrument->envelope[j].arg = BSWAP16(reader->ReadInt16());
}
}
uint32_t soundFlags = reader->ReadUInt32();
bool hasLo = soundFlags & (1 << 0);
bool hasMed = soundFlags & (1 << 1);
bool hasHi = soundFlags & (1 << 2);
if(hasLo){
std::string lowSampleName = reader->ReadString();
instrument->lowNotesSound.sample = LoadChild<AudioBankSample*>(lowSampleName.c_str());
instrument->lowNotesSound.tuning = reader->ReadFloat();
}
if(hasMed){
std::string normalSampleName = reader->ReadString();
instrument->normalNotesSound.sample = LoadChild<AudioBankSample*>(normalSampleName.c_str());
instrument->normalNotesSound.tuning = reader->ReadFloat();
}
if(hasHi){
std::string highSampleName = reader->ReadString();
instrument->highNotesSound.sample = LoadChild<AudioBankSample*>(highSampleName.c_str());
instrument->highNotesSound.tuning = reader->ReadFloat();
}
bank->instruments.push_back(instrument);
}
uint32_t drumCount = reader->ReadUInt32();
for(size_t i = 0; i < drumCount; i++){
auto* drum = new Drum();
drum->releaseRate = reader->ReadUByte();
drum->pan = reader->ReadUByte();
drum->loaded = 1;
uint32_t envelopeSize = reader->ReadUInt32();
if(envelopeSize != 0){
drum->envelope = new AdsrEnvelope[envelopeSize];
for(size_t j = 0; j < envelopeSize; j++){
drum->envelope[j].delay = BSWAP16(reader->ReadInt16());
drum->envelope[j].arg = BSWAP16(reader->ReadInt16());
}
}
std::string sampleName = reader->ReadString();
drum->sound.sample = LoadChild<AudioBankSample*>(sampleName.c_str());
drum->sound.tuning = reader->ReadFloat();
bank->drums.push_back(drum);
}
bank->mData.bankId = bankId;
bank->mData.numInstruments = instrumentCount;
bank->mData.numDrums = drumCount;
bank->mData.instruments = bank->instruments.data();
bank->mData.drums = bank->drums.data();
return bank;
}
@@ -0,0 +1,11 @@
#pragma once
#include "Resource.h"
#include "ResourceFactoryBinary.h"
namespace SM64 {
class AudioBankFactoryV0 : public Ship::ResourceFactoryBinary {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override;
};
}
@@ -0,0 +1,47 @@
#include "AudioSampleFactory.h"
#include <iostream>
#include "../type/AudioSample.h"
#include "spdlog/spdlog.h"
std::shared_ptr<Ship::IResource> SM64::AudioSampleFactoryV0::ReadResource(std::shared_ptr<Ship::File> file) {
if (!FileHasValidFormatAndReader(file)) {
return nullptr;
}
std::shared_ptr<AudioSample> bank = std::make_shared<AudioSample>(file->InitData);
auto reader = std::get<std::shared_ptr<Ship::BinaryReader>>(file->Reader);
bank->loop.start = reader->ReadUInt32();
bank->loop.end = reader->ReadUInt32();
bank->loop.count = reader->ReadInt32();
bank->loop.pad = reader->ReadInt32();
uint32_t stateSize = reader->ReadUInt32();
std::vector<int16_t> state;
if(stateSize > 0){
bank->loop.state = new int16_t[stateSize];
reader->Read((char*) bank->loop.state, stateSize * sizeof(int16_t));
} else {
bank->loop.state = nullptr;
}
bank->book.order = reader->ReadInt32();
bank->book.npredictors = reader->ReadInt32();
uint32_t tableSize = reader->ReadUInt32();
bank->book.book = new int16_t[tableSize];
reader->Read((char*) bank->book.book, tableSize * sizeof(int16_t));
int32_t sampleSize = reader->ReadInt32();
char* sampleData = new char[sampleSize];
reader->Read(sampleData, sampleSize);
bank->mData.unused = 0;
bank->mData.loaded = 1;
bank->mData.loop = &bank->loop;
bank->mData.book = &bank->book;
bank->mData.sampleAddr = (uint8_t*) sampleData;
bank->mData.sampleSize = sampleSize;
return bank;
}
@@ -0,0 +1,11 @@
#pragma once
#include "Resource.h"
#include "ResourceFactoryBinary.h"
namespace SM64 {
class AudioSampleFactoryV0 : public Ship::ResourceFactoryBinary {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override;
};
}
@@ -0,0 +1,33 @@
#include "AudioSequenceFactory.h"
#include "../type/AudioSequence.h"
#include "../type/AudioBank.h"
#include "spdlog/spdlog.h"
#include "port/Engine.h"
std::shared_ptr<Ship::IResource> SM64::AudioSequenceFactoryV0::ReadResource(std::shared_ptr<Ship::File> file) {
if (!FileHasValidFormatAndReader(file)) {
return nullptr;
}
std::shared_ptr<AudioSequence> bank = std::make_shared<AudioSequence>(file->InitData);
auto reader = std::get<std::shared_ptr<Ship::BinaryReader>>(file->Reader);
uint8_t id = reader->ReadUInt32();
size_t bankCount = reader->ReadUInt32();
for(size_t i = 0; i < bankCount; i++){
std::string bankName = reader->ReadString();
bank->banks.push_back(GameEngine::GetBankIdByName(bankName));
}
size_t sampleSize = reader->ReadUInt32();
for(size_t i = 0; i < sampleSize; i++){
bank->sampleData.push_back(reader->ReadUByte());
}
bank->mData.bankCount = bankCount;
bank->mData.banks = bank->banks.data();
bank->mData.data = bank->sampleData.data();
bank->mData.id = id;
return bank;
}
@@ -0,0 +1,12 @@
#pragma once
#include "Resource.h"
#include "ResourceFactoryBinary.h"
#include "../type/AudioSequence.h"
namespace SM64 {
class AudioSequenceFactoryV0 : public Ship::ResourceFactoryBinary {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override;
};
}
+9 -2
View File
@@ -3,7 +3,7 @@
#include "resourcebridge.h"
#include "Context.h"
namespace SF64 {
namespace SM64 {
template <typename T> T LoadChild(uint64_t crc) {
auto path = ResourceGetNameByCrc(crc);
if (path == nullptr) {
@@ -12,4 +12,11 @@ template <typename T> T LoadChild(uint64_t crc) {
auto asset = Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(path);
return asset ? static_cast<T>(asset->GetRawPointer()) : nullptr;
}
} // namespace SF64
template <typename T> T LoadChild(const char* path) {
if (path == nullptr) {
return nullptr;
}
auto asset = Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(path);
return asset ? static_cast<T>(asset->GetRawPointer()) : nullptr;
}
}
+11
View File
@@ -0,0 +1,11 @@
#include "AudioBank.h"
namespace SM64 {
CtlEntry* AudioBank::GetPointer() {
return &mData;
}
size_t AudioBank::GetPointerSize() {
return sizeof(mData);
}
}
+59
View File
@@ -0,0 +1,59 @@
#pragma once
#include <cstdint>
#include "AudioSample.h"
#include "resource/Resource.h"
struct AudioBankSound {
AudioBankSample *sample;
float tuning; // frequency scale factor
}; // size = 0x8
struct AdsrEnvelope {
int16_t delay;
int16_t arg;
}; // size = 0x4
struct Instrument {
/*0x00*/ uint8_t loaded;
/*0x01*/ uint8_t normalRangeLo;
/*0x02*/ uint8_t normalRangeHi;
/*0x03*/ uint8_t releaseRate;
/*0x04*/ AdsrEnvelope *envelope;
/*0x08*/ AudioBankSound lowNotesSound;
/*0x10*/ AudioBankSound normalNotesSound;
/*0x18*/ AudioBankSound highNotesSound;
}; // size = 0x20
struct Drum {
uint8_t releaseRate;
uint8_t pan;
uint8_t loaded;
AudioBankSound sound;
AdsrEnvelope *envelope;
};
struct CtlEntry {
uint8_t bankId;
uint8_t numInstruments;
uint8_t numDrums;
struct Instrument **instruments;
struct Drum **drums;
}; // size = 0xC
namespace SM64 {
class AudioBank : public Ship::Resource<CtlEntry> {
public:
using Resource::Resource;
AudioBank() : Resource(std::shared_ptr<Ship::ResourceInitData>()) {}
CtlEntry* GetPointer();
size_t GetPointerSize();
CtlEntry mData;
std::vector<Instrument*> instruments;
std::vector<Drum*> drums;
};
}
+11
View File
@@ -0,0 +1,11 @@
#include "AudioSample.h"
namespace SM64 {
AudioBankSample* AudioSample::GetPointer() {
return &mData;
}
size_t AudioSample::GetPointerSize() {
return sizeof(mData);
}
}
+47
View File
@@ -0,0 +1,47 @@
#pragma once
#include <cstdint>
#include "resource/Resource.h"
struct AdpcmLoop {
uint32_t start;
uint32_t end;
uint32_t count;
uint32_t pad;
int16_t* state; // only exists if count != 0. 8-byte aligned
};
struct AdpcmBook {
int32_t order;
int32_t npredictors;
int16_t* book; // size 8 * order * npredictors. 8-byte aligned
};
struct AudioBankSample {
uint8_t unused;
uint8_t loaded;
uint8_t *sampleAddr;
AdpcmLoop *loop;
AdpcmBook *book;
uint32_t sampleSize; // never read. either 0 or 1 mod 9, depending on padding
};
namespace SM64 {
class AudioSample : public Ship::Resource<AudioBankSample> {
public:
using Resource::Resource;
AudioSample() : Resource(std::shared_ptr<Ship::ResourceInitData>()) {}
AudioBankSample* GetPointer();
size_t GetPointerSize();
AudioBankSample mData;
AdpcmLoop loop;
AdpcmBook book;
std::vector<uint8_t> sampleAddr;
};
}
+11
View File
@@ -0,0 +1,11 @@
#include "AudioSequence.h"
namespace SM64 {
AudioSequenceData* AudioSequence::GetPointer() {
return &mData;
}
size_t AudioSequence::GetPointerSize() {
return sizeof(mData);
}
}
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#ifdef __cplusplus
#include <cstdint>
#endif
struct AudioSequenceData {
uint32_t bankCount;
uint8_t* banks;
uint8_t* data;
uint8_t id;
};
#ifdef __cplusplus
#include "resource/Resource.h"
namespace SM64 {
class AudioSequence : public Ship::Resource<AudioSequenceData> {
public:
using Resource::Resource;
AudioSequence() : Resource(std::shared_ptr<Ship::ResourceInitData>()) {}
AudioSequenceData* GetPointer();
size_t GetPointerSize();
AudioSequenceData mData;
std::vector<uint8_t> banks;
std::vector<uint8_t> sampleData;
};
}
#endif
+4
View File
@@ -17,6 +17,10 @@ enum class ResourceType {
Vec3f = 0x56433346, // VC3F
Vec3s = 0x56433353, // VC3S
GenericArray = 0x47415252, // GARR
// NAudio v0
Bank = 0x42414E4B, // BANK
Sample = 0x41554643, // AIFC
Sequence = 0x53455143, // SEQC
};
} // namespace SF64
+55 -55
View File
@@ -18,6 +18,7 @@
extern "C" {
extern s32 gGamestateNext;
extern s32 gMenuSelection;
#include "audio/external.h"
#include "defines.h"
}
@@ -125,61 +126,60 @@ static const char* filters[3] = {
void DrawSettingsMenu() {
if (UIWidgets::BeginMenu("Settings")) {
// if (UIWidgets::BeginMenu("Audio")) {
// UIWidgets::CVarSliderFloat("Master Volume", "gGameMasterVolume", 0.0f, 1.0f, 1.0f, {
// .format = "%.0f%%",
// .isPercentage = true,
// });
// if (UIWidgets::CVarSliderFloat("Main Music Volume", "gMainMusicVolume", 0.0f, 1.0f, 1.0f,
// {
// .format = "%.0f%%",
// .isPercentage = true,
// })) {
// audio_set_player_volume(SEQ_PLAYER_LEVEL, CVarGetFloat("gMainMusicVolume", 1.0f));
// }
// if (UIWidgets::CVarSliderFloat("Sound Effects Volume", "gSFXMusicVolume",
// 0.0f, 1.0f, 1.0f, {
// .format = "%.0f%%",
// .isPercentage = true,
// })) {
// audio_set_player_volume(SEQ_PLAYER_SFX, CVarGetFloat("gSFXMusicVolume", 1.0f));
// }
// if (UIWidgets::CVarSliderFloat("Environment Volume", "gEnvironmentVolume",
// 0.0f, 1.0f, 1.0f, {
// .format = "%.0f%%",
// .isPercentage = true,
// })) {
// audio_set_player_volume(SEQ_PLAYER_ENV, CVarGetFloat("gEnvironmentVolume", 1.0f));
// }
//
// static std::unordered_map<Ship::AudioBackend, const char*> audioBackendNames = {
// { Ship::AudioBackend::WASAPI, "Windows Audio Session API" },
// { Ship::AudioBackend::PULSE, "PulseAudio" },
// { Ship::AudioBackend::SDL, "SDL" },
// };
//
// ImGui::Text("Audio API (Needs reload)");
// auto currentAudioBackend = Ship::Context::GetInstance()->GetAudio()->GetAudioBackend();
//
// if (Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) {
// UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f);
// }
// if (ImGui::BeginCombo("##AApi", audioBackendNames[currentAudioBackend])) {
// for (uint8_t i = 0; i <
// Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size(); i++) {
// auto backend = Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->data()[i];
// if (ImGui::Selectable(audioBackendNames[backend], backend == currentAudioBackend)) {
// Ship::Context::GetInstance()->GetAudio()->SetAudioBackend(backend);
// }
// }
// ImGui::EndCombo();
// }
// if (Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) {
// UIWidgets::ReEnableComponent("");
// }
//
// ImGui::EndMenu();
// }
if (UIWidgets::BeginMenu("Audio")) {
UIWidgets::CVarSliderFloat("Master Volume", "gGameMasterVolume", 0.0f, 1.0f, 1.0f, {
.format = "%.0f%%",
.isPercentage = true,
});
if (UIWidgets::CVarSliderFloat("Main Music Volume", "gMainMusicVolume", 0.0f, 1.0f, 1.0f,
{
.format = "%.0f%%",
.isPercentage = true,
})) {
audio_set_player_volume(SEQ_PLAYER_LEVEL, CVarGetFloat("gMainMusicVolume", 1.0f));
}
if (UIWidgets::CVarSliderFloat("Sound Effects Volume", "gSFXMusicVolume",
0.0f, 1.0f, 1.0f, {
.format = "%.0f%%",
.isPercentage = true,
})) {
audio_set_player_volume(SEQ_PLAYER_SFX, CVarGetFloat("gSFXMusicVolume", 1.0f));
}
if (UIWidgets::CVarSliderFloat("Environment Volume", "gEnvironmentVolume",
0.0f, 1.0f, 1.0f, {
.format = "%.0f%%",
.isPercentage = true,
})) {
audio_set_player_volume(SEQ_PLAYER_ENV, CVarGetFloat("gEnvironmentVolume", 1.0f));
}
static std::unordered_map<Ship::AudioBackend, const char*> audioBackendNames = {
{ Ship::AudioBackend::WASAPI, "Windows Audio Session API" },
{ Ship::AudioBackend::SDL, "SDL" },
};
ImGui::Text("Audio API (Needs reload)");
auto currentAudioBackend = Ship::Context::GetInstance()->GetAudio()->GetCurrentAudioBackend();
if (Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) {
UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f);
}
if (ImGui::BeginCombo("##AApi", audioBackendNames[currentAudioBackend])) {
for (uint8_t i = 0; i <
Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size(); i++) {
auto backend = Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->data()[i];
if (ImGui::Selectable(audioBackendNames[backend], backend == currentAudioBackend)) {
Ship::Context::GetInstance()->GetAudio()->SetCurrentAudioBackend(backend);
}
}
ImGui::EndCombo();
}
if (Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) {
UIWidgets::ReEnableComponent("");
}
ImGui::EndMenu();
}
UIWidgets::Spacer(0);
+6 -6
View File
@@ -951,7 +951,7 @@ u16 atan2s(f32 x, f32 y) {
return ret;
}
f32 atan2f(f32 arg0, f32 arg1) {
f32 _atan2f(f32 arg0, f32 arg1) {
return atan2s(arg0, arg1);
}
@@ -999,11 +999,11 @@ UNUSED f32 func_802B79F0(f32 arg0, f32 arg1) {
#endif
UNUSED u16 func_802B7B50(f32 arg0, f32 arg1) {
return ((atan2f(arg0, arg1) * 32768.0f) / M_PI);
return ((_atan2f(arg0, arg1) * 32768.0f) / M_PI);
}
UNUSED void func_802B7C18(f32 arg0) {
atan2f(arg0, 1.0f);
_atan2f(arg0, 1.0f);
}
s16 func_802B7C40(f32 arg0) {
@@ -1011,7 +1011,7 @@ s16 func_802B7C40(f32 arg0) {
}
UNUSED void func_802B7C6C(f32 arg0) {
atan2f(arg0, sqrtf(1.0 - (arg0 * arg0)));
_atan2f(arg0, sqrtf(1.0 - (arg0 * arg0)));
}
s16 func_802B7CA8(f32 arg0) {
@@ -1019,11 +1019,11 @@ s16 func_802B7CA8(f32 arg0) {
}
f32 calculate_vector_angle_xy(f32 vectorX) {
return atan2f(sqrtf(1.0 - (vectorX * vectorX)), vectorX);
return _atan2f(sqrtf(1.0 - (vectorX * vectorX)), vectorX);
}
UNUSED s16 func_802B7D28(f32 arg0) {
return atan2f(sqrtf(1.0 - (f64) (arg0 * arg0)), arg0) * 32768.0f / M_PI;
return _atan2f(sqrtf(1.0 - (f64) (arg0 * arg0)), arg0) * 32768.0f / M_PI;
}
u16 random_u16(void) {
+1 -1
View File
@@ -55,7 +55,7 @@ void mtxf_multiplication(Mat4, Mat4, Mat4);
void mtxf_to_mtx(Mtx*, Mat4);
u16 atan2_lookup(f32, f32);
u16 atan2s(f32, f32);
f32 atan2f(f32, f32);
f32 _atan2f(f32, f32);
s16 func_802B7C40(f32);
s16 func_802B7CA8(f32);
f32 calculate_vector_angle_xy(f32);
+5 -25
View File
@@ -21,6 +21,7 @@
#include "effects.h"
#include "math.h"
#include "menus.h"
#include "sounds.h"
#include "port/Game.h"
#pragma intrinsic(sqrtf)
@@ -423,31 +424,10 @@ void func_8028EC98(s32 arg0) {
func_800029B0();
if (GetCourse() == GetMarioRaceway() || GetCourse() == GetRoyalRaceway() || GetCourse() == GetLuigiRaceway() ||
GetCourse() == GetWarioStadium()) {
func_800C8EAC(3);
} else if (GetCourse() == GetToadsTurnpike()) {
func_800C8EAC(21);
} else if (GetCourse() == GetYoshiValley() || GetCourse() == GetMooMooFarm()) {
func_800C8EAC(4);
} else if (GetCourse() == GetChocoMountain() || GetCourse() == GetBlockFort() || GetCourse() == GetDoubleDeck()) {
func_800C8EAC(5);
} else if (GetCourse() == GetKalimariDesert()) {
func_800C8EAC(10);
} else if (GetCourse() == GetKoopaTroopaBeach()) {
func_800C8EAC(6);
} else if (GetCourse() == GetBowsersCastle()) {
func_800C8EAC(9);
} else if (GetCourse() == GetBansheeBoardwalk()) {
func_800C8EAC(7);
} else if (GetCourse() == GetFrappeSnowland() || GetCourse() == GetSherbetLand()) {
func_800C8EAC(8);
} else if (GetCourse() == GetRainbowRoad()) {
func_800C8EAC(18);
} else if (GetCourse() == GetDkJungle()) {
func_800C8EAC(19);
} else if (GetCourse() == GetSkyscraper() || GetCourse() == GetBigDonut()) {
func_800C8EAC(25);
enum MusicSeq sequence = CourseManager_GetProps()->Sequence;
if(sequence != MUSIC_SEQ_UNKNOWN){
play_sequence(sequence);
}
}
+1 -1
Submodule torch updated: 1d485d7695...e466f58b2c
+88
View File
@@ -0,0 +1,88 @@
:config:
external_files:
- "yamls/us/sound/root.yml"
- "yamls/us/sound/samples.yml"
bank_0:
type: NAUDIO:V0:BANK
id: 0
bank_1:
type: NAUDIO:V0:BANK
id: 1
bank_2:
type: NAUDIO:V0:BANK
id: 2
bank_3:
type: NAUDIO:V0:BANK
id: 3
bank_4:
type: NAUDIO:V0:BANK
id: 4
bank_5:
type: NAUDIO:V0:BANK
id: 5
bank_6:
type: NAUDIO:V0:BANK
id: 6
bank_7:
type: NAUDIO:V0:BANK
id: 7
bank_8:
type: NAUDIO:V0:BANK
id: 8
bank_9:
type: NAUDIO:V0:BANK
id: 9
bank_10:
type: NAUDIO:V0:BANK
id: 10
bank_11:
type: NAUDIO:V0:BANK
id: 11
bank_12:
type: NAUDIO:V0:BANK
id: 12
bank_13:
type: NAUDIO:V0:BANK
id: 13
bank_14:
type: NAUDIO:V0:BANK
id: 14
bank_15:
type: NAUDIO:V0:BANK
id: 15
bank_16:
type: NAUDIO:V0:BANK
id: 16
bank_17:
type: NAUDIO:V0:BANK
id: 17
bank_18:
type: NAUDIO:V0:BANK
id: 18
bank_19:
type: NAUDIO:V0:BANK
id: 19
bank_20:
type: NAUDIO:V0:BANK
id: 20
@@ -13,4 +13,7 @@ header:
size: 0x13840
tbl:
offset: 0x979AA0
size: 0x24C4C0
size: 0x24C4C0
audio_seq_font_table:
{ type: ARRAY, count: 0x80, array_type: u8, offset: 0xBE90E0, symbol: gSeqFontTableInit }
+807
View File
@@ -0,0 +1,807 @@
sample_0:
type: NAUDIO:V0:SAMPLE
id: 0
sample_1:
type: NAUDIO:V0:SAMPLE
id: 1
sample_2:
type: NAUDIO:V0:SAMPLE
id: 2
sample_3:
type: NAUDIO:V0:SAMPLE
id: 3
sample_4:
type: NAUDIO:V0:SAMPLE
id: 4
sample_5:
type: NAUDIO:V0:SAMPLE
id: 5
sample_6:
type: NAUDIO:V0:SAMPLE
id: 6
sample_7:
type: NAUDIO:V0:SAMPLE
id: 7
sample_8:
type: NAUDIO:V0:SAMPLE
id: 8
sample_9:
type: NAUDIO:V0:SAMPLE
id: 9
sample_10:
type: NAUDIO:V0:SAMPLE
id: 10
sample_11:
type: NAUDIO:V0:SAMPLE
id: 11
sample_12:
type: NAUDIO:V0:SAMPLE
id: 12
sample_13:
type: NAUDIO:V0:SAMPLE
id: 13
sample_14:
type: NAUDIO:V0:SAMPLE
id: 14
sample_15:
type: NAUDIO:V0:SAMPLE
id: 15
sample_16:
type: NAUDIO:V0:SAMPLE
id: 16
sample_17:
type: NAUDIO:V0:SAMPLE
id: 17
sample_18:
type: NAUDIO:V0:SAMPLE
id: 18
sample_19:
type: NAUDIO:V0:SAMPLE
id: 19
sample_20:
type: NAUDIO:V0:SAMPLE
id: 20
sample_21:
type: NAUDIO:V0:SAMPLE
id: 21
sample_22:
type: NAUDIO:V0:SAMPLE
id: 22
sample_23:
type: NAUDIO:V0:SAMPLE
id: 23
sample_24:
type: NAUDIO:V0:SAMPLE
id: 24
sample_25:
type: NAUDIO:V0:SAMPLE
id: 25
sample_26:
type: NAUDIO:V0:SAMPLE
id: 26
sample_27:
type: NAUDIO:V0:SAMPLE
id: 27
sample_28:
type: NAUDIO:V0:SAMPLE
id: 28
sample_29:
type: NAUDIO:V0:SAMPLE
id: 29
sample_30:
type: NAUDIO:V0:SAMPLE
id: 30
sample_31:
type: NAUDIO:V0:SAMPLE
id: 31
sample_32:
type: NAUDIO:V0:SAMPLE
id: 32
sample_33:
type: NAUDIO:V0:SAMPLE
id: 33
sample_34:
type: NAUDIO:V0:SAMPLE
id: 34
sample_35:
type: NAUDIO:V0:SAMPLE
id: 35
sample_36:
type: NAUDIO:V0:SAMPLE
id: 36
sample_37:
type: NAUDIO:V0:SAMPLE
id: 37
sample_38:
type: NAUDIO:V0:SAMPLE
id: 38
sample_39:
type: NAUDIO:V0:SAMPLE
id: 39
sample_40:
type: NAUDIO:V0:SAMPLE
id: 40
sample_41:
type: NAUDIO:V0:SAMPLE
id: 41
sample_42:
type: NAUDIO:V0:SAMPLE
id: 42
sample_43:
type: NAUDIO:V0:SAMPLE
id: 43
sample_44:
type: NAUDIO:V0:SAMPLE
id: 44
sample_45:
type: NAUDIO:V0:SAMPLE
id: 45
sample_46:
type: NAUDIO:V0:SAMPLE
id: 46
sample_47:
type: NAUDIO:V0:SAMPLE
id: 47
sample_48:
type: NAUDIO:V0:SAMPLE
id: 48
sample_49:
type: NAUDIO:V0:SAMPLE
id: 49
sample_50:
type: NAUDIO:V0:SAMPLE
id: 50
sample_51:
type: NAUDIO:V0:SAMPLE
id: 51
sample_52:
type: NAUDIO:V0:SAMPLE
id: 52
sample_53:
type: NAUDIO:V0:SAMPLE
id: 53
sample_54:
type: NAUDIO:V0:SAMPLE
id: 54
sample_55:
type: NAUDIO:V0:SAMPLE
id: 55
sample_56:
type: NAUDIO:V0:SAMPLE
id: 56
sample_57:
type: NAUDIO:V0:SAMPLE
id: 57
sample_58:
type: NAUDIO:V0:SAMPLE
id: 58
sample_59:
type: NAUDIO:V0:SAMPLE
id: 59
sample_60:
type: NAUDIO:V0:SAMPLE
id: 60
sample_61:
type: NAUDIO:V0:SAMPLE
id: 61
sample_62:
type: NAUDIO:V0:SAMPLE
id: 62
sample_63:
type: NAUDIO:V0:SAMPLE
id: 63
sample_64:
type: NAUDIO:V0:SAMPLE
id: 64
sample_65:
type: NAUDIO:V0:SAMPLE
id: 65
sample_66:
type: NAUDIO:V0:SAMPLE
id: 66
sample_67:
type: NAUDIO:V0:SAMPLE
id: 67
sample_68:
type: NAUDIO:V0:SAMPLE
id: 68
sample_69:
type: NAUDIO:V0:SAMPLE
id: 69
sample_70:
type: NAUDIO:V0:SAMPLE
id: 70
sample_71:
type: NAUDIO:V0:SAMPLE
id: 71
sample_72:
type: NAUDIO:V0:SAMPLE
id: 72
sample_73:
type: NAUDIO:V0:SAMPLE
id: 73
sample_74:
type: NAUDIO:V0:SAMPLE
id: 74
sample_75:
type: NAUDIO:V0:SAMPLE
id: 75
sample_76:
type: NAUDIO:V0:SAMPLE
id: 76
sample_77:
type: NAUDIO:V0:SAMPLE
id: 77
sample_78:
type: NAUDIO:V0:SAMPLE
id: 78
sample_79:
type: NAUDIO:V0:SAMPLE
id: 79
sample_80:
type: NAUDIO:V0:SAMPLE
id: 80
sample_81:
type: NAUDIO:V0:SAMPLE
id: 81
sample_82:
type: NAUDIO:V0:SAMPLE
id: 82
sample_83:
type: NAUDIO:V0:SAMPLE
id: 83
sample_84:
type: NAUDIO:V0:SAMPLE
id: 84
sample_85:
type: NAUDIO:V0:SAMPLE
id: 85
sample_86:
type: NAUDIO:V0:SAMPLE
id: 86
sample_87:
type: NAUDIO:V0:SAMPLE
id: 87
sample_88:
type: NAUDIO:V0:SAMPLE
id: 88
sample_89:
type: NAUDIO:V0:SAMPLE
id: 89
sample_90:
type: NAUDIO:V0:SAMPLE
id: 90
sample_91:
type: NAUDIO:V0:SAMPLE
id: 91
sample_92:
type: NAUDIO:V0:SAMPLE
id: 92
sample_93:
type: NAUDIO:V0:SAMPLE
id: 93
sample_94:
type: NAUDIO:V0:SAMPLE
id: 94
sample_95:
type: NAUDIO:V0:SAMPLE
id: 95
sample_96:
type: NAUDIO:V0:SAMPLE
id: 96
sample_97:
type: NAUDIO:V0:SAMPLE
id: 97
sample_98:
type: NAUDIO:V0:SAMPLE
id: 98
sample_99:
type: NAUDIO:V0:SAMPLE
id: 99
sample_100:
type: NAUDIO:V0:SAMPLE
id: 100
sample_101:
type: NAUDIO:V0:SAMPLE
id: 101
sample_102:
type: NAUDIO:V0:SAMPLE
id: 102
sample_103:
type: NAUDIO:V0:SAMPLE
id: 103
sample_104:
type: NAUDIO:V0:SAMPLE
id: 104
sample_105:
type: NAUDIO:V0:SAMPLE
id: 105
sample_106:
type: NAUDIO:V0:SAMPLE
id: 106
sample_107:
type: NAUDIO:V0:SAMPLE
id: 107
sample_108:
type: NAUDIO:V0:SAMPLE
id: 108
sample_109:
type: NAUDIO:V0:SAMPLE
id: 109
sample_110:
type: NAUDIO:V0:SAMPLE
id: 110
sample_111:
type: NAUDIO:V0:SAMPLE
id: 111
sample_112:
type: NAUDIO:V0:SAMPLE
id: 112
sample_113:
type: NAUDIO:V0:SAMPLE
id: 113
sample_114:
type: NAUDIO:V0:SAMPLE
id: 114
sample_115:
type: NAUDIO:V0:SAMPLE
id: 115
sample_116:
type: NAUDIO:V0:SAMPLE
id: 116
sample_117:
type: NAUDIO:V0:SAMPLE
id: 117
sample_118:
type: NAUDIO:V0:SAMPLE
id: 118
sample_119:
type: NAUDIO:V0:SAMPLE
id: 119
sample_120:
type: NAUDIO:V0:SAMPLE
id: 120
sample_121:
type: NAUDIO:V0:SAMPLE
id: 121
sample_122:
type: NAUDIO:V0:SAMPLE
id: 122
sample_123:
type: NAUDIO:V0:SAMPLE
id: 123
sample_124:
type: NAUDIO:V0:SAMPLE
id: 124
sample_125:
type: NAUDIO:V0:SAMPLE
id: 125
sample_126:
type: NAUDIO:V0:SAMPLE
id: 126
sample_127:
type: NAUDIO:V0:SAMPLE
id: 127
sample_128:
type: NAUDIO:V0:SAMPLE
id: 128
sample_129:
type: NAUDIO:V0:SAMPLE
id: 129
sample_130:
type: NAUDIO:V0:SAMPLE
id: 130
sample_131:
type: NAUDIO:V0:SAMPLE
id: 131
sample_132:
type: NAUDIO:V0:SAMPLE
id: 132
sample_133:
type: NAUDIO:V0:SAMPLE
id: 133
sample_134:
type: NAUDIO:V0:SAMPLE
id: 134
sample_135:
type: NAUDIO:V0:SAMPLE
id: 135
sample_136:
type: NAUDIO:V0:SAMPLE
id: 136
sample_137:
type: NAUDIO:V0:SAMPLE
id: 137
sample_138:
type: NAUDIO:V0:SAMPLE
id: 138
sample_139:
type: NAUDIO:V0:SAMPLE
id: 139
sample_140:
type: NAUDIO:V0:SAMPLE
id: 140
sample_141:
type: NAUDIO:V0:SAMPLE
id: 141
sample_142:
type: NAUDIO:V0:SAMPLE
id: 142
sample_143:
type: NAUDIO:V0:SAMPLE
id: 143
sample_144:
type: NAUDIO:V0:SAMPLE
id: 144
sample_145:
type: NAUDIO:V0:SAMPLE
id: 145
sample_146:
type: NAUDIO:V0:SAMPLE
id: 146
sample_147:
type: NAUDIO:V0:SAMPLE
id: 147
sample_148:
type: NAUDIO:V0:SAMPLE
id: 148
sample_149:
type: NAUDIO:V0:SAMPLE
id: 149
sample_150:
type: NAUDIO:V0:SAMPLE
id: 150
sample_151:
type: NAUDIO:V0:SAMPLE
id: 151
sample_152:
type: NAUDIO:V0:SAMPLE
id: 152
sample_153:
type: NAUDIO:V0:SAMPLE
id: 153
sample_154:
type: NAUDIO:V0:SAMPLE
id: 154
sample_155:
type: NAUDIO:V0:SAMPLE
id: 155
sample_156:
type: NAUDIO:V0:SAMPLE
id: 156
sample_157:
type: NAUDIO:V0:SAMPLE
id: 157
sample_158:
type: NAUDIO:V0:SAMPLE
id: 158
sample_159:
type: NAUDIO:V0:SAMPLE
id: 159
sample_160:
type: NAUDIO:V0:SAMPLE
id: 160
sample_161:
type: NAUDIO:V0:SAMPLE
id: 161
sample_162:
type: NAUDIO:V0:SAMPLE
id: 162
sample_163:
type: NAUDIO:V0:SAMPLE
id: 163
sample_164:
type: NAUDIO:V0:SAMPLE
id: 164
sample_165:
type: NAUDIO:V0:SAMPLE
id: 165
sample_166:
type: NAUDIO:V0:SAMPLE
id: 166
sample_167:
type: NAUDIO:V0:SAMPLE
id: 167
sample_168:
type: NAUDIO:V0:SAMPLE
id: 168
sample_169:
type: NAUDIO:V0:SAMPLE
id: 169
sample_170:
type: NAUDIO:V0:SAMPLE
id: 170
sample_171:
type: NAUDIO:V0:SAMPLE
id: 171
sample_172:
type: NAUDIO:V0:SAMPLE
id: 172
sample_173:
type: NAUDIO:V0:SAMPLE
id: 173
sample_174:
type: NAUDIO:V0:SAMPLE
id: 174
sample_175:
type: NAUDIO:V0:SAMPLE
id: 175
sample_176:
type: NAUDIO:V0:SAMPLE
id: 176
sample_177:
type: NAUDIO:V0:SAMPLE
id: 177
sample_178:
type: NAUDIO:V0:SAMPLE
id: 178
sample_179:
type: NAUDIO:V0:SAMPLE
id: 179
sample_180:
type: NAUDIO:V0:SAMPLE
id: 180
sample_181:
type: NAUDIO:V0:SAMPLE
id: 181
sample_182:
type: NAUDIO:V0:SAMPLE
id: 182
sample_183:
type: NAUDIO:V0:SAMPLE
id: 183
sample_184:
type: NAUDIO:V0:SAMPLE
id: 184
sample_185:
type: NAUDIO:V0:SAMPLE
id: 185
sample_186:
type: NAUDIO:V0:SAMPLE
id: 186
sample_187:
type: NAUDIO:V0:SAMPLE
id: 187
sample_188:
type: NAUDIO:V0:SAMPLE
id: 188
sample_189:
type: NAUDIO:V0:SAMPLE
id: 189
sample_190:
type: NAUDIO:V0:SAMPLE
id: 190
sample_191:
type: NAUDIO:V0:SAMPLE
id: 191
sample_192:
type: NAUDIO:V0:SAMPLE
id: 192
sample_193:
type: NAUDIO:V0:SAMPLE
id: 193
sample_194:
type: NAUDIO:V0:SAMPLE
id: 194
sample_195:
type: NAUDIO:V0:SAMPLE
id: 195
sample_196:
type: NAUDIO:V0:SAMPLE
id: 196
sample_197:
type: NAUDIO:V0:SAMPLE
id: 197
sample_198:
type: NAUDIO:V0:SAMPLE
id: 198
sample_199:
type: NAUDIO:V0:SAMPLE
id: 199
sample_200:
type: NAUDIO:V0:SAMPLE
id: 200
sample_201:
type: NAUDIO:V0:SAMPLE
id: 201
+239
View File
@@ -0,0 +1,239 @@
seq_00:
type: NAUDIO:V0:SEQUENCE
id: 0
size: 0x2830
offset: 0xBC6060
banks:
- sound/banks/bank_0
title_screen:
type: NAUDIO:V0:SEQUENCE
id: 1
size: 0x1B30
offset: 0xBC8890
banks:
- sound/banks/bank_1
main_menu:
type: NAUDIO:V0:SEQUENCE
id: 2
size: 0x0D60
offset: 0xBCA3C0
banks:
- sound/banks/bank_2
raceways_wario_stadium:
type: NAUDIO:V0:SEQUENCE
id: 3
size: 0x1A10
offset: 0xBCB120
banks:
- sound/banks/bank_3
moo_moo_farm_yoshi_valley:
type: NAUDIO:V0:SEQUENCE
id: 4
size: 0x1CA0
offset: 0xBCCB30
banks:
- sound/banks/bank_4
choco_mountain:
type: NAUDIO:V0:SEQUENCE
id: 5
size: 0x1F70
offset: 0xBCE7D0
banks:
- sound/banks/bank_5
koopa_troopa_beach:
type: NAUDIO:V0:SEQUENCE
id: 6
size: 0x1EE0
offset: 0xBD0740
banks:
- sound/banks/bank_6
banshee_boardwalk:
type: NAUDIO:V0:SEQUENCE
id: 7
size: 0x16D0
offset: 0xBD2620
banks:
- sound/banks/bank_7
frappe_snowland:
type: NAUDIO:V0:SEQUENCE
id: 8
size: 0x23D0
offset: 0xBD3CF0
banks:
- sound/banks/bank_8
bowsers_castle:
type: NAUDIO:V0:SEQUENCE
id: 9
size: 0x1800
offset: 0xBD60C0
banks:
- sound/banks/bank_9
kalimari_desert:
type: NAUDIO:V0:SEQUENCE
id: 10
size: 0x1AE0
offset: 0xBD78C0
banks:
- sound/banks/bank_10
start_grid_gp_vs:
type: NAUDIO:V0:SEQUENCE
id: 11
size: 0x05F0
offset: 0xBD93A0
banks:
- sound/banks/bank_11
final_lap_fanfare:
type: NAUDIO:V0:SEQUENCE
id: 12
size: 0x03D0
offset: 0xBD9990
banks:
- sound/banks/bank_11
finish_1st_place:
type: NAUDIO:V0:SEQUENCE
id: 13
size: 0x0360
offset: 0xBD9D60
banks:
- sound/banks/bank_11
finish_2nd_4th_place:
type: NAUDIO:V0:SEQUENCE
id: 14
size: 0x02E0
offset: 0xBDA0C0
banks:
- sound/banks/bank_11
finish_5th_8th_place:
type: NAUDIO:V0:SEQUENCE
id: 15
size: 0x04C0
offset: 0xBDA3A0
banks:
- sound/banks/bank_11
seq_16:
type: NAUDIO:V0:SEQUENCE
id: 16
size: 0x1410
offset: 0xBDA860
banks:
- sound/banks/bank_12
star_jingle:
type: NAUDIO:V0:SEQUENCE
id: 17
size: 0x06E0
offset: 0xBDBC70
banks:
- sound/banks/bank_14
rainbow_road:
type: NAUDIO:V0:SEQUENCE
id: 18
size: 0x32F0
offset: 0xBDC350
banks:
- sound/banks/bank_15
dk_jungle:
type: NAUDIO:V0:SEQUENCE
id: 19
size: 0x06C0
offset: 0xBDF640
banks:
- sound/banks/bank_16
game_over:
type: NAUDIO:V0:SEQUENCE
id: 20
size: 0x04B0
offset: 0xBDFD00
banks:
- sound/banks/bank_11
toads_turnpike:
type: NAUDIO:V0:SEQUENCE
id: 21
size: 0x1160
offset: 0xBE01B0
banks:
- sound/banks/bank_17
start_gird_time_attack:
type: NAUDIO:V0:SEQUENCE
id: 22
size: 0x0310
offset: 0xBE1310
banks:
- sound/banks/bank_11
vs_battle_results:
type: NAUDIO:V0:SEQUENCE
id: 23
size: 0x12B0
offset: 0xBE1620
banks:
- sound/banks/bank_13
losing_results:
type: NAUDIO:V0:SEQUENCE
id: 24
size: 0x0600
offset: 0xBE28D0
banks:
- sound/banks/bank_12
battle_arenas:
type: NAUDIO:V0:SEQUENCE
id: 25
size: 0x16E0
offset: 0xBE2ED0
banks:
- sound/banks/bank_18
award_ceremony_buildup:
type: NAUDIO:V0:SEQUENCE
id: 26
size: 0x0AD0
offset: 0xBE45B0
banks:
- sound/banks/bank_19
award_ceremony_1st_3rd:
type: NAUDIO:V0:SEQUENCE
id: 27
size: 0x0C80
offset: 0xBE5080
banks:
- sound/banks/bank_19
staff_roll:
type: NAUDIO:V0:SEQUENCE
id: 28
size: 0x2750
offset: 0xBE5D00
banks:
- sound/banks/bank_20
award_ceremony_4th_8th:
type: NAUDIO:V0:SEQUENCE
id: 29
size: 0x0C80
offset: 0xBE8450
banks:
- sound/banks/bank_19