ngs2: size 16-bit PCM blocks in Ngs2CalcWaveformBlock (The Binding of Isaac: Repentance) (#1968)

Ngs2CalcWaveformBlock returned NGS2_ERROR_UNKNOWN_WAVEFORM_FORMAT with a
zeroed block for 16-bit PCM (0x12). The Binding of Isaac: Repentance
(PPSA03311) ignores the error and queues the zeroed blocks, which the
sampler skips, so the game had no audio at all. PCM frames have a fixed
size, so the block now starts at sample_pos frames and spans num_samples
frames.

Fixes #667

Co-authored-by: gl-ungus <notasecondemail63@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
authored and GitHub committed 2026-10-30 05:39:49 +01:00
1 parent b0c8229bd4
commit bc4333e313
2 files changed
+10

No files matched your search

+5
View File
@@ -2210,6 +2210,11 @@ int KYTY_SYSV_ABI Ngs2CalcWaveformBlock(const Ngs2WaveformFormat* format, uint32
: ((skip + num_samples + frame_samples - 1) / frame_samples) *
codec.superframeSize;
block->num_skip_samples = num_samples == 0 ? 0 : static_cast<uint32_t>(skip);
} else if (format->waveform_type == 0x12) {
// 16-bit PCM has fixed-size frames, so the block starts exactly at the sample.
const uint64_t frame_size = uint64_t(format->num_channels) * sizeof(int16_t);
block->data_offset = uint64_t(sample_pos) * frame_size;
block->data_size = uint64_t(num_samples) * frame_size;
} else {
return NGS2_ERROR_UNKNOWN_WAVEFORM_FORMAT;
}
+5
View File
@@ -651,6 +651,11 @@ void TestWaveformBlockGeometry() {
Check(Ngs2CalcWaveformBlock(&format, 0, 0, &block) == OK && block.data_size == 0 &&
block.num_samples == 0,
"empty ATRAC9 block acquired encoded data");
const Ngs2WaveformFormat pcm {0x12, 2, 48000};
Check(Ngs2CalcWaveformBlock(&pcm, 4096, 4096, &block) == OK &&
block.data_offset == 16384 && block.data_size == 16384 &&
block.num_skip_samples == 0 && block.num_samples == 4096,
"PCM block calculation omitted the sample frames");
Fixture f(24000);
const int16_t silence = 0;
f.Queue(&silence, 0, 0, UINT32_MAX);