mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-21 13:53:49 -07:00
Audio support nearly complete.
This commit is contained in:
parent
746c7a5303
commit
114c6e01d9
25 changed files with 1953 additions and 209 deletions
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,6 @@
|
|||
<Root>
|
||||
<File Name="code" OutName="audio" RangeStart="0x0" RangeEnd="0x12CBB0">
|
||||
<Audio Name="audio" Offset="0x00"/>
|
||||
<Audio Name="audio" Offset="0x00">
|
||||
</Audio>
|
||||
</File>
|
||||
</Root>
|
||||
|
|
|
@ -18,11 +18,6 @@
|
|||
#define _AudiotableSegmentRomStart "Audiotable"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define _icon_item_gameover_staticSegmentRomStart 0
|
||||
#define _icon_item_gameover_staticSegmentRomEnd 0
|
||||
#define _icon_item_staticSegmentRomStart 0
|
||||
#define _icon_item_staticSegmentRomEnd 0
|
||||
#define _map_i_staticSegmentRomStart 0
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
#define AIBUF_LEN 0x580
|
||||
|
||||
#define CALC_RESAMPLE_FREQ(sampleRate) (sampleRate / (s32)gAudioContext.audioBufferParameters.frequency)
|
||||
|
||||
typedef enum {
|
||||
/* 0 */ ADSR_STATE_DISABLED,
|
||||
/* 1 */ ADSR_STATE_INITIAL,
|
||||
|
@ -136,6 +138,8 @@ typedef struct
|
|||
/* 0x04 */ u8* sampleAddr;
|
||||
/* 0x08 */ AdpcmLoop* loop;
|
||||
/* 0x0C */ AdpcmBook* book;
|
||||
u32 sampleRateMagicValue; // For wav samples only...
|
||||
s32 sampleRate; // For wav samples only...
|
||||
} SoundFontSample; // size = 0x10
|
||||
|
||||
typedef struct {
|
||||
|
@ -1062,6 +1066,16 @@ typedef enum {
|
|||
/* -1 */ OCARINA_NOTE_INVALID = 0xFF
|
||||
} OcarinaNoteIdx;
|
||||
|
||||
typedef struct {
|
||||
char* seqData;
|
||||
int32_t seqDataSize;
|
||||
uint8_t seqNumber;
|
||||
uint8_t medium;
|
||||
uint8_t cachePolicy;
|
||||
int32_t numFonts;
|
||||
uint8_t fonts[16];
|
||||
} SequenceData;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
|
@ -59,6 +59,7 @@ extern "C" void AudioPlayer_Play(const uint8_t* buf, uint32_t len);
|
|||
extern "C" int AudioPlayer_Buffered(void);
|
||||
extern "C" int AudioPlayer_GetDesiredBuffered(void);
|
||||
extern "C" void ResourceMgr_CacheDirectory(const char* resName);
|
||||
extern "C" SequenceData ResourceMgr_LoadSeqByName(const char* path);
|
||||
|
||||
// C->C++ Bridge
|
||||
extern "C" void OTRAudio_Init()
|
||||
|
@ -198,11 +199,16 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
|
|||
//AudioMgr_ThreadEntry(&gAudioMgr);
|
||||
// 528 and 544 relate to 60 fps at 32 kHz 32000/60 = 533.333..
|
||||
// in an ideal world, one third of the calls should use num_samples=544 and two thirds num_samples=528
|
||||
#define SAMPLES_HIGH 560
|
||||
#define SAMPLES_LOW 528
|
||||
//#define SAMPLES_HIGH 560
|
||||
//#define SAMPLES_LOW 528
|
||||
// PAL values
|
||||
//#define SAMPLES_HIGH 656
|
||||
//#define SAMPLES_LOW 624
|
||||
|
||||
// 44KHZ values
|
||||
#define SAMPLES_HIGH 752
|
||||
#define SAMPLES_LOW 720
|
||||
|
||||
#define AUDIO_FRAMES_PER_UPDATE (R_UPDATE_RATE > 0 ? R_UPDATE_RATE : 1 )
|
||||
#define NUM_AUDIO_CHANNELS 2
|
||||
int samples_left = AudioPlayer_Buffered();
|
||||
|
@ -321,6 +327,22 @@ extern "C" void ResourceMgr_InvalidateCache() {
|
|||
OTRGlobals::Instance->context->GetResourceManager()->InvalidateResourceCache();
|
||||
}
|
||||
|
||||
// OTRTODO: There is probably a more elegant way to go about this...
|
||||
extern "C" char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize) {
|
||||
auto lst = OTRGlobals::Instance->context->GetResourceManager()->ListFiles(searchMask);
|
||||
char** result = (char**)malloc(lst->size() * sizeof(char*));
|
||||
|
||||
for (int i = 0; i < lst->size(); i++) {
|
||||
char* str = (char*)malloc(lst.get()[0][i].size() + 1);
|
||||
memcpy(str, lst.get()[0][i].data(), lst.get()[0][i].size());
|
||||
str[lst.get()[0][i].size()] = '\0';
|
||||
result[i] = str;
|
||||
}
|
||||
|
||||
*resultSize = lst->size();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" void ResourceMgr_LoadFile(const char* resName) {
|
||||
OTRGlobals::Instance->context->GetResourceManager()->LoadResource(resName);
|
||||
|
@ -545,35 +567,53 @@ extern "C" Vtx* ResourceMgr_LoadVtxByName(const char* path)
|
|||
return (Vtx*)res->vertices.data();
|
||||
}
|
||||
|
||||
extern "C" char* ResourceMgr_LoadSeqByID(int seqID)
|
||||
{
|
||||
extern "C" SequenceData ResourceMgr_LoadSeqByID(int seqID) {
|
||||
if (seqID == 0xFF) {
|
||||
SequenceData sDat;
|
||||
sDat.numFonts = 0;
|
||||
|
||||
return sDat;
|
||||
}
|
||||
|
||||
std::string fmtStr = "audio/sequences/seq_%02X";
|
||||
return OTRGlobals::Instance->context->GetResourceManager()->LoadFile(StringHelper::Sprintf(fmtStr.c_str(), seqID)).get()->buffer.get();
|
||||
return ResourceMgr_LoadSeqByName(StringHelper::Sprintf(fmtStr.c_str(), seqID).c_str());
|
||||
}
|
||||
|
||||
extern "C" int ResourceMgr_GetSeqSizeByID(int seqID)
|
||||
extern "C" SequenceData ResourceMgr_LoadSeqByName(const char* path)
|
||||
{
|
||||
return OTRGlobals::Instance->context->GetResourceManager()
|
||||
->LoadFile(StringHelper::Sprintf("audio/sequences/seq_%02X", seqID))
|
||||
.get()
|
||||
->dwBufferSize;
|
||||
auto file = OTRGlobals::Instance->context->GetResourceManager()->LoadFile(path).get();
|
||||
|
||||
char* data = file->buffer.get();
|
||||
|
||||
SequenceData seqData;
|
||||
seqData.seqNumber = data[1];
|
||||
seqData.medium = data[2];
|
||||
seqData.cachePolicy = data[3];
|
||||
seqData.numFonts = data[4];
|
||||
|
||||
for (int i = 0; i < seqData.numFonts; i++)
|
||||
seqData.fonts[i] = data[5 + i];
|
||||
|
||||
seqData.seqData = &data[5 + seqData.numFonts];
|
||||
seqData.seqDataSize = file->dwBufferSize - 5 - seqData.numFonts;
|
||||
|
||||
return seqData;
|
||||
}
|
||||
|
||||
std::map<std::string, SoundFontSample*> cachedCustomSFs;
|
||||
|
||||
extern "C" SoundFontSample* ResourceMgr_LoadAudioSample(int romOffset)
|
||||
extern "C" SoundFontSample* ResourceMgr_LoadAudioSample(const char* path)
|
||||
{
|
||||
auto str = StringHelper::Sprintf("audio/samples/sample_%08X", romOffset);
|
||||
//auto str = StringHelper::Sprintf("audio/samples/sample_%08X", romOffset);
|
||||
|
||||
if (cachedCustomSFs.find(str) != cachedCustomSFs.end())
|
||||
return cachedCustomSFs[str];
|
||||
if (std::string(path) == "")
|
||||
return nullptr;
|
||||
|
||||
if (romOffset == 0x14f0) {
|
||||
int bp = 0;
|
||||
}
|
||||
if (cachedCustomSFs.find(path) != cachedCustomSFs.end())
|
||||
return cachedCustomSFs[path];
|
||||
|
||||
// Check if our file is actually a wav...
|
||||
auto sampleRaw = OTRGlobals::Instance->context->GetResourceManager()->LoadFile(str);
|
||||
auto sampleRaw = OTRGlobals::Instance->context->GetResourceManager()->LoadFile(path);
|
||||
uint32_t* strem = (uint32_t*)sampleRaw->buffer.get();
|
||||
uint8_t* strem2 = (uint8_t*)strem;
|
||||
|
||||
|
@ -587,6 +627,8 @@ extern "C" SoundFontSample* ResourceMgr_LoadAudioSample(int romOffset)
|
|||
|
||||
*strem++; // fmt
|
||||
int fmtChunkSize = *strem++;
|
||||
*strem++; // wFormatTag + wChannels
|
||||
int32_t sampleRate = *strem++; // dwSamplesPerSec
|
||||
// OTRTODO: Make sure wav format is what the audio driver wants!
|
||||
|
||||
strem = (uint32_t*)&strem2[0x0C + fmtChunkSize + 8 + 4];
|
||||
|
@ -599,12 +641,15 @@ extern "C" SoundFontSample* ResourceMgr_LoadAudioSample(int romOffset)
|
|||
sampleC->loop->start = 0;
|
||||
sampleC->loop->end = sampleC->size / 2;
|
||||
sampleC->loop->count = 0;
|
||||
|
||||
cachedCustomSFs[str] = sampleC;
|
||||
sampleC->sampleRateMagicValue = 'RIFF';
|
||||
sampleC->sampleRate = sampleRate;
|
||||
|
||||
cachedCustomSFs[path] = sampleC;
|
||||
return sampleC;
|
||||
}
|
||||
|
||||
auto sample = std::static_pointer_cast<Ship::AudioSample>(OTRGlobals::Instance->context->GetResourceManager()->LoadResource(str));
|
||||
auto sample = std::static_pointer_cast<Ship::AudioSample>(
|
||||
OTRGlobals::Instance->context->GetResourceManager()->LoadResource(path));
|
||||
|
||||
if (sample == nullptr)
|
||||
return NULL;
|
||||
|
@ -612,7 +657,6 @@ extern "C" SoundFontSample* ResourceMgr_LoadAudioSample(int romOffset)
|
|||
if (sample->cachedGameAsset != nullptr)
|
||||
{
|
||||
SoundFontSample* sampleC = (SoundFontSample*)sample->cachedGameAsset;
|
||||
|
||||
return (SoundFontSample*)sample->cachedGameAsset;
|
||||
}
|
||||
else
|
||||
|
@ -692,7 +736,7 @@ extern "C" SoundFont* ResourceMgr_LoadAudioSoundFont(int fontIndex) {
|
|||
}
|
||||
}
|
||||
|
||||
drum->sound.sample = ResourceMgr_LoadAudioSample(soundFont->drums[i].offset);
|
||||
drum->sound.sample = ResourceMgr_LoadAudioSample(soundFont->drums[i].sampleFileName.c_str());
|
||||
drum->sound.tuning = soundFont->drums[i].tuning;
|
||||
|
||||
soundFontC->drums[i] = drum;
|
||||
|
@ -726,7 +770,7 @@ extern "C" SoundFont* ResourceMgr_LoadAudioSoundFont(int fontIndex) {
|
|||
if (soundFont->instruments[i].lowNotesSound != nullptr)
|
||||
{
|
||||
inst->lowNotesSound.sample =
|
||||
ResourceMgr_LoadAudioSample(soundFont->instruments[i].lowNotesSound->sampleOffset);
|
||||
ResourceMgr_LoadAudioSample(soundFont->instruments[i].lowNotesSound->sampleFileName.c_str());
|
||||
inst->lowNotesSound.tuning = soundFont->instruments[i].lowNotesSound->tuning;
|
||||
} else {
|
||||
inst->lowNotesSound.sample = NULL;
|
||||
|
@ -735,7 +779,7 @@ extern "C" SoundFont* ResourceMgr_LoadAudioSoundFont(int fontIndex) {
|
|||
|
||||
if (soundFont->instruments[i].normalNotesSound != nullptr) {
|
||||
inst->normalNotesSound.sample =
|
||||
ResourceMgr_LoadAudioSample(soundFont->instruments[i].normalNotesSound->sampleOffset);
|
||||
ResourceMgr_LoadAudioSample(soundFont->instruments[i].normalNotesSound->sampleFileName.c_str());
|
||||
inst->normalNotesSound.tuning = soundFont->instruments[i].normalNotesSound->tuning;
|
||||
|
||||
} else {
|
||||
|
@ -745,7 +789,7 @@ extern "C" SoundFont* ResourceMgr_LoadAudioSoundFont(int fontIndex) {
|
|||
|
||||
if (soundFont->instruments[i].highNotesSound != nullptr) {
|
||||
inst->highNotesSound.sample =
|
||||
ResourceMgr_LoadAudioSample(soundFont->instruments[i].highNotesSound->sampleOffset);
|
||||
ResourceMgr_LoadAudioSample(soundFont->instruments[i].highNotesSound->sampleFileName.c_str());
|
||||
inst->highNotesSound.tuning = soundFont->instruments[i].highNotesSound->tuning;
|
||||
} else {
|
||||
inst->highNotesSound.sample = NULL;
|
||||
|
@ -763,7 +807,7 @@ extern "C" SoundFont* ResourceMgr_LoadAudioSoundFont(int fontIndex) {
|
|||
|
||||
for (int i = 0; i < soundFont->soundEffects.size(); i++)
|
||||
{
|
||||
soundFontC->soundEffects[i].sample = ResourceMgr_LoadAudioSample(soundFont->soundEffects[i]->sampleOffset);
|
||||
soundFontC->soundEffects[i].sample = ResourceMgr_LoadAudioSample(soundFont->soundEffects[i]->sampleFileName.c_str());
|
||||
soundFontC->soundEffects[i].tuning = soundFont->soundEffects[i]->tuning;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ uint16_t OTRGetPixelDepth(float x, float y);
|
|||
int32_t OTRGetLastScancode();
|
||||
uint32_t ResourceMgr_GetGameVersion();
|
||||
void ResourceMgr_CacheDirectory(const char* resName);
|
||||
char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize);
|
||||
void ResourceMgr_LoadFile(const char* resName);
|
||||
char* ResourceMgr_LoadFileFromDisk(const char* filePath);
|
||||
char* ResourceMgr_LoadTexByName(const char* texPath);
|
||||
|
@ -46,6 +47,10 @@ Gfx* ResourceMgr_LoadGfxByName(const char* path);
|
|||
Gfx* ResourceMgr_PatchGfxByName(const char* path, int size);
|
||||
Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc);
|
||||
Vtx* ResourceMgr_LoadVtxByName(const char* path);
|
||||
SoundFont* ResourceMgr_LoadAudioSoundFont(int fontIndex);
|
||||
SequenceData ResourceMgr_LoadSeqByID(int seqID);
|
||||
SequenceData ResourceMgr_LoadSeqByName(const char* path);
|
||||
SoundFontSample* ResourceMgr_LoadAudioSample(const char* path);
|
||||
CollisionHeader* ResourceMgr_LoadColByName(const char* path);
|
||||
uint64_t GetPerfCounter();
|
||||
struct SkeletonHeader* ResourceMgr_LoadSkeletonByName(const char* path);
|
||||
|
|
|
@ -1875,7 +1875,9 @@ AudioTable gSampleBankTable = { 0x0007,
|
|||
};
|
||||
#endif
|
||||
|
||||
// OTRTODO: Implement This in OTR File
|
||||
#if 0
|
||||
u8 gSequenceFontTable[1] = { 0 };
|
||||
#else
|
||||
u8 gSequenceFontTable[0x1C0] = {
|
||||
0xDC,
|
||||
0x00,
|
||||
|
@ -2111,3 +2113,4 @@ u8 gSequenceFontTable[0x1C0] = {
|
|||
0x03, 0x01, 0x1F, 0x01, 0x20, 0x01, 0x20, 0x01, 0x09, 0x01, 0x21, 0x01, 0x22, 0x01, 0x21, 0x01, 0x09, 0x01, 0x20,
|
||||
0x01, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
#endif
|
|
@ -544,16 +544,10 @@ u8 gDefaultShortNoteGateTimeTable[] = {
|
|||
};
|
||||
|
||||
AdsrEnvelope gDefaultEnvelope[] = {
|
||||
// OTRTODO: Byteswapped manually for quick audio support.
|
||||
{ 0x0100, 0x007D },
|
||||
{ 0xE803, 0x007D },
|
||||
{ 0xFFFF, 0x0000 },
|
||||
{ 0x0000, 0x0000 },
|
||||
/* { 1, 32000 },
|
||||
{ 1000, 32000 },
|
||||
{ -1, 0 },
|
||||
{ 0, 0 },
|
||||
*/
|
||||
};
|
||||
|
||||
NoteSubEu gZeroNoteSub = { 0 };
|
||||
|
|
|
@ -66,23 +66,24 @@ ReverbSettings D_80133420[][3] = {
|
|||
},
|
||||
};
|
||||
|
||||
// OTRTODO
|
||||
AudioSpec gAudioSpecs[18] = {
|
||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x4000, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[1], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 23, 4, 0, 0, 2, D_80133420[4], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 23, 4, 0, 0, 2, D_80133420[5], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[6], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[7], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 23, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[9], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 23, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 28, 3, 0, 0, 2, D_80133420[10], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x2800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 28, 3, 0, 0, 1, D_80133420[11], 0x300, 0x200, 0x7FFF, 0, 0x4800, 0, 0x4000, 0, 0, 0, 0 },
|
||||
{ 32000, 1, 28, 3, 0, 0, 1, D_80133420[11], 0x300, 0x200, 0x7FFF, 0, 0, 0, 0x4000, 0x4800, 0, 0, 0 },
|
||||
{ 32000, 1, 22, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 22, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 16, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44000, 1, 24, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x4000, 0x2880, 0, 0, 0 },
|
||||
{ 44000, 1, 24, 4, 0, 0, 2, D_80133420[1], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44000, 1, 24, 4, 0, 0, 2, D_80133420[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44000, 1, 23, 4, 0, 0, 2, D_80133420[4], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44000, 1, 23, 4, 0, 0, 2, D_80133420[5], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44000, 1, 24, 4, 0, 0, 2, D_80133420[6], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44000, 1, 24, 4, 0, 0, 2, D_80133420[7], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44000, 1, 23, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44000, 1, 24, 4, 0, 0, 2, D_80133420[9], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44000, 1, 23, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44000, 1, 28, 3, 0, 0, 2, D_80133420[10], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x2800, 0x2880, 0, 0, 0 },
|
||||
{ 44000, 1, 28, 3, 0, 0, 1, D_80133420[11], 0x300, 0x200, 0x7FFF, 0, 0x4800, 0, 0x4000, 0, 0, 0, 0 },
|
||||
{ 44000, 1, 28, 3, 0, 0, 1, D_80133420[11], 0x300, 0x200, 0x7FFF, 0, 0, 0, 0x4000, 0x4800, 0, 0, 0 },
|
||||
{ 44000, 1, 22, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44000, 1, 22, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44000, 1, 16, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 22050, 1, 24, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3600, 0x2600, 0, 0, 0 },
|
||||
{ 44000, 1, 24, 4, 0, 0, 2, D_80133420[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3600, 0x2600, 0, 0, 0 },
|
||||
};
|
||||
|
|
|
@ -45,7 +45,7 @@ void* AudioLoad_SyncLoad(u32 tableType, u32 tableId, s32* didAllocate);
|
|||
u32 AudioLoad_GetRealTableIndex(s32 tableType, u32 tableId);
|
||||
void* AudioLoad_SearchCaches(s32 tableType, s32 id);
|
||||
AudioTable* AudioLoad_GetLoadTable(s32 tableType);
|
||||
void AudioLoad_SyncDma(u32 devAddr, u8* addr, size_t size, s32 medium);
|
||||
void AudioLoad_SyncDma(uintptr_t devAddr, u8* addr, size_t size, s32 medium);
|
||||
void AudioLoad_SyncDmaUnkMedium(u32 devAddr, u8* addr, size_t size, s32 unkMediumParam);
|
||||
s32 AudioLoad_Dma(OSIoMesg* mesg, u32 priority, s32 direction, u32 devAddr, void* ramAddr, size_t size,
|
||||
OSMesgQueue* reqQueue, s32 medium, const char* dmaFuncType);
|
||||
|
@ -75,6 +75,8 @@ void* sUnusedHandler = NULL;
|
|||
|
||||
s32 gAudioContextInitalized = false;
|
||||
|
||||
char* sequenceMap[256];
|
||||
|
||||
uintptr_t fontStart;
|
||||
uint32_t fontOffsets[8192];
|
||||
|
||||
|
@ -372,7 +374,7 @@ void AudioLoad_InitTable(AudioTable* table, uintptr_t romAddr, u16 unkMediumPara
|
|||
SoundFontData* AudioLoad_SyncLoadSeqFonts(s32 seqId, u32* outDefaultFontId) {
|
||||
char pad[0x8];
|
||||
s32 index;
|
||||
SoundFontData* font;
|
||||
SoundFontData* font = NULL;
|
||||
s32 numFonts;
|
||||
s32 fontId;
|
||||
s32 i;
|
||||
|
@ -387,6 +389,7 @@ SoundFontData* AudioLoad_SyncLoadSeqFonts(s32 seqId, u32* outDefaultFontId) {
|
|||
|
||||
while (numFonts > 0) {
|
||||
fontId = gAudioContext.sequenceFontTable[index++];
|
||||
|
||||
font = AudioLoad_SyncLoadFont(fontId);
|
||||
numFonts--;
|
||||
}
|
||||
|
@ -479,13 +482,26 @@ void AudioLoad_AsyncLoadFont(s32 fontId, s32 arg1, s32 retData, OSMesgQueue* ret
|
|||
u8* AudioLoad_GetFontsForSequence(s32 seqId, u32* outNumFonts) {
|
||||
s32 index;
|
||||
|
||||
index = ((u16*)gAudioContext.sequenceFontTable)[seqId];
|
||||
if (!gUseLegacySD)
|
||||
{
|
||||
if (seqId == 255)
|
||||
return NULL;
|
||||
|
||||
*outNumFonts = gAudioContext.sequenceFontTable[index++];
|
||||
if (*outNumFonts == 0) {
|
||||
return NULL;
|
||||
SequenceData sDat = ResourceMgr_LoadSeqByName(sequenceMap[seqId]);
|
||||
|
||||
if (sDat.numFonts == 0)
|
||||
return NULL;
|
||||
|
||||
return sDat.fonts;
|
||||
} else {
|
||||
index = ((u16*)gAudioContext.sequenceFontTable)[seqId];
|
||||
|
||||
*outNumFonts = gAudioContext.sequenceFontTable[index++];
|
||||
if (*outNumFonts == 0) {
|
||||
return NULL;
|
||||
}
|
||||
return &gAudioContext.sequenceFontTable[index];
|
||||
}
|
||||
return &gAudioContext.sequenceFontTable[index];
|
||||
}
|
||||
|
||||
void AudioLoad_DiscardSeqFonts(s32 seqId) {
|
||||
|
@ -564,16 +580,29 @@ s32 AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) {
|
|||
AudioSeq_SequencePlayerDisable(seqPlayer);
|
||||
|
||||
fontId = 0xFF;
|
||||
index = ((u16*)gAudioContext.sequenceFontTable)[seqId];
|
||||
numFonts = gAudioContext.sequenceFontTable[index++];
|
||||
|
||||
while (numFonts > 0) {
|
||||
fontId = gAudioContext.sequenceFontTable[index++];
|
||||
|
||||
//if (gUseLegacySD)
|
||||
AudioLoad_SyncLoadFont(fontId);
|
||||
|
||||
numFonts--;
|
||||
if (gUseLegacySD) {
|
||||
index = ((u16*)gAudioContext.sequenceFontTable)[seqId];
|
||||
numFonts = gAudioContext.sequenceFontTable[index++];
|
||||
|
||||
while (numFonts > 0) {
|
||||
fontId = gAudioContext.sequenceFontTable[index++];
|
||||
|
||||
AudioLoad_SyncLoadFont(fontId); // NOTE: If this is commented out, then enemies will play child link sounds...
|
||||
|
||||
numFonts--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SequenceData seqData2 = ResourceMgr_LoadSeqByName(sequenceMap[seqId]);
|
||||
|
||||
for (int i = 0; i < seqData2.numFonts; i++)
|
||||
{
|
||||
fontId = seqData2.fonts[i];
|
||||
AudioLoad_SyncLoadFont(fontId); // NOTE: If this is commented out, then enemies will play child link sounds...
|
||||
numFonts--;
|
||||
}
|
||||
}
|
||||
|
||||
seqData = AudioLoad_SyncLoadSeq(seqId);
|
||||
|
@ -655,7 +684,6 @@ SoundFontData* AudioLoad_SyncLoadFont(u32 fontId) {
|
|||
s32 didAllocate;
|
||||
RelocInfo relocInfo;
|
||||
s32 realFontId = AudioLoad_GetRealTableIndex(FONT_TABLE, fontId);
|
||||
//s32 realFontId = fontId;
|
||||
|
||||
if (gAudioContext.fontLoadStatus[realFontId] == 1) {
|
||||
return NULL;
|
||||
|
@ -720,13 +748,12 @@ void* AudioLoad_SyncLoad(u32 tableType, u32 id, s32* didAllocate) {
|
|||
|
||||
if (!gUseLegacySD && tableType == SEQUENCE_TABLE)
|
||||
{
|
||||
seqData = ResourceMgr_LoadSeqByID(id);
|
||||
size = ResourceMgr_GetSeqSizeByID(id);
|
||||
size -= 2;
|
||||
medium = seqData[0];
|
||||
cachePolicy = seqData[1];
|
||||
SequenceData sData = ResourceMgr_LoadSeqByName(sequenceMap[id]);
|
||||
seqData = sData.seqData;
|
||||
size = sData.seqDataSize;
|
||||
medium = sData.medium;
|
||||
cachePolicy = sData.cachePolicy;
|
||||
romAddr = 0;
|
||||
seqData += 2;
|
||||
}
|
||||
else if (!gUseLegacySD && tableType == FONT_TABLE)
|
||||
{
|
||||
|
@ -996,7 +1023,7 @@ void AudioLoad_RelocateFont(s32 fontId, SoundFontData* mem, RelocInfo* relocInfo
|
|||
}
|
||||
}
|
||||
|
||||
void AudioLoad_SyncDma(u32 devAddr, u8* addr, size_t size, s32 medium) {
|
||||
void AudioLoad_SyncDma(uintptr_t devAddr, u8* addr, size_t size, s32 medium) {
|
||||
OSMesgQueue* msgQueue = &gAudioContext.syncDmaQueue;
|
||||
OSIoMesg* ioMesg = &gAudioContext.syncDmaIoMesg;
|
||||
size = ALIGN16(size);
|
||||
|
@ -1179,7 +1206,6 @@ s32 AudioLoad_AssertValidAddr(uintptr_t ramAddr, uintptr_t startAddr, size_t siz
|
|||
#define BASE_ROM_OFFSET(x) (void*)((u32)(x) + (u32)(romAddr))
|
||||
|
||||
void AudioLoad_InitSwapFontSampleHeaders(SoundFontSample* sample, uintptr_t romAddr) {
|
||||
// OTRTODO: This will be removed when we actually extract the data.
|
||||
size_t maxSoundFontSize = 0x3AA0; // soundFont 0 is the largest size at 0x3AA0
|
||||
AdpcmLoop* loop;
|
||||
AdpcmBook* book;
|
||||
|
@ -1400,7 +1426,12 @@ void AudioLoad_Init(void* heap, u32 heapSize) {
|
|||
AudioLoad_InitTable(gAudioContext.sequenceTable, seqStart, 0);
|
||||
AudioLoad_InitTable(gAudioContext.soundFontTable, bankStart, 0);
|
||||
AudioLoad_InitTable(gAudioContext.sampleBankTable, tableStart, 0);
|
||||
numFonts = gAudioContext.soundFontTable->numEntries;
|
||||
|
||||
if (gUseLegacySD)
|
||||
numFonts = gAudioContext.soundFontTable->numEntries;
|
||||
else
|
||||
numFonts = 0x26; // OTRTODO: Count the number of soundfonts that are inside the OTR(s)
|
||||
|
||||
gAudioContext.soundFonts = AudioHeap_Alloc(&gAudioContext.audioInitPool, numFonts * sizeof(SoundFont));
|
||||
|
||||
if (gUseLegacySD) {
|
||||
|
@ -1409,6 +1440,23 @@ void AudioLoad_Init(void* heap, u32 heapSize) {
|
|||
}
|
||||
|
||||
AudioLoad_InitSwapFont();
|
||||
} else {
|
||||
int seqListSize = 0;
|
||||
char** seqList = ResourceMgr_ListFiles("audio/sequences*", &seqListSize);
|
||||
|
||||
for (int i = 0; i < seqListSize; i++)
|
||||
{
|
||||
SequenceData sDat = ResourceMgr_LoadSeqByName(seqList[i]);
|
||||
|
||||
char* str = malloc(strlen(seqList[i]) + 1);
|
||||
strcpy(str, seqList[i]);
|
||||
|
||||
sequenceMap[sDat.seqNumber] = str;
|
||||
}
|
||||
|
||||
free(seqList);
|
||||
|
||||
int bp = 0;
|
||||
}
|
||||
|
||||
if (temp_v0_3 = AudioHeap_Alloc(&gAudioContext.audioInitPool, D_8014A6C4.permanentPoolSize), temp_v0_3 == NULL) {
|
||||
|
@ -1429,7 +1477,6 @@ void AudioLoad_InitSlowLoads(void) {
|
|||
s32 AudioLoad_SlowLoadSample(s32 fontId, s32 instId, s8* isDone) {
|
||||
SoundFontSample* sample;
|
||||
AudioSlowLoad* slowLoad;
|
||||
|
||||
sample = AudioLoad_GetFontSample(fontId, instId);
|
||||
if (sample == NULL) {
|
||||
*isDone = 0;
|
||||
|
@ -1601,11 +1648,13 @@ s32 AudioLoad_SlowLoadSeq(s32 seqId, u8* ramAddr, s8* isDone) {
|
|||
slowLoad->sample.sampleAddr = NULL;
|
||||
slowLoad->isDone = isDone;
|
||||
|
||||
if (!gUseLegacySD) {
|
||||
char* seqData = ResourceMgr_LoadSeqByID(seqId);
|
||||
size = ResourceMgr_GetSeqSizeByID(seqId) - 2;
|
||||
slowLoad->curDevAddr = seqData + 2;
|
||||
slowLoad->medium = seqData[0];
|
||||
if (!gUseLegacySD)
|
||||
{
|
||||
SequenceData sData = ResourceMgr_LoadSeqByName(sequenceMap[seqId]);
|
||||
char* seqData = sData.seqData;
|
||||
size = sData.seqDataSize;
|
||||
slowLoad->curDevAddr = seqData;
|
||||
slowLoad->medium = sData.medium;
|
||||
} else {
|
||||
size = seqTable->entries[seqId].size;
|
||||
size = ALIGN16(size);
|
||||
|
@ -1829,41 +1878,23 @@ void AudioLoad_AsyncDmaUnkMedium(u32 devAddr, void* ramAddr, size_t size, s16 ar
|
|||
#define RELOC(v, base) (reloc = (void*)((u32)(v) + (u32)(base)))
|
||||
|
||||
void AudioLoad_RelocateSample(SoundFontSound* sound, SoundFontData* mem, RelocInfo* relocInfo, int fontId) {
|
||||
// OTRTODO: This is hack to detect whether or not the sample has been relocated.
|
||||
size_t maxSoundBankSize = 0x3EB2A0; // sample bank 0 is largest size at 0x3EB2A0
|
||||
if ((uintptr_t)mem <= maxSoundBankSize) {
|
||||
// OTRTODO: This can be removed once we have properly byteswapped files on the disk.
|
||||
assert("mem for sound font bank is too low.");
|
||||
if (gUseLegacySD)
|
||||
{
|
||||
// NOTE: This is hack to detect whether or not the sample has been relocated.
|
||||
if ((uintptr_t)mem <= maxSoundBankSize) {
|
||||
assert("mem for sound font bank is too low.");
|
||||
}
|
||||
}
|
||||
|
||||
SoundFontSample* sample;
|
||||
void* reloc;
|
||||
|
||||
// OTRTODO: Seems precarious to assume the RAM is never <= 0x3EB2A0, but it largely works.
|
||||
// NOTE: Seems precarious to assume the RAM is never <= 0x3EB2A0, but it largely works.
|
||||
if ((uintptr_t)sound->sample < maxSoundBankSize || !gUseLegacySD)
|
||||
{
|
||||
if (!gUseLegacySD) {
|
||||
SoundFontSample* sample2 = sound;
|
||||
|
||||
if (sample2->unk_bit25 != 1)
|
||||
{
|
||||
//if (sample2->size == 0x5CC8)
|
||||
//{
|
||||
// switch (sample2->medium) {
|
||||
// case 0:
|
||||
// sample2->medium = relocInfo->medium1;
|
||||
// break;
|
||||
// case 1:
|
||||
// sample2->medium = relocInfo->medium2;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// sample2->unk_bit25 = 1;
|
||||
// if (sample2->unk_bit26 && (sample2->medium != MEDIUM_RAM)) {
|
||||
// // gAudioContext.usedSamples[gAudioContext.numUsedSamples++] = sample2;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
} else {
|
||||
sample = sound->sample = RELOC(sound->sample, mem);
|
||||
|
||||
|
@ -2116,8 +2147,10 @@ s32 AudioLoad_GetSamplesForFont(s32 fontId, SoundFontSample** sampleSet) {
|
|||
void AudioLoad_AddUsedSample(SoundFontSound* sound) {
|
||||
SoundFontSample* sample = sound->sample;
|
||||
|
||||
if ((sample->size != 0) && (sample->unk_bit26) && (sample->medium != MEDIUM_RAM)) {
|
||||
gAudioContext.usedSamples[gAudioContext.numUsedSamples++] = sample;
|
||||
if (sample != NULL) {
|
||||
if ((sample->size != 0) && (sample->unk_bit26) && (sample->medium != MEDIUM_RAM)) {
|
||||
gAudioContext.usedSamples[gAudioContext.numUsedSamples++] = sample;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -286,7 +286,18 @@ void Audio_ProcessNotes(void) {
|
|||
}
|
||||
|
||||
subAttrs.frequency *= playbackState->vibratoFreqScale * playbackState->portamentoFreqScale;
|
||||
subAttrs.frequency *= gAudioContext.audioBufferParameters.resampleRate;
|
||||
|
||||
f32 resampRate = gAudioContext.audioBufferParameters.resampleRate;
|
||||
|
||||
if (!gUseLegacySD && !noteSubEu2->bitField1.isSyntheticWave && noteSubEu2->sound.soundFontSound != NULL &&
|
||||
noteSubEu2->sound.soundFontSound->sample != NULL &&
|
||||
noteSubEu2->sound.soundFontSound->sample->sampleRateMagicValue == 'RIFF') {
|
||||
resampRate = CALC_RESAMPLE_FREQ(noteSubEu2->sound.soundFontSound->sample->sampleRate);
|
||||
}
|
||||
|
||||
subAttrs.frequency *= resampRate;
|
||||
|
||||
|
||||
subAttrs.velocity *= scale;
|
||||
Audio_InitNoteSub(note, noteSubEu2, &subAttrs);
|
||||
noteSubEu->bitField1.bookOffset = bookOffset;
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
#include "ultra64.h"
|
||||
#include "global.h"
|
||||
|
||||
extern bool gUseLegacySD;
|
||||
extern char* sequenceMap[256];
|
||||
|
||||
#define PORTAMENTO_IS_SPECIAL(x) ((x).mode & 0x80)
|
||||
#define PORTAMENTO_MODE(x) ((x).mode & ~0x80)
|
||||
#define PORTAMENTO_MODE_1 1
|
||||
|
@ -1060,9 +1063,15 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
|
|||
command = (u8)parameters[0];
|
||||
|
||||
if (seqPlayer->defaultFont != 0xFF) {
|
||||
offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId];
|
||||
lowBits = gAudioContext.sequenceFontTable[offset];
|
||||
command = gAudioContext.sequenceFontTable[offset + lowBits - result];
|
||||
if (gUseLegacySD) {
|
||||
offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId];
|
||||
lowBits = gAudioContext.sequenceFontTable[offset];
|
||||
command = gAudioContext.sequenceFontTable[offset + lowBits - result];
|
||||
}
|
||||
else {
|
||||
SequenceData sDat = ResourceMgr_LoadSeqByName(sequenceMap[seqPlayer->seqId]);
|
||||
command = sDat.fonts[sDat.numFonts - result - 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, command)) {
|
||||
|
@ -1170,10 +1179,17 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
|
|||
result = (u8)parameters[0];
|
||||
command = (u8)parameters[0];
|
||||
|
||||
if (seqPlayer->defaultFont != 0xFF) {
|
||||
offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId];
|
||||
lowBits = gAudioContext.sequenceFontTable[offset];
|
||||
command = gAudioContext.sequenceFontTable[offset + lowBits - result];
|
||||
if (seqPlayer->defaultFont != 0xFF)
|
||||
{
|
||||
if (gUseLegacySD) {
|
||||
offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId];
|
||||
lowBits = gAudioContext.sequenceFontTable[offset];
|
||||
command = gAudioContext.sequenceFontTable[offset + lowBits - result];
|
||||
}
|
||||
else {
|
||||
SequenceData sDat = ResourceMgr_LoadSeqByName(sequenceMap[seqPlayer->seqId]);
|
||||
command = sDat.fonts[sDat.numFonts - result - 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, command)) {
|
||||
|
@ -1330,14 +1346,12 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
|
|||
break;
|
||||
case 0xB2:
|
||||
offset = (u16)parameters[0];
|
||||
// OTRTODO: Byteswap added for quick audio
|
||||
channel->unk_22 = BOMSWAP16(*(u16*)(seqPlayer->seqData + (uintptr_t)(offset + scriptState->value * 2)));
|
||||
break;
|
||||
case 0xB4:
|
||||
channel->dynTable = (void*)&seqPlayer->seqData[channel->unk_22];
|
||||
break;
|
||||
case 0xB5:
|
||||
// OTRTODO: Byteswap added for quick audio
|
||||
channel->unk_22 = BOMSWAP16(((u16*)(channel->dynTable))[scriptState->value]);
|
||||
break;
|
||||
case 0xB6:
|
||||
|
|
|
@ -440,11 +440,11 @@ void func_800DBE64(void) {
|
|||
void func_800DBE6C(void) {
|
||||
}
|
||||
|
||||
void AudioSynth_LoadFilter(Acmd* cmd, s32 flags, s32 countOrBuf, s32 addr) {
|
||||
void AudioSynth_LoadFilter(Acmd* cmd, s32 flags, s32 countOrBuf, uintptr_t addr) {
|
||||
aFilter(cmd, flags, countOrBuf, addr);
|
||||
}
|
||||
|
||||
void AudioSynth_LoadFilterCount(Acmd* cmd, s32 count, s32 addr) {
|
||||
void AudioSynth_LoadFilterCount(Acmd* cmd, s32 count, uintptr_t addr) {
|
||||
aFilter(cmd, 2, count, addr);
|
||||
}
|
||||
|
||||
|
@ -561,6 +561,9 @@ Acmd* AudioSynth_DoOneAudioUpdate(s16* aiBuf, s32 aiBufLen, Acmd* cmd, s32 updat
|
|||
NoteSubEu* noteSubEu2;
|
||||
s32 unk14;
|
||||
|
||||
if (aiBufLen == 0)
|
||||
return;
|
||||
|
||||
t = gAudioContext.numNotes * updateIndex;
|
||||
count = 0;
|
||||
if (gAudioContext.numSynthesisReverbs == 0) {
|
||||
|
|
|
@ -363,7 +363,11 @@ void Audio_ProcessSeqCmd(u32 cmd) {
|
|||
}
|
||||
}
|
||||
|
||||
void Audio_QueueSeqCmd(u32 cmd) {
|
||||
extern f32 D_80130F24;
|
||||
extern f32 D_80130F28;
|
||||
|
||||
void Audio_QueueSeqCmd(u32 cmd)
|
||||
{
|
||||
sAudioSeqCmds[sSeqCmdWrPos++] = cmd;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue