Repository navigation
fix(cli): read the WAV in JS so Built-in transcription runs inside Electron - #5129
Merged
Merged
Conversation
miguel-heygen
marked this pull request as ready for review
October 6, 2026 21:36
Edit accuracy: accurate 2059 (base branch 2059), smooth 1561 of thoseThe gate passes. Quarantined, measured but not gated (0) |
jrusso1020
approved these changes
Oct 6, 2026
jrusso1020
left a comment
Collaborator
There was a problem hiding this comment.
Approving at 812e5b4.
- The root cause matches the description.
sherpaWorker.tswas the onlyreadWavecaller in the repo (code search), and it now reads the WAV in JS. The recognizer still gets the same{samples, sampleRate}shape. readWavchecks RIFF/WAVE, PCM or EXTENSIBLE, mono and 16-bit.findWavChunkclamps the data size to the buffer, so a piped WAV with a placeholder size still reads.- The
<to<=change in the chunk scan fixes the empty-WAV case.detectSpeechOnsetintranscribe.tsgets the same fix, since it now shares the scanner rather than keeping its own copy. - Reuse: the engine's
readWavinaudioFxRender.tsis private, so a CLI-local reader is reasonable. If a third caller appears, export one from a shared spot. - The stand-in sherpa now throws Electron's exact error from
readWave, so a regression fails 7 tests. That's the right guard.
Non-blocking: the per-sample readInt16LE loop is fine for typical clips. An Int16Array view (when the data offset is even) would be faster on hour-long audio.
Review by Rames
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.
What
Built-in transcription (Parakeet through sherpa-onnx) fails in the packaged Desktop app, seen on 0.8.138. The worker has called
readWavesince 0.8.82; Desktop only recently started running it. The decode worker read the audio with sherpa-onnx'sreadWave, whose sample array points at memory outside V8. Desktop runs the CLI asELECTRON_RUN_AS_NODE, and Electron's V8 memory cage refuses such arrays:readWavethrowsExternal buffers are not allowed. Plain Node allows them, which is why it only broke in the app.The worker now reads the WAV in JS. The CLI always hands it a prepared 16-bit mono PCM WAV, so it parses that into a
Float32Arrayand never callsreadWave. The recognizer,acceptWaveformand decoding already worked under Electron with samples from JS.whisper/wav.tsholds the RIFF chunk scan, moved fromtranscribe.ts, which keeps using it, andreadWav. A file that is not a 16-bit mono PCM WAV fails with a message naming it. An empty WAV, which ffmpeg writes for silent or zero-length input, reads as no samples, as before.readWave(path, false)would also copy into V8 memory. A JS reader also reads WAVsreadWavecannot, such as piped WAVs (wherereadWavereturns no samples), and uses less peak memory. The engine has its own privatereadWavfor audio effects (audioFxRender.ts); it is not exported, so the CLI keeps its own.readWave. If the worker ever calls it again, the tests fail. They write real WAV files instead of faking the reader.Checks
aea76732e) and ran its own CLI exactly as Desktop does: the app binary withELECTRON_RUN_AS_NODE=1and the bundled ffmpeg, runningtranscribe jfk.wav --engine parakeet --json, with the real Parakeet model and a fresh home directory.Parakeet failed: Parakeet decoder exited with code 1: External buffers are not allowed.app.asar(the worker now has noreadWavecall): exit 0,ok: true, 22 words, "And so, my fellow Americans, ask not what your country can do for you. Ask what you can do for your country."wav.test.ts,sherpaWorker.test.ts,sherpa.test.ts, both transcribe test files and the command test pass 151/151, 3 runs in a row.readWavecall back fails 7 tests withExternal buffers are not allowed.