Skip to content

Commit 785946d

Browse files
authored
Merge 2867b6c into c00a14f
2 parents c00a14f + 2867b6c commit 785946d

2 files changed

Lines changed: 29 additions & 4 deletions

File tree

nvdaHelper/local/wasapi.cpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,16 +346,24 @@ HRESULT WasapiPlayer::feed(unsigned char* data, unsigned int size,
346346
return true;
347347
};
348348

349+
bool shouldInsertSilentFrame = false;
349350
if (isTrimmingLeadingSilence) {
350-
size_t silenceSize = SilenceDetect::getLeadingSilenceSize(&format, data, size);
351+
// If data is null, treat the whole chunk as silence.
352+
size_t silenceSize = data ? SilenceDetect::getLeadingSilenceSize(&format, data, size) : size;
351353
if (silenceSize >= size) {
352354
// The whole chunk is silence. Continue checking for silence in the next chunk.
353355
remainingFrames = 0;
354356
} else {
355357
// Silence ends in this chunk. Skip the silence and continue.
356358
data += silenceSize;
357-
remainingFrames = (size - silenceSize) / format.nBlockAlign;
359+
size -= silenceSize;
360+
remainingFrames = size / format.nBlockAlign;
358361
isTrimmingLeadingSilence = false; // Stop checking for silence
362+
363+
// Signals to insert one silent frame before the trimmed audio in this chunk.
364+
// Not doing so may cause the beginning of the audio to be chopped off.
365+
// See: https://github.com/nvaccess/nvda/discussions/17697
366+
shouldInsertSilentFrame = true;
359367
}
360368
}
361369

@@ -407,14 +415,30 @@ HRESULT WasapiPlayer::feed(unsigned char* data, unsigned int size,
407415
}
408416
}
409417
// We might have more frames than will fit in the buffer. Send what we can.
418+
// If we need to insert a silent frame, the frame counts towards the total frame count,
419+
// but does not count towards the total byte count, as it's not in the provided data buffer.
420+
if (shouldInsertSilentFrame) {
421+
remainingFrames++;
422+
}
410423
const UINT32 sendFrames = std::min(remainingFrames,
411424
bufferFrames - paddingFrames);
412-
const UINT32 sendBytes = sendFrames * format.nBlockAlign;
425+
const UINT32 sendBytes = (sendFrames - (shouldInsertSilentFrame ? 1 : 0))
426+
* format.nBlockAlign;
413427
BYTE* buffer;
414428
hr = render->GetBuffer(sendFrames, &buffer);
415429
if (FAILED(hr)) {
416430
return hr;
417431
}
432+
if (shouldInsertSilentFrame) {
433+
// If needed, insert one frame of silence at the beginning
434+
if (format.wFormatTag == WAVE_FORMAT_PCM && format.wBitsPerSample == 8) {
435+
memset(buffer, 0x80, format.nBlockAlign);
436+
} else {
437+
memset(buffer, 0, format.nBlockAlign);
438+
}
439+
buffer += format.nBlockAlign;
440+
shouldInsertSilentFrame = false;
441+
}
418442
if (data) {
419443
memcpy(buffer, data, sendBytes);
420444
hr = render->ReleaseBuffer(sendFrames, 0);

source/nvwave.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,8 @@ def _idleCheck(cls):
497497
if player._lastActiveTime <= threshold:
498498
try:
499499
NVDAHelper.localLib.wasPlay_idle(player._player)
500-
player.startTrimmingLeadingSilence()
500+
if player._enableTrimmingLeadingSilence:
501+
player.startTrimmingLeadingSilence()
501502
except OSError:
502503
# #16125: IAudioClock::GetPosition sometimes fails with an access
503504
# violation on a device which has been invalidated. This shouldn't happen

0 commit comments

Comments
 (0)