Create multi-voice audiobooks from ebooks with AI-powered speaker detection and voice assignment.
RadioShow is a Python Tkinter desktop application that transforms ebooks (EPUB, MOBI, etc.) into professional multi-voice audiobooks. The app automatically detects speakers, resolves character identities using LLM analysis, assigns distinct voices to each character, and generates audio using TTS engines.
localhost:4247 (tested with LM Studio)
Clone the repository:
git clone <repository-url>
cd RadioShow
Create a Python virtual environment:
python -m venv .venv_chatterbox
.\.venv_chatterbox\Scripts\Activate.ps1
Install dependencies:
pip install -r requirements_chatterbox.txt
Verify Calibre installation:
ebook-convert is in your PATH or Calibre is installedebook-convert --versionConfigure LLM (Optional but recommended):
.\.venv_chatterbox\Scripts\python.exe main_app.py
Or on Windows, use the provided batch script:
RadioShow.bat
RadioShow/
├── main_app.py # Entry point - initializes Tkinter root and launches UI
├── ui_setup.py # Main UI orchestration, queue handling, workflow transitions
├── app_logic.py # Operational orchestration, background task management
├── app_state.py # Application state management and serialization
├── text_processing.py # Core text analysis, cast extraction, LLM orchestration
│
├── views/ # UI views for each wizard step
│ ├── editor_view.py # Step 3: Text editor and cast extraction
│ ├── cast_refinement_view.py # Step 4: Cast list refinement UI
│ ├── voice_assignment_view.py # Step 5: Voice assignment
│ ├── review_view.py # Step 6: Audio review and editing
│ └── ...
│
├── config_manager.py # Configuration loading and management
├── validators.py # Input validation rules
├── theming.py # Theme definitions (light/dark)
├── dialogs.py # Common dialog utilities
├── file_operations.py # File I/O, ebook conversion, directory management
├── tts_engines.py # TTS engine adapters (Chatterbox, etc.)
├── voice_analyzer.py # Voice feature analysis and matching
├── audio_effects.py # Audio post-processing effects
├── batch_processor.py # Batch audio processing and generation
├── performance_monitor.py # Performance tracking and diagnostics
├── progress_tracker.py # Progress calculation and reporting
│
├── tests/ # Pytest test suite
├── scripts/ # Helper scripts (test runners, etc.)
├── requirements_chatterbox.txt
├── README.md
└── GEMINI.md # Feature overview document
main_app.py - Entry Pointui_setup.py - UI Orchestrationapp_logic.py - Operation Managementtext_processing.py - Core Analysis EngineCast Extraction: extract_cast_list_from_book_beginning() - Extracts character list from book beginning with LLM
Pass 1 (Rules-Based): analyze_text_to_lines() - Identifies dialogue speakers using regex patterns
Pass 2 (LLM Resolution): resolve_ambiguous_speakers() - Uses LLM to resolve remaining unknown speakers
Speaker Refinement: refine_speaker_cast_list() - Groups speakers into canonical characters
Single-Speaker Review: run_single_speaker_review() - Targeted AI review for one speaker
app_state.py - State ManagementPersists across save/load cycles:
views/cast_refinement_view.py - Step 4 UIThe app generates detailed diagnostic logs in Audiobook_Output/:
Example diagnostic output:
2026-05-07T17:29:54 | PASS1 | lines=7713 dialogue=2959 unresolved_dialogue=2603 cast_seed_count=0 cast_seed_source=none
2026-05-07T20:46:21 | PASS2 | complete processed=2652 id_unresolved=1025/2603 verify_kept_pass1=2/16
Voices are managed in Audiobook_Output/voices_config.json:
{
"narrator": "Neil Gaiman",
"speaker": "Commander Spock",
"voices": { "Character Name": "voice_id", ... }
}
http://localhost:4247/v1 (OpenAI-compatible)/models endpointUse the repository virtualenv when running tests to ensure imports and test stubs load consistently.
python scripts/run_tests.py [pytest args]
./scripts/run_tests.ps1 -Args "-k test_name"
.venv_chatterbox):.\.venv_chatterbox\Scripts\python.exe -m pytest tests/test_cast_list_extraction.py -q
If pytest is not installed:
.\.venv_chatterbox\Scripts\python.exe -m pip install pytest
pytest: repo venvAdjust virtualenv path in scripts if using a different name.
tests/test_cast_list_extraction.py - Cast extraction with truncation/recoverytests/test_cast_seed_integration.py - Pass 1/2 cast seed integrationtests/test_single_speaker_review_helpers.py - Single-speaker AI review parsingtests/test_voice_alias_auto_assign.py - Voice alias matchingtests/test_speaker_validation.py - Speaker name validation151 commits
Python
99.9%
Create multi-voice audiobooks from ebooks with AI-powered speaker detection and voice assignment.
RadioShow is a Python Tkinter desktop application that transforms ebooks (EPUB, MOBI, etc.) into professional multi-voice audiobooks. The app automatically detects speakers, resolves character identities using LLM analysis, assigns distinct voices to each character, and generates audio using TTS engines.
localhost:4247 (tested with LM Studio)
Clone the repository:
git clone <repository-url>
cd RadioShow
Create a Python virtual environment:
python -m venv .venv_chatterbox
.\.venv_chatterbox\Scripts\Activate.ps1
Install dependencies:
pip install -r requirements_chatterbox.txt
Verify Calibre installation:
ebook-convert is in your PATH or Calibre is installedebook-convert --versionConfigure LLM (Optional but recommended):
.\.venv_chatterbox\Scripts\python.exe main_app.py
Or on Windows, use the provided batch script:
RadioShow.bat
RadioShow/
├── main_app.py # Entry point - initializes Tkinter root and launches UI
├── ui_setup.py # Main UI orchestration, queue handling, workflow transitions
├── app_logic.py # Operational orchestration, background task management
├── app_state.py # Application state management and serialization
├── text_processing.py # Core text analysis, cast extraction, LLM orchestration
│
├── views/ # UI views for each wizard step
│ ├── editor_view.py # Step 3: Text editor and cast extraction
│ ├── cast_refinement_view.py # Step 4: Cast list refinement UI
│ ├── voice_assignment_view.py # Step 5: Voice assignment
│ ├── review_view.py # Step 6: Audio review and editing
│ └── ...
│
├── config_manager.py # Configuration loading and management
├── validators.py # Input validation rules
├── theming.py # Theme definitions (light/dark)
├── dialogs.py # Common dialog utilities
├── file_operations.py # File I/O, ebook conversion, directory management
├── tts_engines.py # TTS engine adapters (Chatterbox, etc.)
├── voice_analyzer.py # Voice feature analysis and matching
├── audio_effects.py # Audio post-processing effects
├── batch_processor.py # Batch audio processing and generation
├── performance_monitor.py # Performance tracking and diagnostics
├── progress_tracker.py # Progress calculation and reporting
│
├── tests/ # Pytest test suite
├── scripts/ # Helper scripts (test runners, etc.)
├── requirements_chatterbox.txt
├── README.md
└── GEMINI.md # Feature overview document
main_app.py - Entry Pointui_setup.py - UI Orchestrationapp_logic.py - Operation Managementtext_processing.py - Core Analysis EngineCast Extraction: extract_cast_list_from_book_beginning() - Extracts character list from book beginning with LLM
Pass 1 (Rules-Based): analyze_text_to_lines() - Identifies dialogue speakers using regex patterns
Pass 2 (LLM Resolution): resolve_ambiguous_speakers() - Uses LLM to resolve remaining unknown speakers
Speaker Refinement: refine_speaker_cast_list() - Groups speakers into canonical characters
Single-Speaker Review: run_single_speaker_review() - Targeted AI review for one speaker
app_state.py - State ManagementPersists across save/load cycles:
views/cast_refinement_view.py - Step 4 UIThe app generates detailed diagnostic logs in Audiobook_Output/:
Example diagnostic output:
2026-05-07T17:29:54 | PASS1 | lines=7713 dialogue=2959 unresolved_dialogue=2603 cast_seed_count=0 cast_seed_source=none
2026-05-07T20:46:21 | PASS2 | complete processed=2652 id_unresolved=1025/2603 verify_kept_pass1=2/16
Voices are managed in Audiobook_Output/voices_config.json:
{
"narrator": "Neil Gaiman",
"speaker": "Commander Spock",
"voices": { "Character Name": "voice_id", ... }
}
http://localhost:4247/v1 (OpenAI-compatible)/models endpointUse the repository virtualenv when running tests to ensure imports and test stubs load consistently.
python scripts/run_tests.py [pytest args]
./scripts/run_tests.ps1 -Args "-k test_name"
.venv_chatterbox):.\.venv_chatterbox\Scripts\python.exe -m pytest tests/test_cast_list_extraction.py -q
If pytest is not installed:
.\.venv_chatterbox\Scripts\python.exe -m pip install pytest
pytest: repo venvAdjust virtualenv path in scripts if using a different name.
tests/test_cast_list_extraction.py - Cast extraction with truncation/recoverytests/test_cast_seed_integration.py - Pass 1/2 cast seed integrationtests/test_single_speaker_review_helpers.py - Single-speaker AI review parsingtests/test_voice_alias_auto_assign.py - Voice alias matchingtests/test_speaker_validation.py - Speaker name validation151 commits
Python
99.9%