Local, privacy-first wake-word control for the official ChatGPT Voice experience on macOS.
microphone
↓
local sherpa-onnx keyword spotting
↓
“Hey GPT”
↓
ChatGPT launch when needed
↓
user-configured Voice hotkey
↓
official ChatGPT Voice
GPTIRL implements only the wake layer. It does not recreate ChatGPT Voice, connect to an OpenAI model, or automate ChatGPT's interface.
Preview status:
v0.2.2-previewis an Apple Silicon, macOS 14+ release candidate. Raw input measured15/30wake detections in the initial noisy hardware test. Experimental DPDFNet measured only3/21, so Automatic now falls back directly to Raw and DPDFNet remains diagnostic-only. This build is ad-hoc signed and not notarized.
- Fully local streaming detection of
Hey GPTusing sherpa-onnx. - High-quality 44.1/48 kHz to 16 kHz mono conversion using
AVAudioConverter. - Automatic Apple Voice Processing with direct Raw fallback.
- Optional causal 16 kHz
dpdfnet_baselineneural noise suppression. - An adaptive 8-second noise floor and 6 dB SNR verification gate.
- Menu-bar operation while ChatGPT is visible, minimized, or covered.
- Optional automatic ChatGPT launch when the official app is not running.
- Configurable 3–30 second cold-start delay; default is 10 seconds.
- Non-activating desktop feedback for:
- wake phrase recognized;
- ChatGPT startup countdown;
- Voice shortcut sent;
- launch or Accessibility failure.
- Ten-run visual validation gate before background listening can be enabled.
- Microphone PCM, wake-model, and on-device Live Caption diagnostics.
- Automatic audio-pipeline recovery after microphone or sample-rate changes.
- Daily GitHub Release checks with an explicit manual check in the menu.
- No OpenAI API key and no independent API charges.
- Apple Silicon Mac.
- macOS 14 or newer.
- Official ChatGPT desktop app installed.
- ChatGPT bundle ID
com.openai.codex. - ChatGPT
Settings → Voice → Voice chat hotkeyconfigured to the same shortcut as GPTIRL. The default GPTIRL value is⌃⌥G. - Microphone and Accessibility permissions for GPTIRL.
-
Download
GPTIRL-v0.2.2-preview-macos-arm64.zipand its.sha256file from the GitHub Release. -
Verify the download:
shasum -a 256 -c GPTIRL-v0.2.2-preview-macos-arm64.zip.sha256 unzip -tq GPTIRL-v0.2.2-preview-macos-arm64.zip
-
Extract the ZIP and move
GPTIRL.appto~/Applicationsor/Applications. -
In Finder, Control-click GPTIRL and choose Open.
-
Grant Microphone permission.
-
In
System Settings → Privacy & Security → Accessibility, add and enable the exact installed copy of GPTIRL.
Because this Preview uses ad-hoc signing, macOS may invalidate Accessibility authorization when the app is replaced by a new build. If shortcut dispatch stops after an upgrade, quit GPTIRL, remove its old Accessibility entry, add the newly installed app, and reopen it.
- In ChatGPT, set
Settings → Voice → Voice chat hotkeyto⌃⌥G. - Keep ChatGPT running.
- Open the GPTIRL menu-bar menu and choose Test Voice Shortcut.
- Confirm Voice Appeared only when the official Voice UI is visible.
- Repeat until all ten consecutive tests pass.
- Enable Listening.
- Say
Hey GPT.
A failed confirmation resets the validation count. CGEvent.post provides no
public delivery acknowledgement, so GPTIRL cannot programmatically prove that
ChatGPT displayed Voice. The ten-run gate intentionally requires visual
confirmation.
“Hey GPT”
→ Automatic Apple Voice Processing/Raw, or manually selected DPDFNet
→ adaptive local SNR verification
→ local wake confirmation
→ microphone capture pauses
→ Voice hotkey is posted after a 300 ms audio handoff
→ official ChatGPT Voice appears
→ GPTIRL resumes listening after the 30-second cooldown
With Auto-launch ChatGPT enabled:
“Hey GPT”
→ local wake confirmation
→ GPTIRL launches ChatGPT
→ configurable startup countdown
→ process availability check
→ Voice hotkey is posted
→ official ChatGPT Voice appears
The default startup delay is 10 seconds. Increase it on slower machines if ChatGPT launches but Voice does not appear.
- Listening: enables or releases continuous local microphone capture.
- Noise Reduction: selects Automatic (Apple Voice Processing, then Raw), forces DPDFNet for evaluation, or forces Raw for comparison.
- Auto-launch ChatGPT: permits wake detection while ChatGPT is closed.
- ChatGPT Startup Delay: chooses 3–30 seconds before cold-start dispatch.
- Test Voice Shortcut: validates the official ChatGPT integration.
- Test Microphone: proves that 16 kHz mono PCM reaches GPTIRL.
- Test Wake Word: reports raw model candidates and verification results.
- Test Noise Robustness: runs matched 5-second ambient and 10-second wake-phrase passes in DPDFNet and Raw modes. It reports the active mode, fallback reason, inference timing, noise floor, SNR, candidates, verified wakes, and rejection reason without saving PCM.
- Live Caption: uses Apple's on-device Speech framework to display a short diagnostic transcription. It is not part of normal wake detection.
- Automatically Check for Updates: queries published GitHub Releases at most once every 24 hours. It is enabled by default and can be disabled.
- Check for Updates: compares the installed semantic version with the newest published GPTIRL release immediately.
- Diagnostics: reports app state, permissions, audio counts, keyword candidates, and ChatGPT process information.
- Wake-word audio remains on device.
- PCM is converted to 16 kHz mono and retained only in a two-second in-memory ring buffer.
- Noise calibration stores only numeric RMS/SNR summaries, not audio.
- GPTIRL creates no audio recording files.
- GPTIRL does not call the OpenAI API and never sends microphone audio over the network.
- DPDFNet and keyword inference use bundled ONNX files on the local CPU.
- Building from source downloads pinned model assets once; the installed app never downloads models at runtime.
- When update checks are enabled, GPTIRL sends a version-metadata request to GitHub's public Releases API. No audio, transcript, shortcut, or ChatGPT data is included. Disabling automatic checks removes this background request; manual checks still contact GitHub when selected.
- Disabling Listening stops
AVAudioEngineand releases its input tap. - After a verified wake, local capture pauses before ChatGPT Voice starts.
- GPTIRL does not read or modify ChatGPT settings, private files, chats, or application resources.
- GPTIRL does not use CDP, UI selectors, mouse automation, or private URL schemes.
The optional Live Caption diagnostic uses Apple's on-device Speech framework and has a separate Speech Recognition permission.
The Preview is ad-hoc signed. Replacing the app changes its code identity and can leave an apparently enabled but stale Accessibility entry. Remove and re-add the installed app if the Voice shortcut stops working after an update. A Developer ID signature and notarization are required before general distribution.
GPTIRL checks the public GitHub Releases list and can open the exact page for a newer version. It does not silently replace itself. Preview builds are ad-hoc signed, and replacing the bundle changes its code identity; macOS may therefore require Accessibility authorization again after every installed update.
macOS exposes event posting, but not confirmation that another app handled the event. The desktop notification means GPTIRL recognized the wake phrase and posted the configured shortcut. ChatGPT can still ignore it because of a shortcut mismatch, stale permission, startup timing, account availability, or an application update.
GPTIRL confirms that the ChatGPT process exists, then waits for the configured delay. It cannot inspect the private readiness state of ChatGPT Voice. The current workaround is increasing the startup delay.
The bundled bilingual 3M keyword model is shared by all users. Noise, distance, microphone processing, pronunciation, and other speech containing similar sounds can affect recall or false activations. The Preview does not include speaker verification or per-user model training.
Automatic first requests Apple's Voice Processing path for acoustic echo cancellation, noise reduction, and automatic gain control. If the selected device or format cannot enable or start that path, GPTIRL continues listening with Raw PCM and exposes the fallback reason in Diagnostics. GPTIRL also detects the macOS failure mode where Voice Processing starts but returns no PCM or sustained digital silence, then rebuilds the input as Raw without disabling Listening. The runtime failure is cached until the audio device changes, avoiding a repeated silent probe after every cooldown. Use DPDFNet only for comparison, or Raw to skip the Apple probe without enhancement.
The current sherpa-onnx keyword score and threshold remain 4.0 and 0.05.
They are intentionally unchanged while input processing is evaluated. The
initial Raw baseline was 15/30. DPDFNet produced only 3/21 in the matched
follow-up, so it failed the improvement gate and is not used by Automatic.
Its near-zero noise floor indicates aggressive suppression that removes
phonetic detail needed by the current KWS model.
- Apple Silicon only.
- macOS 14+ only.
- No lock-screen or sleep wake.
- No automatic Chat, Work, or Codex context selection.
- No guarantee that future ChatGPT releases retain the same bundle ID or global Voice-hotkey behavior.
- Current post-wake cooldown is 30 seconds.
| Symptom | Recommended action |
|---|---|
| Test Shortcut posts but Voice does not appear | Confirm ChatGPT Voice and GPTIRL both use ⌃⌥G; then remove and re-add GPTIRL under Accessibility. |
| Wake phrase is recognized but dispatch fails | Reauthorize Accessibility; GPTIRL now reports this as a permission failure instead of a successful dispatch. |
| ChatGPT launches but Voice never appears | Increase ChatGPT Startup Delay, then repeat the shortcut test. |
| No wake feedback appears | Run Test Microphone, then Test Wake Word. Confirm Listening is enabled and the 30-second cooldown has ended. |
| Model candidates appear but verified wakes remain zero | Inspect noise floor, SNR, and the rejection reason in Test Wake Word. The adaptive gate requires 80 ms at least 6 dB above the calibrated floor. |
| Automatic shows Raw fallback | Apple Voice Processing was unavailable or silent. GPTIRL is continuing with unmodified Raw PCM. |
| DPDFNet shows Raw fallback | Confirm dpdfnet_baseline.onnx exists in the installed app's Resources/Models directory, then copy Diagnostics. |
| Media volume changes while listening | Select Noise Reduction → DPDFNet or Raw, then run the DPDFNet-versus-Raw test. |
| Microphone works but recognition is unclear | Use Live Caption only as a diagnostic to confirm intelligible speech reaches the app. |
| Shortcut works once after using Test Shortcut | Treat this as a likely stale PostEvent/Accessibility authorization; re-add the final installed app rather than relying on repeated tests. |
| Update check fails | Confirm the Mac can reach api.github.com, then use Check for Updates… again. Wake detection remains local and continues without GitHub access. |
The bootstrap script downloads pinned sherpa-onnx runtime/model artifacts and verifies their SHA-256 hashes.
git clone https://github.com/d8dzmf5mfn/GPTIRL.git
cd GPTIRL
./script/bootstrap_sherpa.sh
./script/build_and_install.shThe app is installed to ~/Applications/GPTIRL.app.
To build and verify without replacing the installed app:
./script/build_and_install.sh --no-installTo create a Preview archive:
./script/package_release.shThe packaging workflow runs all tests, performs a clean Release build, signs
the app and nested libraries ad hoc, verifies the bundle before and after ZIP
extraction, tests the ZIP, and produces a SHA-256 checksum under release/.
Run Test Noise Robustness (DPDFNet vs Raw) in the same microphone
position and background-noise scene. Stay quiet for each five-second ambient
phase; after the tone, say Hey GPT three times in the following ten seconds.
The saved summary contains numbers only.
Before promoting this Preview beyond experimental distribution, validate:
- quiet room: at least 19/20 wakes;
- mixed fan, traffic, television, speech, and music at about 8–12 dB SNR: at least 27/30;
- about 5 dB SNR: at least 24/30;
- two hours of normal media and similar phrases: zero false wakes;
- built-in microphone, AirPods, and post-device-switch recovery;
- no perceptible sustained media ducking in DPDFNet mode;
- wake phrase end to shortcut dispatch P95 below 700 ms;
- 30-minute average CPU below 5% and memory below 200 MB.
The recorded Raw baseline is 15/30. The tested DPDFNet baseline produced
3/21, so it is retained only as an explicit diagnostic mode and is not an
Automatic fallback.
GPTIRL is maintained as a macOS-only project. An iPhone or iPad application is not planned, and mobile Shortcuts/controller experiments are outside this repository's scope.
- sherpa-onnx, pinned to the version
and commit recorded in
THIRD_PARTY_NOTICES.md. - Bilingual 3M KWS model from the official sherpa-onnx model releases.
Third-party licenses are bundled inside the app. This repository does not yet include a project-level open-source license.