diff --git a/Audio/AudioRecorder.cs b/Audio/AudioRecorder.cs index 0a76180..aad2ac4 100644 --- a/Audio/AudioRecorder.cs +++ b/Audio/AudioRecorder.cs @@ -19,12 +19,12 @@ public static class AudioRecorder File.Delete(WavPath); } - Logger.LogDebug("Starting ffmpeg to record audio..."); + Logger.LogDebug("Starting pw-record to record audio..."); var pInfo = new ProcessStartInfo { - FileName = "ffmpeg", - Arguments = $"-f alsa -i default -y {WavPath}", + FileName = "pw-record", + Arguments = $"--rate=16000 --channels=1 --format=s16 \"{WavPath}\"", UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, @@ -50,17 +50,22 @@ public static class AudioRecorder var process = Process.GetProcessById(pid.Value); if (!process.HasExited) { - // Send gracefully? Process.Kill on linux sends SIGKILL by default. - // But ffmpeg can sometimes handle SIGINT or SIGTERM if we use alternative tools or Process.Kill. - // Standard .NET Process.Kill(true) kills the tree. Let's start with basic Kill. - process.Kill(); - process.WaitForExit(); + // Gracefully stop pw-record using SIGINT to ensure WAV headers are finalizing cleanly + Process.Start(new ProcessStartInfo + { + FileName = "kill", + Arguments = $"-INT {pid.Value}", + CreateNoWindow = true, + UseShellExecute = false + })?.WaitForExit(); + + process.WaitForExit(2000); // give it a moment to flush } } catch (Exception ex) { // Process might already be dead - Console.WriteLine($"[AudioRecorder] Error stopping ffmpeg: {ex.Message}"); + Console.WriteLine($"[AudioRecorder] Error stopping pw-record: {ex.Message}"); } finally { diff --git a/README.md b/README.md index 9525ef3..3350dde 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Built with **.NET 10** and compiled to **Native AOT**, Toak runs as a lightning- ## 🛠 Prerequisites - **.NET 10 SDK** (for building from source) -- **ffmpeg** (for audio capture processing) +- **pipewire** / **pw-record** (for native Wayland/Linux audio capture) - **Typing Backend**: `wtype` (Wayland) or `xdotool` (X11) - **Groq API Key**: Get one at [console.groq.com](https://console.groq.com/) diff --git a/docs/STRUCTURE.md b/docs/STRUCTURE.md index a450261..f0a7983 100644 --- a/docs/STRUCTURE.md +++ b/docs/STRUCTURE.md @@ -15,7 +15,7 @@ Toak/ │ └── Models/ # API payload representations ├── Assets/ # Sound files or other static resources ├── Audio/ -│ └── AudioRecorder.cs # Handles audio capture via system utilities (e.g., ffmpeg/arecord) +│ └── AudioRecorder.cs # Handles audio capture via system utilities (e.g., pw-record from PipeWire) ├── Commands/ │ ├── ToggleCommand.cs # Start/stop recording and pass pipe/copy flags │ ├── DiscardCommand.cs # Abort the current recording diff --git a/install.sh b/install.sh index ceddb74..220034d 100755 --- a/install.sh +++ b/install.sh @@ -6,6 +6,8 @@ set -e echo "Building Toak Native AOT executable..." dotnet publish -c Release -r linux-x64 +systemctl --user stop toak.service +systemctl --user disable toak.service echo "Installing to /usr/bin/toak... (This may prompt for your sudo password)" sudo cp bin/Release/net10.0/linux-x64/publish/Toak /usr/bin/toak