Fix WASAPI haptic playback truncating clips when endpoint sample rate differs from source#75
Closed
tomaabe wants to merge 1 commit into
Closed
Conversation
…s from source The WASAPI playback path in the Advanced Haptics sample resamples the source WAV to the haptic audio endpoint's sample rate in WaveSampleGenerator::GenerateSampleBuffer. The previous code wrote a whole-integer number of destination blocks per source block via for (unsigned int j = 0; j < sampleRatio; j++), where sampleRatio is a float. For any non-integer ratio (endpoint rate != source rate) the block counts are wrong and the writer reaches the end of the pre-sized render buffers before all source frames are consumed, so the tail of longer clips is silently dropped. Symptom: on Play WASAPI (L1) a multi-second clip only plays/vibrates at the very beginning; Play XAudio2 (R1) is unaffected because XAudio2 resamples natively. Replace the integer loop with a phase-accumulator nearest-neighbor resampler that advances the source by 1 / sampleRatio source frames per destination frame, correctly handling fractional and downsampling ratios. Also fix two memory leaks in the same file: FillSampleBuffer now frees each consumed RenderBuffer, and Flush now frees the remaining RenderBuffers and restores the queue tail pointer.
|
Fixed internally, will be in the next github publish. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes Advanced Haptics WASAPI playback for WAV files when the haptic audio endpoint sample rate is not an integer multiple of the source WAV sample rate. The previous resampling loop could under/overproduce destination frames and silently drop the tail of longer clips. This change also fixes RenderBuffer leaks in the sample queue cleanup paths.
Repro steps
Root cause
WaveSampleGenerator::GenerateSampleBuffercomputedsampleRatioas afloat, but used it as the upper bound of an integer loop:For non-integer ratios, this writes a whole-integer number of destination blocks per source block. As a result, the pre-sized render buffers can be exhausted before all source frames are consumed, silently truncating the tail of longer clips.
Fix
1 / sampleRatiosource frames per destination frame.FillSampleBuffernow deletes each consumedRenderBuffer.Flushnow deletes all remaining queuedRenderBufferobjects and restores the queue tail pointer.Testing
Notes
Samples/System/Haptics/HapticsManager/Audio/WaveSampleGenerator.cpp.