Skip to content

Commit b44dbda

Browse files
ryan-frankclaude
authored andcommitted
fix(voice): use file-size based duration for Windows audio playback
pocket-tts can produce WAV files with malformed headers (reporting 1 billion frames instead of the actual count). The previous fix used MediaPlayer.NaturalDuration which read the bogus header, causing playback to either hang or cut off unpredictably. Now calculates duration directly from file size using the known pocket-tts output format (24kHz, 16-bit, mono WAV). This is reliable regardless of header accuracy. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0f7b913 commit b44dbda

1 file changed

Lines changed: 7 additions & 2 deletions

File tree

  • plugins/voice/scripts

plugins/voice/scripts/say

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,14 @@ play_audio_file() {
114114
elif [[ "$(uname -o 2>/dev/null)" == "Msys" ]] || [[ -n "$MSYSTEM" ]]; then
115115
# Windows (Git Bash / MSYS2) - use WPF MediaPlayer with dynamic duration detection
116116
# SoundPlayer often routes audio to the wrong device on multi-output Windows systems
117-
local winpath
117+
# Calculate duration from file size (WAV headers from pocket-tts can be malformed)
118+
# WAV format: (filesize - 44 header) / (sample_rate * bytes_per_sample * channels)
119+
# pocket-tts outputs 24kHz, 16-bit, mono
120+
local winpath filesize duration_ms
118121
winpath=$(cygpath -w "$file")
119-
powershell.exe -NoProfile -Command "Add-Type -AssemblyName PresentationCore; \$mp = New-Object System.Windows.Media.MediaPlayer; \$mp.Open([uri]::new('file:///$winpath')); Start-Sleep -Milliseconds 500; \$mp.Play(); while (-not \$mp.NaturalDuration.HasTimeSpan) { Start-Sleep -Milliseconds 100 }; \$dur = [int](\$mp.NaturalDuration.TimeSpan.TotalMilliseconds); Start-Sleep -Milliseconds (\$dur + 500); \$mp.Close()"
122+
filesize=$(stat -c%s "$file" 2>/dev/null || wc -c < "$file")
123+
duration_ms=$(( (filesize - 44) * 1000 / (24000 * 2 * 1) + 1000 ))
124+
powershell.exe -NoProfile -Command "Add-Type -AssemblyName PresentationCore; \$mp = New-Object System.Windows.Media.MediaPlayer; \$mp.Open([uri]::new('file:///$winpath')); Start-Sleep -Milliseconds 500; \$mp.Play(); Start-Sleep -Milliseconds $duration_ms; \$mp.Close()"
120125
elif command -v aplay > /dev/null 2>&1; then
121126
aplay -q "$file"
122127
elif command -v paplay > /dev/null 2>&1; then

0 commit comments

Comments
 (0)