Audio loaded from OTR

This commit is contained in:
KiritoDv 2024-11-20 02:01:16 -06:00 committed by Alejandro Asenjo Nitti
parent 5dd3b06d03
commit bd7c4b6df6
46 changed files with 801 additions and 44 deletions

View File

@ -1,8 +1,30 @@
audio_seq:
{ type: BLOB, offset: 0xDEA20, size: 0x3ACF0, symbol: gAudioSeq }
:config:
force: true
header:
code:
- '#include "sys.h"'
- '#include "sf64audio_provisional.h"'
audio_bank:
{ type: BLOB, offset: 0x119710, size: 0x1E020, symbol: gAudioBank }
audio_setup:
type: NAUDIO:V1:AUDIO_SETUP
audio_seq:
size: 0x3ACF0
offset: 0xDEA20
audio_bank:
size: 0x1E020
offset: 0x119710
audio_table:
size: 0x73C580
offset: 0x137730
audio_table:
{ type: BLOB, offset: 0x137730, size: 0x73C580, symbol: gAudioTable }
audio_sample_bank_table:
{ type: NAUDIO:V1:AUDIO_TABLE, format: SAMPLE, offset: 0xC4210, symbol: gSampleBankTableInit }
audio_seq_table:
{ type: NAUDIO:V1:AUDIO_TABLE, format: SEQUENCE, offset: 0xC4260, symbol: gSeqTableInit }
audio_soundfont_table:
{ type: NAUDIO:V1:AUDIO_TABLE, format: SOUNDFONT, offset: 0xC4690, symbol: gSoundFontTableInit }
audio_seq_font_table:
{ type: ARRAY, count: 283, array_type: u8, offset: 0xC48B0, symbol: gSeqFontTableInit }

View File

