roseeast/PawnTTS
Real-time clientless text-to-speech and 3D spatial voice streamer for SA-MP legacy plugins and native open.mp components.
README.md
Pawn TTS brings real-time, clientless text-to-speech (TTS) and spatial audio streaming to SA-MP and open.mp Pawn servers. Players on standard PC (GTA: San Andreas) and Android mobile launchers do not require any client modifications, ASI plugins, or external software. Audio is streamed natively through the GTA audio engine via PlayAudioStreamForPlayer with full 3D spatial sound (distance attenuation and stereo panning).
Overview
| Item | Detail |
|---|---|
| Plugin name | pawn_tts |
| Target | SA-MP (0.3.7) and open.mp |
| Plugin type | Legacy SA-MP plugin API & Native open.mp Component |
| Language | C++17 |
| Audio streaming | Native HTTP chunked/range audio stream (audio/mpeg) |
| Default HTTP port | 7788 |
| Default TTS voice | Microsoft Edge voice ID (en-US-GuyNeural by default) |
| Default provider | Edge provider ID with Google legacy as optional fallback |
| Providers | ElevenLabs, Edge TTS, Kokoro, Piper, Custom HTTP, Google legacy fallback |
| Caching engine | RAM LRU cache + Disk caching with SHA-256 deduplication |
| Included platforms | Linux x86_64, Linux x86 (32-bit), Windows x86 (32-bit) |
| Pawn include | pawno/include/pawn_tts.inc |
Features
| Feature | Native / Stock | Notes |
|---|---|---|
| Check engine status | TTS_IsReady | Returns true if the HTTP stream server and audio engine are running. |
| Get streaming URL | TTS_GetBaseURL | Retrieves the active base stream URL (e.g. http://ip:7788/audio/). |
| Set public URL | TTS_SetPublicURL | Overrides the public URL (useful behind reverse proxies, NAT, or domain names). |
| Private speech | TTS_Speak | Streams voice privately to a single player in 2D stereo. |
| Broadcast speech | TTS_SpeakToAll | Streams voice to all connected players simultaneously. |
| 3D spatial speech | TTS_SpeakAtPos | Plays 3D positioned voice at world coordinates (X, Y, Z) with falloff distance. |
| 3D speech for player | TTS_SpeakAtPosForPlayer | Plays positioned 3D voice audible only to a targeted player. |
| Player body audio | TTS_SpeakFromPlayer | Plays 3D voice originating directly from a player's physical coordinate. |
| Stop player audio | TTS_Stop | Immediately stops any active speech stream for a player. |
| Stop all audio | TTS_StopAll | Immediately stops active speech streams for all players. |
| Pre-cache audio | TTS_Precache | Asynchronously generates and caches frequent phrases for instant 0 ms playback. |
| Check cached status | TTS_IsCached | Checks if a phrase has already been synthesized and cached. |
| Cache statistics | TTS_GetStats | Queries memory cache count, disk cache count, and total cache size in KB. |
| Purge cache | TTS_ClearCache | Clears memory and optionally disk audio cache. |
| Set provider | TTS_SetProvider | Selects ElevenLabs, Edge, Kokoro, Piper, Custom, or Google legacy. |
| Request control | TTS_Cancel | Cancels queued requests and marks active requests cancelled when possible. |
| Request state | TTS_GetRequestState | Queries queued, processing, completed, failed, or cancelled state. |
| Synthesis callback | OnTTSGenerated | Called when a speech synthesis request finishes generating. |
| Modern callback | OnTTSGeneratedEx | Includes request ID, player ID, provider, and audio URL. |
| Playback callback | OnTTSReady | Dispatches audio stream to the client via PlayAudioStreamForPlayer. |
Release Files
Prebuilt release packages are available in release/.
| File | Format | Contents |
|---|---|---|
release/pawn-tts-v0.2.0-windows-x86.zip | ZIP | Windows 32-bit release archive (legacy plugin & native component). |
release/pawn-tts-v0.2.0-linux-x86.zip | ZIP | Linux 32-bit release archive (legacy plugin & native component). |
release/pawn-tts-v0.2.0-linux-x86_64.tar.gz | tar.gz | Linux 64-bit release archive (legacy plugin & native component). |
release/pawn-tts-v0.2.0.zip | ZIP | Universal bundle containing all platforms and examples. |
Package layout:
pawn-tts-v0.2.0/
plugins/
pawn_tts.so
pawn_tts.dll
components/
pawn_tts.so
pawn_tts.dll
pawno/include/
pawn_tts.inc
examples/
example.pwn
commands.pwn
pawn_tts.json
README.md
LICENSE
Compatibility
| Runtime | Status | Notes |
|---|---|---|
| SA-MP Windows server | Supported | Use plugins/pawn_tts.dll (32-bit for classic SA-MP Windows servers). |
| SA-MP Linux server | Supported | Use plugins/pawn_tts.so (32-bit x86 for classic SA-MP Linux servers). |
| open.mp Windows server | Supported (Component & Plugin) | Native component: components/pawn_tts.dll. Legacy plugin: plugins/pawn_tts.dll. |
| open.mp Linux server | Supported (Component & Plugin) | Native component: components/pawn_tts.so. Legacy plugin: plugins/pawn_tts.so. |
| Android SA-MP clients | Supported | Fully clientless; streams through native GTA audio stream engine. |
| PC SA-MP clients | Supported | 100% stock GTA San Andreas client, no ASI plugins required. |
Pawn TTS does not hook RakNet, patch memory, or depend on internal server offsets. It registers standard Pawn natives and runs a high-performance HTTP stream listener to deliver audio directly to GTA game clients.
Installation
1. Install Files
For SA-MP (Legacy Plugin)
Copy the files into your server directory:
plugins/pawn_tts.so -> Linux server plugins folder (use x86 32-bit for classic SA-MP)
plugins/pawn_tts.dll -> Windows server plugins folder
pawno/include/pawn_tts.inc -> Pawn compiler include folder
pawn_tts.json -> Server root folder
For open.mp (Native Component - Recommended)
Copy the files into your server directory:
components/pawn_tts.so -> Linux server components folder
components/pawn_tts.dll -> Windows server components folder
pawno/include/pawn_tts.inc -> Pawn compiler include folder
pawn_tts.json -> Server root folder
For Qawno or custom build systems, place pawn_tts.inc in the include path used by your compiler.
2. Load The Plugin / Component
For SA-MP server.cfg:
plugins pawn_tts
On Linux setups where explicit extensions are required:
plugins pawn_tts.so
For open.mp config.json (Native Component Mode - Recommended):
{
"components": [
"pawn_tts"
]
}
For open.mp config.json (Legacy Plugin Mode):
{
"pawn": {
"legacy_plugins": ["pawn_tts"]
}
}
3. Include In Pawn
#include <pawn_tts>
Quick Start
#include <a_samp>
#include <pawn_tts>
public OnGameModeInit()
{
// Pre-cache frequent phrases for instant 0 ms playback
TTS_SetProvider(TTS_PROVIDER_EDGE);
TTS_SetVoice("en-US-GuyNeural");
TTS_Precache("Welcome to the server!");
return 1;
}
public OnPlayerConnect(playerid)
{
// Private 2D stereo welcome greeting
new requestid = TTS_Speak(playerid, "Welcome to Los Santos.");
printf("[TTS] queued request %d", requestid);
return 1;
}
// 3D Proximity Voice Chat: speech originates from the player character in world space
public OnPlayerText(playerid, text[])
{
TTS_SpeakFromPlayer(playerid, text, "id", 25.0);
return 1;
}
Native API
| Native | Signature | Return | Description |
|---|---|---|---|
TTS_IsReady | none | bool | Checks whether the HTTP server and audio engine are initialized. |
TTS_GetBaseURL | output[], maxlen = sizeof(output) | 1 | Copies the current base streaming URL into the output string. |
TTS_SetPublicURL | const url[] | 1 | Dynamically overrides the public streaming URL. |
TTS_SetProvider | provider | 1 | Changes the default provider for future requests. |
TTS_GetProvider | none | provider | Returns the current default provider ID. |
TTS_SetVoice | const voice[] | 1 | Sets the default voice ID/name. |
TTS_GetVoice | destination[], size | 1 | Copies the current default voice. |
TTS_SetModel | const model[] | 1 | Sets the default model name/path. |
TTS_SetSpeed | Float:speed | 1 | Sets the default speech speed. |
TTS_SetPitch | Float:pitch | 1 | Sets the default pitch where the provider supports it. |
TTS_SetVolume | Float:volume | 1 | Sets the default volume where the provider supports it. |
TTS_SetOption | const key[], const value[] | 1 | Sets a provider-specific option for future requests. |
TTS_Precache | const text[], const voice[] = "", Float:speed = 1.0 | request ID | Synthesizes and caches an audio phrase in the background without playing it. |
TTS_IsCached | const text[], const voice[] = "", Float:speed = 1.0 | bool | Checks whether a phrase is already available in memory or disk cache. |
TTS_ClearCache | bool:clear_disk = false | 1 | Clears memory cache (and optionally disk cache). |
TTS_GetStats | &cached_mem, &cached_disk, &total_bytes_kb | 1 | Retrieves current cache counts and total memory footprint in KB. |
TTS_Speak | playerid, const text[], const voice[] = "", Float:speed = 1.0 | request ID | Plays private 2D stereo audio directly to a player. |
TTS_SpeakEx | playerid, const text[], provider, const voice[] = "", const model[] = "", Float:speed = 1.0, Float:pitch = 0.0, Float:volume = 1.0 | request ID | Queues speech with per-request provider, voice, model, speed, pitch, and volume. |
TTS_SpeakToAll | const text[], const voice[] = "", Float:speed = 1.0 | request ID | Broadcasts audio to all connected players on the server. |
TTS_SpeakAtPos | const text[], const voice[] = "", Float:x, Float:y, Float:z, Float:distance = 30.0, Float:speed = 1.0 | request ID | Plays 3D spatial audio at specific world coordinates with distance falloff. |
TTS_SpeakAtPosForPlayer | playerid, const text[], const voice[] = "", Float:x, Float:y, Float:z, Float:distance = 30.0, Float:speed = 1.0 | request ID | Plays 3D spatial audio at specific coordinates audible only to a targeted player. |
TTS_Cancel | requestid | bool | Cancels a queued request and marks active work cancelled when the worker observes it. |
TTS_IsRequestActive | requestid | bool | Returns whether a request is queued or processing. |
TTS_GetRequestProvider | requestid | provider | Returns the provider used by a request. |
TTS_GetRequestState | requestid | state | Returns queued, processing, completed, failed, or cancelled. |
TTS_GetVoiceCount | provider | count | Returns the cached/static voice count known by a provider. |
TTS_SpeakFromPlayer | speakerid, const text[], const voice[] = "id", Float:distance = 25.0, Float:speed = 1.0 | bool | Plays 3D spatial audio emanating from a player's character body. |
TTS_Stop | playerid | 1 | Stops any active audio stream for a specific player. |
TTS_StopAll | none | 1 | Stops active audio streams for all connected players. |
Callbacks
forward OnTTSGenerated(const hash[], const text[], const voice[], bool:success);
forward OnTTSRequestQueued(requestid, playerid, provider);
forward OnTTSGeneratedEx(requestid, playerid, provider, const audio_url[]);
forward OnTTSError(requestid, playerid, provider, error_code, const error_message[]);
forward OnTTSCacheHit(requestid, playerid, const cache_key[]);
forward OnTTSFallback(requestid, playerid, old_provider, new_provider);
forward OnTTSReady(playerid, const hash[], const url[], Float:x, Float:y, Float:z, Float:distance, usepos);
OnTTSGenerated
Called asynchronously when a speech synthesis request finishes:
public OnTTSGenerated(const hash[], const text[], const voice[], bool:success)
{
if (success) {
printf("[TTS] Audio generated: hash=%s voice=%s", hash, voice);
}
return 1;
}
OnTTSReady
Dispatched automatically by the include hook to play audio via PlayAudioStreamForPlayer. If you define TTS_OnTTSReady, you can customize or filter stream playback before dispatch.
Configuration
Configuration is managed via pawn_tts.json in the server root folder:
{
"port": 7788,
"bind_ip": "0.0.0.0",
"public_url": "",
"provider": "edge",
"default_voice": "en-US-GuyNeural",
"default_model": "",
"default_speed": 1.0,
"default_pitch": 0.0,
"default_volume": 1.0,
"worker_threads": 2,
"cache_dir": "cache/tts",
"cache_memory_limit": 256,
"edge_enabled": true,
"edge_command": "",
"elevenlabs_enabled": false,
"elevenlabs_api_key_env": "ELEVENLABS_API_KEY",
"elevenlabs_command": "",
"kokoro_enabled": false,
"kokoro_command": "",
"piper_enabled": false,
"piper_command": "",
"custom_enabled": false,
"custom_http_url": "http://127.0.0.1:5000/tts",
"google_legacy_enabled": true
}
| Key | Type | Default | Description |
|---|---|---|---|
port | Integer | 7788 | Port for the embedded HTTP audio server. |
bind_ip | String | "0.0.0.0" | Network interface to bind the HTTP server. |
public_url | String | "" | Public base URL sent to clients (e.g. "http://play.example.com:7788"). If empty, auto-detects from client connection. |
provider | String | "edge" | Default provider ("elevenlabs", "edge", "kokoro", "piper", "custom", or "google_legacy"). |
default_voice | String | "en-US-GuyNeural" | Default provider voice ID. |
default_model | String | "" | Default provider model name/path. |
default_speed | Number | 1.0 | Default speech speed. |
default_pitch | Number | 0.0 | Default pitch value where supported. |
default_volume | Number | 1.0 | Default volume value where supported. |
worker_threads | Integer | 2 | Number of background synthesis workers. |
cache_dir | String | "cache/tts" | Directory path for persistent MP3 disk cache. |
cache_memory_limit | Integer | 256 | Maximum memory cache size in megabytes (MB). |
*_enabled | Boolean | varies | Enables a provider. Google legacy is fallback-only and is not the default provider. |
*_command | String | "" | Optional command adapter for Edge, ElevenLabs, Kokoro, or Piper. Supports {text}, {voice}, {model}, {output}, {request_id}, {speed}, {pitch}, and {volume}. |
custom_http_url | String | "" | Endpoint URL when using custom or local HTTP TTS engines. |
The C++ core now uses a provider interface internally. Edge, Kokoro, Piper, and ElevenLabs are isolated provider modules; this repository currently exposes them through command/config adapters unless you wire a native backend in the provider module. ElevenLabs API keys must come from an environment variable such as ELEVENLABS_API_KEY and are never exposed to Pawn.
3D Spatial Audio Mechanics
When using TTS_SpeakAtPos or TTS_SpeakFromPlayer, audio streams leverage GTA San Andreas's built-in BASS audio engine:
- Distance Falloff: Audio volume decreases smoothly from the center coordinate out to the configured radius (
distance). - Stereo Panning: Audio dynamically pans between the player's left and right audio channels based on their camera and character orientation relative to the sound source.
- Client Compatibility: Fully operational on standard PC GTA:SA clients and official Android mobile launchers without any custom
.asior APK modifications.
Build From Source
This repository uses CMake (version 3.20+).
Requirements
| Target | Requirement |
|---|---|
Linux .so (x86_64) | CMake 3.20+, C++17 compiler (g++ / clang++) |
Linux .so (x86 32-bit) | CMake 3.20+, Multilib 32-bit C++ compiler (g++ -m32) |
Windows .dll (x86 32-bit) | CMake 3.20+, MinGW toolchain (i686-w64-mingw32-g++-posix) or MSVC |
Linux (Native x86_64)
cmake -B build -S . -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release
Output:
build/plugins/pawn_tts.so(Legacy SA-MP plugin)build/components/pawn_tts.so(Native open.mp component)
Linux (32-bit x86 for Classic SA-MP)
cmake -B build-linux-x86 -S . \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS="-m32" \
-DCMAKE_SHARED_LINKER_FLAGS="-m32"
cmake --build build-linux-x86 --config Release
Output:
build-linux-x86/plugins/pawn_tts.so(Legacy SA-MP plugin)build-linux-x86/components/pawn_tts.so(Native open.mp component)
Windows (Cross-compile with MinGW)
cmake -B build-win -S . \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_C_COMPILER=i686-w64-mingw32-gcc-posix \
-DCMAKE_CXX_COMPILER=i686-w64-mingw32-g++-posix
cmake --build build-win --config Release
Output:
build-win/plugins/pawn_tts.dll(Legacy SA-MP plugin)build-win/components/pawn_tts.dll(Native open.mp component)
Troubleshooting
| Problem | Fix |
|---|---|
Failed (plugins/pawn_tts.so: wrong ELF class: ELFCLASS64) | Standard SA-MP Linux server is 32-bit. Use the 32-bit Linux binary from build-linux-x86/plugins/pawn_tts.so or release/pawn-tts-v0.2.0-linux-x86.zip. |
Failed (plugins/pawn_tts.so: cannot open shared object file) | Verify that pawn_tts.so is inside your plugins/ directory and referenced correctly in server.cfg. |
| Players cannot hear speech | Ensure TCP port 7788 is open in your firewall/security group, or configure "public_url" in pawn_tts.json with your server's reachable public IP or domain. |
| Audio stream cuts off or stutters | Increase "cache_memory_limit" in pawn_tts.json and use TTS_Precache during OnGameModeInit for frequently repeated server phrases. |
undefined symbol: TTS_Speak while compiling Pawn | Ensure pawn_tts.inc is placed in pawno/include/ and #include <pawn_tts> is present after #include <a_samp>. |
License
Pawn TTS is released under the MIT License.
audio-streamingopenmppawnpawn-packagesa-mpsa-mp-librarysa-mp-pluginspatial-audiotext-to-speechtts
Esta página se genera con lo que GitHub publica sobre el repositorio. samp.directory no aloja el código. Informar de un problema con esta ficha