chore: change DECTalk port to 33001, Morshu port to 33002, add AI context file
This commit is contained in:
@@ -0,0 +1,52 @@
|
|||||||
|
# scrapyard-cogworks
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
Red-DiscordBot cog pack for Kingston's Scrapyard Discord server. Primary cog is **ttstoy** — a multi-engine TTS system with Discord integration, web UI, and Minecraft mod support.
|
||||||
|
|
||||||
|
## Cogs
|
||||||
|
|
||||||
|
### ttstoy
|
||||||
|
Multi-engine TTS cog with Discord slash commands, web UI, and Minecraft server integration.
|
||||||
|
|
||||||
|
**TTS Engines:**
|
||||||
|
- `chatterbox` — AI voice synthesis via Chatterbox API (port 8099)
|
||||||
|
- `clone` — Voice cloning from reference audio
|
||||||
|
- `dectalk` — DECTalk retro TTS server (port 33001)
|
||||||
|
- `vox` — Half-Life VOX concatenative speech
|
||||||
|
- `morshu` — Morshuspeak meme TTS server (port 33002)
|
||||||
|
- `minimax` — MiniMax cloud TTS API
|
||||||
|
|
||||||
|
**Key components:**
|
||||||
|
- `ttstoy.py` — Main cog (~150KB): Discord commands, queue system, voice management, guild config
|
||||||
|
- `webui/app.py` — Flask web UI for browser-based TTS with login system
|
||||||
|
- `dectalk-server/` — Node.js DECTalk wrapper (Express, port 33001)
|
||||||
|
- `morshu-server/server.py` — Python HTTP server for Morshuspeak (port 33002)
|
||||||
|
- `morshutalk_engine.py` — Audio concatenation engine for Morshu voice
|
||||||
|
- `vox_engine.py` — Half-Life VOX word concatenation
|
||||||
|
- `vox_words/`, `vox2_words/` — VOX audio sample packs
|
||||||
|
|
||||||
|
**Web UI features:**
|
||||||
|
- User login via Discord token (issued by bot command `[p]ttstoy login`)
|
||||||
|
- Voice management (predefined + personal voices)
|
||||||
|
- Minecraft `/tts` integration via `/api/mc/tts` proxy endpoint
|
||||||
|
- DECTalk page with server status
|
||||||
|
|
||||||
|
### autoroom
|
||||||
|
Auto voice channel creation/management cog (fork of PCXCogs AutoRoom).
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
```
|
||||||
|
Discord user → [p]ttstoy commands → ttstoy.py → Chatterbox API (port 8099)
|
||||||
|
Web UI user → webui/app.py → ttstoy.py → Chatterbox API / DECTalk (33001) / Morshu (33002)
|
||||||
|
Minecraft → mod → webui /api/mc/tts → Chatterbox API / DECTalk / Morshu
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related Repositories
|
||||||
|
- `http://192.168.0.200:3000/kingston/chatterbox-ttstoy-api` — Chatterbox TTS API server
|
||||||
|
- `http://192.168.0.200:3000/kingston/minecraft-tts-server-mod` — NeoForge Minecraft TTS mod
|
||||||
|
|
||||||
|
## Tech Stack
|
||||||
|
- Python 3.10+, Red-DiscordBot (discord.py)
|
||||||
|
- Flask (web UI)
|
||||||
|
- Node.js/Express (DECTalk server)
|
||||||
|
- pydub, librosa (audio processing)
|
||||||
@@ -22,7 +22,7 @@ The `dectalk` package provides:
|
|||||||
## Start the Server
|
## Start the Server
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
PORT=3001 npm start
|
PORT=33001 npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
Or use the start script:
|
Or use the start script:
|
||||||
@@ -34,10 +34,10 @@ Or use the start script:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Test health
|
# Test health
|
||||||
curl http://127.0.0.1:3001/health
|
curl http://127.0.0.1:33001/health
|
||||||
|
|
||||||
# Generate audio
|
# Generate audio
|
||||||
curl "http://127.0.0.1:3001/say?text=aeiou" -o aeiou.mp3
|
curl "http://127.0.0.1:33001/say?text=aeiou" -o aeiou.mp3
|
||||||
ffplay aeiou.mp3
|
ffplay aeiou.mp3
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ ffplay aeiou.mp3
|
|||||||
In Discord:
|
In Discord:
|
||||||
```
|
```
|
||||||
[p]ttstoy mode dectalk
|
[p]ttstoy mode dectalk
|
||||||
[p]ttstoy dectalkurl http://127.0.0.1:3001
|
[p]ttstoy dectalkurl http://127.0.0.1:33001
|
||||||
[p]tts aeiou john madden
|
[p]tts aeiou john madden
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ Run `npm install` in the dectalk-server directory.
|
|||||||
|
|
||||||
Use a different port:
|
Use a different port:
|
||||||
```bash
|
```bash
|
||||||
PORT=3002 npm start
|
PORT=33002 npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
### Linux dependency issues
|
### Linux dependency issues
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ DECTalk supports special commands for controlling speech:
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
```bash
|
```bash
|
||||||
curl "http://127.0.0.1:3001/say?text=%5B:rate%20150%5DHello%20world&voice=paul" -o test.mp3
|
curl "http://127.0.0.1:33001/say?text=%5B:rate%20150%5DHello%20world&voice=paul" -o test.mp3
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also use these in Discord:
|
You can also use these in Discord:
|
||||||
@@ -212,13 +212,13 @@ DECTalk includes 9 classic voices:
|
|||||||
|
|
||||||
**Direct API:**
|
**Direct API:**
|
||||||
```bash
|
```bash
|
||||||
curl "http://127.0.0.1:3001/say?text=Hello&voice=paul" -o paul.mp3
|
curl "http://127.0.0.1:33001/say?text=Hello&voice=paul" -o paul.mp3
|
||||||
curl "http://127.0.0.1:3001/say?text=Hello&voice=betty" -o betty.mp3
|
curl "http://127.0.0.1:33001/say?text=Hello&voice=betty" -o betty.mp3
|
||||||
```
|
```
|
||||||
|
|
||||||
**List available voices:**
|
**List available voices:**
|
||||||
```bash
|
```bash
|
||||||
curl http://127.0.0.1:3001/voices
|
curl http://127.0.0.1:33001/voices
|
||||||
```
|
```
|
||||||
|
|
||||||
## Customization
|
## Customization
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ Quick testing guide to verify everything works.
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/Desktop/ttstoy/dectalk-server
|
cd ~/Desktop/ttstoy/dectalk-server
|
||||||
PORT=3001 npm start
|
PORT=33001 npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
You should see:
|
You should see:
|
||||||
```
|
```
|
||||||
DECTalk TTS Server running on http://localhost:3001
|
DECTalk TTS Server running on http://localhost:33001
|
||||||
Health check: http://localhost:3001/health
|
Health check: http://localhost:33001/health
|
||||||
Simple API: http://localhost:3001/say?text=Hello
|
Simple API: http://localhost:33001/say?text=Hello
|
||||||
MiniMax-compatible API: POST http://localhost:3001/v1/t2a_v2
|
MiniMax-compatible API: POST http://localhost:33001/v1/t2a_v2
|
||||||
```
|
```
|
||||||
|
|
||||||
## Step 2: Test the API Directly
|
## Step 2: Test the API Directly
|
||||||
@@ -23,10 +23,10 @@ Open a new terminal and test:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Test health check
|
# Test health check
|
||||||
curl http://127.0.0.1:3001/health
|
curl http://127.0.0.1:33001/health
|
||||||
|
|
||||||
# Test simple endpoint (saves to test.mp3)
|
# Test simple endpoint (saves to test.mp3)
|
||||||
curl "http://127.0.0.1:3001/say?text=Hello%20world" -o test.mp3
|
curl "http://127.0.0.1:33001/say?text=Hello%20world" -o test.mp3
|
||||||
|
|
||||||
# Play the audio
|
# Play the audio
|
||||||
ffplay test.mp3
|
ffplay test.mp3
|
||||||
@@ -34,7 +34,7 @@ ffplay test.mp3
|
|||||||
mpv test.mp3
|
mpv test.mp3
|
||||||
|
|
||||||
# Test MiniMax-compatible endpoint
|
# Test MiniMax-compatible endpoint
|
||||||
curl -X POST http://127.0.0.1:3001/v1/t2a_v2 \
|
curl -X POST http://127.0.0.1:33001/v1/t2a_v2 \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d '{"text": "Testing DECTalk compatibility", "voice_setting": {"voice_id": "default"}}' \
|
-d '{"text": "Testing DECTalk compatibility", "voice_setting": {"voice_id": "default"}}' \
|
||||||
| jq '.base_resp'
|
| jq '.base_resp'
|
||||||
@@ -53,7 +53,7 @@ Expected output:
|
|||||||
In Discord:
|
In Discord:
|
||||||
|
|
||||||
```
|
```
|
||||||
[p]ttstoy dectalkurl http://127.0.0.1:3001
|
[p]ttstoy dectalkurl http://127.0.0.1:33001
|
||||||
[p]ttstoy mode dectalk
|
[p]ttstoy mode dectalk
|
||||||
[p]ttstoy mode
|
[p]ttstoy mode
|
||||||
```
|
```
|
||||||
@@ -61,7 +61,7 @@ In Discord:
|
|||||||
You should see:
|
You should see:
|
||||||
```
|
```
|
||||||
Current TTS Mode: 🤖 DECTALK
|
Current TTS Mode: 🤖 DECTALK
|
||||||
DECTalk API URL: http://127.0.0.1:3001
|
DECTalk API URL: http://127.0.0.1:33001
|
||||||
```
|
```
|
||||||
|
|
||||||
## Step 4: Test TTS in Discord
|
## Step 4: Test TTS in Discord
|
||||||
@@ -88,21 +88,21 @@ The bot should mix DECTalk voice with sound effects.
|
|||||||
### Server won't start (port in use)
|
### Server won't start (port in use)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Find what's using port 3001
|
# Find what's using port 33001
|
||||||
lsof -i :3001
|
lsof -i :33001
|
||||||
|
|
||||||
# Use a different port
|
# Use a different port
|
||||||
PORT=3002 npm start
|
PORT=33002 npm start
|
||||||
|
|
||||||
# Update TTSTOY
|
# Update TTSTOY
|
||||||
[p]ttstoy dectalkurl http://127.0.0.1:3002
|
[p]ttstoy dectalkurl http://127.0.0.1:33002
|
||||||
```
|
```
|
||||||
|
|
||||||
### "Cannot reach DECTalk API"
|
### "Cannot reach DECTalk API"
|
||||||
|
|
||||||
1. Check server is running:
|
1. Check server is running:
|
||||||
```bash
|
```bash
|
||||||
curl http://127.0.0.1:3001/health
|
curl http://127.0.0.1:33001/health
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Check server logs in the terminal where you started it
|
2. Check server logs in the terminal where you started it
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ Voice commands:
|
|||||||
# Test all voices
|
# Test all voices
|
||||||
for voice in paul betty harry frank dennis kit ursula rita wendy; do
|
for voice in paul betty harry frank dennis kit ursula rita wendy; do
|
||||||
echo "Testing $voice..."
|
echo "Testing $voice..."
|
||||||
curl "http://127.0.0.1:3001/say?text=Hello%20I%20am%20$voice&voice=$voice" -o "${voice}.mp3"
|
curl "http://127.0.0.1:33001/say?text=Hello%20I%20am%20$voice&voice=$voice" -o "${voice}.mp3"
|
||||||
done
|
done
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const path = require('path');
|
|||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
const PORT = process.env.PORT || 3000;
|
const PORT = process.env.PORT || 33001;
|
||||||
const OUTPUT_DIR = process.env.OUTPUT_DIR || path.join(__dirname, 'output');
|
const OUTPUT_DIR = process.env.OUTPUT_DIR || path.join(__dirname, 'output');
|
||||||
|
|
||||||
// Ensure output directory exists
|
// Ensure output directory exists
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""
|
||||||
Morshu TTS Server — standalone HTTP API for MorshuTalk engine.
|
Morshu TTS Server — standalone HTTP API for MorshuTalk engine.
|
||||||
Runs on port 3002. GET /say?text=... returns WAV audio.
|
Runs on port 33002. GET /say?text=... returns WAV audio.
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@@ -18,7 +18,7 @@ sys.path.insert(0, str(TTSTOY_DIR))
|
|||||||
from morshutalk_engine import Morshu
|
from morshutalk_engine import Morshu
|
||||||
|
|
||||||
morshu = Morshu()
|
morshu = Morshu()
|
||||||
PORT = int(os.environ.get("PORT", 3002))
|
PORT = int(os.environ.get("PORT", 33002))
|
||||||
|
|
||||||
|
|
||||||
class Handler(BaseHTTPRequestHandler):
|
class Handler(BaseHTTPRequestHandler):
|
||||||
|
|||||||
+3
-3
@@ -344,7 +344,7 @@ class TtsToy(Cog):
|
|||||||
sfx_volume=100,
|
sfx_volume=100,
|
||||||
tts_mode="minimax",
|
tts_mode="minimax",
|
||||||
chatterbox_api_url=CHATTERBOX_DEFAULT_URL,
|
chatterbox_api_url=CHATTERBOX_DEFAULT_URL,
|
||||||
dectalk_api_url=f"http://127.0.0.1:3001",
|
dectalk_api_url=f"http://127.0.0.1:33001",
|
||||||
dectalk_auto_start=True,
|
dectalk_auto_start=True,
|
||||||
accessibility_mode=False,
|
accessibility_mode=False,
|
||||||
vox_pack="vox",
|
vox_pack="vox",
|
||||||
@@ -688,7 +688,7 @@ class TtsToy(Cog):
|
|||||||
text: Text to synthesize
|
text: Text to synthesize
|
||||||
audio_path: Output file path
|
audio_path: Output file path
|
||||||
"""
|
"""
|
||||||
morshu_url = "http://127.0.0.1:3002"
|
morshu_url = "http://127.0.0.1:33002"
|
||||||
try:
|
try:
|
||||||
r = requests.get(f"{morshu_url}/say", params={"text": text}, timeout=60)
|
r = requests.get(f"{morshu_url}/say", params={"text": text}, timeout=60)
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
@@ -1970,7 +1970,7 @@ class TtsToy(Cog):
|
|||||||
Show or set DECTalk API URL.
|
Show or set DECTalk API URL.
|
||||||
|
|
||||||
- `[p]ttstoy dectalkurl` → show current URL
|
- `[p]ttstoy dectalkurl` → show current URL
|
||||||
- `[p]ttstoy dectalkurl http://127.0.0.1:3001` → set URL
|
- `[p]ttstoy dectalkurl http://127.0.0.1:33001` → set URL
|
||||||
"""
|
"""
|
||||||
if url is None:
|
if url is None:
|
||||||
current = await self._get_dectalk_api_url()
|
current = await self._get_dectalk_api_url()
|
||||||
|
|||||||
+4
-4
@@ -172,7 +172,7 @@ def get_chatterbox_url() -> str:
|
|||||||
|
|
||||||
def get_dectalk_url() -> str:
|
def get_dectalk_url() -> str:
|
||||||
cfg = get_global_config()
|
cfg = get_global_config()
|
||||||
return cfg.get("dectalk_api_url", "http://127.0.0.1:3001")
|
return cfg.get("dectalk_api_url", "http://127.0.0.1:33001")
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -403,7 +403,7 @@ def api_tts_generate():
|
|||||||
# Direct server modes — generate audio without the bot
|
# Direct server modes — generate audio without the bot
|
||||||
if mode == "morshu":
|
if mode == "morshu":
|
||||||
try:
|
try:
|
||||||
r = requests.get("http://127.0.0.1:3002/say", params={"text": text}, timeout=60)
|
r = requests.get("http://127.0.0.1:33002/say", params={"text": text}, timeout=60)
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
job_id = str(uuid.uuid4())
|
job_id = str(uuid.uuid4())
|
||||||
out_path = tempfile.mktemp(suffix=".wav")
|
out_path = tempfile.mktemp(suffix=".wav")
|
||||||
@@ -416,7 +416,7 @@ def api_tts_generate():
|
|||||||
|
|
||||||
if mode == "dectalk":
|
if mode == "dectalk":
|
||||||
try:
|
try:
|
||||||
dectalk_url = gcfg.get("dectalk_api_url", "http://127.0.0.1:3001")
|
dectalk_url = gcfg.get("dectalk_api_url", "http://127.0.0.1:33001")
|
||||||
r = requests.get(f"{dectalk_url}/say", params={"text": text}, timeout=30)
|
r = requests.get(f"{dectalk_url}/say", params={"text": text}, timeout=30)
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
job_id = str(uuid.uuid4())
|
job_id = str(uuid.uuid4())
|
||||||
@@ -680,7 +680,7 @@ def api_mc_tts():
|
|||||||
return r.content, 200, {"Content-Type": "audio/wav"}
|
return r.content, 200, {"Content-Type": "audio/wav"}
|
||||||
|
|
||||||
elif mode == "morshu":
|
elif mode == "morshu":
|
||||||
r = requests.get("http://127.0.0.1:3002/say", params={"text": text}, timeout=60)
|
r = requests.get("http://127.0.0.1:33002/say", params={"text": text}, timeout=60)
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
return r.content, 200, {"Content-Type": "audio/wav"}
|
return r.content, 200, {"Content-Type": "audio/wav"}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>About</h2>
|
<h2>About</h2>
|
||||||
<div style="font-size:0.85rem;color:#b0c8e0;margin-bottom:0.5rem;">Classic 1980s robotic speech synthesizer. Voices are controlled inline using commands embedded in your text.</div>
|
<div style="font-size:0.85rem;color:#b0c8e0;margin-bottom:0.5rem;">Classic 1980s robotic speech synthesizer. Voices are controlled inline using commands embedded in your text.</div>
|
||||||
<div class="muted">Server URL: <code>{{ gcfg.get('dectalk_api_url', 'http://127.0.0.1:3001') }}</code></div>
|
<div class="muted">Server URL: <code>{{ gcfg.get('dectalk_api_url', 'http://127.0.0.1:33001') }}</code></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
|||||||
Reference in New Issue
Block a user