Skip to content

Latest commit

Β 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🎧 The Descent β€” Interactive Audio Drama Engine

A lightweight, dependency-free interactive audio drama and fiction podcast framework with dynamic state-driven branching, Web Audio API visualizers, and automatic TTS/procedural sound fallback.

By : SAMUELSON G

HTML5 JavaScript Web Audio API License


Overview

The Descent bridges traditional fiction podcasting with dynamic, choice-driven video game storytelling. Built entirely in vanilla JavaScript with zero external runtime dependencies, the engine renders synchronous audio-transcript experiences, tracks persistent session variables, and branches narrative pathways seamlessly based on player decisions.

If external audio files fail to load or face CORS restrictions, the system gracefully degrades to a procedural synthesis fallback layer utilizing the Web Speech API (SpeechSynthesis) for dialogue and Web Audio API (OscillatorNode, BiquadFilterNode) for sound effects.


Key Features

  • Stateful Decision Graph: Interactive choice nodes modify persistent session variables, dynamically altering downstream conditional plot points.
  • Dual-Layer Audio Engine:
    • Primary: Native HTML5 Audio playback with millisecond-accurate transcript synchronization.
    • Fallback: Built-in SpeechSynthesis voice parameterization (pitch/rate per character) and procedural synthesis for SFX.
  • 6-Band Logarithmic FFT Visualizer: Hardware-accelerated real-time audio spectrum analyzer built on AnalyserNode.
  • WCAG 2.1 AAA Accessibility Compliance:
    • Full keyboard navigation and tab-focus trapping in modals (Tab / Shift+Tab).
    • Escape key listeners and focus restoration.
    • Dynamic ARIA live-region and slider updates (aria-valuenow, aria-valuemax).
  • Sub-Millisecond UI Sync Loop: Driven by requestAnimationFrame for smooth transcript scrolling, visualizer updates, and progress bar synchronization.
  • Defensive Local Persistence: Encapsulated state storage with error-guarded localStorage serialization.
  • Responsive Dark/Light System: CSS custom-property theme switcher with memory retention.

System Architecture

                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                   β”‚   Episode Data Graph    β”‚
                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                β”‚
                                β–Ό
                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                   β”‚    Engine Controller    β”‚
                   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                          β”‚           β”‚
       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜           └──────────────────┐
       β–Ό                                                 β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Primary HTML5 Audio  β”‚                         β”‚ Synthesis Fallback  β”‚
β”‚  (CORS / File Stream) β”‚                         β”‚ (Speech & Web Audio)β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚                                                 β”‚
           └──────────────────┐           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β–Ό           β–Ό
                      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                      β”‚  rAF Render Loop & Sync β”‚
                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                   β”‚
            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
            β–Ό                      β–Ό                      β–Ό
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ 6-Band FFT Viz   β”‚    β”‚ Active Transcriptβ”‚   β”‚ State Mutations  β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜


Project Structure

the-descent/
β”œβ”€β”€ assets/
β”‚   └── audio/                  # Audio assets (.mp3 / .wav)
β”‚       β”œβ”€β”€ scene1_entrance.mp3
β”‚       β”œβ”€β”€ scene2_water.mp3
β”‚       β”œβ”€β”€ scene2_wind.mp3
β”‚       β”œβ”€β”€ scene3_reunion.mp3
β”‚       β”œβ”€β”€ scene4_escape.mp3
β”‚       └── scene4_lost.mp3
β”œβ”€β”€ index.html                  # Core application entry point (HTML, CSS, JS)
β”œβ”€β”€ LICENSE                     # MIT License
└── README.md                   # System documentation


Quick Start

Because the project relies on native Web APIs without build steps or npm packages, you can launch it immediately using any local web server.

Option 1: Local HTTP Server (Recommended)

  1. Clone the repository:
