diff options
| author | KiritoDv <kiritodev01@gmail.com> | 2026-07-03 00:44:07 -0600 |
|---|---|---|
| committer | KiritoDv <kiritodev01@gmail.com> | 2026-07-03 00:44:07 -0600 |
| commit | b62fa5db1540d565dad4ffb6985bd5f7e74da10e (patch) | |
| tree | 0a4ee0a3a565c3d8cf4798f0ee9b6b78144edec6 /src | |
| parent | 0e2e844d8c7329259b88004c114d666c5781006e (diff) | |
Fixed different audio drivers exporting wrong to aiff
Diffstat (limited to 'src')
| -rw-r--r-- | src/factories/naudio/v0/AIFCDecode.cpp | 17 | ||||
| -rw-r--r-- | src/factories/naudio/v0/SampleFactory.cpp | 24 | ||||
| -rw-r--r-- | src/factories/naudio/v1/AudioConverter.cpp | 11 | ||||
| -rw-r--r-- | src/factories/naudio/v1/SequencePlayerV1.cpp | 48 |
4 files changed, 68 insertions, 32 deletions
diff --git a/src/factories/naudio/v0/AIFCDecode.cpp b/src/factories/naudio/v0/AIFCDecode.cpp index 3782d98..95ed57e 100644 --- a/src/factories/naudio/v0/AIFCDecode.cpp +++ b/src/factories/naudio/v0/AIFCDecode.cpp @@ -112,7 +112,22 @@ typedef struct { s16 state[16]; } ALADPCMloop; -#define checked_fread(a, b, c, d) d.Read((char*)a, b* c) +NORETURN +void fail_parse(const char* fmt, ...); + +// Bounds-checked read: refuses to read past the end of the underlying buffer, +// turning malformed/truncated input into a catchable parse error instead of a +// heap-buffer-overflow. +static void checked_read(LUS::BinaryReader& reader, void* dst, size_t len) { + size_t pos = reader.GetBaseAddress(); + size_t length = reader.GetLength(); + if (pos > length || len > length - pos) { + fail_parse("unexpected end of file while reading %zu bytes at offset %zu", len, pos); + } + reader.Read((char*)dst, (int32_t)len); +} + +#define checked_fread(a, b, c, d) checked_read(d, (void*)(a), (size_t)(b) * (size_t)(c)) NORETURN void fail_parse(const char* fmt, ...) { diff --git a/src/factories/naudio/v0/SampleFactory.cpp b/src/factories/naudio/v0/SampleFactory.cpp index 7f1898d..5860cff 100644 --- a/src/factories/naudio/v0/SampleFactory.cpp +++ b/src/factories/naudio/v0/SampleFactory.cpp @@ -164,16 +164,22 @@ bool DecodeAiffBytes(const std::vector<char>& bytes, std::vector<int16_t>& pcm, } bool DecodeSampleToPcm(AudioBankSample* sample, std::vector<int16_t>& pcm, int& rate) { - LUS::BinaryWriter aifc; - AudioConverter::SampleV0ToAIFC(sample, aifc); - LUS::BinaryWriter aiff; - write_aiff(aifc.ToVector(), aiff); - aifc.Close(); - DecodedSample decoded; - const bool ok = ParseAiff(aiff.ToVector(), decoded); - aiff.Close(); - if (!ok) { + try { + LUS::BinaryWriter aifc; + AudioConverter::SampleV0ToAIFC(sample, aifc); + LUS::BinaryWriter aiff; + // write_aiff throws std::runtime_error on malformed/truncated sample data. + write_aiff(aifc.ToVector(), aiff); + aifc.Close(); + + const bool ok = ParseAiff(aiff.ToVector(), decoded); + aiff.Close(); + if (!ok) { + return false; + } + } catch (const std::exception& e) { + SPDLOG_ERROR("Failed to decode audio sample: {}", e.what()); return false; } // The converter's header overwrites the head of the decoded stream; pad the diff --git a/src/factories/naudio/v1/AudioConverter.cpp b/src/factories/naudio/v1/AudioConverter.cpp index 59bbd3c..910ae8c 100644 --- a/src/factories/naudio/v1/AudioConverter.cpp +++ b/src/factories/naudio/v1/AudioConverter.cpp @@ -152,10 +152,13 @@ void AudioConverter::SampleV0ToAIFC(AudioBankSample* sample, LUS::BinaryWriter& vloops.Write(sample->loop.end); vloops.Write(sample->loop.count); - if (sample->loop.state.has_value()) { - for (auto state : sample->loop.state.value()) { - vcodes.Write(state); - } + // The decoder reads back a fixed-size ALADPCMloop whose state is a + // 16-entry array; always emit all 16 (zero-filled when absent) so the + // chunk is exactly 44 bytes. Note: this must target vloops, not vcodes. + const std::vector<int16_t>* state = + sample->loop.state.has_value() ? &sample->loop.state.value() : nullptr; + for (size_t i = 0; i < 16; i++) { + vloops.Write((int16_t)(state != nullptr && i < state->size() ? (*state)[i] : 0)); } aifc.End("APPL", vloops); } diff --git a/src/factories/naudio/v1/SequencePlayerV1.cpp b/src/factories/naudio/v1/SequencePlayerV1.cpp index e48bb93..881ab3a 100644 --- a/src/factories/naudio/v1/SequencePlayerV1.cpp +++ b/src/factories/naudio/v1/SequencePlayerV1.cpp @@ -234,19 +234,25 @@ std::shared_ptr<UI::SynthSample> SynthSampleFor(NSampleData* sample) { AudioConverter::SampleV1ToAIFC(sample, lit0->second, bit->second, aifc); const auto bytes = aifc.ToVector(); if (!bytes.empty()) { - LUS::BinaryWriter aiff; - write_aiff(bytes, aiff); - int rate = 0; - const bool ok = DecodeAiffBytes(aiff.ToVector(), synth->pcm, rate); - if ((!ok || synth->pcm.empty()) && std::getenv("TORCH_SEQ_DEBUG") != nullptr) { - printf("[sample] DECODE FAIL addr=0x%X book(order=%d npred=%d coeffs=%zu) loop(%u..%u x%u) aifc=%zu\n", - sample->sampleAddr, bit->second->order, bit->second->numPredictors, bit->second->book.size(), - lit0->second->start, lit0->second->end, lit0->second->count, bytes.size()); - } - aiff.Close(); - const size_t expected = (size_t)sample->size * 16 / 9; - if (synth->pcm.size() < expected) { - synth->pcm.insert(synth->pcm.begin(), expected - synth->pcm.size(), 0); + try { + LUS::BinaryWriter aiff; + // write_aiff throws std::runtime_error on malformed/truncated sample data. + write_aiff(bytes, aiff); + int rate = 0; + const bool ok = DecodeAiffBytes(aiff.ToVector(), synth->pcm, rate); + if ((!ok || synth->pcm.empty()) && std::getenv("TORCH_SEQ_DEBUG") != nullptr) { + printf("[sample] DECODE FAIL addr=0x%X book(order=%d npred=%d coeffs=%zu) loop(%u..%u x%u) aifc=%zu\n", + sample->sampleAddr, bit->second->order, bit->second->numPredictors, bit->second->book.size(), + lit0->second->start, lit0->second->end, lit0->second->count, bytes.size()); + } + aiff.Close(); + const size_t expected = (size_t)sample->size * 16 / 9; + if (synth->pcm.size() < expected) { + synth->pcm.insert(synth->pcm.begin(), expected - synth->pcm.size(), 0); + } + } catch (const std::exception& e) { + SPDLOG_ERROR("Failed to decode audio sample at addr 0x{:X}: {}", sample->sampleAddr, e.what()); + synth->pcm.clear(); } } aifc.Close(); @@ -1408,11 +1414,17 @@ bool DecodeV1SampleToPcm(const ParseResultData& item, std::vector<int16_t>& pcm, if (bytes.empty()) { return false; } - LUS::BinaryWriter aiff; - write_aiff(bytes, aiff); - const bool ok = DecodeAiffBytes(aiff.ToVector(), pcm, rate); - aiff.Close(); - return ok && !pcm.empty(); + try { + LUS::BinaryWriter aiff; + // write_aiff throws std::runtime_error on malformed/truncated sample data. + write_aiff(bytes, aiff); + const bool ok = DecodeAiffBytes(aiff.ToVector(), pcm, rate); + aiff.Close(); + return ok && !pcm.empty(); + } catch (const std::exception& e) { + SPDLOG_ERROR("Failed to decode audio sample at addr 0x{:X}: {}", sample->sampleAddr, e.what()); + return false; + } } bool SequencePlayerV1::Render(const ParseResultData& item, int, UI::RenderedAudio& out) { |
