# JoyVox Documentation

---

## 17) `joyvox.py` (`joy_speechtotext 4.0.1`)

### What it is for
A background speech-to-text utility for **Kingpin or other Quake II engine games**.

You hold a hotkey (or mouse button), speak into your microphone, release the key, and the script:

1. records your voice,
2. transcribes it with Whisper,
3. writes the result to a Quake-style `.cfg` file,
4. optionally auto-presses your in-game transmit bind so the message is sent.

It supports both:
- **public chat** via `say`
- **team chat** via `say_team`

It also supports a custom dictionary for correcting player names and game terms.

### Main files in the ZIP
- `joyvox.py` — the actual speech-to-text program
- `joyvox_config.cfg` — all settings and keybinds
- `joyvox_dictionary.cfg` — optional word/name corrections
- `joyvox_run.bat` — starts the Python script
- `joyvox_install_requirements.bat` — installs some dependencies
- `mic_on.ogg`, `mic_off.ogg`, `trans_success.ogg`, `trans_fail.ogg` — optional sound effects
- `joyvox_install.txt` — quick-start notes

### Important install note
The included install note and batch file are **out of date** for this version.

They install:
```bash
pip install pyaudio SpeechRecognition pynput pygame
```

But the current script also requires a **Whisper backend**:
- preferred: `faster-whisper`
- fallback: `openai-whisper`

So a more accurate install would be one of these:

```bash
pip install pyaudio pynput pygame faster-whisper
```

or:

```bash
pip install pyaudio pynput pygame openai-whisper
```

`SpeechRecognition` is listed in the batch file, but the current `joyvox.py` does not actually use it.

### Usage
```bash
python joyvox.py
```

or:

```bash
joyvox_run.bat
```

### Arguments
None.

This program is **not** configured through command-line arguments. It is controlled through:
- `joyvox_config.cfg`
- `joyvox_dictionary.cfg`
- the generated Quake/Kingpin `.cfg` files in your game folder

### Basic setup
1. Install Python.
2. Install the required Python packages.
3. Edit `joyvox_config.cfg`.
4. Run `joyvox.py` once so it can:
   - list audio devices,
   - load the Whisper model,
   - generate the in-game exec/bind file.
5. In Kingpin (or another Quake II engine game), run:
   ```
   exec joyvox.cfg
   ```
   or add that exec line to `autoexec.cfg`.
6. Leave `joyvox.py` running while you play.

### How to use it in-game
Default behavior:
- hold **`STT_LISTEN`** to record,
- release it to transcribe,
- the program writes the message,
- if auto-send is enabled, it simulates your chosen chat key.

Default chat mode behavior:
- auto-send defaults to **public chat** at startup,
- pressing the “auto public” key sets future auto-sends to `say`,
- pressing the “auto team” key sets future auto-sends to `say_team`.

You can also manually resend the last transcribed line using the in-game keys bound in the generated exec file.

### Generated output files
The script writes two important files into `STT_OUTPUT_PATH`:

1. **Exec/bind file** (`STT_EXEC_FILE`, default `joyvox.cfg`)
   - creates aliases
   - binds your listen/send keys in-game
   - intended to be executed from the game console or `autoexec.cfg`

2. **Message file** (`STT_OUTPUT_FILE`, default `joyvoxinput.cfg`)
   - contains aliases that expand to one or more `say` / `say_team` commands
   - gets rewritten after each successful transcription

### In-game aliases it generates
The exec file creates these aliases:
- `+stt`
- `-stt`
- `sttsay`
- `sttsayteam`

And binds:
- `STT_LISTEN` → `+stt`
- `STT_KEY` → `sttsay`
- `STT_TEAMKEY` → `sttsayteam`

### What the program does with long messages
Quake/Kingpin chat lines are short, so the script splits long transcription output into chunks:
- maximum **130 characters per transmission**
- up to **3 transmissions**
- if text still does not fit, the final chunk is truncated and ends in `...`

That means a long spoken sentence may become multiple `say` or `say_team` commands.

### Configuration reference (`joyvox_config.cfg`)

#### Keybinds
- `STT_LISTEN`  
  Push-to-talk key/button for recording.  
  Example: `mouse4`

- `STT_KEY_AUTO`  
  Sets future **auto-send** mode to public chat.  
  Example: `f5`

- `STT_TEAMKEY_AUTO`  
  Sets future **auto-send** mode to team chat.  
  Example: `f6`

- `STT_KEY`  
  Manual/repeat send key for public chat, and also the key auto-send simulates when public mode is active.  
  Example: `j`

- `STT_TEAMKEY`  
  Manual/repeat send key for team chat, and also the key auto-send simulates when team mode is active.  
  Example: `k`

#### Paths and filenames
- `STT_OUTPUT_PATH`  
  Folder where generated `.cfg` files are written. This should be your active game folder, such as `main` or a mod directory.

