fix: audio export quality and Whisper language selection#4
Open
ScreepCode wants to merge 1 commit into
Open
Conversation
- SystemAudioCapture: raise sample rate from 16 kHz to 48 kHz so exported audio captures the full voice frequency range (0–24 kHz) instead of being limited to 8 kHz (Nyquist of 16 kHz) - MeetingRecorder: update audio file settings to 48 kHz / 128 kbps AAC; write original 48 kHz PCM to the audio file in handleSystemAudioBuffer instead of the already-downsampled 16 kHz buffer that was fed to SFSpeech; fix writeMicAudio memcpy fast-path to also trigger for stereo hardware input (was gated on channelCount == 1 unnecessarily) - WhisperEngine: add `language` property (default "en"), use it in transcribeChunk instead of a hardcoded language string; set it from MeetingRecorder.startRecording() via the 2-letter ISO prefix of recognitionLanguage (e.g. "de-DE" → "de") Fixes thehwang#2, fixes thehwang#3
c211121 to
0c22e3d
Compare
thehwang
approved these changes
Jun 27, 2026
thehwang
left a comment
Owner
There was a problem hiding this comment.
Reviewed the diff against the code in context. This is a clean, correct bugfix — happy to approve. Both goals land well: higher-quality audio export, and selectable Whisper language.
Quality path is self-consistent
SystemAudioCapture.sampleRate = 48_000is SCK's native rate; capturing at 16k was effectively asking SCK to downsample for us, so 48k is cleaner.handleSystemAudioBuffernow writes the originalpcmto disk and only downsamples a separatebufferfor SFSpeech.writeSystemAudioalready has a format-conversion fallback, and the file's processing format is now 48k mono, so the original buffer matches and no extra conversion happens.audioFileSettings(48k / 128 kbps mono) is shared by both the mic and system writers, so sample rates stay consistent when the two tracks are merged.
Language path is correct
strdup(self.language)is still released by the existingfree(langStr)— no leak introduced.recognitionLanguage.components(separatedBy: "-").first?.lowercased()mapsen-US -> en,zh-CN -> zh, matching Whisper's two-letter codes.
Suggestions (non-blocking)
- Multilingual model is a prerequisite. Language selection only works when a multilingual model (
ggml-base.bin) is loaded; with an English-only*.enmodel, setting e.g.zhwill produce garbage. Worth a guard/warning when a non-enlanguage is chosen but the loaded model is.en. - Dropping
&& buffer.format.channelCount == 1inwriteMicAudiois fine here — the slow path also reads onlych0, so the result is identical. It's only safe because our buffers are non-interleaved (interleaved: false); a one-line comment noting that assumption would prevent a future interleaved-stereomemcpy(ch0)foot-gun. - Multi-subtag locales like
yue-Hant-HK -> yueparse fine, butyueis only supported by larger Whisper models, notbase. Edge case, just flagging. self.languageis read onprocessingQueue. It isn't mutated during recording so it's safe in practice; capturinglet lang = self.languagebefore the async block would make that explicit.
Not affected (double-checked)
- Whisper's 16 kHz input requirement: the mic→whisper feed is unchanged; only the saved file's sample rate changed.
- Mic/system merge: both share the 48k settings, so they stay aligned.
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
languageproperty toWhisperEngineand wires it up fromMeetingRecorder.startRecording()using the 2-letter ISO prefix ofrecognitionLanguage(e.g."de-DE"→"de"). PreviouslytranscribeChunkhad the language hardcoded, so the mic channel always transcribed in one language regardless of the UI selection.Changes
SystemAudioCapture.swiftconfig.sampleRate: 16 000 → 48 000MeetingRecorder.swiftaudioFileSettings: 48 kHz / 128 kbps; write original PCM to file; fixwriteMicAudiomemcpy conditionWhisperEngine.swiftlanguageproperty, useself.languageintranscribeChunkTest plan
audio-mic.m4aandaudio-system.m4asound noticeably louder/fuller than before