You've already forked Microtransactions64
mirror of
https://github.com/Print-and-Panic/Microtransactions64.git
synced 2026-01-21 10:17:19 -08:00
Add MAX_SIMULTANEOUS_NOTES defines and better document audio allocations for audio heap (looks kinda awful still)
This commit is contained in:
@@ -4,12 +4,19 @@
|
||||
* AUDIO SETTINGS *
|
||||
******************/
|
||||
|
||||
// Fixes the castle music sometimes triggering after getting a dialog
|
||||
// Fixes the castle music sometimes triggering after getting a dialog.
|
||||
#define CASTLE_MUSIC_FIX
|
||||
|
||||
// Increase audio heap size to allow for more concurrent notes to be played and for more custom sequences/banks to be imported (not supported for SH)
|
||||
// Increase audio heap size to allow for more concurrent notes to be played and for more custom sequences/banks to be imported (not supported for SH).
|
||||
#define EXPAND_AUDIO_HEAP
|
||||
|
||||
// The maximum number of notes (sfx inclusive) that can sound at any given time (not supported for SH).
|
||||
// Lower values may cause notes to get cut more easily but can potentially improve performance slightly.
|
||||
// Lower values may cause problems with streamed audio if a sequence used for it is missing channel priority data.
|
||||
// Vanilla by default only generally allocates 16 or 20 notes at once. Memory usage is always determined by the largest of the two values here.
|
||||
#define MAX_SIMULTANEOUS_NOTES_EMULATOR 40
|
||||
#define MAX_SIMULTANEOUS_NOTES_CONSOLE 32
|
||||
|
||||
// Use a much better implementation of reverb over vanilla's fake echo reverb. Great for caves or eerie levels, as well as just a better audio experience in general.
|
||||
// Reverb parameters can be configured in audio/synthesis.c to meet desired aesthetic/performance needs. Currently US/JP only. Hurts emulator and console performance.
|
||||
//#define BETTER_REVERB
|
||||
|
||||
@@ -10,6 +10,39 @@
|
||||
*/
|
||||
|
||||
|
||||
/*****************
|
||||
* config_audio
|
||||
*/
|
||||
|
||||
#ifndef MAX_SIMULTANEOUS_NOTES_EMULATOR
|
||||
#ifdef EXPAND_AUDIO_HEAP
|
||||
#define MAX_SIMULTANEOUS_NOTES_EMULATOR 40
|
||||
#else
|
||||
#define MAX_SIMULTANEOUS_NOTES_EMULATOR 20
|
||||
#endif
|
||||
#endif // MAX_SIMULTANEOUS_NOTES_EMULATOR
|
||||
|
||||
#ifndef MAX_SIMULTANEOUS_NOTES_CONSOLE
|
||||
#ifdef EXPAND_AUDIO_HEAP
|
||||
#define MAX_SIMULTANEOUS_NOTES_EMULATOR 32
|
||||
#else
|
||||
#define MAX_SIMULTANEOUS_NOTES_EMULATOR 16
|
||||
#endif
|
||||
#endif // MAX_SIMULTANEOUS_NOTES_CONSOLE
|
||||
|
||||
#if (MAX_SIMULTANEOUS_NOTES_EMULATOR >= MAX_SIMULTANEOUS_NOTES_CONSOLE)
|
||||
#define MAX_SIMULTANEOUS_NOTES MAX_SIMULTANEOUS_NOTES_EMULATOR
|
||||
#else
|
||||
#define MAX_SIMULTANEOUS_NOTES MAX_SIMULTANEOUS_NOTES_CONSOLE
|
||||
#endif
|
||||
|
||||
// Anything higher than 64 will most likely crash on boot. Even if it doesn't, it's still dangerous.
|
||||
#if (MAX_SIMULTANEOUS_NOTES > 64)
|
||||
#undef MAX_SIMULTANEOUS_NOTES
|
||||
#define MAX_SIMULTANEOUS_NOTES 64
|
||||
#endif
|
||||
|
||||
|
||||
/*****************
|
||||
* config_graphics
|
||||
*/
|
||||
|
||||
@@ -38,9 +38,9 @@ struct ReverbSettingsEU sReverbSettings[8] = {
|
||||
|
||||
struct AudioSessionSettingsEU gAudioSessionPresets[] = {
|
||||
#ifdef EXPAND_AUDIO_HEAP
|
||||
{ /*1*/ 32000,/*2*/ 1,/*3*/ 40,/*4*/ 1,/*5*/ 0, &sReverbSettings[0],/*6*/ 0x7FFF,/*7*/ 0,/*8*/ 0x8200,/*9*/ 0xDC00,/*10*/ 0xE800,/*11*/ 0x5500 },
|
||||
{ /*1*/ 32000,/*2*/ 1,/*3*/ MAX_SIMULTANEOUS_NOTES,/*4*/ 1,/*5*/ 0, &sReverbSettings[0],/*6*/ 0x7FFF,/*7*/ 0,/*8*/ 0x8200,/*9*/ 0xDC00,/*10*/ 0xE800,/*11*/ 0x5500 },
|
||||
#else
|
||||
{ /*1*/ 32000,/*2*/ 1,/*3*/ 20,/*4*/ 1,/*5*/ 0, &sReverbSettings[0],/*6*/ 0x7FFF,/*7*/ 0,/*8*/ 0x4100,/*9*/ 0x6E00,/*10*/ 0x7400,/*11*/ 0x2A80 },
|
||||
{ /*1*/ 32000,/*2*/ 1,/*3*/ MAX_SIMULTANEOUS_NOTES,/*4*/ 1,/*5*/ 0, &sReverbSettings[0],/*6*/ 0x7FFF,/*7*/ 0,/*8*/ 0x4100,/*9*/ 0x6E00,/*10*/ 0x7400,/*11*/ 0x2A80 },
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
@@ -80,14 +80,13 @@ struct ReverbSettingsUS gReverbSettings[18] = {
|
||||
{ 1, 0x0800, 0x2FFF },
|
||||
};
|
||||
|
||||
// TODO: Does using 40/20 instead of 32/16 for gMaxSimultaneousNotes cause memory problems at high capacities or is it good as is?
|
||||
#ifdef EXPAND_AUDIO_HEAP
|
||||
struct AudioSessionSettings gAudioSessionPresets[1] = {
|
||||
{ 32000, 40, 1, 0x1000, 0x2FFF, 0x7FFF, 0x8200, 0xDC00, 0xE800, 0x5500 },
|
||||
{ 32000, MAX_SIMULTANEOUS_NOTES, 1, 0x1000, 0x2FFF, 0x7FFF, 0x8200, 0xDC00, 0xE800, 0x5500 },
|
||||
};
|
||||
#else
|
||||
struct AudioSessionSettings gAudioSessionPresets[1] = {
|
||||
{ 32000, 20, 1, 0x1000, 0x2FFF, 0x7FFF, 0x4100, 0x6E00, 0x7400, 0x2A80 },
|
||||
{ 32000, MAX_SIMULTANEOUS_NOTES, 1, 0x1000, 0x2FFF, 0x7FFF, 0x4100, 0x6E00, 0x7400, 0x2A80 },
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -13,6 +13,14 @@
|
||||
|
||||
#define NUMAIBUFFERS 3
|
||||
|
||||
#if defined(VERSION_EU)
|
||||
#define DMA_BUF_SIZE_0 0x400
|
||||
#define DMA_BUF_SIZE_1 0x200
|
||||
#else
|
||||
#define DMA_BUF_SIZE_0 (144 * 9)
|
||||
#define DMA_BUF_SIZE_1 (160 * 9)
|
||||
#endif
|
||||
|
||||
// constant .data
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
extern struct AudioSessionSettingsEU gAudioSessionPresets[];
|
||||
@@ -108,18 +116,42 @@ extern s16 gAiBufferLengths[NUMAIBUFFERS];
|
||||
|
||||
extern u32 gAudioRandom;
|
||||
|
||||
#if defined(VERSION_US) || defined(VERSION_JP)
|
||||
#define NOTES_BUFFER_SIZE \
|
||||
( \
|
||||
MAX_SIMULTANEOUS_NOTES * ((4 /* updatesPerFrame */ * 20 * 2 * sizeof(u64)) \
|
||||
+ ALIGN16(sizeof(struct Note)) \
|
||||
+ (DMA_BUF_SIZE_0 * 3) \
|
||||
+ (DMA_BUF_SIZE_1) \
|
||||
+ ALIGN16(sizeof(struct NoteSynthesisBuffers))) \
|
||||
+ 320 * 2 * sizeof(u64) /* gMaxAudioCmds */ \
|
||||
)
|
||||
#elif defined(VERSION_EU)
|
||||
#define NOTES_BUFFER_SIZE \
|
||||
( \
|
||||
MAX_SIMULTANEOUS_NOTES * ((4 /* updatesPerFrame */ * 0x10 * 2 * sizeof(u64)) \
|
||||
+ ALIGN16(sizeof(struct Note)) \
|
||||
+ (DMA_BUF_SIZE_0 * 3 * 1 /* presetUnk4 */) \
|
||||
+ (DMA_BUF_SIZE_1) \
|
||||
+ ALIGN16(sizeof(struct NoteSynthesisBuffers)) \
|
||||
+ ALIGN16(4 /* updatesPerFrame */ * sizeof(struct NoteSubEu))) \
|
||||
+ (0x300 + 4 /* numReverbs */ * 0x20) * 2 * sizeof(u64) /* gMaxAudioCmds */ \
|
||||
+ 0x4000 /* Extra space to hopefully tolerate whatever the note patch behavior is */ \
|
||||
)
|
||||
#endif
|
||||
|
||||
#ifdef EXPAND_AUDIO_HEAP
|
||||
#if defined(VERSION_US) || defined(VERSION_JP) || defined(VERSION_EU)
|
||||
#define EXT_AUDIO_HEAP_SIZE 0x27400
|
||||
#define EXT_AUDIO_INIT_POOL_SIZE 0x02000
|
||||
#define EXT_AUDIO_INIT_POOL_SIZE (0x1800 + 0x300)
|
||||
#define EXT_AUDIO_HEAP_SIZE 0x14D80
|
||||
#else
|
||||
// SH not yet supported for expanded audio heap
|
||||
#define EXT_AUDIO_HEAP_SIZE 0x0
|
||||
#define EXT_AUDIO_INIT_POOL_SIZE 0x0
|
||||
#define EXT_AUDIO_HEAP_SIZE 0x0
|
||||
#endif
|
||||
#else
|
||||
#define EXT_AUDIO_HEAP_SIZE 0x0
|
||||
#define EXT_AUDIO_INIT_POOL_SIZE 0x0
|
||||
#define EXT_AUDIO_HEAP_SIZE 0x0
|
||||
#endif
|
||||
|
||||
#ifdef VERSION_SH
|
||||
@@ -148,14 +180,15 @@ extern OSMesgQueue *D_SH_80350FA8;
|
||||
#endif
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
#define AUDIO_HEAP_BASE 0x36B00
|
||||
#define AUDIO_INIT_POOL_SIZE (0x2C00 + EXT_AUDIO_INIT_POOL_SIZE)
|
||||
#define AUDIO_INIT_POOL_SIZE (0x1B00 + EXT_AUDIO_INIT_POOL_SIZE + ALIGN16(MAX_SIMULTANEOUS_NOTES * sizeof(struct Note)))
|
||||
#else
|
||||
#define AUDIO_HEAP_BASE 0x30750
|
||||
#define AUDIO_INIT_POOL_SIZE (0x2500 + EXT_AUDIO_INIT_POOL_SIZE)
|
||||
#define AUDIO_INIT_POOL_SIZE (0x1600 + EXT_AUDIO_INIT_POOL_SIZE + ALIGN16(MAX_SIMULTANEOUS_NOTES * sizeof(struct Note)))
|
||||
#endif
|
||||
|
||||
#define AUDIO_HEAP_SIZE (AUDIO_HEAP_BASE + EXT_AUDIO_HEAP_SIZE + EXT_AUDIO_INIT_POOL_SIZE + BETTER_REVERB_SIZE + REVERB_WINDOW_HEAP_SIZE)
|
||||
// TODO: needs validation once EU can compile. EU is very likely incorrect!
|
||||
#define AUDIO_HEAP_BASE (0x14D80 /* sound bank space */ + AUDIO_INIT_POOL_SIZE + EXT_AUDIO_HEAP_SIZE + NOTES_BUFFER_SIZE)
|
||||
|
||||
#define AUDIO_HEAP_SIZE (AUDIO_HEAP_BASE + BETTER_REVERB_SIZE + REVERB_WINDOW_HEAP_SIZE)
|
||||
|
||||
#ifdef VERSION_SH
|
||||
extern u32 D_SH_80315EF0;
|
||||
|
||||
@@ -1382,19 +1382,20 @@ void audio_reset_session(void) {
|
||||
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
for (j = 0; j < 2; j++) {
|
||||
gAudioCmdBuffers[j] = soundAlloc(&gNotesAndBuffersPool, gMaxAudioCmds * sizeof(u64));
|
||||
gAudioCmdBuffers[j] = soundAlloc(&gNotesAndBuffersPool, ALIGN16(gMaxAudioCmds * sizeof(u64)));
|
||||
}
|
||||
#endif
|
||||
|
||||
gNotes = soundAlloc(&gNotesAndBuffersPool, gMaxSimultaneousNotes * sizeof(struct Note));
|
||||
gNotes = soundAlloc(&gNotesAndBuffersPool, ALIGN16(gMaxSimultaneousNotes * sizeof(struct Note)));
|
||||
note_init_all();
|
||||
init_note_free_list();
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
gNoteSubsEu = soundAlloc(&gNotesAndBuffersPool, (gAudioBufferParameters.updatesPerFrame * gMaxSimultaneousNotes) * sizeof(struct NoteSubEu));
|
||||
// NOTE: Cannot be computed automatically in the audio heap define; approximation to be used instead
|
||||
gNoteSubsEu = soundAlloc(&gNotesAndBuffersPool, ALIGN16((gAudioBufferParameters.updatesPerFrame * gMaxSimultaneousNotes) * sizeof(struct NoteSubEu)));
|
||||
|
||||
for (j = 0; j != 2; j++) {
|
||||
gAudioCmdBuffers[j] = soundAlloc(&gNotesAndBuffersPool, gMaxAudioCmds * sizeof(u64));
|
||||
gAudioCmdBuffers[j] = soundAlloc(&gNotesAndBuffersPool, ALIGN16(gMaxAudioCmds * sizeof(u64)));
|
||||
}
|
||||
|
||||
init_reverb_eu();
|
||||
@@ -1427,6 +1428,15 @@ void audio_reset_session(void) {
|
||||
append_puppyprint_log("Audio Initialised in %dus.", (s32)OS_CYCLES_TO_USEC(osGetTime() - first));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (gIsConsole)
|
||||
gMaxSimultaneousNotes = MAX_SIMULTANEOUS_NOTES_CONSOLE;
|
||||
else
|
||||
gMaxSimultaneousNotes = MAX_SIMULTANEOUS_NOTES_EMULATOR;
|
||||
|
||||
if (gMaxSimultaneousNotes > MAX_SIMULTANEOUS_NOTES)
|
||||
gMaxSimultaneousNotes = MAX_SIMULTANEOUS_NOTES;
|
||||
|
||||
sAudioFirstBoot = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -680,6 +680,7 @@ struct Note {
|
||||
/*0x18, 0x38*/ f32 portamentoFreqScale;
|
||||
/*0x1C, 0x3C*/ f32 vibratoFreqScale;
|
||||
/*0x20*/ u16 samplePosFrac;
|
||||
/* */ u8 pad2[2];
|
||||
/*0x24*/ struct AudioBankSound *sound;
|
||||
/*0x28, 0x40*/ struct SequenceChannelLayer *prevParentLayer;
|
||||
/*0x2C, 0x44*/ struct SequenceChannelLayer *parentLayer;
|
||||
@@ -690,6 +691,7 @@ struct Note {
|
||||
/*0x3E*/ u16 targetVolRight; // Q1.15, but will always be non-negative
|
||||
/*0x40*/ u8 reverbVol; // Q1.7
|
||||
/*0x41*/ u8 unused1; // never read, set to 0x3f
|
||||
/* */ u8 pad3[2];
|
||||
/*0x44*/ struct NoteAttributes attributes;
|
||||
/*0x54, 0x58*/ struct AdsrState adsr;
|
||||
/*0x74, 0x7C*/ struct Portamento portamento;
|
||||
@@ -699,7 +701,7 @@ struct Note {
|
||||
/*0xA0*/ s16 reverbVolShifted; // Q1.15
|
||||
/*0xA2*/ s16 unused2; // never read, set to 0
|
||||
/*0xA4, 0x00*/ struct AudioListItem listItem;
|
||||
/* */ u8 pad2[0xc];
|
||||
/* */ u8 pad4[0xc];
|
||||
}; // size = 0xC0
|
||||
#endif
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ OSMesgQueue gAudioDmaMesgQueue;
|
||||
OSMesg gAudioDmaMesg;
|
||||
OSIoMesg gAudioDmaIoMesg;
|
||||
|
||||
struct SharedDma sSampleDmas[0x60];
|
||||
struct SharedDma sSampleDmas[MAX_SIMULTANEOUS_NOTES * 4];
|
||||
u32 gSampleDmaNumListItems; // sh: 0x803503D4
|
||||
u32 sSampleDmaListSize1; // sh: 0x803503D8
|
||||
|
||||
@@ -335,11 +335,7 @@ void init_sample_dma_buffers(UNUSED s32 arg0) {
|
||||
s32 j;
|
||||
#endif
|
||||
|
||||
#if defined(VERSION_EU)
|
||||
sDmaBufSize = 0x400;
|
||||
#else
|
||||
sDmaBufSize = 144 * 9;
|
||||
#endif
|
||||
sDmaBufSize = DMA_BUF_SIZE_0;
|
||||
|
||||
#if defined(VERSION_EU)
|
||||
for (i = 0; i < gMaxSimultaneousNotes * 3 * gAudioBufferParameters.presetUnk4; i++) {
|
||||
@@ -378,11 +374,8 @@ out1:
|
||||
sSampleDmaReuseQueueHead1 = (u8) gSampleDmaNumListItems;
|
||||
sSampleDmaListSize1 = gSampleDmaNumListItems;
|
||||
|
||||
#if defined(VERSION_EU)
|
||||
sDmaBufSize = 0x200;
|
||||
#else
|
||||
sDmaBufSize = 160 * 9;
|
||||
#endif
|
||||
sDmaBufSize = DMA_BUF_SIZE_1;
|
||||
|
||||
for (i = 0; i < gMaxSimultaneousNotes; i++) {
|
||||
sSampleDmas[gSampleDmaNumListItems].buffer = soundAlloc(&gNotesAndBuffersPool, sDmaBufSize);
|
||||
if (sSampleDmas[gSampleDmaNumListItems].buffer == NULL) {
|
||||
@@ -442,7 +435,7 @@ void patch_sound(UNUSED struct AudioBankSound *sound, UNUSED u8 *memBase, UNUSED
|
||||
#if defined(VERSION_EU)
|
||||
else if (sample->loaded == 0x80) {
|
||||
PATCH(sample->sampleAddr, offsetBase);
|
||||
u8 *mem = soundAlloc(&gNotesAndBuffersPool, sample->sampleSize); // TODO: Memory leak!
|
||||
u8 *mem = soundAlloc(&gNotesAndBuffersPool, sample->sampleSize); // TODO: Memory issue most likely!
|
||||
if (mem == NULL) {
|
||||
sample->sampleAddr = patched;
|
||||
sample->loaded = 1;
|
||||
|
||||
@@ -1443,9 +1443,9 @@ void note_init_all(void) {
|
||||
#if defined(VERSION_SH)
|
||||
note->synthesisState.synthesisBuffers = sound_alloc_uninitialized(&gNotesAndBuffersPool, sizeof(struct NoteSynthesisBuffers));
|
||||
#elif defined(VERSION_EU)
|
||||
note->synthesisState.synthesisBuffers = soundAlloc(&gNotesAndBuffersPool, sizeof(struct NoteSynthesisBuffers));
|
||||
note->synthesisState.synthesisBuffers = soundAlloc(&gNotesAndBuffersPool, ALIGN16(sizeof(struct NoteSynthesisBuffers)));
|
||||
#else
|
||||
note->synthesisBuffers = soundAlloc(&gNotesAndBuffersPool, sizeof(struct NoteSynthesisBuffers));
|
||||
note->synthesisBuffers = soundAlloc(&gNotesAndBuffersPool, ALIGN16(sizeof(struct NoteSynthesisBuffers)));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,22 @@ extern u8 toggleBetterReverb;
|
||||
|
||||
#endif
|
||||
|
||||
#define REVERB_WINDOW_HEAP_SIZE (REVERB_WINDOW_SIZE_MAX * sizeof(s16) * 2)
|
||||
#if defined(VERSION_JP) || defined(VERSION_US)
|
||||
#define REVERB_WINDOW_HEAP_SIZE \
|
||||
( \
|
||||
(REVERB_WINDOW_SIZE_MAX * sizeof(s16) * 2) \
|
||||
+ (4 * (16 * sizeof(s16))) \
|
||||
+ (4 /* gAudioUpdatesPerFrame */ * (2 * DEFAULT_LEN_2CH)) \
|
||||
)
|
||||
#else
|
||||
#define REVERB_WINDOW_HEAP_SIZE \
|
||||
( \
|
||||
((REVERB_WINDOW_SIZE_MAX * sizeof(s16) * 2) \
|
||||
+ (4 * (16 * sizeof(s16))) \
|
||||
+ (4 /* gAudioUpdatesPerFrame */ * (2 * DEFAULT_LEN_2CH))) \
|
||||
* 4 /* gNumSynthesisReverbs */ \
|
||||
)
|
||||
#endif
|
||||
|
||||
struct ReverbRingBufferItem {
|
||||
s16 numSamplesAfterDownsampling;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "game/main.h"
|
||||
#include "game/rumble_init.h"
|
||||
#include "game/version.h"
|
||||
#include "game/vc_check.h"
|
||||
#ifdef UNF
|
||||
#include "usb/usb.h"
|
||||
#include "usb/debug.h"
|
||||
@@ -317,6 +318,15 @@ void thread3_main(UNUSED void *arg) {
|
||||
osSyncPrintf("Linker : %s\n", __linker__);
|
||||
#endif
|
||||
|
||||
if (IO_READ(DPC_CLOCK_REG) == 0) {
|
||||
gIsConsole = FALSE;
|
||||
gBorderHeight = BORDER_HEIGHT_EMULATOR;
|
||||
gIsVC = IS_VC();
|
||||
} else {
|
||||
gIsConsole = TRUE;
|
||||
gBorderHeight = BORDER_HEIGHT_CONSOLE;
|
||||
}
|
||||
|
||||
create_thread(&gSoundThread, THREAD_4_SOUND, thread4_sound, NULL, gThread4Stack + 0x2000, 20);
|
||||
osStartThread(&gSoundThread);
|
||||
|
||||
|
||||
@@ -391,15 +391,6 @@ void render_init(void) {
|
||||
#ifdef DEBUG_FORCE_CRASH_ON_BOOT
|
||||
FORCE_CRASH
|
||||
#endif
|
||||
if (IO_READ(DPC_PIPEBUSY_REG) == 0) {
|
||||
gIsConsole = FALSE;
|
||||
gBorderHeight = BORDER_HEIGHT_EMULATOR;
|
||||
gIsVC = IS_VC();
|
||||
} else {
|
||||
gIsConsole = TRUE;
|
||||
gBorderHeight = BORDER_HEIGHT_CONSOLE;
|
||||
}
|
||||
|
||||
gGfxPool = &gGfxPools[0];
|
||||
set_segment_base_addr(SEGMENT_RENDER, gGfxPool->buffer);
|
||||
gGfxSPTask = &gGfxPool->spTask;
|
||||
|
||||
Reference in New Issue
Block a user