diff --git a/soh/soh/Enhancements/accessible-actors/AccessibleActorList.cpp b/soh/soh/Enhancements/accessible-actors/AccessibleActorList.cpp index 35ca0c3a5..90a9c313f 100644 --- a/soh/soh/Enhancements/accessible-actors/AccessibleActorList.cpp +++ b/soh/soh/Enhancements/accessible-actors/AccessibleActorList.cpp @@ -461,13 +461,6 @@ void accessible_goma(AccessibleActor* actor) { } } -void accessible_door_of_time(AccessibleActor* actor) { - ActorAccessibility_PlaySampleForActor(actor, 0, "Chanting", false); - ActorAccessibility_SetSoundPitch(actor, 0, 1.0); - - // ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_DIAMOND_SWITCH, false); -} - void accessible_sticks(AccessibleActor* actor) { EnKarebaba* baba = (EnKarebaba*)actor->actor; @@ -891,8 +884,6 @@ void ActorAccessibility_InitActors() { ActorAccessibility_InitPolicy(&policy, "Amos Statue", NA_SE_EN_AMOS_WAVE); policy.n = 30; ActorAccessibility_AddSupportedActor(ACTOR_EN_AM, policy); - ActorAccessibility_InitPolicy(&policy, "door of time", accessible_door_of_time); - ActorAccessibility_AddSupportedActor(ACTOR_BG_MJIN, policy); ActorAccessibility_InitPolicy(&policy, "shooting gallery rupees", nullptr); policy.aimAssist.isProvider = true; policy.distance = 1000; diff --git a/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.cpp b/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.cpp index bb25ec07f..0c2e07807 100644 --- a/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.cpp +++ b/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.cpp @@ -30,8 +30,7 @@ enum AAE_COMMANDS { AAE_PAN, AAE_FILTER, AAE_SEEK, - AAE_LISTENER, // Set the listener's position and direction. - AAE_POS, // Set the sound source's position and direction. + AAE_POS, AAE_PREPARE, AAE_TERMINATE, }; @@ -108,11 +107,12 @@ void AccessibleAudioEngine::destroy() { ma_resource_manager_uninit(&resourceManager); } } + void AccessibleAudioEngine::destroyAndThrow(const char* exceptionText) { destroy(); - throw std::runtime_error(exceptionText); } + uint32_t AccessibleAudioEngine::retrieve(float* buffer, uint32_t nFrames) { uint32_t framesAvailable = ma_pcm_rb_available_read(&preparedOutput); if (nFrames > framesAvailable) @@ -136,6 +136,7 @@ uint32_t AccessibleAudioEngine::retrieve(float* buffer, uint32_t nFrames) { return ogNFrames; } + void AccessibleAudioEngine::doPrepare(SoundAction& action) { framesUntilGC--; int nFrames = ma_pcm_rb_available_write(&preparedOutput); @@ -214,7 +215,6 @@ void AccessibleAudioEngine::runThread() { case AAE_STOP_ALL: doStopAllSounds(action); break; - case AAE_PITCH: doSetPitch(action); break; @@ -233,13 +233,9 @@ void AccessibleAudioEngine::runThread() { case AAE_SEEK: doSeekSound(action); break; - case AAE_LISTENER: - doSetListenerPos(action); - break; case AAE_POS: doSetSoundPos(action); break; - case AAE_PREPARE: doPrepare(action); break; @@ -351,8 +347,6 @@ void AccessibleAudioEngine::doSeekSound(SoundAction& action) { return; ma_sound_seek_to_pcm_frame(&slot->sound, action.offset); } -void AccessibleAudioEngine::doSetListenerPos(SoundAction& action) { -} void AccessibleAudioEngine::doSetSoundPos(SoundAction& action) { SoundSlot* slot = findSound(action); if (slot == NULL) @@ -469,13 +463,12 @@ void AccessibleAudioEngine::mix(int16_t* ogBuffer, uint32_t nFrames) { float mixedChunk[AAE_MIX_CHUNK_SIZE * AAE_CHANNELS]; while (nFrames > 0) { uint32_t nextChunk = std::min(AAE_MIX_CHUNK_SIZE, nFrames); - ma_silence_pcm_frames( - sourceChunk, nextChunk, ma_format_f32, - AAE_CHANNELS); // This is so that it doesn't matter if we have less output available than expected. + // This is so that it doesn't matter if we have less output available than expected. + ma_silence_pcm_frames(sourceChunk, nextChunk, ma_format_f32, AAE_CHANNELS); ma_silence_pcm_frames(mixedChunk, nextChunk, ma_format_f32, AAE_CHANNELS); retrieve(sourceChunk, nextChunk); - ma_pcm_s16_to_f32(mixedChunk, ogBuffer, nextChunk * AAE_CHANNELS, - ma_dither_mode_none); // The game's output is changed to 32-bit floating point samples. + // The game's output is changed to 32-bit floating point samples. + ma_pcm_s16_to_f32(mixedChunk, ogBuffer, nextChunk * AAE_CHANNELS, ma_dither_mode_none); ma_mix_pcm_frames_f32(mixedChunk, sourceChunk, nextChunk, AAE_CHANNELS, 1.0); // If we've gone over 1.0, we'll need to scale back before we go back to 16-bit or we'll distort. float scalar = 1.0; @@ -486,12 +479,13 @@ void AccessibleAudioEngine::mix(int16_t* ogBuffer, uint32_t nFrames) { for (int i = 0; i < nextChunk * AAE_CHANNELS; i++) mixedChunk[i] *= scalar; } - ma_pcm_f32_to_s16(ogBuffer, mixedChunk, nextChunk * AAE_CHANNELS, - ma_dither_mode_triangle); // Chunk is ready to go out via the game's usual channels. + // Chunk is ready to go out via the game's usual channels + ma_pcm_f32_to_s16(ogBuffer, mixedChunk, nextChunk * AAE_CHANNELS, ma_dither_mode_triangle); ogBuffer += nextChunk * AAE_CHANNELS; nFrames -= nextChunk; } } + void AccessibleAudioEngine::playSound(uintptr_t handle, int slot, const char* path, bool looping) { if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) return; @@ -502,6 +496,7 @@ void AccessibleAudioEngine::playSound(uintptr_t handle, int slot, const char* pa action.path = path; action.looping = looping; } + void AccessibleAudioEngine::stopSound(uintptr_t handle, int slot) { if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) return; @@ -510,25 +505,26 @@ void AccessibleAudioEngine::stopSound(uintptr_t handle, int slot) { action.handle = (uintptr_t)handle; action.slot = slot; } + void AccessibleAudioEngine::stopAllSounds(uintptr_t handle) { SoundAction& action = getNextOutgoingSoundAction(); action.command = AAE_STOP_ALL; action.handle = handle; } + void AccessibleAudioEngine::setPitch(uintptr_t handle, int slot, float pitch) { if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) return; - SoundAction& action = getNextOutgoingSoundAction(); action.command = AAE_PITCH; action.handle = handle; action.slot = slot; action.pitch = pitch; } + void AccessibleAudioEngine::setPitchBehindModifier(uintptr_t handle, int slot, float mod) { if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) return; - SoundAction& action = getNextOutgoingSoundAction(); action.command = AAE_PITCH_BEHIND; action.handle = handle; @@ -537,7 +533,6 @@ void AccessibleAudioEngine::setPitchBehindModifier(uintptr_t handle, int slot, f } void AccessibleAudioEngine::setVolume(uintptr_t handle, int slot, float volume) { - if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) return; SoundAction& action = getNextOutgoingSoundAction(); @@ -546,6 +541,7 @@ void AccessibleAudioEngine::setVolume(uintptr_t handle, int slot, float volume) action.slot = slot; action.volume = volume; } + void AccessibleAudioEngine::setPan(uintptr_t handle, int slot, float pan) { if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) return; @@ -576,6 +572,7 @@ void AccessibleAudioEngine::seekSound(uintptr_t handle, int slot, size_t offset) action.command = AAE_SEEK; action.offset = offset; } + void AccessibleAudioEngine::setSoundPosition(uintptr_t handle, int slot, float posX, float posY, float posZ, float distToPlayer, float maxDistance) { if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) @@ -590,14 +587,15 @@ void AccessibleAudioEngine::setSoundPosition(uintptr_t handle, int slot, float p action.distToPlayer = distToPlayer; action.maxDistance = maxDistance; } + void AccessibleAudioEngine::prepare() { SoundAction& action = getNextOutgoingSoundAction(); action.command = AAE_PREPARE; // This is called once at the end of every frame, so now is the time to post all of the accumulated commands. postSoundActions(); } -void AccessibleAudioEngine::cacheDecodedSample(std::string& path, void* data, size_t size) { - // The data is stored in wave format, so we register it with MiniAudio as an encoded asset as opposed to a decoded - // one. - ma_resource_manager_register_encoded_data(&resourceManager, path.c_str(), data, size); + +void AccessibleAudioEngine::cacheDecodedSample(const char* path, void* data, size_t size) { + // data stored as wave, so we register it with MiniAudio as an encoded asset as opposed to a decoded one + ma_resource_manager_register_encoded_data(&resourceManager, path, data, size); } \ No newline at end of file diff --git a/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.h b/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.h index f25b79586..898adce77 100644 --- a/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.h +++ b/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.h @@ -32,7 +32,7 @@ struct SoundAction { float distance; }; - // Position and rotation vectors for AAE_LISTENER and AAE_POS. + // Position and rotation vectors for AAE_POS float posX; float posY; float posZ; @@ -147,5 +147,5 @@ class AccessibleAudioEngine { float maxDistance); // Schedule the preparation of output for delivery. void prepare(); - void cacheDecodedSample(std::string& path, void* data, size_t size); + void cacheDecodedSample(const char* path, void* data, size_t size); }; diff --git a/soh/soh/Enhancements/accessible-actors/ActorAccessibility.cpp b/soh/soh/Enhancements/accessible-actors/ActorAccessibility.cpp index ccdd7f639..85a8d197e 100644 --- a/soh/soh/Enhancements/accessible-actors/ActorAccessibility.cpp +++ b/soh/soh/Enhancements/accessible-actors/ActorAccessibility.cpp @@ -62,7 +62,6 @@ typedef std::unordered_set SceneList_t; typedef struct { std::string path; std::shared_ptr resource; - std::shared_ptr decodedSample; // Set if the record is for a raw sample as opposed to a SFX. } SfxRecord; class AudioGlossaryData { @@ -88,9 +87,10 @@ class ActorAccessibility { SceneList_t sceneList; AccessibleAudioEngine* audioEngine; SfxExtractor sfxExtractor; - std::unordered_map sfxMap; // Maps internal sfx to external (prerendered) resources. - std::unordered_map - sampleMap; // Similar to above, but this one maps raw audio samples as opposed to SFX. + // Maps internal sfx to external (prerendered) resources. + std::unordered_map sfxMap; + // Similar to above, but this one maps raw audio samples as opposed to SFX. + std::unordered_set sampleMap; int extractSfx = 0; s16 currentScene = -1; s8 currentRoom = -1; @@ -708,7 +708,7 @@ const char* ActorAccessibility_MapSfxToExternalAudio(s16 sfxId) { tempRecord.path = ss.str(); aa->sfxMap[sfxId] = tempRecord; record = &aa->sfxMap[sfxId]; - aa->audioEngine->cacheDecodedSample(record->path, record->resource->Buffer->data(), + aa->audioEngine->cacheDecodedSample(record->path.c_str(), record->resource->Buffer->data(), record->resource->Buffer->size()); } else { record = &it->second; @@ -718,32 +718,24 @@ const char* ActorAccessibility_MapSfxToExternalAudio(s16 sfxId) { } // Map the path to a raw sample to the external audio engine. const char* ActorAccessibility_MapRawSampleToExternalAudio(const char* name) { - SfxRecord* record; - std::string key(name); - auto it = aa->sampleMap.find(key); + auto it = aa->sampleMap.find(name); if (it == aa->sampleMap.end()) { - SfxRecord tempRecord; std::stringstream ss; - ss << "audio/samples/" << key; + ss << "audio/samples/" << name; std::string fullPath = ss.str(); auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResource(fullPath); if (res == nullptr) return NULL; // Resource doesn't exist, user's gotta run the extractor. AudioDecoder decoder; decoder.setSample((SOH::AudioSample*)res.get()); + // TODO track wav somehow & free it with drwav_free s16* wav; size_t wavSize = decoder.decodeToWav(&wav); - - tempRecord.path = key; - tempRecord.decodedSample = std::make_shared(wav); - aa->sampleMap[key] = tempRecord; - record = &aa->sampleMap[key]; - aa->audioEngine->cacheDecodedSample(record->path, wav, wavSize); - } else { - record = &it->second; + aa->sampleMap.insert(name); + aa->audioEngine->cacheDecodedSample(name, wav, wavSize); } - return record->path.c_str(); + return name; } // Call once per frame to tell the audio engine to start working on the latest batch of queued instructions. diff --git a/soh/soh/Enhancements/accessible-actors/SfxExtractor.cpp b/soh/soh/Enhancements/accessible-actors/SfxExtractor.cpp index c18445408..8733e4ec3 100644 --- a/soh/soh/Enhancements/accessible-actors/SfxExtractor.cpp +++ b/soh/soh/Enhancements/accessible-actors/SfxExtractor.cpp @@ -6,7 +6,6 @@ #include "soh/OTRGlobals.h" #include "SfxTable.h" #include -const char* GetLanguageCode(); extern "C" { #include "z64.h" #include "functions.h" @@ -93,14 +92,14 @@ bool SfxExtractor::renderOutput(size_t endOfInput) { } drwav_uninit(&wav); std::vector fileData((uint8_t*)mem, (uint8_t*)mem + size); - drwav_free(mem, NULL); + drwav_free(mem, nullptr); return archive->WriteFile(fileName.c_str(), fileData); } void SfxExtractor::setup() { try { SpeechSynthesizer::Instance->Speak( - "Sfx extraction speedrun initiated. Please wait. This will take a few minutes.", GetLanguageCode()); + "Sfx extraction speedrun initiated. Please wait. This will take a few minutes.", "en-US"); // Kill the audio thread so we can take control. captureThreadState = CT_WAITING; OTRAudio_InstallSfxCaptureThread(); @@ -171,7 +170,7 @@ void SfxExtractor::finished() { << std::endl; if (currentStep == STEP_ERROR_OTR) ss << "In all seriousness, please delete accessibility.o2r and try again."; - SpeechSynthesizer::Instance->Speak(ss.str().c_str(), GetLanguageCode()); + SpeechSynthesizer::Instance->Speak(ss.str().c_str(), "en-US"); } else Audio_PlayFanfare(NA_BGM_ITEM_GET); } @@ -180,7 +179,7 @@ void SfxExtractor::maybeGiveProgressReport() { if (sfxToRip == sfxCount * (i + 1) / 10) { std::stringstream ss; ss << (i + 1) * 10 << " percent complete."; - SpeechSynthesizer::Instance->Speak(ss.str().c_str(), GetLanguageCode()); + SpeechSynthesizer::Instance->Speak(ss.str().c_str(), "en-US"); } } } diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 2a47b7a34..9ff253c3c 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2567,8 +2567,7 @@ extern "C" void OTRAudio_UninstallSfxCaptureThread() { std::unique_lock OTRAudio_Lock() { return std::unique_lock(audio.mutex); } -// extern "C" void CheckTracker_OnMessageClose() { -// CheckTracker::CheckTrackerDialogClosed(); + extern "C" void Gfx_UnregisterBlendedTexture(const char* name) { gfx_unregister_blended_texture(name); }