# amonhoorilal/duosound architecture

> Architecture diagram of the GitHub repository amonhoorilal/duosound, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-13). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/amonhoorilal/duosound
- Repository: https://github.com/amonhoorilal/duosound

## Overview

DuoSound is a Windows desktop audio-sharing app: users choose a sound source and headphone outputs, start playback, and adjust synchronization manually or through microphone-based calibration. The controller coordinates device discovery, audio routing, saved settings, and speaker-volume changes; either the Flet or tkinter UI presents the controls, with Flet preferred and tkinter as fallback. The README also documents testing individual outputs, help, diagnostics, and tray controls. Some backend calls are supported by the source index rather than full excerpts, so uncertain links are omitted.

Main entry points: [`duosound/ui_flet/app.py`](https://github.com/amonhoorilal/duosound/blob/main/duosound/ui_flet/app.py) (Flet window), [`duosound/controller.py`](https://github.com/amonhoorilal/duosound/blob/main/duosound/controller.py) (App controller), [`duosound/ui/main_window.py`](https://github.com/amonhoorilal/duosound/blob/main/duosound/ui/main_window.py) (Classic window), [`main.py`](https://github.com/amonhoorilal/duosound/blob/main/main.py) (App launcher)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_entry_ui["App entry and UI"]
  node_entry["App launcher<br/>[main.py]"]
end

subgraph group_control["Playback control"]
  node_controller["App controller<br/>[controller.py]"]
end

subgraph group_audio["Audio and devices"]
  node_devices["Audio device discovery<br/>[devices.py]"]
  node_engine["Capture and playback engine<br/>[engine.py]"]
  node_calibrate["Sync calibration<br/>[calibrate.py]"]
  node_volume["Speaker volume control<br/>[volume.py]"]
end

subgraph group_support["Settings and help"]
  node_settings[("Persistent settings<br/>[settings.py]")]
  node_help_text["Help content<br/>[help_text.py]"]
  node_logging[("Logs and diagnostics<br/>[log_setup.py]")]
end

subgraph group_flet_ui["Flet presentation"]
  node_flet_app["Flet window<br/>[app.py]"]
  node_flet_pages["Flet pages<br/>[pages.py]"]
  node_flet_widgets["Flet widgets<br/>[widgets.py]"]
  node_flet_scenery["Flet scenery<br/>[scenery.py]"]
  node_flet_tokens["Flet design tokens<br/>[tokens.py]"]
  node_flet_words["Flet UI words<br/>[words.py]"]
  node_flet_icon["Flet app icon<br/>[icon.py]"]
end

subgraph group_classic_ui["Classic presentation"]
  node_classic_window["Classic window<br/>[main_window.py]"]
  node_classic_theme["Classic theme<br/>[theme.py]"]
  node_classic_widgets["Classic widgets<br/>[widgets.py]"]
  node_classic_scenery["Classic scenery<br/>[scenery.py]"]
  node_help_page["Help page<br/>[help_page.py]"]
  node_about_page["About and donate<br/>[about_page.py]"]
end

node_user(("Listener"))
node_windows_audio(("Windows audio endpoints"))

node_user -->|"launches"| node_entry
node_entry -->|"creates"| node_controller
node_entry -->|"launches when available"| node_flet_app
node_entry -->|"falls back to"| node_classic_window
node_user -->|"operates"| node_flet_app
node_user -->|"operates"| node_classic_window
node_flet_app -->|"calls"| node_controller
node_classic_window -->|"calls"| node_controller
node_controller -->|"discovers outputs"| node_devices
node_controller -->|"starts playback"| node_engine
node_controller -->|"runs calibration"| node_calibrate
node_controller -->|"controls speakers"| node_volume
node_controller -->|"loads and saves"| node_settings
node_devices -->|"enumerates endpoints"| node_windows_audio
node_engine -->|"captures and plays"| node_windows_audio
node_calibrate -->|"finds microphones"| node_devices
node_calibrate -->|"uses audio playback"| node_engine
node_entry -->|"configures"| node_logging
node_controller -.->|"records events"| node_logging
node_classic_window -->|"uses styles"| node_classic_theme
node_classic_window -->|"uses controls"| node_classic_widgets
node_classic_window -->|"opens"| node_help_page
node_classic_window -->|"opens"| node_about_page
node_classic_window -.->|"uses scenery"| node_classic_scenery
node_help_page -->|"renders"| node_help_text
node_about_page -->|"uses content"| node_help_text
node_flet_app -->|"uses pages"| node_flet_pages
node_flet_app -->|"uses controls"| node_flet_widgets
node_flet_app -->|"uses scenery"| node_flet_scenery
node_flet_app -->|"uses design tokens"| node_flet_tokens
node_flet_app -->|"uses icon"| node_flet_icon
node_flet_app -->|"uses UI words"| node_flet_words
node_flet_pages -->|"renders help"| node_help_text
node_flet_widgets -->|"uses tokens"| node_flet_tokens
node_flet_widgets -->|"uses UI words"| node_flet_words

click node_entry "https://github.com/amonhoorilal/duosound/blob/main/main.py"
click node_controller "https://github.com/amonhoorilal/duosound/blob/main/duosound/controller.py"
click node_classic_window "https://github.com/amonhoorilal/duosound/blob/main/duosound/ui/main_window.py"
click node_classic_theme "https://github.com/amonhoorilal/duosound/blob/main/duosound/ui/theme.py"
click node_classic_widgets "https://github.com/amonhoorilal/duosound/blob/main/duosound/ui/widgets.py"
click node_classic_scenery "https://github.com/amonhoorilal/duosound/blob/main/duosound/ui/scenery.py"
click node_help_page "https://github.com/amonhoorilal/duosound/blob/main/duosound/ui/help_page.py"
click node_about_page "https://github.com/amonhoorilal/duosound/blob/main/duosound/ui/about_page.py"
click node_flet_app "https://github.com/amonhoorilal/duosound/blob/main/duosound/ui_flet/app.py"
click node_flet_pages "https://github.com/amonhoorilal/duosound/blob/main/duosound/ui_flet/pages.py"
click node_flet_widgets "https://github.com/amonhoorilal/duosound/blob/main/duosound/ui_flet/widgets.py"
click node_flet_scenery "https://github.com/amonhoorilal/duosound/blob/main/duosound/ui_flet/scenery.py"
click node_flet_tokens "https://github.com/amonhoorilal/duosound/blob/main/duosound/ui_flet/tokens.py"
click node_flet_words "https://github.com/amonhoorilal/duosound/blob/main/duosound/ui_flet/words.py"
click node_flet_icon "https://github.com/amonhoorilal/duosound/blob/main/duosound/ui_flet/icon.py"
click node_devices "https://github.com/amonhoorilal/duosound/blob/main/duosound/devices.py"
click node_engine "https://github.com/amonhoorilal/duosound/blob/main/duosound/engine.py"
click node_calibrate "https://github.com/amonhoorilal/duosound/blob/main/duosound/calibrate.py"
click node_volume "https://github.com/amonhoorilal/duosound/blob/main/duosound/volume.py"
click node_settings "https://github.com/amonhoorilal/duosound/blob/main/duosound/settings.py"
click node_help_text "https://github.com/amonhoorilal/duosound/blob/main/duosound/help_text.py"
click node_logging "https://github.com/amonhoorilal/duosound/blob/main/duosound/log_setup.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_entry toneBlue
class node_controller toneAmber
class node_devices,node_engine,node_calibrate,node_volume toneMint
class node_settings,node_help_text,node_logging toneRose
class node_flet_app,node_flet_pages,node_flet_widgets,node_flet_scenery,node_flet_tokens,node_flet_words,node_flet_icon,node_user,node_windows_audio toneIndigo
class node_classic_window,node_classic_theme,node_classic_widgets,node_classic_scenery,node_help_page,node_about_page toneTeal
```

## Components

### App entry and UI

- [App launcher](https://github.com/amonhoorilal/duosound/blob/main/main.py): `main.py`

### Playback control

- [App controller](https://github.com/amonhoorilal/duosound/blob/main/duosound/controller.py): `duosound/controller.py`

### Audio and devices

- [Audio device discovery](https://github.com/amonhoorilal/duosound/blob/main/duosound/devices.py): `duosound/devices.py`
- [Capture and playback engine](https://github.com/amonhoorilal/duosound/blob/main/duosound/engine.py): `duosound/engine.py`
- [Sync calibration](https://github.com/amonhoorilal/duosound/blob/main/duosound/calibrate.py): `duosound/calibrate.py`
- [Speaker volume control](https://github.com/amonhoorilal/duosound/blob/main/duosound/volume.py): `duosound/volume.py`

### Settings and help

- [Persistent settings](https://github.com/amonhoorilal/duosound/blob/main/duosound/settings.py): `duosound/settings.py`
- [Help content](https://github.com/amonhoorilal/duosound/blob/main/duosound/help_text.py): `duosound/help_text.py`
- [Logs and diagnostics](https://github.com/amonhoorilal/duosound/blob/main/duosound/log_setup.py): `duosound/log_setup.py`

### Flet presentation

- [Flet window](https://github.com/amonhoorilal/duosound/blob/main/duosound/ui_flet/app.py): `duosound/ui_flet/app.py`
- [Flet pages](https://github.com/amonhoorilal/duosound/blob/main/duosound/ui_flet/pages.py): `duosound/ui_flet/pages.py`
- [Flet widgets](https://github.com/amonhoorilal/duosound/blob/main/duosound/ui_flet/widgets.py): `duosound/ui_flet/widgets.py`
- [Flet scenery](https://github.com/amonhoorilal/duosound/blob/main/duosound/ui_flet/scenery.py): `duosound/ui_flet/scenery.py`
- [Flet design tokens](https://github.com/amonhoorilal/duosound/blob/main/duosound/ui_flet/tokens.py): `duosound/ui_flet/tokens.py`
- [Flet UI words](https://github.com/amonhoorilal/duosound/blob/main/duosound/ui_flet/words.py): `duosound/ui_flet/words.py`
- [Flet app icon](https://github.com/amonhoorilal/duosound/blob/main/duosound/ui_flet/icon.py): `duosound/ui_flet/icon.py`

### Classic presentation

- [Classic window](https://github.com/amonhoorilal/duosound/blob/main/duosound/ui/main_window.py): `duosound/ui/main_window.py`
- [Classic theme](https://github.com/amonhoorilal/duosound/blob/main/duosound/ui/theme.py): `duosound/ui/theme.py`
- [Classic widgets](https://github.com/amonhoorilal/duosound/blob/main/duosound/ui/widgets.py): `duosound/ui/widgets.py`
- [Classic scenery](https://github.com/amonhoorilal/duosound/blob/main/duosound/ui/scenery.py): `duosound/ui/scenery.py`
- [Help page](https://github.com/amonhoorilal/duosound/blob/main/duosound/ui/help_page.py): `duosound/ui/help_page.py`
- [About and donate](https://github.com/amonhoorilal/duosound/blob/main/duosound/ui/about_page.py): `duosound/ui/about_page.py`

### Other components

- **Listener**
- **Windows audio endpoints**

## Connections

- Listener → App launcher: launches (evidence: `README.md`)
- App launcher → App controller: creates (evidence: `main.py`)
- App launcher → Flet window: launches when available (evidence: `main.py`)
- App launcher → Classic window: falls back to (evidence: `main.py`)
- Listener → Flet window: operates (evidence: `README.md`)
- Listener → Classic window: operates (evidence: `README.md`)
- Flet window → App controller: calls (evidence: `duosound/ui_flet/app.py`)
- Classic window → App controller: calls (evidence: `duosound/ui/main_window.py`)
- App controller → Audio device discovery: discovers outputs (evidence: `duosound/controller.py`)
- App controller → Capture and playback engine: starts playback (evidence: `duosound/controller.py`)
- App controller → Sync calibration: runs calibration (evidence: `duosound/controller.py`)
- App controller → Speaker volume control: controls speakers (evidence: `duosound/controller.py`)
- App controller → Persistent settings: loads and saves (evidence: `duosound/controller.py`)
- Audio device discovery → Windows audio endpoints: enumerates endpoints (evidence: `duosound/devices.py`)
- Capture and playback engine → Windows audio endpoints: captures and plays (evidence: `duosound/engine.py`)
- Sync calibration → Audio device discovery: finds microphones (evidence: `duosound/calibrate.py`)
- Sync calibration → Capture and playback engine: uses audio playback (evidence: `duosound/calibrate.py`)
- App launcher → Logs and diagnostics: configures (evidence: `main.py`)
- App controller → Logs and diagnostics: records events (evidence: `duosound/controller.py`)
- Classic window → Classic theme: uses styles (evidence: `duosound/ui/main_window.py`)
- Classic window → Classic widgets: uses controls (evidence: `duosound/ui/main_window.py`)
- Classic window → Help page: opens (evidence: `duosound/ui/main_window.py`)
- Classic window → About and donate: opens (evidence: `duosound/ui/main_window.py`)
- Classic window → Classic scenery: uses scenery
- Help page → Help content: renders (evidence: `duosound/ui/help_page.py`)
- About and donate → Help content: uses content (evidence: `duosound/ui/about_page.py`)
- Flet window → Flet pages: uses pages (evidence: `duosound/ui_flet/app.py`)
- Flet window → Flet widgets: uses controls (evidence: `duosound/ui_flet/app.py`)
- Flet window → Flet scenery: uses scenery (evidence: `duosound/ui_flet/app.py`)
- Flet window → Flet design tokens: uses design tokens (evidence: `duosound/ui_flet/app.py`)
- Flet window → Flet app icon: uses icon (evidence: `duosound/ui_flet/app.py`)
- Flet window → Flet UI words: uses UI words (evidence: `duosound/ui_flet/app.py`)
- Flet pages → Help content: renders help (evidence: `duosound/ui_flet/pages.py`)
- Flet widgets → Flet design tokens: uses tokens (evidence: `duosound/ui_flet/widgets.py`)
- Flet widgets → Flet UI words: uses UI words (evidence: `duosound/ui_flet/widgets.py`)
