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>
* audio: support standard NGS2 PCM16 sampler playback
Extend the existing fixed-point PCM path to standard samplers, loops, and progress reporting. Apply voice events immediately and honor callback interruption during source advancement.
Reuse upstream rate and pitch handling. Add regression coverage for streaming, routing, callbacks, loops, and custom sampler controls; ngs2_sampler passes.
* audio: apply NGS2 rear low-pass filters
Handle rear low-pass FCQ controls at the output sample rate with per-channel history and channel masks. Preserve filter tails through streaming gaps and use the standard pi constant for coefficients.
Add regression coverage for frequency response, control layout, channel isolation, and starvation/refill continuity. Emulator build and both audio test suites pass.
* Preserve resampling phase for accepting voices
Only reset voice.sample_phase when there are no blocks and the voice does not accept blocks (change in src/libs/ngs2.cpp). Add TestResamplingPhaseAfterStarvation to tests to ensure sampler and custom sampler retain resampling phase and pending source advancement after starvation, and that SetupSampler still resets the phase. This prevents resampling phase loss during starvation/refill across sample rates.
* audio: correct sampler controls, lifecycle, and filter tails
---------
Co-authored-by: nmzik <Nmzik@mail.ru>