From 61889eb9dab3d5cb3e7c8a0c1a2ea074c3758beb Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sat, 26 Apr 2025 03:55:21 +0000 Subject: [PATCH] remove AudioDecoder --- .../AccessibleAudioEngine.cpp | 1 + .../accessible-actors/ActorAccessibility.cpp | 36 ---- .../accessible-actors/ActorAccessibility.h | 4 - .../accessible-actors/SfxExtractor.cpp | 1 - soh/soh/Enhancements/audio/AudioDecoder.cpp | 158 ------------------ soh/soh/Enhancements/audio/AudioDecoder.h | 33 ---- 6 files changed, 1 insertion(+), 232 deletions(-) delete mode 100644 soh/soh/Enhancements/audio/AudioDecoder.cpp delete mode 100644 soh/soh/Enhancements/audio/AudioDecoder.h diff --git a/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.cpp b/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.cpp index f63ed5ca9..2f69f4702 100644 --- a/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.cpp +++ b/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.cpp @@ -8,6 +8,7 @@ #define AAE_LPF_ORDER 4 #define NOMINMAX // because Windows is a joke. +#define MINIAUDIO_IMPLEMENTATION #include "AccessibleAudioEngine.h" extern "C" { diff --git a/soh/soh/Enhancements/accessible-actors/ActorAccessibility.cpp b/soh/soh/Enhancements/accessible-actors/ActorAccessibility.cpp index 99d1f0c35..60c806ea5 100644 --- a/soh/soh/Enhancements/accessible-actors/ActorAccessibility.cpp +++ b/soh/soh/Enhancements/accessible-actors/ActorAccessibility.cpp @@ -18,7 +18,6 @@ #include "soh/Enhancements/speechsynthesizer/SpeechSynthesizer.h" #include "soh/Enhancements/tts/tts.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" -#include "soh/Enhancements/audio/AudioDecoder.h" extern "C" { extern PlayState* gPlayState; @@ -89,8 +88,6 @@ class ActorAccessibility { SfxExtractor sfxExtractor; // 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_map> sampleMap; int extractSfx = 0; s16 currentScene = -1; s8 currentRoom = -1; @@ -266,14 +263,7 @@ void ActorAccessibility_PlaySound(void* handle, int slot, s16 sfxId, bool loopin return; aa->audioEngine->playSound((uintptr_t)handle, slot, path, looping); } -const char* ActorAccessibility_MapRawSampleToExternalAudio(const char* name); -void ActorAccessibility_PlayRawSample(void* handle, int slot, const char* name, bool looping) { - const char* path = ActorAccessibility_MapRawSampleToExternalAudio(name); - if (path == NULL) - return; - aa->audioEngine->playSound((uintptr_t)handle, slot, path, looping); -} void ActorAccessibility_StopSound(void* handle, int slot) { aa->audioEngine->stopSound((uintptr_t)handle, slot); } @@ -319,12 +309,6 @@ void ActorAccessibility_PlaySoundForActor(AccessibleActor* actor, int slot, s16 ActorAccessibility_PlaySound(actor, slot, sfxId, looping); ActorAccessibility_ConfigureSoundForActor(actor, slot); } -void ActorAccessibility_PlaySampleForActor(AccessibleActor* actor, int slot, const char* name, bool looping) { - if (slot < 0 || slot > AAE_SLOTS_PER_HANDLE) - return; - ActorAccessibility_PlayRawSample(actor, slot, name, looping); - ActorAccessibility_ConfigureSoundForActor(actor, slot); -} void ActorAccessibility_StopSoundForActor(AccessibleActor* actor, int slot) { if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) return; @@ -717,26 +701,6 @@ const char* ActorAccessibility_MapSfxToExternalAudio(s16 sfxId) { return record->path.c_str(); } -// Map the path to a raw sample to the external audio engine. -const char* ActorAccessibility_MapRawSampleToExternalAudio(const char* name) { - auto it = aa->sampleMap.find(name); - if (it == aa->sampleMap.end()) { - std::stringstream ss; - 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()); - auto pair = aa->sampleMap.insert({ name, decoder.decodeToWav() }); - ma_resource_manager_register_encoded_data(&aa->audioEngine->resourceManager, name, - pair.first->second.data(), pair.first->second.size()); - } - - return name; -} - // Call once per frame to tell the audio engine to start working on the latest batch of queued instructions. void ActorAccessibility_PrepareNextAudioFrame() { aa->audioEngine->prepare(); diff --git a/soh/soh/Enhancements/accessible-actors/ActorAccessibility.h b/soh/soh/Enhancements/accessible-actors/ActorAccessibility.h index 8fa7a34c1..218d04e87 100644 --- a/soh/soh/Enhancements/accessible-actors/ActorAccessibility.h +++ b/soh/soh/Enhancements/accessible-actors/ActorAccessibility.h @@ -103,9 +103,6 @@ void ActorAccessibility_RunAccessibilityForAllActors(PlayState* play); *must have previously prepared. looping: whether to play the sound just once or on a continuous loop. */ void ActorAccessibility_PlaySound(void* actor, int slot, s16 sfxId, bool looping); -// Play one of the game's internal samples. -void ActorAccessibility_PlayRawSample(void* handle, int slot, const char* name, bool looping); -// // Stop a sound. Todo: consider making this a short fade instead of just cutting it off. void ActorAccessibility_StopSound(void* handle, int slot); void ActorAccessibility_StopAllSounds(void* handle); @@ -130,7 +127,6 @@ void ActorAccessibility_SeekSound(void* handle, int slot, size_t offset); * */ void ActorAccessibility_PlaySoundForActor(AccessibleActor* actor, int slot, s16 sfxId, bool looping); -void ActorAccessibility_PlaySampleForActor(AccessibleActor* actor, int slot, const char* name, bool looping); void ActorAccessibility_StopSoundForActor(AccessibleActor* actor, int slot); void ActorAccessibility_StopAllSoundsForActor(AccessibleActor* actor); diff --git a/soh/soh/Enhancements/accessible-actors/SfxExtractor.cpp b/soh/soh/Enhancements/accessible-actors/SfxExtractor.cpp index e92c9d2e3..1af6569a1 100644 --- a/soh/soh/Enhancements/accessible-actors/SfxExtractor.cpp +++ b/soh/soh/Enhancements/accessible-actors/SfxExtractor.cpp @@ -1,5 +1,4 @@ #include "SfxExtractor.h" -#include "soh/Enhancements/audio/AudioDecoder.h" #include "soh/Enhancements/audio/miniaudio.h" #include "soh/Enhancements/speechsynthesizer/SpeechSynthesizer.h" #include "soh/Enhancements/tts/tts.h" diff --git a/soh/soh/Enhancements/audio/AudioDecoder.cpp b/soh/soh/Enhancements/audio/AudioDecoder.cpp deleted file mode 100644 index 80f7b753e..000000000 --- a/soh/soh/Enhancements/audio/AudioDecoder.cpp +++ /dev/null @@ -1,158 +0,0 @@ -#define MINIAUDIO_IMPLEMENTATION -#include "AudioDecoder.h" -#include "z64audio.h" -#include -#define WAV_DECODE_CHUNK_SIZE 64 -// A handful of definitions need to be copied from mixer.c. -#define ROUND_UP_32(v) (((v) + 31) & ~31) -// The below is copied verbatim from mixer.c. -static inline int16_t clamp16(int32_t v) { - if (v < -0x8000) { - return -0x8000; - } else if (v > 0x7fff) { - return 0x7fff; - } else { - return v; - } -} - -AudioDecoder::AudioDecoder() { - prev1 = 0; - prev2 = 0; -} -AudioDecoder::~AudioDecoder() { -} - -void AudioDecoder::setSample(SOH::AudioSample* sample) { - this->sample.codec = sample->sample.codec; - this->sample.loop.start = sample->sample.loop->start; - this->sample.loop.end = sample->sample.loop->end; - this->sample.loop.count = sample->sample.loop->count; - - if (sample->book.book == nullptr) - memset(adpcm_table, 0, 8 * 2 * 8 * 2); - else - memcpy(adpcm_table, sample->sample.book->book, - 16 * sample->sample.book->order * sample->sample.book->npredictors); - prev1 = 0; - prev2 = 0; - in = sample->sample.sampleAddr; - inStart = in; - inEnd = in + sample->sample.size; -} - -void AudioDecoder::setSample(SoundFontSample* sample) { - this->sample.codec = sample->codec; - this->sample.loop.start = sample->loop->start; - this->sample.loop.end = sample->loop->end; - this->sample.loop.count = sample->loop->count; - - if (sample->book->book == nullptr) - memset(adpcm_table, 0, 8 * 2 * 8 * 2); - else - memcpy(adpcm_table, sample->book->book, 16 * sample->book->order * sample->book->npredictors); - prev1 = 0; - prev2 = 0; - in = sample->sampleAddr; - inStart = in; - inEnd = in + sample->size; -} - -size_t AudioDecoder::decode(int16_t* out, size_t nSamples) { - size_t samplesOut = 0; - size_t nbytes = nSamples * 2; - // Prevent the decoder from using more output bytes than declared to be available by the callee. - nbytes -= 31; - nbytes = ROUND_UP_32(nbytes); - while (nbytes > 0 && in < inEnd) { - int shift = *in >> 4; // should be in 0..12 or 0..14 - int table_index = *in++ & 0xf; // should be in 0..7 - int16_t(*tbl)[8] = adpcm_table[table_index]; - int i; - - for (i = 0; i < 2; i++) { - int16_t ins[8]; - int j, k; - if (sample.codec == CODEC_SMALL_ADPCM) { - for (j = 0; j < 2; j++) { - ins[j * 4] = (((*in >> 6) << 30) >> 30) << shift; - ins[j * 4 + 1] = ((((*in >> 4) & 0x3) << 30) >> 30) << shift; - ins[j * 4 + 2] = ((((*in >> 2) & 0x3) << 30) >> 30) << shift; - ins[j * 4 + 3] = (((*in++ & 0x3) << 30) >> 30) << shift; - } - } else { - for (j = 0; j < 4; j++) { - ins[j * 2] = (((*in >> 4) << 28) >> 28) << shift; - ins[j * 2 + 1] = (((*in++ & 0xf) << 28) >> 28) << shift; - } - } - for (j = 0; j < 8; j++) { - int32_t acc = tbl[0][j] * prev2 + tbl[1][j] * prev1 + (ins[j] << 11); - for (k = 0; k < j; k++) { - acc += tbl[1][((j - k) - 1)] * ins[k]; - } - acc >>= 11; - *out++ = clamp16(acc); - samplesOut++; - } - prev1 = out[-1]; - prev2 = out[-2]; - } - nbytes -= 16 * sizeof(int16_t); - } - return samplesOut; -} - -ma_result wavWrite(ma_encoder* pEncoder, const void* pBufferIn, size_t bytesToWrite, size_t* pBytesWritten) { - auto fileData = (std::vector*)pEncoder->pUserData; - fileData->insert(fileData->end(), (uint8_t*)pBufferIn, (uint8_t*)pBufferIn + bytesToWrite); - if (pBytesWritten != NULL) { - *pBytesWritten = bytesToWrite; - } - return MA_SUCCESS; -} - -ma_result wavSeek(ma_encoder* pEncoder, ma_int64 offset, ma_seek_origin origin) { - return MA_ERROR; -} - -std::vector AudioDecoder::decodeToWav() { - std::vector fileData; - - ma_uint32 sampleRate; - // Todo: figure out how to really determine the sample rate. CODEC_ADPCM tends to stream at higher rates (usually - // 20KHZ) while CODEC_SMALL_ADPCM is usually around 14000. They're still not consistent though. - if (sample.codec == CODEC_ADPCM) - sampleRate = 20000; - else if (sample.codec = CODEC_SMALL_ADPCM) - sampleRate = 14000; - else - throw std::runtime_error("AudioDecoder: Unsupported codec."); - - ma_encoder_config maconfig = ma_encoder_config_init(ma_encoding_format_wav, ma_format_s16, 1, sampleRate); - ma_encoder wavEncoder; - ma_result init_result = ma_encoder_init(wavWrite, wavSeek, &fileData, &maconfig, &wavEncoder); - if (init_result != MA_SUCCESS) { - return fileData; - } - - int16_t chunk[WAV_DECODE_CHUNK_SIZE]; - // Don't decode past the end of the loop. - size_t samplesLeft = sample.loop.end; - // Unless the loop is 0? - if (samplesLeft == 0) - samplesLeft = sample.loop.count; - - while (samplesLeft > 0) { - size_t samplesRead = decode(chunk, WAV_DECODE_CHUNK_SIZE); - if (samplesRead > samplesLeft) - samplesRead = samplesLeft; - - if (samplesRead == 0) - break; - ma_encoder_write_pcm_frames(&wavEncoder, chunk, samplesRead, NULL); - samplesLeft -= samplesRead; - } - ma_encoder_uninit(&wavEncoder); - return fileData; -} diff --git a/soh/soh/Enhancements/audio/AudioDecoder.h b/soh/soh/Enhancements/audio/AudioDecoder.h deleted file mode 100644 index 8d611787a..000000000 --- a/soh/soh/Enhancements/audio/AudioDecoder.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -// A standalone, incremental audio sample decoder. -// Based on the ADPCM decoding routines in mixer.c. - -#include "miniaudio.h" -#include "libultraship/libultraship.h" -#include "soh/resource/type/AudioSample.h" -#include "z64audio.h" -class AudioDecoder { - struct { - int codec; - struct { - int start; - int end; - int count; - - } loop; - } sample; - - uint8_t *in, *inStart, *inEnd; - int16_t adpcm_table[8][2][8]; - int16_t prev1, prev2; // The internal decoder takes an array of 16 shorts which it calls ADPCM_STATE. Strictly - // speaking only the last two decoded samples are needed for continuation. - public: - AudioDecoder(); - ~AudioDecoder(); - // Support both SOH samples and Z64 samples. - void setSample(SOH::AudioSample* sample); - void setSample(SoundFontSample* sample); - - size_t decode(int16_t* out, size_t nSamples); - std::vector decodeToWav(); -}; \ No newline at end of file