- `STT_OUTPUT_FILE`  
  The temporary/generated file that holds the current transcribed message.  
  Default: `joyvoxinput.cfg`

- `STT_EXEC_FILE`  
  The bind/alias file you `exec` from the game console.  
  Default: `joyvox.cfg`

- `STT_DICTIONARY_FILE`  
  Optional correction dictionary file.  
  Default: `joyvox_dictionary.cfg`

#### Sound effect options
- `SFX_ENABLED`  
  Master toggle for sounds.

- `SFX_MIC_ONOFF`  
  Plays mic-on / mic-off sounds when recording starts and stops.

- `SFX_TRANSCRIBE_SUCCESS`  
  Plays a sound when any speech was recognized.

- `SFX_TRANSCRIBE_FAIL`  
  Plays a sound when nothing usable was recognized.

#### Whisper / transcription options
- `STT_WHISPER_MODEL`  
  Whisper model name. Supported values in the config comments include:
  - `tiny.en`
  - `base.en`
  - `small.en`
  - `medium.en`
  - `large`

  Smaller models are faster; larger models are usually more accurate.

- `STT_WHISPER_DEVICE`  
  Whisper device selection:
  - `auto`
  - `cpu`
  - `cuda`

  `auto` tries CUDA first and falls back to CPU.

- `STT_LANGUAGE`  
  Language code passed to Whisper, such as `en`, `es`, or `fr`.

- `STT_MIN_AUDIO_LENGTH`  
  Minimum audio duration, in seconds, required before the script will attempt transcription.  
  Useful for filtering accidental taps.

- `STT_PROMPT`  
  Optional initial prompt sent to Whisper to improve recognition of context and terminology.

#### Text formatting options
- `STT_SENTENCECASE`  
  If `yes`, the first letter of the final message is capitalized. If `no`, the first letter is forced lowercase unless the first word is an acronym.

- `STT_CAPITALIZE`  
  If `no`, most words are forced lowercase, but all-caps acronyms are preserved.

- `STT_ENDWITHPERIOD`  
  If `yes`, the message ends with punctuation if it does not already. If `no`, a trailing period is removed.

- `STT_ALLOWEXCLAMATION`  
  If `no`, `!` is converted to `.`.

#### Send behavior options
- `STT_AUTO_KEY`  
  If `yes`, the script automatically simulates the configured public/team send key after transcription.

- `STT_CLEAR_AFTER_SEND`  
  If `yes`, the generated output file is cleared shortly after an auto-send, which helps prevent accidental repeats.

#### Audio input selection
- `STT_AUDIO_INPUT_INDEX`  
  Recording device index.
  - `auto` = use the system/default device
  - numeric value = use the numbered input device shown when the script starts

### Dictionary file format (`joyvox_dictionary.cfg`)
Format:
```text
wrong_transcription=correct_word
```

Examples:
```text
l4=Elfor
kingpen=Kingpin
cashola=cash
```

Behavior:
- matching is case-insensitive
- replacement preserves punctuation after the word
- useful for player names, map names, slang, and game-specific terms

### Supported input names for binds
The script explicitly understands these mouse names:
- `mouse1`
- `mouse2`
- `mouse3`
- `mouse4`
- `mouse5`

Keyboard keys are read as plain names such as:
- `j`
- `k`
- `f5`
- `f6`

### Audio behavior
- records **mono 16 kHz / 16-bit** audio
- uses a hold-to-record model
- transcribes only after the listen key is released
- writes to a temporary WAV file during transcription, then deletes it

### Best use case
This is mainly a **live voice-to-chat bridge** for multiplayer games where:
- voice chat is unavailable,
- you want faster typed callouts,
- or you want to keep chat in text form for teammates.

### Limitations / things to know
- The script must be left running in the background while you play.
- The game must be able to execute the generated `.cfg` files.
- Auto-send works by simulating the configured send key, so key conflicts may matter.
- If your microphone is not the default device and `STT_AUDIO_INPUT_INDEX=auto`, recording may come from the wrong input.
- The bundled install helper does not install Whisper even though the script requires it.
- This is configured entirely through files; there is no in-program GUI and no command-line argument system.

### Example workflow
1. Set:
   - `STT_OUTPUT_PATH=c:\games\kingpin2\main`
   - `STT_LISTEN=mouse4`
   - `STT_KEY_AUTO=f5`
   - `STT_TEAMKEY_AUTO=f6`
   - `STT_KEY=j`
   - `STT_TEAMKEY=k`
2. Run `python joyvox.py`.
3. In-game, run:
   ```
   exec joyvox.cfg
   ```
4. Press `f6` to put auto-send into team-chat mode.
5. Hold `mouse4`, speak, and release.
6. The script transcribes your speech and sends it as `say_team`.
