lift startOfInput/endOfInput

This commit is contained in:
Demur Rumed 2025-04-21 21:56:54 +00:00
commit 498a5d583a
3 changed files with 46 additions and 44 deletions

View file

@ -904,7 +904,8 @@ void ActorAccessibility_InitActors() {
ActorAccessibility_InitPolicy(&policy, "bubble", NULL, NA_SE_EN_DAIOCTA_SPLASH); ActorAccessibility_InitPolicy(&policy, "bubble", NULL, NA_SE_EN_DAIOCTA_SPLASH);
policy.ydist = 200; policy.ydist = 200;
ActorAccessibility_AddSupportedActor(ACTOR_EN_BUBBLE, policy); ActorAccessibility_AddSupportedActor(ACTOR_EN_BUBBLE, policy);
ActorAccessibility_InitPolicy(&policy, "tentacle obstacle", NULL, NA_SE_EN_BALINADE_THUNDER); ActorAccessibility_InitPolicy(&policy, "tentacle", NULL, NA_SE_EN_BALINADE_THUNDER);
ActorAccessibility_AddSupportedActor(ACTOR_EN_BA, policy);
policy.distance = 100; policy.distance = 100;
ActorAccessibility_AddSupportedActor(ACTOR_EN_BX, policy); ActorAccessibility_AddSupportedActor(ACTOR_EN_BX, policy);
ActorAccessibility_InitPolicy(&policy, "redead", NULL, NA_SE_EN_REDEAD_CRY); ActorAccessibility_InitPolicy(&policy, "redead", NULL, NA_SE_EN_REDEAD_CRY);

View file

@ -31,31 +31,38 @@ enum {
} CAPTURE_THREAD_STATES; } CAPTURE_THREAD_STATES;
#define SFX_EXTRACTION_BUFFER_SIZE 44100 * 15 #define SFX_EXTRACTION_BUFFER_SIZE 44100 * 15
#define SFX_EXTRACTION_ONE_FRAME 736 #define SFX_EXTRACTION_ONE_FRAME 736
bool SfxExtractor::isAllZero(int16_t* buffer, size_t count) bool SfxExtractor::isAllZero(int16_t* buffer, size_t count) {
for (size_t i = 0; i < count; i++) {
{
for (auto i = 0; i < count; i++) {
if (buffer[i] != 0) if (buffer[i] != 0)
return false; return false;
} }
return true; return true;
} }
void SfxExtractor::setStartOfInput() {
startOfInput = 0; // Find the beginning of a captured signal.
for (startOfInput = 0; startOfInput < SFX_EXTRACTION_BUFFER_SIZE * 2; startOfInput += 2) { size_t SfxExtractor::adjustedStartOfInput() {
if (tempBuffer[startOfInput] != 0 || tempBuffer[startOfInput + 1] != 0) size_t startOfInput = 0;
break; while (startOfInput + 2 < SFX_EXTRACTION_BUFFER_SIZE * 2 &&
} (tempBuffer[startOfInput] == 0 || tempBuffer[startOfInput + 1] == 0)) {
} startOfInput += 2;
void SfxExtractor::setEndOfInput() {
while (endOfInput > 0) {
if (tempBuffer[endOfInput] != 0 || tempBuffer[endOfInput - 1] != 0)
break;
endOfInput -= 2;
} }
return startOfInput;
} }
void SfxExtractor::renderOutput() { size_t SfxExtractor::adjustedEndOfInput(size_t endOfInput) {
while (endOfInput > 0 && (tempBuffer[endOfInput] == 0 || tempBuffer[endOfInput - 1] == 0)) {
endOfInput -= 2;
}
return endOfInput;
}
void SfxExtractor::renderOutput(size_t endOfInput) {
size_t startOfInput = adjustedStartOfInput();
endOfInput = adjustedEndOfInput(endOfInput);
if (endOfInput <= startOfInput) {
return;
}
ma_channel_converter_config config = ma_channel_converter_config config =
ma_channel_converter_config_init(ma_format_s16, 2, NULL, 1, NULL, ma_channel_mix_mode_default); ma_channel_converter_config_init(ma_format_s16, 2, NULL, 1, NULL, ma_channel_mix_mode_default);
ma_channel_converter converter; ma_channel_converter converter;
@ -103,8 +110,8 @@ void SfxExtractor::setup() {
currentStep = STEP_ERROR_OTR; currentStep = STEP_ERROR_OTR;
return; return;
} }
tempStorage.resize((SFX_EXTRACTION_BUFFER_SIZE + (SFX_EXTRACTION_ONE_FRAME * 3)) * 2, // Over-allocated just a tad because otherwise we'll overrun if the last frame is short.
0); // Over-allocated just a tad because otherwise we'll overrun if the last frame is short. tempStorage.resize((SFX_EXTRACTION_BUFFER_SIZE + (SFX_EXTRACTION_ONE_FRAME * 3)) * 2, 0);
tempBuffer = tempStorage.data(); tempBuffer = tempStorage.data();
sfxToRip = 0; sfxToRip = 0;
@ -135,8 +142,6 @@ void SfxExtractor::ripNextSfx() {
} }
currentSfx = sfxTable[sfxToRip++]; currentSfx = sfxTable[sfxToRip++];
startOfInput = 0;
endOfInput = 0;
Audio_PlaySoundGeneral(currentSfx, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, Audio_PlaySoundGeneral(currentSfx, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultReverb); &gSfxDefaultReverb);
@ -150,6 +155,7 @@ void SfxExtractor::finished() {
OTRAudio_UninstallSfxCaptureThread(); // Returns to normal audio opperation. OTRAudio_UninstallSfxCaptureThread(); // Returns to normal audio opperation.
CVarClear("gExtractSfx"); CVarClear("gExtractSfx");
CVarSave(); CVarSave();
archive->Close();
archive = nullptr; archive = nullptr;
freezeGame = false; freezeGame = false;
@ -170,16 +176,15 @@ void SfxExtractor::finished() {
Audio_PlayFanfare(NA_BGM_ITEM_GET); Audio_PlayFanfare(NA_BGM_ITEM_GET);
} }
void SfxExtractor::maybeGiveProgressReport() { void SfxExtractor::maybeGiveProgressReport() {
size_t ripsRemaining = sfxCount - sfxToRip;
for (int i = 0; i < 9; i++) { for (int i = 0; i < 9; i++) {
if (ripsRemaining == sfxCount - ((int)ceil(sfxCount * ((i + 1) / 10.0f)))) { if (sfxToRip == sfxCount * (i + 1) / 10) {
int percentDone = (i + 1) * 10;
std::stringstream ss; std::stringstream ss;
ss << percentDone << " percent complete."; ss << (i + 1) * 10 << " percent complete.";
SpeechSynthesizer::Instance->Speak(ss.str().c_str(), GetLanguageCode()); SpeechSynthesizer::Instance->Speak(ss.str().c_str(), GetLanguageCode());
} }
} }
} }
SfxExtractor::SfxExtractor() { SfxExtractor::SfxExtractor() {
currentStep = STEP_SETUP; currentStep = STEP_SETUP;
} }
@ -196,6 +201,7 @@ void SfxExtractor::frameCallback() {
finished(); finished();
} }
} }
void SfxExtractor::prime() { void SfxExtractor::prime() {
while (true) { while (true) {
AudioMgr_CreateNextAudioBuffer(tempBuffer, SFX_EXTRACTION_ONE_FRAME); AudioMgr_CreateNextAudioBuffer(tempBuffer, SFX_EXTRACTION_ONE_FRAME);
@ -204,6 +210,7 @@ void SfxExtractor::prime() {
} }
captureThreadState = CT_FINISHED; captureThreadState = CT_FINISHED;
} }
void SfxExtractor::captureCallback() { void SfxExtractor::captureCallback() {
if (captureThreadState == CT_PRIMING) if (captureThreadState == CT_PRIMING)
prime(); prime();
@ -213,30 +220,27 @@ void SfxExtractor::captureCallback() {
int16_t* mark = tempBuffer; int16_t* mark = tempBuffer;
size_t samplesLeft = SFX_EXTRACTION_BUFFER_SIZE; size_t samplesLeft = SFX_EXTRACTION_BUFFER_SIZE;
bool outputStarted = false; bool outputStarted = false;
endOfInput = 0; size_t endOfInput = 0;
int waitTime = 0; int waitTime = 0;
while (samplesLeft > 0) { while (samplesLeft > 0) {
AudioMgr_CreateNextAudioBuffer(mark, SFX_EXTRACTION_ONE_FRAME); AudioMgr_CreateNextAudioBuffer(mark, SFX_EXTRACTION_ONE_FRAME);
if (!outputStarted && isAllZero(mark, SFX_EXTRACTION_ONE_FRAME * 2)) { if (isAllZero(mark, SFX_EXTRACTION_ONE_FRAME * 2)) {
waitTime++; if (outputStarted) {
if (waitTime < 300) break;
continue; // Output is silent, allow more time for audio to begin. } else if (waitTime++ < 300) {
continue; // Output is silent, allow more time for audio to begin.
}
captureThreadState = CT_FINISHED; // Sound is unavailable, so skip over it and move on. captureThreadState = CT_FINISHED; // Sound is unavailable, so skip over it and move on.
return; return;
} }
else outputStarted = true;
outputStarted = true;
if (isAllZero(mark, SFX_EXTRACTION_ONE_FRAME * 2))
break; // End of sound.
mark += (SFX_EXTRACTION_ONE_FRAME * 2); mark += (SFX_EXTRACTION_ONE_FRAME * 2);
endOfInput += (SFX_EXTRACTION_ONE_FRAME * 2); endOfInput += (SFX_EXTRACTION_ONE_FRAME * 2);
samplesLeft -= std::min<size_t>(SFX_EXTRACTION_ONE_FRAME, samplesLeft); samplesLeft -= std::min<size_t>(SFX_EXTRACTION_ONE_FRAME, samplesLeft);
} }
setStartOfInput(); renderOutput(endOfInput);
setEndOfInput();
renderOutput();
captureThreadState = CT_FINISHED; // Go to the next one. captureThreadState = CT_FINISHED; // Go to the next one.
} }
std::string SfxExtractor::getExternalFileName(int16_t sfxId) { std::string SfxExtractor::getExternalFileName(int16_t sfxId) {

View file

@ -5,17 +5,14 @@ class SfxExtractor {
int currentStep; int currentStep;
int captureThreadState; int captureThreadState;
int sfxToRip; int sfxToRip;
size_t startOfInput;
size_t endOfInput;
s16 currentSfx; s16 currentSfx;
std::vector<int16_t> tempStorage; // Stores raw audio data for the sfx currently being ripped. std::vector<int16_t> tempStorage; // Stores raw audio data for the sfx currently being ripped.
int16_t* tempBuffer; // Raw pointer to the above vector. int16_t* tempBuffer; // Raw pointer to the above vector.
// Check if a buffer contains meaningful audio output. // Check if a buffer contains meaningful audio output.
bool isAllZero(int16_t* buffer, size_t count); bool isAllZero(int16_t* buffer, size_t count);
// Find the beginning of a captured signal. size_t adjustedStartOfInput();
void setStartOfInput(); size_t adjustedEndOfInput(size_t endOfInput);
void setEndOfInput(); void renderOutput(size_t endOfInput);
void renderOutput();
void setup(); void setup();
void ripNextSfx(); void ripNextSfx();
void finished(); // Also handles failure. void finished(); // Also handles failure.