@ -840,7 +840,7 @@ typedef struct {
typedef struct {
/* 0x00 */ AudioTableBase base;
/* 0x10 */ AudioTableEntry entries[]; // (dynamic size)
/* 0x10 */ AudioTableEntry* entries; // (dynamic size)
} AudioTable; // size >= 0x20
typedef struct SampleDma {
@ -1091,10 +1091,10 @@ bool AudioThread_ResetComplete(void);
void AudioThread_ResetAudioHeap(s32);
void AudioThread_Init(void);
extern AudioTable gSampleBankTableInit;
extern AudioTable gSeqTableInit;
extern AudioTable gSoundFontTableInit;
extern u8 gSeqFontTableInit[];
// extern AudioTable gSampleBankTableInit;
// extern AudioTable gSeqTableInit;
// extern AudioTable gSoundFontTableInit;
// extern u8 gSeqFontTableInit[];
extern AudioSpec gAudioSpecs[];
extern s16 gSeqTicksPerBeat;

View File

@ -390,11 +390,11 @@ void AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) {
s32 fontId;
s32 i;
seqId = AudioLoad_GetLoadTableIndex(SEQUENCE_TABLE, seqId);
// seqId = AudioLoad_GetLoadTableIndex(SEQUENCE_TABLE, seqId);
AudioSeq_SequencePlayerDisable(&gSeqPlayers[playerIdx]);
index = *((u16*) gSeqFontTable + seqId);
index = BSWAP16(*((u16*) gSeqFontTable + seqId));
numFonts = gSeqFontTable[index++];
fontId = 0xFF;
@ -419,12 +419,12 @@ void AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) {
void* AudioLoad_SyncLoadSeq(s32 seqId) {
AudioTable* table = AudioLoad_GetLoadTable(SEQUENCE_TABLE);
s32 seqIdx = AudioLoad_GetLoadTableIndex(SEQUENCE_TABLE, seqId);
return Audio_LoadBlob(gAudioSeq, table->entries[seqIdx].romAddr);
return ResourceGetDataByCrc((uint64_t) table->entries[seqId].romAddr);
}
void* AudioLoad_SyncLoadSampleBank(u32 sampleBankId, s32* outMedium) {
return NULL;
void* ramAddr;
AudioTable* sampleBankTable = AudioLoad_GetLoadTable(2);
s32 cachePolicy;
@ -433,7 +433,7 @@ void* AudioLoad_SyncLoadSampleBank(u32 sampleBankId, s32* outMedium) {
sampleBankId = AudioLoad_GetLoadTableIndex(SAMPLE_TABLE, sampleBankId);
gSampleFontLoadStatus[sampleBankId] = 2;
return Audio_LoadBlob(gAudioTable, sampleBankTable->entries[sampleBankId].romAddr);
// return Audio_LoadBlob(gAudioTable, sampleBankTable->entries[sampleBankId].romAddr);
ramAddr = AudioLoad_SearchCaches(2, sampleBankId);
if (ramAddr != NULL) {
@ -468,7 +468,7 @@ void* AudioLoad_SyncLoadFont(s32 fontId) {
s32 didAllocate;
SampleBankRelocInfo relocInfo;
fontId = AudioLoad_GetLoadTableIndex(FONT_TABLE, fontId);
// fontId = AudioLoad_GetLoadTableIndex(FONT_TABLE, fontId);
sampleBankId1 = gSoundFontList[fontId].sampleBankId1;
sampleBankId2 = gSoundFontList[fontId].sampleBankId2;
@ -522,13 +522,11 @@ void* AudioLoad_SyncLoad(u32 tableType, u32 id, s32* didAllocate) {
switch (tableType) {
case SEQUENCE_TABLE:
gSeqLoadStatus[id] = LOAD_STATUS_COMPLETE;
//ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_PERSISTENT, id);
return Audio_LoadBlob(gAudioSeq, table->entries[id].romAddr);
return ResourceGetDataByCrc((uint64_t) table->entries[id].romAddr);
case FONT_TABLE:
gFontLoadStatus[id] = LOAD_STATUS_COMPLETE;
//ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_PERSISTENT, id);
return Audio_LoadFont(table->entries[id]);
return Audio_LoadFont(table->entries[id], id);
case SAMPLE_TABLE:
loadStatus = 0;
break;
@ -613,7 +611,7 @@ void AudioLoad_RelocateFont(s32 fontId, uintptr_t fontBaseAddr, SampleBankRelocI
// }
AudioTable* table = AudioLoad_GetLoadTable(FONT_TABLE);
printf("fontId: %d\n", fontId);
SoundFont* font = Audio_LoadFont(table->entries[fontId]);
SoundFont* font = Audio_LoadFont(table->entries[fontId], fontId);
gSoundFontList[fontId] = *font;
}
@ -713,16 +711,16 @@ void* AudioLoad_AsyncLoadInner(s32 tableType, s32 id, s32 nChunks, s32 retData,
case SEQUENCE_TABLE:
gSeqLoadStatus[id] = LOAD_STATUS_COMPLETE;
osSendMesg(retQueue, OS_MESG_32(retData << 0x18), OS_MESG_NOBLOCK);
return Audio_LoadBlob(gAudioSeq, table->entries[id].romAddr);
return ResourceGetDataByCrc((uint64_t) table->entries[id].romAddr);
case FONT_TABLE:
gFontLoadStatus[id] = LOAD_STATUS_COMPLETE;
printf("fontId: %d\n", id);
osSendMesg(retQueue, OS_MESG_32(retData << 0x18), OS_MESG_NOBLOCK);
return Audio_LoadFont(table->entries[id]);
return Audio_LoadFont(table->entries[id], id);
case SAMPLE_TABLE:
gSampleFontLoadStatus[id] = LOAD_STATUS_COMPLETE;
// LTODO: Validate this
return Audio_LoadSample(table->entries[id].romAddr, table->entries[id], id);
// return Audio_LoadSample(table->entries[id].romAddr, table->entries[id], id);
return NULL;
}
@ -873,10 +871,10 @@ void AudioLoad_Init(void) {
gAudioResetStep = 1;
AudioHeap_ResetStep();
gSequenceTable = &gSeqTableInit;
gSoundFontTable = &gSoundFontTableInit;
gSampleBankTable = &gSampleBankTableInit;
gSeqFontTable = gSeqFontTableInit;
gSequenceTable = SEGMENTED_TO_VIRTUAL(gSeqTableInit);
gSoundFontTable = SEGMENTED_TO_VIRTUAL(gSoundFontTableInit);
gSampleBankTable = SEGMENTED_TO_VIRTUAL(gSampleBankTableInit);
gSeqFontTable = SEGMENTED_TO_VIRTUAL(gSeqFontTableInit);
gNumSequences = gSequenceTable->base.numEntries;
// AudioLoad_InitTable(gSequenceTable, LOAD_ASSET(gAudioSeq), gSequenceMedium);

View File

@ -175,7 +175,7 @@ Instrument* Audio_GetInstrument(s32 fontId, s32 instId) {
//fontId = 7;
if(gSoundFontList[fontId].instruments == NULL){
gSoundFontList[fontId] = *Audio_LoadFont(gSoundFontTable->entries[fontId]);
gSoundFontList[fontId] = *Audio_LoadFont(gSoundFontTable->entries[fontId], fontId);
}
if ((gFontLoadStatus[fontId] < 2) != 0) {
@ -199,7 +199,7 @@ Drum* Audio_GetDrum(s32 fontId, s32 drumId) {
// LTODO: Remove this
if(gSoundFontList[fontId].drums == NULL){
gSoundFontList[fontId] = *Audio_LoadFont(gSoundFontTable->entries[fontId]);
gSoundFontList[fontId] = *Audio_LoadFont(gSoundFontTable->entries[fontId], fontId);
}
if ((gFontLoadStatus[fontId] < 2) != 0) {

View File

@ -1,5 +1,6 @@
#include "sys.h"
#include "sf64audio_provisional.h"
#include "endianness.h"
#define PORTAMENTO_IS_SPECIAL(x) ((x).mode & 0x80)
#define PORTAMENTO_MODE(x) ((x).mode & ~0x80)
@ -1014,7 +1015,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
case 0xC6:
cmd = AudioSeq_ScriptReadU8(state);
sp52 = ((u16*) gSeqFontTable)[seqPlayer->seqId];
sp52 = BSWAP16(((u16*) gSeqFontTable)[seqPlayer->seqId]);
loBits = gSeqFontTable[sp52];
cmd = gSeqFontTable[sp52 + loBits - cmd];

View File

@ -669,7 +669,6 @@ Acmd* AudioSynth_Update(Acmd* aList, s32* cmdCount, s16* aiBufStart, s32 aiBufLe
//if (gAudioBufferParams.ticksPerUpdate > 3 && gGameState != GSTATE_PLAY) return;
aCmdPtr = aList;
for (i = gAudioBufferParams.ticksPerUpdate; i > 0; i--) {
AudioSeq_ProcessSequences(i - 1);
AudioSynth_SyncSampleStates(gAudioBufferParams.ticksPerUpdate - i);
}

View File

@ -1,6 +1,7 @@
#include "sys.h"
#include "sf64audio_provisional.h"
#if 0
AudioTable gSampleBankTableInit = {
{ 4, 0, 0 },
{
@ -98,7 +99,7 @@ AudioTable gSoundFontTableInit = {
// clang-format off
u8 gSeqFontTableInit[283] = {
u8 gSeqFontTableInitOriginal[283] = {
// Offset into this table for sequence sound font list
AS_BYTES(132), AS_BYTES(134), AS_BYTES(155), AS_BYTES(157), AS_BYTES(159), AS_BYTES(161), AS_BYTES(163),
AS_BYTES(165), AS_BYTES(167), AS_BYTES(169), AS_BYTES(171), AS_BYTES(173), AS_BYTES(175), AS_BYTES(177),
@ -123,3 +124,5 @@ u8 gSeqFontTableInit[283] = {
};
// clang-format on
#endif

View File

@ -17,6 +17,16 @@
#include "resource/importers/SkeletonFactory.h"
#include "resource/importers/Vec3fFactory.h"
#include "resource/importers/Vec3sFactory.h"
#include "resource/importers/audio/AudioTableFactory.h"
#include "resource/importers/audio/BookFactory.h"
#include "resource/importers/audio/DrumFactory.h"
#include "resource/importers/audio/EnvelopeFactory.h"
#include "resource/importers/audio/InstrumentFactory.h"
#include "resource/importers/audio/LoopFactory.h"
#include "resource/importers/audio/SampleFactory.h"
#include "resource/importers/audio/SoundFontFactory.h"
#include "port/interpolation/FrameInterpolation.h"
#include <Fast3D/Fast3dWindow.h>
#include <DisplayListFactory.h>
@ -25,6 +35,7 @@
#include <BlobFactory.h>
#include <VertexFactory.h>
#include "audio/GameAudio.h"
#include "port/patches/DisplayListPatch.h"
// #include "sf64audio_provisional.h"
#include <Fast3D/gfx_pc.h>
@ -127,11 +138,36 @@ GameEngine::GameEngine() {
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryBlobV0>(), RESOURCE_FORMAT_BINARY,
"Blob", static_cast<uint32_t>(LUS::ResourceType::Blob), 0);
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryAudioTableV0>(), RESOURCE_FORMAT_BINARY,
"AudioTable", static_cast<uint32_t>(SF64::ResourceType::AudioTable), 0);
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryAdpcmBookV0>(), RESOURCE_FORMAT_BINARY,
"AdpcmBook", static_cast<uint32_t>(SF64::ResourceType::AdpcmBook), 0);
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryDrumV0>(), RESOURCE_FORMAT_BINARY,
"Drum", static_cast<uint32_t>(SF64::ResourceType::Drum), 0);
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryEnvelopeV0>(), RESOURCE_FORMAT_BINARY,
"Envelope", static_cast<uint32_t>(SF64::ResourceType::Envelope), 0);
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryInstrumentV0>(), RESOURCE_FORMAT_BINARY,
"Instrument", static_cast<uint32_t>(SF64::ResourceType::Instrument), 0);
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryAdpcmLoopV0>(), RESOURCE_FORMAT_BINARY,
"AdpcmLoop", static_cast<uint32_t>(SF64::ResourceType::AdpcmLoop), 0);
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinarySampleV1>(), RESOURCE_FORMAT_BINARY,
"Sample", static_cast<uint32_t>(SF64::ResourceType::Sample), 1);
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinarySoundFontV0>(), RESOURCE_FORMAT_BINARY,
"SoundFont", static_cast<uint32_t>(SF64::ResourceType::SoundFont), 0);
}
void GameEngine::Create() {
const auto instance = Instance = new GameEngine();
instance->AudioInit();
DisplayListPatch::Run();
GameUI::SetupGuiElements();
#if defined(__SWITCH__) || defined(__WIIU__)
CVarRegisterInteger("gControlNav", 1); // always enable controller nav on switch/wii u

View File

@ -0,0 +1,21 @@
#include "DisplayListPatch.h"
#include <libultraship.h>
std::unordered_map<const char*, std::vector<std::pair<uint32_t, Gfx>>> patches = {
// { ast_corneria_seg6_gfx_23420, {
// { 23, gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, 0x003C, 0x003C) }
// }}
};
void DisplayListPatch::Run() {
SPDLOG_INFO("Applying display list patches");
for(auto& entry : patches){
auto data = (Gfx*) ResourceGetDataByName(entry.first);
for(auto& patch : entry.second){
data[patch.first] = patch.second;
}
SPDLOG_INFO("{} patched successfully!", entry.first);
}
}

View File

@ -0,0 +1,5 @@
#pragma once
class DisplayListPatch {
public:
static void Run();
};

View File

@ -0,0 +1,38 @@
#include "AudioTableFactory.h"
#include "port/resource/type/audio/AudioTable.h"
#include "../ResourceUtil.h"
namespace SF64 {
std::shared_ptr<Ship::IResource> ResourceFactoryBinaryAudioTableV0::ReadResource(std::shared_ptr<Ship::File> file) {
if (!FileHasValidFormatAndReader(file)) {
return nullptr;
}
auto table = std::make_shared<AudioTable>(file->InitData);
auto reader = std::get<std::shared_ptr<Ship::BinaryReader>>(file->Reader);
int16_t med = reader->ReadInt16();
uint32_t addr = reader->ReadUInt32();
uint32_t count = reader->ReadUInt32();
for(size_t i = 0; i < count; i++){
uint64_t crc = reader->ReadUInt64();
uint32_t size = reader->ReadUInt32();
int8_t medium = reader->ReadInt8();
int8_t policy = reader->ReadInt8();
int16_t sd1 = reader->ReadInt16();
int16_t sd2 = reader->ReadInt16();
int16_t sd3 = reader->ReadInt16();
table->mEntries.push_back({
(uintptr_t) crc,
size, medium, policy, sd1, sd2, sd3
});
}
table->mTable.base = { (int16_t)count, med, addr };
table->mTable.entries = table->mEntries.data();
return table;
}
} // namespace LUS

View File

@ -0,0 +1,11 @@
#pragma once
#include "Resource.h"
#include "ResourceFactoryBinary.h"
namespace SF64 {
class ResourceFactoryBinaryAudioTableV0 : public Ship::ResourceFactoryBinary {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override;
};
}; // namespace LUS

View File

@ -0,0 +1,24 @@
#include "BookFactory.h"
#include "port/resource/type/audio/AdpcmBook.h"
namespace SF64 {
std::shared_ptr<Ship::IResource> ResourceFactoryBinaryAdpcmBookV0::ReadResource(std::shared_ptr<Ship::File> file) {
if (!FileHasValidFormatAndReader(file)) {
return nullptr;
}
auto book = std::make_shared<AdpcmBook>(file->InitData);
auto reader = std::get<std::shared_ptr<Ship::BinaryReader>>(file->Reader);
book->mBook.order = reader->ReadUInt32();
book->mBook.numPredictors = reader->ReadUInt32();
uint32_t count = reader->ReadUInt32();
for(size_t i = 0; i < count; i++){
book->mPages.push_back(reader->ReadInt16());
}
book->mBook.book = book->mPages.data();
return book;
}
} // namespace LUS

View File

@ -0,0 +1,11 @@
#pragma once
#include "Resource.h"
#include "ResourceFactoryBinary.h"
namespace SF64 {
class ResourceFactoryBinaryAdpcmBookV0 : public Ship::ResourceFactoryBinary {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override;
};
}; // namespace LUS

View File

@ -0,0 +1,24 @@
#include "DrumFactory.h"
#include "../ResourceUtil.h"
#include "port/resource/type/audio/Drum.h"
namespace SF64 {
std::shared_ptr<Ship::IResource> ResourceFactoryBinaryDrumV0::ReadResource(std::shared_ptr<Ship::File> file) {
if (!FileHasValidFormatAndReader(file)) {
return nullptr;
}
auto drum = std::make_shared<Drum>(file->InitData);
auto reader = std::get<std::shared_ptr<Ship::BinaryReader>>(file->Reader);
drum->mDrum.adsrDecayIndex = reader->ReadUByte();
drum->mDrum.pan = reader->ReadUByte();
drum->mDrum.isRelocated = reader->ReadUByte();
drum->mDrum.tunedSample.sample = LoadChild<SampleData*>(reader->ReadUInt64());
drum->mDrum.tunedSample.tuning = reader->ReadFloat();
drum->mDrum.envelope = LoadChild<EnvelopePointData*>(reader->ReadUInt64());
drum->mDrum.isRelocated = 1;
return drum;
}
} // namespace LUS

View File

@ -0,0 +1,11 @@
#pragma once
#include "Resource.h"
#include "ResourceFactoryBinary.h"
namespace SF64 {
class ResourceFactoryBinaryDrumV0 : public Ship::ResourceFactoryBinary {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override;
};
}; // namespace LUS

View File

@ -0,0 +1,20 @@
#include "EnvelopeFactory.h"
#include "port/resource/type/audio/Envelope.h"
namespace SF64 {
std::shared_ptr<Ship::IResource> ResourceFactoryBinaryEnvelopeV0::ReadResource(std::shared_ptr<Ship::File> file) {
if (!FileHasValidFormatAndReader(file)) {
return nullptr;
}
auto envelope = std::make_shared<Envelope>(file->InitData);
auto reader = std::get<std::shared_ptr<Ship::BinaryReader>>(file->Reader);
uint32_t count = reader->ReadUInt32();
for(size_t i = 0; i < count; i++){
envelope->mPoints.push_back({ reader->ReadInt16(), reader->ReadInt16() });
}
return envelope;
}
} // namespace LUS

View File

@ -0,0 +1,11 @@
#pragma once
#include "Resource.h"
#include "ResourceFactoryBinary.h"
namespace SF64 {
class ResourceFactoryBinaryEnvelopeV0 : public Ship::ResourceFactoryBinary {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override;
};
}; // namespace LUS

View File

@ -0,0 +1,29 @@
#include "InstrumentFactory.h"
#include "../ResourceUtil.h"
#include "port/resource/type/audio/Instrument.h"
namespace SF64 {
std::shared_ptr<Ship::IResource> ResourceFactoryBinaryInstrumentV0::ReadResource(std::shared_ptr<Ship::File> file) {
if (!FileHasValidFormatAndReader(file)) {
return nullptr;
}
auto instrument = std::make_shared<Instrument>(file->InitData);
auto reader = std::get<std::shared_ptr<Ship::BinaryReader>>(file->Reader);
instrument->mInstrument.isRelocated = reader->ReadUByte();
instrument->mInstrument.normalRangeLo = reader->ReadUByte();
instrument->mInstrument.normalRangeHi = reader->ReadUByte();
instrument->mInstrument.adsrDecayIndex = reader->ReadUByte();
instrument->mInstrument.envelope = LoadChild<EnvelopePointData*>(reader->ReadUInt64());
instrument->mInstrument.lowPitchTunedSample.sample = LoadChild<SampleData*>(reader->ReadUInt64());
instrument->mInstrument.lowPitchTunedSample.tuning = reader->ReadFloat();
instrument->mInstrument.normalPitchTunedSample.sample = LoadChild<SampleData*>(reader->ReadUInt64());
instrument->mInstrument.normalPitchTunedSample.tuning = reader->ReadFloat();
instrument->mInstrument.highPitchTunedSample.sample = LoadChild<SampleData*>(reader->ReadUInt64());
instrument->mInstrument.highPitchTunedSample.tuning = reader->ReadFloat();
instrument->mInstrument.isRelocated = 1;
return instrument;
}
} // namespace LUS

View File

@ -0,0 +1,11 @@
#pragma once
#include "Resource.h"
#include "ResourceFactoryBinary.h"
namespace SF64 {
class ResourceFactoryBinaryInstrumentV0 : public Ship::ResourceFactoryBinary {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override;
};
}; // namespace LUS

View File

@ -0,0 +1,24 @@
#include "LoopFactory.h"
#include "port/resource/type/audio/AdpcmLoop.h"
namespace SF64 {
std::shared_ptr<Ship::IResource> ResourceFactoryBinaryAdpcmLoopV0::ReadResource(std::shared_ptr<Ship::File> file) {
if (!FileHasValidFormatAndReader(file)) {
return nullptr;
}
auto loop = std::make_shared<AdpcmLoop>(file->InitData);
auto reader = std::get<std::shared_ptr<Ship::BinaryReader>>(file->Reader);
loop->mLoop.start = reader->ReadUInt32();
loop->mLoop.end = reader->ReadUInt32();
loop->mLoop.count = reader->ReadUInt32();
if(loop->mLoop.count != 0){
for(size_t i = 0; i < 16; i++){
loop->mLoop.predictorState[i] = reader->ReadInt16();
}
}
return loop;
}
} // namespace LUS

View File

@ -0,0 +1,11 @@
#pragma once
#include "Resource.h"
#include "ResourceFactoryBinary.h"
namespace SF64 {
class ResourceFactoryBinaryAdpcmLoopV0 : public Ship::ResourceFactoryBinary {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override;
};
}; // namespace LUS

View File

@ -0,0 +1,28 @@
#include "SampleFactory.h"
#include "../ResourceUtil.h"
#include "port/resource/type/audio/Sample.h"
namespace SF64 {
std::shared_ptr<Ship::IResource> ResourceFactoryBinarySampleV1::ReadResource(std::shared_ptr<Ship::File> file) {
if (!FileHasValidFormatAndReader(file)) {
return nullptr;
}
auto sample = std::make_shared<Sample>(file->InitData);
auto reader = std::get<std::shared_ptr<Ship::BinaryReader>>(file->Reader);
sample->mSample.codec = reader->ReadUInt32();
sample->mSample.medium = reader->ReadUInt32();
sample->mSample.unk = reader->ReadUInt32();
sample->mSample.size = reader->ReadUInt32();
sample->mSample.loop = LoadChild<AdpcmLoopData*>(reader->ReadUInt64());
sample->mSample.book = LoadChild<AdpcmBookData*>(reader->ReadUInt64());
sample->mSample.sampleAddr = new uint8_t[sample->mSample.size];
reader->Read((char*) sample->mSample.sampleAddr, sample->mSample.size);
sample->mSample.medium = 0;
sample->mSample.isRelocated = 1;
return sample;
}
} // namespace LUS

View File

@ -0,0 +1,11 @@
#pragma once
#include "Resource.h"
#include "ResourceFactoryBinary.h"
namespace SF64 {
class ResourceFactoryBinarySampleV1 : public Ship::ResourceFactoryBinary {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override;
};
}; // namespace LUS

View File

@ -0,0 +1,32 @@
#include "SoundFontFactory.h"
#include "../ResourceUtil.h"
#include "port/resource/type/audio/SoundFont.h"
namespace SF64 {
std::shared_ptr<Ship::IResource> ResourceFactoryBinarySoundFontV0::ReadResource(std::shared_ptr<Ship::File> file) {
if (!FileHasValidFormatAndReader(file)) {
return nullptr;
}
auto font = std::make_shared<SoundFont>(file->InitData);
auto reader = std::get<std::shared_ptr<Ship::BinaryReader>>(file->Reader);
font->mFont.numInstruments = reader->ReadUByte();
font->mFont.numDrums = reader->ReadUByte();
font->mFont.sampleBankId1 = reader->ReadUByte();
font->mFont.sampleBankId2 = reader->ReadUByte();
for(size_t i = 0; i < font->mFont.numInstruments; i++){
font->mInstruments.push_back(LoadChild<InstrumentData*>(reader->ReadUInt64()));
}
for(size_t i = 0; i < font->mFont.numDrums; i++){
font->mDrums.push_back(LoadChild<DrumData*>(reader->ReadUInt64()));
}
font->mFont.instruments = font->mInstruments.data();
font->mFont.drums = font->mDrums.data();
return font;
}
} // namespace LUS

View File

@ -0,0 +1,11 @@
#pragma once
#include "Resource.h"
#include "ResourceFactoryBinary.h"
namespace SF64 {
class ResourceFactoryBinarySoundFontV0 : public Ship::ResourceFactoryBinary {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override;
};
}; // namespace LUS

View File

@ -6,8 +6,12 @@
#include <vector>
#include <fstream>
#include <filesystem>
#include "test.c"
#ifdef OTR_AUDIO
extern "C" SoundFont* Audio_LoadFont(AudioTableEntry entry, uint32_t fontId) {
return (SoundFont*) ResourceGetDataByCrc((uint64_t) gSoundFontTable->entries[fontId].romAddr);
}
#else
namespace fs = std::filesystem;
std::unordered_map<uint32_t, void*> gAudioCache;
@ -56,7 +60,7 @@ EnvelopePoint* Audio_LoadEnvelope(uint32_t addr) {
return envelopes;
}
extern "C" SoundFont* Audio_LoadFont(AudioTableEntry entry) {
extern "C" SoundFont* Audio_LoadFont(AudioTableEntry entry, uint32_t fontId) {
auto reader = Audio_MakeReader(gAudioBank, entry.romAddr);
if(gAudioCache.contains(entry.romAddr)){
@ -213,3 +217,4 @@ extern "C" Drum* Audio_LoadDrum(uint32_t addr, AudioTableEntry entry, uint32_t s
return drum;
}
#endif

View File

@ -3,18 +3,23 @@
#include <stdint.h>
#include "sf64audio_provisional.h"
#define OTR_AUDIO 1
#ifdef __cplusplus
extern "C" {
#endif
#ifdef OTR_AUDIO
SoundFont* Audio_LoadFont(AudioTableEntry entry, uint32_t fontId);
#else
char* Audio_LoadBlob(const char* resource, u32 offset);
AdpcmBook* Audio_LoadBook(uint32_t addr);
AdpcmLoop* Audio_LoadLoop(uint32_t addr);
Instrument* Audio_LoadInstrument(uint32_t addr, AudioTableEntry entry, uint32_t sampleBankID);
Drum* Audio_LoadDrum(uint32_t addr, AudioTableEntry entry, uint32_t sampleBankID);
Sample* Audio_LoadSample(uint32_t addr, AudioTableEntry entry, uint32_t sampleBankID);
SoundFont* Audio_LoadFont(AudioTableEntry entry);
SoundFont* Audio_LoadFont(AudioTableEntry entry, uint32_t fontId);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -17,5 +17,19 @@ enum class ResourceType {
Vec3f = 0x56433346, // VC3F
Vec3s = 0x56433353, // VC3S
GenericArray = 0x47415252, // GARR
// NAudio v0
Bank = 0x42414E4B, // BANK
Sample = 0x41554643, // AIFC
Sequence = 0x53455143, // SEQC
// NAudio v1
SoundFont = 0x53464E54, // SFNT
Drum = 0x4452554D, // DRUM
Instrument = 0x494E5354, // INST
AdpcmLoop = 0x4150434C, // APCL
AdpcmBook = 0x41504342, // APCB
Envelope = 0x45564C50, // EVLP
AudioTable = 0x4154424C // ATBL
};
} // namespace SOH

View File

@ -0,0 +1,11 @@
#include "AdpcmBook.h"
namespace SF64 {
AdpcmBookData* AdpcmBook::GetPointer() {
return &mBook;
}
size_t AdpcmBook::GetPointerSize() {
return sizeof(AdpcmBookData) + sizeof(int16_t) * mPages.size();
}
}

View File

@ -0,0 +1,25 @@
#pragma once
#include <cstdint>
#include <Resource.h>
namespace SF64 {
struct AdpcmBookData {
/* 0x00 */ int32_t order;
/* 0x04 */ int32_t numPredictors;
/* 0x08 */ int16_t* book;
};
class AdpcmBook : public Ship::Resource<AdpcmBookData> {
public:
using Resource::Resource;
AdpcmBook() : Resource(std::shared_ptr<Ship::ResourceInitData>()) {}
AdpcmBookData* GetPointer();
size_t GetPointerSize();
AdpcmBookData mBook;
std::vector<int16_t> mPages;
};
}

View File

@ -0,0 +1,11 @@
#include "AdpcmLoop.h"
namespace SF64 {
AdpcmLoopData* AdpcmLoop::GetPointer() {
return &mLoop;
}
size_t AdpcmLoop::GetPointerSize() {
return sizeof(AdpcmLoopData);
}
}

View File

@ -0,0 +1,25 @@
#pragma once
#include <cstdint>
#include <Resource.h>
namespace SF64 {
struct AdpcmLoopData {
/* 0x00 */ uint32_t start;
/* 0x04 */ uint32_t end;
/* 0x08 */ uint32_t count;
/* 0x10 */ int16_t predictorState[16]; // only exists if count != 0. 8-byte aligned
};
class AdpcmLoop : public Ship::Resource<AdpcmLoopData> {
public:
using Resource::Resource;
AdpcmLoop() : Resource(std::shared_ptr<Ship::ResourceInitData>()) {}
AdpcmLoopData* GetPointer();
size_t GetPointerSize();
AdpcmLoopData mLoop;
};
}

View File

@ -0,0 +1,16 @@
#pragma once
#include <cstdint>
#include "Sample.h"
namespace SF64 {
struct TunedSample {
SampleData* sample;
float tuning;
};
enum class AudioTableType {
SAMPLE_TABLE,
SEQ_TABLE,
FONT_TABLE
};
}

View File

@ -0,0 +1,11 @@
#include "AudioTable.h"
namespace SF64 {
AudioTableData* AudioTable::GetPointer() {
return &mTable;
}
size_t AudioTable::GetPointerSize() {
return sizeof(AudioTableData);
}
}

View File

@ -0,0 +1,41 @@
#pragma once
#include <cstdint>
#include <Resource.h>
namespace SF64 {
struct AudioTableBase {
/* 0x00 */ int16_t numEntries;
/* 0x02 */ int16_t unkMediumParam;
/* 0x04 */ uintptr_t romAddr;
/* 0x08 */ char pad[8];
};
struct AudioTableEntry {
/* 0x00 */ uintptr_t romAddr;
/* 0x04 */ uint32_t size;
/* 0x08 */ int8_t medium;
/* 0x09 */ int8_t cachePolicy;
/* 0x0A */ int16_t shortData1;
/* 0x0C */ int16_t shortData2;
/* 0x0E */ int16_t shortData3;
}; // size = 0x10
struct AudioTableData {
/* 0x00 */ AudioTableBase base;
/* 0x10 */ AudioTableEntry* entries;
};
class AudioTable : public Ship::Resource<AudioTableData> {
public:
using Resource::Resource;
AudioTable() : Resource(std::shared_ptr<Ship::ResourceInitData>()) {}
AudioTableData* GetPointer();
size_t GetPointerSize();
AudioTableData mTable;
std::vector<AudioTableEntry> mEntries;
};
}

View File

@ -0,0 +1,11 @@
#include "Drum.h"
namespace SF64 {
DrumData* Drum::GetPointer() {
return &mDrum;
}
size_t Drum::GetPointerSize() {
return sizeof(DrumData);
}
}

View File

@ -0,0 +1,28 @@
#pragma once
#include <cstdint>
#include <Resource.h>
#include "Envelope.h"
#include "AudioContext.h"
namespace SF64 {
struct DrumData {
uint8_t adsrDecayIndex;
uint8_t pan;
uint8_t isRelocated;
TunedSample tunedSample;
EnvelopePointData* envelope;
};
class Drum : public Ship::Resource<DrumData> {
public:
using Resource::Resource;
Drum() : Resource(std::shared_ptr<Ship::ResourceInitData>()) {}
DrumData* GetPointer();
size_t GetPointerSize();
DrumData mDrum;
};
}

View File

@ -0,0 +1,11 @@
#include "Envelope.h"
namespace SF64 {
EnvelopePointData* Envelope::GetPointer() {
return mPoints.data();
}
size_t Envelope::GetPointerSize() {
return sizeof(EnvelopePointData) * mPoints.size();
}
}

View File

@ -0,0 +1,24 @@
#pragma once
#include <cstdint>
#include <Resource.h>
namespace SF64 {
struct EnvelopePointData {
int16_t delay;
int16_t arg;
};
class Envelope : public Ship::Resource<EnvelopePointData> {
public:
using Resource::Resource;
Envelope() : Resource(std::shared_ptr<Ship::ResourceInitData>()) {}
EnvelopePointData* GetPointer();
size_t GetPointerSize();
std::vector<EnvelopePointData> mPoints;
};
}

View File

@ -0,0 +1,11 @@
#include "Instrument.h"
namespace SF64 {
InstrumentData* Instrument::GetPointer() {
return &mInstrument;
}
size_t Instrument::GetPointerSize() {
return sizeof(InstrumentData);
}
}

View File

@ -0,0 +1,31 @@
#pragma once
#include <cstdint>
#include <Resource.h>
#include "Envelope.h"
#include "AudioContext.h"
namespace SF64 {
struct InstrumentData {
uint8_t isRelocated;
uint8_t normalRangeLo;
uint8_t normalRangeHi;
uint8_t adsrDecayIndex;
EnvelopePointData* envelope;
TunedSample lowPitchTunedSample;
TunedSample normalPitchTunedSample;
TunedSample highPitchTunedSample;
};
class Instrument : public Ship::Resource<InstrumentData> {
public:
using Resource::Resource;
Instrument() : Resource(std::shared_ptr<Ship::ResourceInitData>()) {}
InstrumentData* GetPointer();
size_t GetPointerSize();
InstrumentData mInstrument;
};
}

View File

@ -0,0 +1,11 @@
#include "Sample.h"
namespace SF64 {
SampleData* Sample::GetPointer() {
return &mSample;
}
size_t Sample::GetPointerSize() {
return sizeof(mSample);
}
}

View File

@ -0,0 +1,32 @@
#pragma once
#include <cstdint>
#include <Resource.h>
#include "Envelope.h"
#include "AdpcmLoop.h"
#include "AdpcmBook.h"
namespace SF64 {
struct SampleData {
uint32_t codec : 4;
uint32_t medium : 2;
uint32_t unk : 1;
uint32_t isRelocated : 1;
uint32_t size : 24;
uint8_t* sampleAddr;
AdpcmLoopData* loop;
AdpcmBookData* book;
};
class Sample : public Ship::Resource<SampleData> {
public:
using Resource::Resource;
Sample() : Resource(std::shared_ptr<Ship::ResourceInitData>()) {}
SampleData* GetPointer();
size_t GetPointerSize();
SampleData mSample;
};
}

View File

@ -0,0 +1,11 @@
#include "SoundFont.h"
namespace SF64 {
SoundFontData* SoundFont::GetPointer() {
return &mFont;
}
size_t SoundFont::GetPointerSize() {
return sizeof(SoundFontData);
}
}

View File

@ -0,0 +1,31 @@
#pragma once
#include <cstdint>
#include <Resource.h>
#include "Instrument.h"
#include "Drum.h"
namespace SF64 {
struct SoundFontData {
/* 0x00 */ uint8_t numInstruments;
/* 0x01 */ uint8_t numDrums;
/* 0x02 */ uint8_t sampleBankId1;
/* 0x03 */ uint8_t sampleBankId2;
/* 0x04 */ InstrumentData** instruments;
/* 0x08 */ DrumData** drums;
};
class SoundFont : public Ship::Resource<SoundFontData> {
public:
using Resource::Resource;
SoundFont() : Resource(std::shared_ptr<Ship::ResourceInitData>()) {}
SoundFontData* GetPointer();
size_t GetPointerSize();
SoundFontData mFont;
std::vector<InstrumentData*> mInstruments;
std::vector<DrumData*> mDrums;
};
}