diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2024-07-29 09:23:27 +1000 |
---|---|---|
committer | Kae <80987908+Novaenia@users.noreply.github.com> | 2024-07-29 09:23:27 +1000 |
commit | e9e87a1c3c74e503d00e5166f91f0b4c81c66e07 (patch) | |
tree | d1430ef04d45f56be84f32087ed8e311d51b009d /source/base | |
parent | 8b1a2d6f0c9a1592a5c550ab23f6bf949ce65fc4 (diff) |
Avoid crashing when a OGG file is broken (thanks to @kblaschke !)
Also added a name tag to Audio for logging so that it's easier to find the audio asset that's causing it
Diffstat (limited to 'source/base')
-rw-r--r-- | source/base/StarAssets.cpp | 2 | ||||
-rw-r--r-- | source/base/StarMixer.cpp | 79 |
2 files changed, 43 insertions, 38 deletions
diff --git a/source/base/StarAssets.cpp b/source/base/StarAssets.cpp index a56abd8..c47b71c 100644 --- a/source/base/StarAssets.cpp +++ b/source/base/StarAssets.cpp @@ -1241,7 +1241,7 @@ shared_ptr<Assets::AssetData> Assets::loadImage(AssetPath const& path) const { shared_ptr<Assets::AssetData> Assets::loadAudio(AssetPath const& path) const { return unlockDuring([&]() { auto newData = make_shared<AudioData>(); - newData->audio = make_shared<Audio>(open(path.basePath)); + newData->audio = make_shared<Audio>(open(path.basePath), path.basePath); newData->needsPostProcessing = newData->audio->compressed(); return newData; }); diff --git a/source/base/StarMixer.cpp b/source/base/StarMixer.cpp index 72a6cd6..bbcb23a 100644 --- a/source/base/StarMixer.cpp +++ b/source/base/StarMixer.cpp @@ -310,49 +310,54 @@ void Mixer::read(int16_t* outBuffer, size_t frameCount, ExtraMixFunction extraMi m_mixBuffer[i] = 0; ramt += silentSamples * channels; } - ramt += audioInstance->m_audio.resample(channels, sampleRate, m_mixBuffer.ptr() + ramt, bufferSize - ramt, pitchMultiplier); - while (ramt != bufferSize && !finished) { - // Only seek back to the beginning and read more data if loops is < 0 - // (loop forever), or we have more loops to go, otherwise, the sample is - // finished. - if (audioInstance->m_loops != 0) { - audioInstance->m_audio.seekSample(0); - ramt += audioInstance->m_audio.resample(channels, sampleRate, m_mixBuffer.ptr() + ramt, bufferSize - ramt, pitchMultiplier); - if (audioInstance->m_loops > 0) - --audioInstance->m_loops; - } else { - finished = true; + try { + ramt += audioInstance->m_audio.resample(channels, sampleRate, m_mixBuffer.ptr() + ramt, bufferSize - ramt, pitchMultiplier); + while (ramt != bufferSize && !finished) { + // Only seek back to the beginning and read more data if loops is < 0 + // (loop forever), or we have more loops to go, otherwise, the sample is + // finished. + if (audioInstance->m_loops != 0) { + audioInstance->m_audio.seekSample(0); + ramt += audioInstance->m_audio.resample(channels, sampleRate, m_mixBuffer.ptr() + ramt, bufferSize - ramt, pitchMultiplier); + if (audioInstance->m_loops > 0) + --audioInstance->m_loops; + } else { + finished = true; + } } - } - if (audioInstance->m_clockStop && *audioInstance->m_clockStop < sampleEndTime) { - for (size_t s = 0; s < ramt / channels; ++s) { - unsigned millisecondsInBuffer = (s * 1000) / sampleRate; - auto sampleTime = sampleStartTime + millisecondsInBuffer; - if (sampleTime > *audioInstance->m_clockStop) { - float volume = 0.0f; - if (audioInstance->m_clockStopFadeOut > 0) - volume = 1.0f - (float)(sampleTime - *audioInstance->m_clockStop) / (float)audioInstance->m_clockStopFadeOut; - - if (volume <= 0) { - for (size_t c = 0; c < channels; ++c) - m_mixBuffer[s * channels + c] = 0; - } else { - for (size_t c = 0; c < channels; ++c) - m_mixBuffer[s * channels + c] *= volume; + if (audioInstance->m_clockStop && *audioInstance->m_clockStop < sampleEndTime) { + for (size_t s = 0; s < ramt / channels; ++s) { + unsigned millisecondsInBuffer = (s * 1000) / sampleRate; + auto sampleTime = sampleStartTime + millisecondsInBuffer; + if (sampleTime > *audioInstance->m_clockStop) { + float volume = 0.0f; + if (audioInstance->m_clockStopFadeOut > 0) + volume = 1.0f - (float)(sampleTime - *audioInstance->m_clockStop) / (float)audioInstance->m_clockStopFadeOut; + + if (volume <= 0) { + for (size_t c = 0; c < channels; ++c) + m_mixBuffer[s * channels + c] = 0; + } else { + for (size_t c = 0; c < channels; ++c) + m_mixBuffer[s * channels + c] *= volume; + } } } + if (sampleEndTime > *audioInstance->m_clockStop + audioInstance->m_clockStopFadeOut) + finished = true; } - if (sampleEndTime > *audioInstance->m_clockStop + audioInstance->m_clockStopFadeOut) - finished = true; - } - for (size_t s = 0; s < ramt / channels; ++s) { - float vol = lerp((float)s / frameCount, beginVolume * groupVolume * audioStopVolBegin, endVolume * groupEndVolume * audioStopVolEnd); - for (size_t c = 0; c < channels; ++c) { - float sample = m_mixBuffer[s * channels + c] * vol * audioState.positionalChannelVolumes[c] * audioInstance->m_volume.value; - int16_t& outSample = outBuffer[s * channels + c]; - outSample = clamp(sample + outSample, -32767.0f, 32767.0f); + for (size_t s = 0; s < ramt / channels; ++s) { + float vol = lerp((float)s / frameCount, beginVolume * groupVolume * audioStopVolBegin, endVolume * groupEndVolume * audioStopVolEnd); + for (size_t c = 0; c < channels; ++c) { + float sample = m_mixBuffer[s * channels + c] * vol * audioState.positionalChannelVolumes[c] * audioInstance->m_volume.value; + int16_t& outSample = outBuffer[s * channels + c]; + outSample = clamp(sample + outSample, -32767.0f, 32767.0f); + } } + } catch (Star::AudioException const& e) { + Logger::error("Error reading audio '{}': {}", audioInstance->m_audio.name(), e.what()); + finished = true; } audioInstance->m_volume.value = audioStopVolEnd; |