git clone [https://github.com/Samuelson777/the-descent-interactive-audio.git](https://github.com/Samuelson777/the-descent-interactive-audio.git)
cd the-descent-interactive-audio
  1. Serve the directory using Python:
# Python 3
python3 -m http.server 8000
  1. Open in browser: Navigate to http://localhost:8000 in Google Chrome, Mozilla Firefox, or Apple Safari.

Option 2: VS Code Live Server

  1. Open the project folder in Visual Studio Code.
  2. Right-click index.html and select Open with Live Server.

Story Authoring & Data Format

Narratives are configured as JSON node graphs inside index.html. You can add new scenes or choices by defining nodes in episodeData:

const episodeData = {
    showId: "my-custom-story",
    title: "Episode 1: Into the Dark",
    initialNode: "scene_01",
    nodes: {
        "scene_01": {
            audioSrc: "assets/audio/scene1.mp3",
            transcript: [
                { start: 0.0, end: 4.0, speaker: "Narrator", text: "The rain pounded against the window." },
                { start: 4.5, end: 8.0, speaker: "Alex", text: "Do we open the lock or keep running?" }
            ],
            onComplete: {
                type: "branch",
                prompt: "What should we do?",
                choices: [
                    { 
                        label: "Unlock the door", 
                        nextNode: "scene_02_unlock", 
                        mutations: [{ key: "hasKey", value: true }] 
                    },
                    { 
                        label: "Keep running", 
                        nextNode: "scene_02_run", 
                        mutations: [{ key: "hasKey", value: false }] 
                    }
                ]
            }
        }
    }
};

Node Types on Completion

  • continue: Immediately proceeds to nextNode.
  • branch: Renders interactive decision buttons on screen.
  • conditional: Evaluates state variables to route the player automatically.

Conclusion

The Descent successfully demonstrates a production-grade, stateful interactive audio drama framework that bridges traditional fiction podcasting with dynamic choice-driven video game storytelling. By pairing a state-variable choice graph with dual-layer audio rendering (native HTML5 Audio with an automated Web Speech API / procedural Web Audio synthesis fallback), the engine achieves resilient, sub-millisecond transcript and visualizer synchronization. Integrated with WCAG 2.1 AAA modal accessibility, seamless theme toggling, and resilient local storage recovery, the architecture delivers an immersive, fault-tolerant experience across all desktop and mobile browsers.


Future Enhancements & Roadmap

  • Spatial & Binaural 3D Audio Processing: Integrate PannerNode and AudioListener spatialization into the Web Audio graph to position voices and sound effects in 3D binaural space for headphone listeners.
  • Dynamic Multitrack Stem Layering: Transition from static single-track audio files to stem-based mixing (separating Dialogue, Ambient SFX, and Music), enabling real-time music tension shifts and dynamic atmospheric ducking based on player state variables.
  • Generative AI Voice Streaming Integration: Upgrade the Web Speech synthesis fallback to stream low-latency, emotive AI voice models via WebRTC or Server-Sent Events for realistic voice rendering during dynamic content generation.
  • Visual Story Tree & Branch Replayer: Add an interactive WebGL narrative node map that lets listeners visually inspect unlocked paths, view decision statistics, and jump back to previous decision forks without clearing session state.
  • Visual & Haptic Sync Engine: Expand the time-indexed transcript schema to trigger synchronized haptic feedback patterns (via the Navigator Vibration API) and screen-shake canvas effects during high-intensity audio cues or ambient transitions.
  • Progressive Web App (PWA) & Offline Pre-caching: Implement Service Worker audio chunk caching and offline support so users can stream or pre-download episodic audio packages seamlessly on mobile devices.

Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository.
  2. Create a feature branch (git checkout -b feature/AmazingFeature).
  3. Commit your changes (git commit -m 'Add some AmazingFeature').
  4. Push to the branch (git push origin feature/AmazingFeature).
  5. Open a Pull Request.

License

Distributed under the MIT License. See LICENSE for more information.


About

Zero-dependency interactive audio drama engine featuring state-driven narrative branching, real-time Web Audio API visualizers, sub-millisecond transcript sync, and automatic speech synthesis fallback.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages