mirror of
https://github.com/zeldaret/oot.git
synced 2024-12-24 13:46:07 +00:00
[Audio 5/?] Build the Samplebank Table (#2044)
This commit is contained in:
parent
56ca23663a
commit
ba5574be6d
24 changed files with 343 additions and 68 deletions
16
Makefile
16
Makefile
|
@ -237,6 +237,7 @@ BUILD_DIR_REPLACE := sed -e 's|$$(BUILD_DIR)|$(BUILD_DIR)|g'
|
|||
AUDIO_EXTRACT := $(PYTHON) tools/audio_extraction.py
|
||||
SAMPLECONV := tools/audio/sampleconv/sampleconv
|
||||
SBC := tools/audio/sbc
|
||||
ATBLGEN := tools/audio/atblgen
|
||||
|
||||
SBCFLAGS := --matching
|
||||
|
||||
|
@ -745,6 +746,21 @@ ifeq ($(AUDIO_BUILD_DEBUG),1)
|
|||
@cmp $(@:.o=.bin) $(patsubst $(BUILD_DIR)/assets/audio/samplebanks/%,$(EXTRACTED_DIR)/baserom_audiotest/audiotable_files/%,$(@:.o=.bin)) && echo "$(<F) OK"
|
||||
endif
|
||||
|
||||
# put together the tables
|
||||
|
||||
$(BUILD_DIR)/assets/audio/samplebank_table.h: $(SAMPLEBANK_BUILD_XMLS)
|
||||
$(ATBLGEN) --banks $@ $^
|
||||
|
||||
# build the tables into objects, move data -> rodata
|
||||
|
||||
$(BUILD_DIR)/src/audio/tables/samplebank_table.o: src/audio/tables/samplebank_table.c $(BUILD_DIR)/assets/audio/samplebank_table.h
|
||||
ifneq ($(RUN_CC_CHECK),0)
|
||||
$(CC_CHECK) $<
|
||||
endif
|
||||
$(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $(@:.o=.tmp) $<
|
||||
$(LD) -r -T linker_scripts/audio_table_rodata.ld $(@:.o=.tmp) -o $@
|
||||
@$(RM) $(@:.o=.tmp)
|
||||
|
||||
-include $(DEP_FILES)
|
||||
|
||||
# Print target for debugging
|
||||
|
|
|
@ -41,10 +41,6 @@ incbins:
|
|||
segment: code
|
||||
vram: 0x80155500
|
||||
size: 0x6F0
|
||||
- name: gSampleBankTable
|
||||
segment: code
|
||||
vram: 0x80155BF0
|
||||
size: 0x80
|
||||
- name: aspMainData
|
||||
segment: code
|
||||
vram: 0x80155C70
|
||||
|
|
|
@ -33,10 +33,6 @@ incbins:
|
|||
segment: code
|
||||
vram: 0x801108A0
|
||||
size: 0x6F0
|
||||
- name: gSampleBankTable
|
||||
segment: code
|
||||
vram: 0x80110F90
|
||||
size: 0x80
|
||||
- name: aspMainData
|
||||
segment: code
|
||||
vram: 0x80111010
|
||||
|
|
|
@ -33,10 +33,6 @@ incbins:
|
|||
segment: code
|
||||
vram: 0x801108C0
|
||||
size: 0x6F0
|
||||
- name: gSampleBankTable
|
||||
segment: code
|
||||
vram: 0x80110FB0
|
||||
size: 0x80
|
||||
- name: aspMainData
|
||||
segment: code
|
||||
vram: 0x80111030
|
||||
|
|
|
@ -33,10 +33,6 @@ incbins:
|
|||
segment: code
|
||||
vram: 0x801130B0
|
||||
size: 0x6F0
|
||||
- name: gSampleBankTable
|
||||
segment: code
|
||||
vram: 0x801137A0
|
||||
size: 0x80
|
||||
- name: aspMainData
|
||||
segment: code
|
||||
vram: 0x80113820
|
||||
|
|
|
@ -33,10 +33,6 @@ incbins:
|
|||
segment: code
|
||||
vram: 0x801130B0
|
||||
size: 0x6F0
|
||||
- name: gSampleBankTable
|
||||
segment: code
|
||||
vram: 0x801137A0
|
||||
size: 0x80
|
||||
- name: aspMainData
|
||||
segment: code
|
||||
vram: 0x80113820
|
||||
|
|
|
@ -33,10 +33,6 @@ incbins:
|
|||
segment: code
|
||||
vram: 0x801130D0
|
||||
size: 0x6F0
|
||||
- name: gSampleBankTable
|
||||
segment: code
|
||||
vram: 0x801137C0
|
||||
size: 0x80
|
||||
- name: aspMainData
|
||||
segment: code
|
||||
vram: 0x80113840
|
||||
|
|
|
@ -33,10 +33,6 @@ incbins:
|
|||
segment: code
|
||||
vram: 0x80113090
|
||||
size: 0x6F0
|
||||
- name: gSampleBankTable
|
||||
segment: code
|
||||
vram: 0x80113780
|
||||
size: 0x80
|
||||
- name: aspMainData
|
||||
segment: code
|
||||
vram: 0x80113800
|
||||
|
|
|
@ -33,10 +33,6 @@ incbins:
|
|||
segment: code
|
||||
vram: 0x801130B0
|
||||
size: 0x6F0
|
||||
- name: gSampleBankTable
|
||||
segment: code
|
||||
vram: 0x801137A0
|
||||
size: 0x80
|
||||
- name: aspMainData
|
||||
segment: code
|
||||
vram: 0x80113820
|
||||
|
|
|
@ -36,10 +36,6 @@ incbins:
|
|||
segment: code
|
||||
vram: 0x80114220
|
||||
size: 0x6F0
|
||||
- name: gSampleBankTable
|
||||
segment: code
|
||||
vram: 0x80114910
|
||||
size: 0x80
|
||||
- name: aspMainData
|
||||
segment: code
|
||||
vram: 0x80114990
|
||||
|
|
|
@ -17,6 +17,3 @@ glabel gSequenceFontTable
|
|||
|
||||
glabel gSequenceTable
|
||||
.incbin "incbin/gSequenceTable"
|
||||
|
||||
glabel gSampleBankTable
|
||||
.incbin "incbin/gSampleBankTable"
|
||||
|
|
|
@ -8,5 +8,6 @@
|
|||
#define UNUSED __attribute__((unused))
|
||||
#define FALLTHROUGH __attribute__((fallthrough))
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
#define NO_REORDER __attribute__((no_reorder))
|
||||
|
||||
#endif
|
||||
|
|
|
@ -171,7 +171,7 @@ extern s16 gOcarinaSongItemMap[];
|
|||
extern u8 gSoundFontTable[];
|
||||
extern u8 gSequenceFontTable[];
|
||||
extern u8 gSequenceTable[];
|
||||
extern u8 gSampleBankTable[];
|
||||
extern AudioTable gSampleBankTable;
|
||||
|
||||
extern SaveContext gSaveContext;
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#ifndef Z64_AUDIO_H
|
||||
#define Z64_AUDIO_H
|
||||
|
||||
#include "ultra64.h"
|
||||
#include "sequence.h"
|
||||
|
||||
typedef void (*AudioCustomUpdateFunction)(void);
|
||||
|
||||
|
||||
|
@ -110,6 +113,14 @@ typedef enum AudioCacheType {
|
|||
/* 3 */ CACHE_PERMANENT
|
||||
} AudioCacheType;
|
||||
|
||||
typedef enum AudioCacheLoadType {
|
||||
/* 0 */ CACHE_LOAD_PERMANENT,
|
||||
/* 1 */ CACHE_LOAD_PERSISTENT,
|
||||
/* 2 */ CACHE_LOAD_TEMPORARY,
|
||||
/* 3 */ CACHE_LOAD_EITHER,
|
||||
/* 4 */ CACHE_LOAD_EITHER_NOSYNC
|
||||
} AudioCacheLoadType;
|
||||
|
||||
typedef enum AudioLoadStatus {
|
||||
/* 0 */ LOAD_STATUS_NOT_LOADED, // the entry data is not loaded
|
||||
/* 1 */ LOAD_STATUS_IN_PROGRESS, // the entry data is being loaded asynchronously
|
||||
|
@ -807,6 +818,13 @@ typedef struct AudioSlowLoad {
|
|||
/* 0x4C */ OSIoMesg ioMesg;
|
||||
} AudioSlowLoad; // size = 0x64
|
||||
|
||||
typedef struct AudioTableHeader {
|
||||
/* 0x00 */ s16 numEntries;
|
||||
/* 0x02 */ s16 unkMediumParam;
|
||||
/* 0x04 */ uintptr_t romAddr;
|
||||
/* 0x08 */ char pad[0x8];
|
||||
} AudioTableHeader; // size = 0x10
|
||||
|
||||
typedef struct AudioTableEntry {
|
||||
/* 0x00 */ u32 romAddr;
|
||||
/* 0x04 */ u32 size;
|
||||
|
@ -818,10 +836,7 @@ typedef struct AudioTableEntry {
|
|||
} AudioTableEntry; // size = 0x10
|
||||
|
||||
typedef struct AudioTable {
|
||||
/* 0x00 */ s16 numEntries;
|
||||
/* 0x02 */ s16 unkMediumParam;
|
||||
/* 0x04 */ u32 romAddr;
|
||||
/* 0x08 */ char pad[0x8];
|
||||
/* 0x00 */ AudioTableHeader header;
|
||||
/* 0x10 */ AudioTableEntry entries[1]; // (dynamic size)
|
||||
} AudioTable; // size >= 0x20
|
||||
|
||||
|
|
17
linker_scripts/audio_table_rodata.ld
Normal file
17
linker_scripts/audio_table_rodata.ld
Normal file
|
@ -0,0 +1,17 @@
|
|||
OUTPUT_ARCH (mips)
|
||||
|
||||
/* Audio Table Linker Script, maps data into rodata */
|
||||
|
||||
SECTIONS {
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.data*)
|
||||
*(.rodata*)
|
||||
}
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(*);
|
||||
}
|
||||
}
|
1
spec
1
spec
|
@ -649,6 +649,7 @@ beginseg
|
|||
include_no_data "$(BUILD_DIR)/src/code/z_game_over.o"
|
||||
include "$(BUILD_DIR)/src/code/z_construct.o"
|
||||
include "$(BUILD_DIR)/data/audio_tables.rodata.o"
|
||||
include "$(BUILD_DIR)/src/audio/tables/samplebank_table.o"
|
||||
include "$(BUILD_DIR)/data/rsp.text.o"
|
||||
include "$(BUILD_DIR)/data/rsp.rodata.o"
|
||||
endseg
|
||||
|
|
|
@ -1265,7 +1265,7 @@ void AudioHeap_DiscardSampleCacheEntry(SampleCacheEntry* entry) {
|
|||
s32 sampleBankId2;
|
||||
s32 fontId;
|
||||
|
||||
numFonts = gAudioCtx.soundFontTable->numEntries;
|
||||
numFonts = gAudioCtx.soundFontTable->header.numEntries;
|
||||
for (fontId = 0; fontId < numFonts; fontId++) {
|
||||
sampleBankId1 = gAudioCtx.soundFontList[fontId].sampleBankId1;
|
||||
sampleBankId2 = gAudioCtx.soundFontList[fontId].sampleBankId2;
|
||||
|
@ -1322,7 +1322,7 @@ void AudioHeap_DiscardSampleCaches(void) {
|
|||
s32 fontId;
|
||||
s32 j;
|
||||
|
||||
numFonts = gAudioCtx.soundFontTable->numEntries;
|
||||
numFonts = gAudioCtx.soundFontTable->header.numEntries;
|
||||
for (fontId = 0; fontId < numFonts; fontId++) {
|
||||
sampleBankId1 = gAudioCtx.soundFontList[fontId].sampleBankId1;
|
||||
sampleBankId2 = gAudioCtx.soundFontList[fontId].sampleBankId2;
|
||||
|
@ -1392,7 +1392,7 @@ void AudioHeap_ApplySampleBankCacheInternal(s32 apply, s32 sampleBankId) {
|
|||
s32 pad[4];
|
||||
|
||||
sampleBankTable = gAudioCtx.sampleBankTable;
|
||||
numFonts = gAudioCtx.soundFontTable->numEntries;
|
||||
numFonts = gAudioCtx.soundFontTable->header.numEntries;
|
||||
change.oldAddr = (u32)AudioHeap_SearchCaches(SAMPLE_TABLE, CACHE_EITHER, sampleBankId);
|
||||
if (change.oldAddr == 0) {
|
||||
return;
|
||||
|
|
|
@ -338,10 +338,10 @@ void AudioLoad_SetSampleFontLoadStatus(s32 sampleBankId, s32 loadStatus) {
|
|||
void AudioLoad_InitTable(AudioTable* table, u32 romAddr, u16 unkMediumParam) {
|
||||
s32 i;
|
||||
|
||||
table->unkMediumParam = unkMediumParam;
|
||||
table->romAddr = romAddr;
|
||||
table->header.unkMediumParam = unkMediumParam;
|
||||
table->header.romAddr = romAddr;
|
||||
|
||||
for (i = 0; i < table->numEntries; i++) {
|
||||
for (i = 0; i < table->header.numEntries; i++) {
|
||||
if ((table->entries[i].size != 0) && (table->entries[i].medium == MEDIUM_CART)) {
|
||||
table->entries[i].romAddr += romAddr;
|
||||
}
|
||||
|
@ -401,7 +401,7 @@ s32 AudioLoad_SyncLoadSample(Sample* sample, s32 fontId) {
|
|||
|
||||
if (sample->medium == MEDIUM_UNK) {
|
||||
AudioLoad_SyncDmaUnkMedium((u32)sample->sampleAddr, sampleAddr, sample->size,
|
||||
gAudioCtx.sampleBankTable->unkMediumParam);
|
||||
gAudioCtx.sampleBankTable->header.unkMediumParam);
|
||||
} else {
|
||||
AudioLoad_SyncDma((u32)sample->sampleAddr, sampleAddr, sample->size, sample->medium);
|
||||
}
|
||||
|
@ -707,7 +707,7 @@ void* AudioLoad_SyncLoad(u32 tableType, u32 id, s32* didAllocate) {
|
|||
|
||||
*didAllocate = true;
|
||||
if (medium == MEDIUM_UNK) {
|
||||
AudioLoad_SyncDmaUnkMedium(romAddr, ramAddr, size, (s16)table->unkMediumParam);
|
||||
AudioLoad_SyncDmaUnkMedium(romAddr, ramAddr, size, (s16)table->header.unkMediumParam);
|
||||
} else {
|
||||
AudioLoad_SyncDma(romAddr, ramAddr, size, medium);
|
||||
}
|
||||
|
@ -1066,8 +1066,8 @@ void* AudioLoad_AsyncLoadInner(s32 tableType, s32 id, s32 nChunks, s32 retData,
|
|||
}
|
||||
|
||||
if (medium == MEDIUM_UNK) {
|
||||
AudioLoad_StartAsyncLoadUnkMedium((s16)table->unkMediumParam, devAddr, ramAddr, size, medium, nChunks,
|
||||
retQueue, MK_ASYNC_MSG(retData, tableType, id, loadStatus));
|
||||
AudioLoad_StartAsyncLoadUnkMedium((s16)table->header.unkMediumParam, devAddr, ramAddr, size, medium,
|
||||
nChunks, retQueue, MK_ASYNC_MSG(retData, tableType, id, loadStatus));
|
||||
} else {
|
||||
AudioLoad_StartAsyncLoad(devAddr, ramAddr, size, medium, nChunks, retQueue,
|
||||
MK_ASYNC_MSG(retData, tableType, realId, loadStatus));
|
||||
|
@ -1215,10 +1215,10 @@ void AudioLoad_Init(void* heap, u32 heapSize) {
|
|||
// Set audio tables pointers
|
||||
gAudioCtx.sequenceTable = (AudioTable*)gSequenceTable;
|
||||
gAudioCtx.soundFontTable = (AudioTable*)gSoundFontTable;
|
||||
gAudioCtx.sampleBankTable = (AudioTable*)gSampleBankTable;
|
||||
gAudioCtx.sampleBankTable = &gSampleBankTable;
|
||||
gAudioCtx.sequenceFontTable = gSequenceFontTable;
|
||||
|
||||
gAudioCtx.numSequences = gAudioCtx.sequenceTable->numEntries;
|
||||
gAudioCtx.numSequences = gAudioCtx.sequenceTable->header.numEntries;
|
||||
|
||||
gAudioCtx.specId = 0;
|
||||
gAudioCtx.resetStatus = 1; // Set reset to immediately initialize the audio heap
|
||||
|
@ -1229,7 +1229,7 @@ void AudioLoad_Init(void* heap, u32 heapSize) {
|
|||
AudioLoad_InitTable(gAudioCtx.sequenceTable, (u32)_AudioseqSegmentRomStart, 0);
|
||||
AudioLoad_InitTable(gAudioCtx.soundFontTable, (u32)_AudiobankSegmentRomStart, 0);
|
||||
AudioLoad_InitTable(gAudioCtx.sampleBankTable, (u32)_AudiotableSegmentRomStart, 0);
|
||||
numFonts = gAudioCtx.soundFontTable->numEntries;
|
||||
numFonts = gAudioCtx.soundFontTable->header.numEntries;
|
||||
gAudioCtx.soundFontList = AudioHeap_Alloc(&gAudioCtx.initPool, numFonts * sizeof(SoundFont));
|
||||
|
||||
for (i = 0; i < numFonts; i++) {
|
||||
|
@ -1295,7 +1295,7 @@ s32 AudioLoad_SlowLoadSample(s32 fontId, s32 instId, s8* status) {
|
|||
slowLoad->seqOrFontId = fontId;
|
||||
slowLoad->instId = instId;
|
||||
if (slowLoad->medium == MEDIUM_UNK) {
|
||||
slowLoad->unkMediumParam = gAudioCtx.sampleBankTable->unkMediumParam;
|
||||
slowLoad->unkMediumParam = gAudioCtx.sampleBankTable->header.unkMediumParam;
|
||||
}
|
||||
|
||||
gAudioCtx.slowLoadPos ^= 1;
|
||||
|
@ -1439,7 +1439,7 @@ s32 AudioLoad_SlowLoadSeq(s32 seqId, u8* ramAddr, s8* status) {
|
|||
slowLoad->seqOrFontId = seqId;
|
||||
|
||||
if (slowLoad->medium == MEDIUM_UNK) {
|
||||
slowLoad->unkMediumParam = seqTable->unkMediumParam;
|
||||
slowLoad->unkMediumParam = seqTable->header.unkMediumParam;
|
||||
}
|
||||
|
||||
gAudioCtx.slowLoadPos ^= 1;
|
||||
|
@ -1616,7 +1616,7 @@ void AudioLoad_ProcessAsyncLoad(AudioAsyncLoad* asyncLoad, s32 resetStatus) {
|
|||
if (asyncLoad->bytesRemaining < asyncLoad->chunkSize) {
|
||||
if (asyncLoad->medium == MEDIUM_UNK) {
|
||||
AudioLoad_AsyncDmaUnkMedium(asyncLoad->curDevAddr, asyncLoad->curRamAddr, asyncLoad->bytesRemaining,
|
||||
sampleBankTable->unkMediumParam);
|
||||
sampleBankTable->header.unkMediumParam);
|
||||
} else {
|
||||
AudioLoad_AsyncDma(asyncLoad, asyncLoad->bytesRemaining);
|
||||
}
|
||||
|
@ -1626,7 +1626,7 @@ void AudioLoad_ProcessAsyncLoad(AudioAsyncLoad* asyncLoad, s32 resetStatus) {
|
|||
|
||||
if (asyncLoad->medium == MEDIUM_UNK) {
|
||||
AudioLoad_AsyncDmaUnkMedium(asyncLoad->curDevAddr, asyncLoad->curRamAddr, asyncLoad->chunkSize,
|
||||
sampleBankTable->unkMediumParam);
|
||||
sampleBankTable->header.unkMediumParam);
|
||||
} else {
|
||||
AudioLoad_AsyncDma(asyncLoad, asyncLoad->chunkSize);
|
||||
}
|
||||
|
@ -1783,7 +1783,7 @@ void AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, SoundFontData* fontData
|
|||
case false:
|
||||
if (sample->medium == MEDIUM_UNK) {
|
||||
AudioLoad_SyncDmaUnkMedium((u32)sample->sampleAddr, sampleRamAddr, sample->size,
|
||||
gAudioCtx.sampleBankTable->unkMediumParam);
|
||||
gAudioCtx.sampleBankTable->header.unkMediumParam);
|
||||
sample->sampleAddr = sampleRamAddr;
|
||||
sample->medium = MEDIUM_RAM;
|
||||
} else {
|
||||
|
@ -2039,7 +2039,7 @@ void AudioLoad_PreloadSamplesForFont(s32 fontId, s32 async, SampleBankRelocInfo*
|
|||
case false:
|
||||
if (sample->medium == MEDIUM_UNK) {
|
||||
AudioLoad_SyncDmaUnkMedium((u32)sample->sampleAddr, addr, sample->size,
|
||||
gAudioCtx.sampleBankTable->unkMediumParam);
|
||||
gAudioCtx.sampleBankTable->header.unkMediumParam);
|
||||
sample->sampleAddr = addr;
|
||||
sample->medium = MEDIUM_RAM;
|
||||
} else {
|
||||
|
|
50
src/audio/tables/samplebank_table.c
Normal file
50
src/audio/tables/samplebank_table.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
#include "attributes.h"
|
||||
#include "z64audio.h"
|
||||
|
||||
// Symbol definition
|
||||
|
||||
extern AudioTable gSampleBankTable;
|
||||
#pragma weak gSampleBankTable = sSampleBankTableHeader
|
||||
|
||||
// Externs for table
|
||||
|
||||
#define DEFINE_SAMPLE_BANK(name, medium, cachePolicy) \
|
||||
extern u8 name##_Start[]; \
|
||||
extern u8 name##_Size[];
|
||||
#define DEFINE_SAMPLE_BANK_PTR(index, medium, cachePolicy) /*empty*/
|
||||
|
||||
#include "assets/audio/samplebank_table.h"
|
||||
|
||||
#undef DEFINE_SAMPLE_BANK
|
||||
#undef DEFINE_SAMPLE_BANK_PTR
|
||||
|
||||
// Table header
|
||||
|
||||
NO_REORDER AudioTableHeader sSampleBankTableHeader = {
|
||||
// The table contains the number of samplebanks, count them with the preprocessor
|
||||
#define DEFINE_SAMPLE_BANK(name, medium, cachePolicy) 1 +
|
||||
#define DEFINE_SAMPLE_BANK_PTR(index, medium, cachePolicy) 1 +
|
||||
|
||||
#include "assets/audio/samplebank_table.h"
|
||||
0,
|
||||
|
||||
#undef DEFINE_SAMPLE_BANK
|
||||
#undef DEFINE_SAMPLE_BANK_PTR
|
||||
|
||||
0,
|
||||
0x00000000,
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
// Table body
|
||||
|
||||
NO_REORDER AudioTableEntry sSampleBankTableEntries[] = {
|
||||
#define DEFINE_SAMPLE_BANK(name, medium, cachePolicy) \
|
||||
{ (u32)name##_Start, (u32)name##_Size, (medium), (cachePolicy), 0, 0, 0 },
|
||||
#define DEFINE_SAMPLE_BANK_PTR(index, medium, cachePolicy) { (index), 0, (medium), (cachePolicy), 0, 0, 0 },
|
||||
|
||||
#include "assets/audio/samplebank_table.h"
|
||||
|
||||
#undef DEFINE_SAMPLE_BANK
|
||||
#undef DEFINE_SAMPLE_BANK_PTR
|
||||
};
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "z64frame_advance.h"
|
||||
|
||||
#pragma increment_block_number "gc-eu:24 gc-eu-mq:24 gc-jp:28 gc-jp-ce:28 gc-jp-mq:28 gc-us:28 gc-us-mq:28"
|
||||
|
||||
TransitionTile gTransitionTile;
|
||||
s32 gTransitionTileState;
|
||||
VisMono gPlayVisMono;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "cic6105.h"
|
||||
#endif
|
||||
|
||||
#pragma increment_block_number "gc-eu:204 gc-eu-mq:204 gc-jp:206 gc-jp-ce:206 gc-jp-mq:206 gc-us:206 gc-us-mq:206"
|
||||
#pragma increment_block_number "gc-eu:198 gc-eu-mq:198 gc-jp:200 gc-jp-ce:200 gc-jp-mq:200 gc-us:200 gc-us-mq:200"
|
||||
|
||||
#define FLAGS ACTOR_FLAG_4
|
||||
|
||||
|
|
1
tools/audio/.gitignore
vendored
1
tools/audio/.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
__pycache__/
|
||||
|
||||
atblgen
|
||||
sbc
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
PROGRAMS := sbc
|
||||
PROGRAMS := atblgen sbc
|
||||
|
||||
ifeq ($(shell which xml2-config),)
|
||||
$(error xml2-config not found. Did you install libxml2-dev?)
|
||||
|
@ -30,11 +30,14 @@ format:
|
|||
$(CLANG_FORMAT) $(FORMAT_ARGS) $(shell find . -maxdepth 1 -type f -name "*.[ch]")
|
||||
$(MAKE) -C sampleconv format
|
||||
|
||||
sbc_SOURCES := samplebank_compiler.c samplebank.c aifc.c xml.c util.c
|
||||
atblgen_SOURCES := audio_tablegen.c samplebank.c xml.c util.c
|
||||
sbc_SOURCES := samplebank_compiler.c samplebank.c aifc.c xml.c util.c
|
||||
|
||||
sbc_CFLAGS := $(XML_CFLAGS)
|
||||
atblgen_CFLAGS := $(XML_CFLAGS)
|
||||
sbc_CFLAGS := $(XML_CFLAGS)
|
||||
|
||||
sbc_LDFLAGS := $(XML_LDFLAGS)
|
||||
atblgen_LDFLAGS := $(XML_LDFLAGS)
|
||||
sbc_LDFLAGS := $(XML_LDFLAGS)
|
||||
|
||||
define COMPILE =
|
||||
$(1): $($1_SOURCES)
|
||||
|
|
208
tools/audio/audio_tablegen.c
Normal file
208
tools/audio/audio_tablegen.c
Normal file
|
@ -0,0 +1,208 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: Copyright (C) 2024 ZeldaRET
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "samplebank.h"
|
||||
#include "xml.h"
|
||||
#include "util.h"
|
||||
|
||||
/* Utility */
|
||||
|
||||
static bool
|
||||
is_xml(const char *path)
|
||||
{
|
||||
size_t len = strlen(path);
|
||||
|
||||
if (len < 4)
|
||||
return false;
|
||||
if (path[len - 4] == '.' && tolower(path[len - 3]) == 'x' && tolower(path[len - 2]) == 'm' &&
|
||||
tolower(path[len - 1]) == 'l')
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Samplebanks */
|
||||
|
||||
static int
|
||||
tablegen_samplebanks(const char *sb_hdr_out, const char **samplebanks_paths, int num_samplebank_files)
|
||||
{
|
||||
// Read in all samplebank xml files
|
||||
|
||||
samplebank *samplebanks = malloc(num_samplebank_files * sizeof(samplebank));
|
||||
|
||||
for (int i = 0; i < num_samplebank_files; i++) {
|
||||
const char *path = samplebanks_paths[i];
|
||||
|
||||
if (!is_xml(path))
|
||||
error("Not an xml file? (\"%s\")", path);
|
||||
|
||||
xmlDocPtr document = xmlReadFile(path, NULL, XML_PARSE_NONET);
|
||||
if (document == NULL)
|
||||
error("Could not read xml file \"%s\"\n", path);
|
||||
|
||||
read_samplebank_xml(&samplebanks[i], document);
|
||||
}
|
||||
|
||||
// Find largest index, including pointer indices
|
||||
|
||||
size_t index_max = 0;
|
||||
|
||||
for (int i = 0; i < num_samplebank_files; i++) {
|
||||
samplebank *sb = &samplebanks[i];
|
||||
unsigned index = sb->index;
|
||||
if (index > index_max)
|
||||
index_max = index;
|
||||
|
||||
for (size_t j = 0; j < sb->num_pointers; j++) {
|
||||
index = sb->pointer_indices[j];
|
||||
if (index > index_max)
|
||||
index_max = index;
|
||||
}
|
||||
}
|
||||
|
||||
size_t indices_len = index_max + 1;
|
||||
|
||||
// Classify indices and check that no two indices are the same
|
||||
|
||||
#define INDEX_NONE 0
|
||||
#define INDEX_NOPOINTER 1
|
||||
#define INDEX_POINTER 2
|
||||
|
||||
struct sb_index_info {
|
||||
const char *name;
|
||||
unsigned index_type;
|
||||
unsigned ptr_index;
|
||||
const char *medium;
|
||||
const char *cache_policy;
|
||||
};
|
||||
struct sb_index_info *index_info = calloc(indices_len, sizeof(struct sb_index_info));
|
||||
|
||||
for (int i = 0; i < num_samplebank_files; i++) {
|
||||
samplebank *sb = &samplebanks[i];
|
||||
unsigned index = sb->index;
|
||||
|
||||
if (index_info[index].index_type != INDEX_NONE)
|
||||
error("Overlapping samplebank indices, saw index %u more than once", index);
|
||||
index_info[index].index_type = INDEX_NOPOINTER;
|
||||
|
||||
index_info[index].name = sb->name;
|
||||
index_info[index].medium = sb->medium;
|
||||
index_info[index].cache_policy = sb->cache_policy;
|
||||
|
||||
unsigned real_index = index;
|
||||
|
||||
// Add pointers defined for this bank
|
||||
for (size_t j = 0; j < sb->num_pointers; j++) {
|
||||
index = sb->pointer_indices[j];
|
||||
|
||||
if (index_info[index].index_type != INDEX_NONE)
|
||||
error("Overlapping samplebank indices, saw index %u more than once", index);
|
||||
index_info[index].index_type = INDEX_POINTER;
|
||||
|
||||
index_info[index].ptr_index = real_index;
|
||||
index_info[index].medium = sb->medium;
|
||||
index_info[index].cache_policy = sb->cache_policy;
|
||||
}
|
||||
}
|
||||
|
||||
// Check that we have no gaps in the indices
|
||||
|
||||
for (size_t i = 0; i < indices_len; i++) {
|
||||
if (index_info[i].index_type == INDEX_NONE)
|
||||
error("Missing samplebank index %lu", i);
|
||||
}
|
||||
|
||||
// Emit the table
|
||||
|
||||
FILE *out = fopen(sb_hdr_out, "w");
|
||||
if (out == NULL)
|
||||
error("Failed to open samplebank header output");
|
||||
|
||||
fprintf(out,
|
||||
// clang-format off
|
||||
"/**" "\n"
|
||||
" * DEFINE_SAMPLE_BANK(name, medium, cachePolicy)" "\n"
|
||||
" * DEFINE_SAMPLE_BANK_PTR(index, medium, cachePolicy)" "\n"
|
||||
" */" "\n"
|
||||
// clang-format on
|
||||
);
|
||||
|
||||
for (size_t i = 0; i < indices_len; i++) {
|
||||
unsigned index_type = index_info[i].index_type;
|
||||
|
||||
// By this point we shouldn't have any INDEX_NONEs, since it would have been caught before this
|
||||
// when we checked for gaps
|
||||
assert(index_type == INDEX_NOPOINTER || index_type == INDEX_POINTER);
|
||||
|
||||
if (index_type == INDEX_NOPOINTER) {
|
||||
fprintf(out, "DEFINE_SAMPLE_BANK (%s, %s, %s)\n", index_info[i].name, index_info[i].medium,
|
||||
index_info[i].cache_policy);
|
||||
} else {
|
||||
fprintf(out, "DEFINE_SAMPLE_BANK_PTR(%u, %s, %s)\n", index_info[i].ptr_index, index_info[i].medium,
|
||||
index_info[i].cache_policy);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(out);
|
||||
|
||||
free(index_info);
|
||||
free(samplebanks);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* Common */
|
||||
|
||||
static int
|
||||
usage(const char *progname)
|
||||
{
|
||||
fprintf(stderr,
|
||||
// clang-format off
|
||||
"%s: Generate code tables for audio data" "\n"
|
||||
"Usage:" "\n"
|
||||
" %s --banks <samplebank_table.h> <samplebank xml files...>" "\n",
|
||||
// clang-format on
|
||||
progname, progname);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ret = EXIT_SUCCESS;
|
||||
|
||||
const char *progname = argv[0];
|
||||
|
||||
if (argc < 2)
|
||||
return usage(progname);
|
||||
|
||||
const char *mode = argv[1];
|
||||
|
||||
if (strequ(mode, "--banks")) {
|
||||
if (argc < 4)
|
||||
return usage(progname);
|
||||
|
||||
const char *sb_hdr_out = argv[2];
|
||||
const char **samplebanks_paths = (const char **)&argv[3];
|
||||
int num_samplebank_files = argc - 3;
|
||||
|
||||
ret = tablegen_samplebanks(sb_hdr_out, samplebanks_paths, num_samplebank_files);
|
||||
} else {
|
||||
return usage(progname);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
Loading…
Reference in a new issue