# muvox-io/euphonium architecture

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

- Interactive diagram: https://gitdiagram.com/muvox-io/euphonium
- Repository: https://github.com/muvox-io/euphonium

## Overview

Euphonium is an extensible streaming audio player for low-cost devices, including ESP32. Its principal workflow is controlling playback through a browser UI, which fetches playback state and sends controls to the device; device-side core services and audio outputs provide playback. The README gives only a brief product description, so several subsystem links are shown as unverified rather than inferred from names. The Berry interpreter is an embedded scripting capability; only its parser relationship is supported by the excerpts and source index.

Main entry points: [`src/core/main/app/Core.cpp`](https://github.com/muvox-io/euphonium/blob/develop/src/core/main/app/Core.cpp) (Application core), [`src/targets/esp32/main/app/EuphoniumApp.cpp`](https://github.com/muvox-io/euphonium/blob/develop/src/targets/esp32/main/app/EuphoniumApp.cpp) (ESP32 application), [`src/frontend/src/components/Playback/index.tsx`](https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/components/Playback/index.tsx) (Playback controls), [`src/core/external/berry/src/be_parser.c`](https://github.com/muvox-io/euphonium/blob/develop/src/core/external/berry/src/be_parser.c) (Berry parser)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_frontend["Web interface"]
  node_webapp["Web app<br/>[index.tsx]"]
  node_playback["Playback controls<br/>[index.tsx]"]
  node_playback_api["Playback API<br/>[playbackApi.ts]"]
  node_frontend_store["UI state store<br/>[store.ts]"]
  node_local_playback["Local playback state"]
  node_plugin_config["Plugin configuration"]
  node_plugin_models["Plugin models<br/>[models.ts]"]
  node_form_fields["Configuration forms<br/>[index.tsx]"]
  node_wifi_config["Wi-Fi setup<br/>[index.tsx]"]
  node_ota_ui["OTA controls"]
  node_radio_ui["Radio browser"]
end

subgraph group_core["Device core"]
  node_core["Application core<br/>[Core.cpp]"]
  node_http["HTTP dispatcher<br/>[HTTPDispatcher.cpp]"]
  node_connectivity["Connectivity service<br/>[Connectivity.h]"]
  node_ota["OTA handling<br/>[OTAHandler.cpp]"]
  node_service_task["Background jobs<br/>[ServiceTask.cpp]"]
end

subgraph group_audio["Audio and plugins"]
  node_audio_task["Audio task<br/>[AudioTask.cpp]"]
  node_plugins["Audio plugins"]
  node_snapcast["Multiroom audio"]
end

subgraph group_platform["Device platforms"]
  node_cli_target["Desktop target<br/>[main.cpp]"]
  node_esp_target["ESP32 target<br/>[main.cpp]"]
  node_esp_app["ESP32 application<br/>[EuphoniumApp.cpp]"]
  node_i2s_output["I2S output<br/>[I2SAudioOutput.cpp]"]
  node_bluetooth_sink["Bluetooth sink"]
end

subgraph group_berry["Berry scripting"]
  node_berry_parser["Berry parser<br/>[be_parser.c]"]
  node_berry_binding["Berry bindings<br/>[BerryBind.cpp]"]
  node_berry_objects["Berry objects<br/>[be_object.h]"]
  node_berry_strings["Berry strings<br/>[be_string.h]"]
end

node_user(("Device user"))

node_user -->|"uses"| node_webapp
node_webapp -.->|"renders"| node_playback
node_playback -->|"requests state"| node_playback_api
node_playback -->|"reads and updates"| node_local_playback
node_playback_api -->|"feeds state"| node_local_playback
node_frontend_store -->|"registers reducer"| node_playback_api
node_frontend_store -->|"registers reducer"| node_plugin_config
node_plugin_config -->|"uses models"| node_plugin_models
node_form_fields -->|"uses configuration"| node_plugin_config
node_form_fields -->|"uses models"| node_plugin_models
node_wifi_config -.->|"configures"| node_connectivity
node_ota_ui -.->|"requests updates"| node_ota
node_core -.->|"dispatches requests"| node_http
node_http -.->|"routes updates"| node_ota
node_ota -.->|"submits jobs"| node_service_task
node_core -.->|"coordinates playback"| node_audio_task
node_core -.->|"hosts"| node_plugins
node_plugins -.->|"supports multiroom"| node_snapcast
node_radio_ui -.->|"selects sources"| node_plugins
node_cli_target -->|"starts"| node_core
node_esp_target -->|"starts"| node_esp_app
node_esp_app -.->|"initializes"| node_core
node_esp_app -.->|"configures output"| node_i2s_output
node_esp_app -.->|"provides sink"| node_bluetooth_sink
node_berry_binding -.->|"integrates"| node_berry_parser
node_berry_parser -->|"uses object definitions"| node_berry_objects
node_berry_parser -->|"uses string definitions"| node_berry_strings

click node_webapp "https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/components/App/index.tsx"
click node_playback "https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/components/Playback/index.tsx"
click node_playback_api "https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/redux/api/euphonium/playbackApi.ts"
click node_frontend_store "https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/redux/store.ts"
click node_local_playback "https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/redux/reducers/localPlaybackState.ts"
click node_plugin_config "https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/redux/reducers/pluginConfigurationsReducer.ts"
click node_plugin_models "https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/api/euphonium/plugins/models.ts"
click node_form_fields "https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/components/FormFields/index.tsx"
click node_wifi_config "https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/components/WiFiConfig/index.tsx"
click node_ota_ui "https://github.com/muvox-io/euphonium/tree/develop/src/frontend/src/apps/ota"
click node_radio_ui "https://github.com/muvox-io/euphonium/tree/develop/src/frontend/src/apps/webradio"
click node_core "https://github.com/muvox-io/euphonium/blob/develop/src/core/main/app/Core.cpp"
click node_http "https://github.com/muvox-io/euphonium/blob/develop/src/core/main/app/HTTPDispatcher.cpp"
click node_connectivity "https://github.com/muvox-io/euphonium/blob/develop/src/core/main/app/include/Connectivity.h"
click node_ota "https://github.com/muvox-io/euphonium/blob/develop/src/core/main/app/OTAHandler.cpp"
click node_service_task "https://github.com/muvox-io/euphonium/blob/develop/src/core/main/app/ServiceTask.cpp"
click node_audio_task "https://github.com/muvox-io/euphonium/blob/develop/src/core/main/app/AudioTask.cpp"
click node_plugins "https://github.com/muvox-io/euphonium/tree/develop/src/core/main/plugins"
click node_snapcast "https://github.com/muvox-io/euphonium/tree/develop/src/core/main/multiroom"
click node_cli_target "https://github.com/muvox-io/euphonium/blob/develop/src/targets/cli/main.cpp"
click node_esp_target "https://github.com/muvox-io/euphonium/blob/develop/src/targets/esp32/main/main.cpp"
click node_esp_app "https://github.com/muvox-io/euphonium/blob/develop/src/targets/esp32/main/app/EuphoniumApp.cpp"
click node_i2s_output "https://github.com/muvox-io/euphonium/blob/develop/src/targets/esp32/main/app/I2SAudioOutput.cpp"
click node_bluetooth_sink "https://github.com/muvox-io/euphonium/blob/develop/src/targets/esp32/main/bluetooth_sink/BluetoothSinkPlugin.cpp"
click node_berry_parser "https://github.com/muvox-io/euphonium/blob/develop/src/core/external/berry/src/be_parser.c"
click node_berry_binding "https://github.com/muvox-io/euphonium/blob/develop/src/core/main/app/BerryBind.cpp"
click node_berry_objects "https://github.com/muvox-io/euphonium/blob/develop/src/core/external/berry/src/be_object.h"
click node_berry_strings "https://github.com/muvox-io/euphonium/blob/develop/src/core/external/berry/src/be_string.h"

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_webapp,node_playback,node_playback_api,node_frontend_store,node_local_playback,node_plugin_config,node_plugin_models,node_form_fields,node_wifi_config,node_ota_ui,node_radio_ui,node_user toneBlue
class node_core,node_http,node_connectivity,node_ota,node_service_task toneAmber
class node_audio_task,node_plugins,node_snapcast toneMint
class node_cli_target,node_esp_target,node_esp_app,node_i2s_output,node_bluetooth_sink toneRose
class node_berry_parser,node_berry_binding,node_berry_objects,node_berry_strings toneIndigo
```

## Components

### Web interface

- [Web app](https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/components/App/index.tsx): `src/frontend/src/components/App/index.tsx`
- [Playback controls](https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/components/Playback/index.tsx): `src/frontend/src/components/Playback/index.tsx`
- [Playback API](https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/redux/api/euphonium/playbackApi.ts): `src/frontend/src/redux/api/euphonium/playbackApi.ts`
- [UI state store](https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/redux/store.ts): `src/frontend/src/redux/store.ts`
- [Local playback state](https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/redux/reducers/localPlaybackState.ts): `src/frontend/src/redux/reducers/localPlaybackState.ts`
- [Plugin configuration](https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/redux/reducers/pluginConfigurationsReducer.ts): `src/frontend/src/redux/reducers/pluginConfigurationsReducer.ts`
- [Plugin models](https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/api/euphonium/plugins/models.ts): `src/frontend/src/api/euphonium/plugins/models.ts`
- [Configuration forms](https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/components/FormFields/index.tsx): `src/frontend/src/components/FormFields/index.tsx`
- [Wi-Fi setup](https://github.com/muvox-io/euphonium/blob/develop/src/frontend/src/components/WiFiConfig/index.tsx): `src/frontend/src/components/WiFiConfig/index.tsx`
- [OTA controls](https://github.com/muvox-io/euphonium/tree/develop/src/frontend/src/apps/ota): `src/frontend/src/apps/ota`
- [Radio browser](https://github.com/muvox-io/euphonium/tree/develop/src/frontend/src/apps/webradio): `src/frontend/src/apps/webradio`

### Device core

- [Application core](https://github.com/muvox-io/euphonium/blob/develop/src/core/main/app/Core.cpp): `src/core/main/app/Core.cpp`
- [HTTP dispatcher](https://github.com/muvox-io/euphonium/blob/develop/src/core/main/app/HTTPDispatcher.cpp): `src/core/main/app/HTTPDispatcher.cpp`
- [Connectivity service](https://github.com/muvox-io/euphonium/blob/develop/src/core/main/app/include/Connectivity.h): `src/core/main/app/include/Connectivity.h`
- [OTA handling](https://github.com/muvox-io/euphonium/blob/develop/src/core/main/app/OTAHandler.cpp): `src/core/main/app/OTAHandler.cpp`
- [Background jobs](https://github.com/muvox-io/euphonium/blob/develop/src/core/main/app/ServiceTask.cpp): `src/core/main/app/ServiceTask.cpp`

### Audio and plugins

- [Audio task](https://github.com/muvox-io/euphonium/blob/develop/src/core/main/app/AudioTask.cpp): `src/core/main/app/AudioTask.cpp`
- [Audio plugins](https://github.com/muvox-io/euphonium/tree/develop/src/core/main/plugins): `src/core/main/plugins`
- [Multiroom audio](https://github.com/muvox-io/euphonium/tree/develop/src/core/main/multiroom): `src/core/main/multiroom`

### Device platforms

- [Desktop target](https://github.com/muvox-io/euphonium/blob/develop/src/targets/cli/main.cpp): `src/targets/cli/main.cpp`
- [ESP32 target](https://github.com/muvox-io/euphonium/blob/develop/src/targets/esp32/main/main.cpp): `src/targets/esp32/main/main.cpp`
- [ESP32 application](https://github.com/muvox-io/euphonium/blob/develop/src/targets/esp32/main/app/EuphoniumApp.cpp): `src/targets/esp32/main/app/EuphoniumApp.cpp`
- [I2S output](https://github.com/muvox-io/euphonium/blob/develop/src/targets/esp32/main/app/I2SAudioOutput.cpp): `src/targets/esp32/main/app/I2SAudioOutput.cpp`
- [Bluetooth sink](https://github.com/muvox-io/euphonium/blob/develop/src/targets/esp32/main/bluetooth_sink/BluetoothSinkPlugin.cpp): `src/targets/esp32/main/bluetooth_sink/BluetoothSinkPlugin.cpp`

### Berry scripting

- [Berry parser](https://github.com/muvox-io/euphonium/blob/develop/src/core/external/berry/src/be_parser.c): `src/core/external/berry/src/be_parser.c`
- [Berry bindings](https://github.com/muvox-io/euphonium/blob/develop/src/core/main/app/BerryBind.cpp): `src/core/main/app/BerryBind.cpp`
- [Berry objects](https://github.com/muvox-io/euphonium/blob/develop/src/core/external/berry/src/be_object.h): `src/core/external/berry/src/be_object.h`
- [Berry strings](https://github.com/muvox-io/euphonium/blob/develop/src/core/external/berry/src/be_string.h): `src/core/external/berry/src/be_string.h`

### Other components

- **Device user**

## Connections

- Device user → Web app: uses
- Web app → Playback controls: renders
- Playback controls → Playback API: requests state (evidence: `src/frontend/src/components/Playback/index.tsx`)
- Playback controls → Local playback state: reads and updates (evidence: `src/frontend/src/components/Playback/index.tsx`)
- Playback API → Local playback state: feeds state (evidence: `src/frontend/src/redux/reducers/localPlaybackState.ts`)
- UI state store → Playback API: registers reducer (evidence: `src/frontend/src/redux/store.ts`)
- UI state store → Plugin configuration: registers reducer (evidence: `src/frontend/src/redux/store.ts`)
- Plugin configuration → Plugin models: uses models (evidence: `src/frontend/src/api/euphonium/plugins/models.ts`)
- Configuration forms → Plugin configuration: uses configuration (evidence: `src/frontend/src/components/FormFields/index.tsx`)
- Configuration forms → Plugin models: uses models (evidence: `src/frontend/src/components/FormFields/index.tsx`)
- Wi-Fi setup → Connectivity service: configures
- OTA controls → OTA handling: requests updates
- Application core → HTTP dispatcher: dispatches requests
- HTTP dispatcher → OTA handling: routes updates
- OTA handling → Background jobs: submits jobs
- Application core → Audio task: coordinates playback
- Application core → Audio plugins: hosts
- Audio plugins → Multiroom audio: supports multiroom
- Radio browser → Audio plugins: selects sources
- Desktop target → Application core: starts (evidence: `src/targets/cli/main.cpp`)
- ESP32 target → ESP32 application: starts (evidence: `src/targets/esp32/main/main.cpp`)
- ESP32 application → Application core: initializes
- ESP32 application → I2S output: configures output
- ESP32 application → Bluetooth sink: provides sink
- Berry bindings → Berry parser: integrates
- Berry parser → Berry objects: uses object definitions (evidence: `src/core/external/berry/src/be_parser.c`)
- Berry parser → Berry strings: uses string definitions (evidence: `src/core/external/berry/src/be_parser.c`)
