Bug Description
When this machine is used over Remote Desktop, the microphone is the redirected "Remote Audio" device. Handy's recordings from it contain only about half of the audio that was spoken: the saved WAV is roughly half as long as the recording, and it sounds choppy because the missing pieces are cut out. Transcription accuracy drops accordingly. No error or overrun is logged.
The microphone itself is fine: Windows Sound Recorder and Windows voice typing capture the same device cleanly at full length, at the same time and place.
What seems to cause it
I reproduced the loss outside Handy with a small PortAudio script (attached, rate_test.py) reading the same device through WASAPI shared mode. The amount of audio that arrives depends only on the capture buffer size:
| WASAPI buffer | Recorded | Audio received |
|---|---|---|
| default (low latency) | 10 s | 5.6 – 6.7 s |
| 50 ms | 10 s | 9.4 s |
| 100 ms | 10 s | 10.0 s |
| 150 / 200 / 300 / 500 ms | 10 s | 10.0 s |
The Remote Audio device delivers in bursts roughly every 70 ms, so it looks like a small buffer overflows and Windows drops the excess silently. MME and DirectSound with their defaults lose audio the same way (about 67%).
As far as I can see, recorder.rs builds the input stream from the device's default config (config.clone().into()), so cpal uses BufferSize::Default. Requesting a larger buffer on Windows (100–200 ms), at least for this device, would likely fix it. Possibly related to #2141 (Windows-specific capture behaviour), but the symptom is different.
Steps to reproduce
- Connect to a Windows 11 PC over Remote Desktop with microphone redirection on.
- In Handy, record yourself counting 1 to 10 at one number per second (about 12 seconds).
- Play it back from History: the file is about 5–6 seconds long and choppy.
- Record the same count with Windows Sound Recorder: about 10 seconds, clean.
Expected
The full recording, as other apps capture it.
Actual
About 45–55% of the audio is missing, consistently across many recordings and several Handy restarts.
Already tried, no change
- VAD on and off
- "Always-on microphone" on and off
- Transcription on CPU and on GPU (Vulkan)
- Parakeet Unified EN 0.6B (streaming) and Parakeet TDT 0.6B v2
Attachments (handy-rdp-audio-samples.zip)
1-voice-recorder-count-to-10.m4a: Windows Sound Recorder, count to 10, clean, 10 s2-handy-count-to-10.wav: Handy, same count, 12 s of recording, 5.6 s saved3-wasapi-default-buffer-count-to-10.wav: test script, default buffer, 11 s of recording, 5.4 s received4-wasapi-200ms-buffer-count-to-10.wav: test script, 200 ms buffer, 11 s of recording, 11.0 s received, cleanrate_test.py,compare_buffers.py: the test scripts (pip install sounddevice numpy)handy-log-excerpt.txt: Handy's debug log for recording 2
System Information
App Version: 0.9.8
Operating System: Windows 11 (build 26200), used over Remote Desktop. Device: "Remote Audio", 44100 Hz, 2 channels, captured by Handy as F32
CPU: Intel Core i9-12900H
GPU: Intel Iris Xe Graphics
Logs
Excerpt attached (handy-log-excerpt.txt). The relevant line:
TranscribeAction::start 13:41:03 ... stop 13:41:15
Recording stopped and samples retrieved in 38.233ms, sample count: 89280 (= 5.58 s at 16 kHz for 12 s of recording)Thanks for Handy, it's great when the audio gets through.
Activity
6Reproduced on 0.9.8 with a different RDP client, plus a local control on the same machine.
Setup: Windows 11 Pro (build 26300) host, Parakeet TDT 0.6B v3 (Q8_0 GGUF), Silero VAD on, default settings. Client: Microsoft Windows App on macOS with microphone redirection ("Remoteaudio").
Recording window (TranscribeAction start → stop, whole seconds from the log) vs. samples retrieved at 16 kHz:
| Input | Window | Samples | Audio | Kept |
|---|---|---|---|---|
| Remoteaudio | 19 s | 139,680 | 8.7 s | 46 % |
| Remoteaudio | 26 s | 189,600 | 11.9 s | 46 % |
| Remoteaudio | 22 s | 184,800 | 11.6 s | 53 % |
| Remoteaudio | 29 s | 221,760 | 13.9 s | 48 % |
| Local USB mic (RØDE NT-USB+) | 42 s | 616,320 | 38.5 s | 92 % |
The RDP recordings sound sped up, the local one sounds normal. Parakeet still transcribes most of the RDP audio (64 words in 13.9 s of kept audio), so the loss is easy to miss in casual testing. One transcript partly switched to English.
Our use case is dictation on Windows terminal servers (RDS) with thin clients, where the redirected Remote Audio device is the only microphone. A larger capture buffer for this device would make Handy usable there. Happy to test a build.
Sorry for the slow reply, it's been a busy week at work.
I installed and tested the build you shared: same issue, no difference at all. Over Remote Desktop, recordings from the "Remote Audio" mic still come out about half length and choppy, while Windows Sound Recorder on the same mic is clean.
So that's now two of us confirming it on this build. Happy to test another one, or run the buffer-size script from my first post again, if that helps.
Thanks for looking into it!
Thanks for confirmation, I've got a few big things in the works at the moment, once they are merged I'll be back to this!
I could confirm the root cause in the current capture stack and test a fix over RDP. On Windows the input stream uses BufferSize::Default, so WASAPI gets its smallest shared-mode buffer and the Remote Audio bursts overflow it.
Where
- 0.9.8:
recorder.rsusesconfig.clone().into(), i.e.BufferSize::Default. - Test build and
main(handy-recorder 0.1.0): a fixed buffer is only set for PulseAudio (mod.rs). That's why the test build changed nothing. - handy-cpal passes
BufferSize::DefaulttoIAudioClient::Initializeas a buffer duration of 0 (device.rs#L1440).
Test
Small binary on handy-recorder 0.1.0, patched to set BufferSize::Fixed on Windows, recording 10 s inside the RDP session (same setup as my comment above, LAN, device "Remoteaudio" at 44.1 kHz / 2 ch):
| WASAPI buffer | Audio received | Xruns |
|---|---|---|
| Default | 4.49 of 10.03 s (45 %) | 407 |
| 200 ms | 9.71 of 10.02 s (97 %) | 1 |
The missing 3 % at 200 ms is startup latency (first audio after 337 ms). The xruns are Windows' DATA_DISCONTINUITY flags, and main already logs them as the platform reported N xruns during the recording. The local mic on the same machine accepts 200 ms to 2 s with 100 % received.
Suggested fix in CpalOpenDevice::start, for all Windows devices:
#[cfg(target_os = "windows")]
{
// Callbacks still come every device period; this only adds headroom
// for devices that deliver in bursts (RDP Remote Audio).
config.buffer_size = cpal::BufferSize::Fixed(config.sample_rate / 2); // 500 ms
}I'd use 500 ms to 1 s. 100–200 ms is enough on a LAN, but thin clients over WAN or VPN will likely see bigger bursts, and the extra buffer costs no latency in normal operation. One catch: handy-cpal reports the supported range as min = max = device period (device.rs#L687-L697), so clamping the request to it would undo the fix.
Happy to test a build over RDP.
@DeLuke84 can you submit a PR please? Would love to fix this
Are you able to reproduce the same thing on this build. Just curious. I imagine it has the same issue, but there's a small chance it's fixed
https://blob.handy.computer/handy-7b2a28a.zip