# serptail/gamut architecture

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

- Interactive diagram: https://gitdiagram.com/serptail/gamut
- Repository: https://github.com/serptail/gamut

## Overview

gamut is an Android music-streaming app. Users discover or search for tracks, start playback, build a library, download music for offline use, and optionally sync favorites, playlists, and artist follows across devices; song recognition and Android Auto are additional capabilities. The graph preserves those product stages and the playback, persistence, and sync layers. Several feature implementations are represented by their exact source directories because their wiring was not sampled; links are limited to README documentation or relationships visible in the source index and excerpts.

Main entry points: [`feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/TrackDownloadManager.kt`](https://github.com/serptail/gamut/blob/main/feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/TrackDownloadManager.kt) (Offline downloads), [`app/src/main/kotlin/com/gamut/MainActivity.kt`](https://github.com/serptail/gamut/blob/main/app/src/main/kotlin/com/gamut/MainActivity.kt) (App entry), [`core/core-sync/src/main/kotlin/com/gamut/core/sync/SyncEngine.kt`](https://github.com/serptail/gamut/blob/main/core/core-sync/src/main/kotlin/com/gamut/core/sync/SyncEngine.kt) (Cloud sync), [`feature/feature-search/src/main/kotlin/com/gamut/feature/search/ShazamSession.kt`](https://github.com/serptail/gamut/blob/main/feature/feature-search/src/main/kotlin/com/gamut/feature/search/ShazamSession.kt) (Song recognition)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["App and experience"]
  node_appentry["App entry<br/>[MainActivity.kt]"]
end

subgraph group_discovery["Discovery and recognition"]
  node_discover["Discover feed"]
  node_search["Track search"]
  node_catalogs["Music catalogs<br/>[DeezerChartsApi.kt]"]
  node_recognition["Song recognition<br/>[ShazamSession.kt]"]
  node_shazamservice["Recognition service"]
  node_shazamclient["Shazam client<br/>[ShazamClient.kt]"]
end

subgraph group_playback["Playback and offline"]
  node_tracksource["Source resolution"]
  node_youtube["YouTube extractor"]
  node_playerui["Player interface<br/>[PlayerScreen.kt]"]
  node_musicplayer["Music player"]
  node_session["Media session"]
  node_audioprocessing["Audio effects"]
  node_downloads["Offline downloads"]
  node_downloadservice["Download service<br/>[DownloadService.kt]"]
  node_storage["Storage settings<br/>[StorageSettings.kt]"]
end

subgraph group_data["Library and sync"]
  node_library["Library and playlists"]
  node_localmusic["Local music"]
  node_database[("App database<br/>[GamutDatabase.kt]")]
  node_downloadindex["Download index<br/>[DownloadIndex.kt]"]
  node_sync["Cloud sync<br/>[SyncEngine.kt]"]
  node_auth["Account sign-in<br/>[AuthRepository.kt]"]
end

node_listener(("Listener"))
node_supabase[("Supabase")]

node_listener -->|"opens app"| node_appentry
node_appentry -->|"browses"| node_discover
node_appentry -->|"searches"| node_search
node_discover -->|"loads charts"| node_catalogs
node_search -->|"searches tracks"| node_youtube
node_listener -->|"identifies music"| node_recognition
node_recognition -->|"uses service"| node_shazamservice
node_shazamclient -.->|"supports sessions"| node_recognition
node_listener -->|"selects track"| node_playerui
node_playerui -.->|"resolves track"| node_tracksource
node_tracksource -.->|"resolves stream"| node_youtube
node_youtube -.->|"provides stream"| node_musicplayer
node_musicplayer -.->|"processes audio"| node_audioprocessing
node_session -->|"controls playback"| node_musicplayer
node_listener -->|"builds library"| node_library
node_library -.->|"stores library"| node_database
node_listener -->|"browses device music"| node_localmusic
node_listener -->|"downloads tracks"| node_downloads
node_downloads -->|"resolves download"| node_tracksource
node_downloads -->|"records downloads"| node_downloadindex
node_downloadservice -->|"observes batch"| node_downloads
node_downloadindex -->|"reads database"| node_database
node_listener -->|"signs in optionally"| node_auth
node_auth -.->|"authenticates sync"| node_sync
node_sync -->|"syncs library"| node_supabase
node_sync -->|"syncs local data"| node_database
node_listener -->|"sets download options"| node_storage

click node_appentry "https://github.com/serptail/gamut/blob/main/app/src/main/kotlin/com/gamut/MainActivity.kt"
click node_discover "https://github.com/serptail/gamut/blob/main/feature/feature-search/src/main/kotlin/com/gamut/feature/search/DiscoverRepository.kt"
click node_search "https://github.com/serptail/gamut/blob/main/feature/feature-search/src/main/kotlin/com/gamut/feature/search/SearchRepository.kt"
click node_catalogs "https://github.com/serptail/gamut/blob/main/core/core-network/src/main/kotlin/com/gamut/core/network/DeezerChartsApi.kt"
click node_recognition "https://github.com/serptail/gamut/blob/main/feature/feature-search/src/main/kotlin/com/gamut/feature/search/ShazamSession.kt"
click node_shazamservice "https://github.com/serptail/gamut/blob/main/app/src/main/kotlin/com/gamut/ShazamListenService.kt"
click node_shazamclient "https://github.com/serptail/gamut/blob/main/core/core-network/src/main/kotlin/com/gamut/core/network/ShazamClient.kt"
click node_tracksource "https://github.com/serptail/gamut/blob/main/feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/ResolveTrackSourceUseCase.kt"
click node_youtube "https://github.com/serptail/gamut/blob/main/feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/NewPipeYoutubeSource.kt"
click node_playerui "https://github.com/serptail/gamut/blob/main/feature/feature-player-ui/src/main/kotlin/com/gamut/feature/playerui/PlayerScreen.kt"
click node_musicplayer "https://github.com/serptail/gamut/blob/main/core/core-player/src/main/kotlin/com/gamut/core/player/Media3MusicPlayer.kt"
click node_session "https://github.com/serptail/gamut/blob/main/core/core-player/src/main/kotlin/com/gamut/core/player/GamutMediaSessionService.kt"
click node_audioprocessing "https://github.com/serptail/gamut/blob/main/core/core-player/src/main/kotlin/com/gamut/core/player/SoundEngineProcessor.kt"
click node_downloads "https://github.com/serptail/gamut/blob/main/feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/TrackDownloadManager.kt"
click node_downloadservice "https://github.com/serptail/gamut/blob/main/feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/DownloadService.kt"
click node_library "https://github.com/serptail/gamut/blob/main/feature/feature-library/src/main/kotlin/com/gamut/feature/library/LibraryRepository.kt"
click node_localmusic "https://github.com/serptail/gamut/blob/main/feature/feature-library/src/main/kotlin/com/gamut/feature/library/LocalMusicScreen.kt"
click node_database "https://github.com/serptail/gamut/blob/main/core/core-database/src/main/kotlin/com/gamut/core/database/GamutDatabase.kt"
click node_downloadindex "https://github.com/serptail/gamut/blob/main/core/core-database/src/main/kotlin/com/gamut/core/database/DownloadIndex.kt"
click node_sync "https://github.com/serptail/gamut/blob/main/core/core-sync/src/main/kotlin/com/gamut/core/sync/SyncEngine.kt"
click node_auth "https://github.com/serptail/gamut/blob/main/core/core-sync/src/main/kotlin/com/gamut/core/sync/AuthRepository.kt"
click node_storage "https://github.com/serptail/gamut/blob/main/feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/StorageSettings.kt"

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_appentry toneBlue
class node_discover,node_search,node_catalogs,node_recognition,node_shazamservice,node_shazamclient,node_supabase toneAmber
class node_tracksource,node_youtube,node_playerui,node_musicplayer,node_session,node_audioprocessing,node_downloads,node_downloadservice,node_storage toneMint
class node_library,node_localmusic,node_database,node_downloadindex,node_sync,node_auth toneRose
class node_listener toneIndigo
```

## Components

### App and experience

- [App entry](https://github.com/serptail/gamut/blob/main/app/src/main/kotlin/com/gamut/MainActivity.kt): `app/src/main/kotlin/com/gamut/MainActivity.kt`

### Discovery and recognition

- [Discover feed](https://github.com/serptail/gamut/blob/main/feature/feature-search/src/main/kotlin/com/gamut/feature/search/DiscoverRepository.kt): `feature/feature-search/src/main/kotlin/com/gamut/feature/search/DiscoverRepository.kt`
- [Track search](https://github.com/serptail/gamut/blob/main/feature/feature-search/src/main/kotlin/com/gamut/feature/search/SearchRepository.kt): `feature/feature-search/src/main/kotlin/com/gamut/feature/search/SearchRepository.kt`
- [Music catalogs](https://github.com/serptail/gamut/blob/main/core/core-network/src/main/kotlin/com/gamut/core/network/DeezerChartsApi.kt): `core/core-network/src/main/kotlin/com/gamut/core/network/DeezerChartsApi.kt`
- [Song recognition](https://github.com/serptail/gamut/blob/main/feature/feature-search/src/main/kotlin/com/gamut/feature/search/ShazamSession.kt): `feature/feature-search/src/main/kotlin/com/gamut/feature/search/ShazamSession.kt`
- [Recognition service](https://github.com/serptail/gamut/blob/main/app/src/main/kotlin/com/gamut/ShazamListenService.kt): `app/src/main/kotlin/com/gamut/ShazamListenService.kt`
- [Shazam client](https://github.com/serptail/gamut/blob/main/core/core-network/src/main/kotlin/com/gamut/core/network/ShazamClient.kt): `core/core-network/src/main/kotlin/com/gamut/core/network/ShazamClient.kt`

### Playback and offline

- [Source resolution](https://github.com/serptail/gamut/blob/main/feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/ResolveTrackSourceUseCase.kt): `feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/ResolveTrackSourceUseCase.kt`
- [YouTube extractor](https://github.com/serptail/gamut/blob/main/feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/NewPipeYoutubeSource.kt): `feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/NewPipeYoutubeSource.kt`
- [Player interface](https://github.com/serptail/gamut/blob/main/feature/feature-player-ui/src/main/kotlin/com/gamut/feature/playerui/PlayerScreen.kt): `feature/feature-player-ui/src/main/kotlin/com/gamut/feature/playerui/PlayerScreen.kt`
- [Music player](https://github.com/serptail/gamut/blob/main/core/core-player/src/main/kotlin/com/gamut/core/player/Media3MusicPlayer.kt): `core/core-player/src/main/kotlin/com/gamut/core/player/Media3MusicPlayer.kt`
- [Media session](https://github.com/serptail/gamut/blob/main/core/core-player/src/main/kotlin/com/gamut/core/player/GamutMediaSessionService.kt): `core/core-player/src/main/kotlin/com/gamut/core/player/GamutMediaSessionService.kt`
- [Audio effects](https://github.com/serptail/gamut/blob/main/core/core-player/src/main/kotlin/com/gamut/core/player/SoundEngineProcessor.kt): `core/core-player/src/main/kotlin/com/gamut/core/player/SoundEngineProcessor.kt`
- [Offline downloads](https://github.com/serptail/gamut/blob/main/feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/TrackDownloadManager.kt): `feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/TrackDownloadManager.kt`
- [Download service](https://github.com/serptail/gamut/blob/main/feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/DownloadService.kt): `feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/DownloadService.kt`
- [Storage settings](https://github.com/serptail/gamut/blob/main/feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/StorageSettings.kt): `feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/StorageSettings.kt`

### Library and sync

- [Library and playlists](https://github.com/serptail/gamut/blob/main/feature/feature-library/src/main/kotlin/com/gamut/feature/library/LibraryRepository.kt): `feature/feature-library/src/main/kotlin/com/gamut/feature/library/LibraryRepository.kt`
- [Local music](https://github.com/serptail/gamut/blob/main/feature/feature-library/src/main/kotlin/com/gamut/feature/library/LocalMusicScreen.kt): `feature/feature-library/src/main/kotlin/com/gamut/feature/library/LocalMusicScreen.kt`
- [App database](https://github.com/serptail/gamut/blob/main/core/core-database/src/main/kotlin/com/gamut/core/database/GamutDatabase.kt): `core/core-database/src/main/kotlin/com/gamut/core/database/GamutDatabase.kt`
- [Download index](https://github.com/serptail/gamut/blob/main/core/core-database/src/main/kotlin/com/gamut/core/database/DownloadIndex.kt): `core/core-database/src/main/kotlin/com/gamut/core/database/DownloadIndex.kt`
- [Cloud sync](https://github.com/serptail/gamut/blob/main/core/core-sync/src/main/kotlin/com/gamut/core/sync/SyncEngine.kt): `core/core-sync/src/main/kotlin/com/gamut/core/sync/SyncEngine.kt`
- [Account sign-in](https://github.com/serptail/gamut/blob/main/core/core-sync/src/main/kotlin/com/gamut/core/sync/AuthRepository.kt): `core/core-sync/src/main/kotlin/com/gamut/core/sync/AuthRepository.kt`

### Other components

- **Listener**
- **Supabase**

## Connections

- Listener → App entry: opens app (evidence: `README.md`)
- App entry → Discover feed: browses (evidence: `README.md`)
- App entry → Track search: searches (evidence: `README.md`)
- Discover feed → Music catalogs: loads charts
- Track search → YouTube extractor: searches tracks (evidence: `feature/feature-search/src/main/kotlin/com/gamut/feature/search/SearchRepository.kt`)
- Listener → Song recognition: identifies music (evidence: `README.md`)
- Song recognition → Recognition service: uses service (evidence: `app/src/main/kotlin/com/gamut/ShazamListenService.kt`)
- Shazam client → Song recognition: supports sessions
- Listener → Player interface: selects track (evidence: `README.md`)
- Player interface → Source resolution: resolves track
- Source resolution → YouTube extractor: resolves stream
- YouTube extractor → Music player: provides stream (evidence: `README.md`)
- Music player → Audio effects: processes audio (evidence: `README.md`)
- Media session → Music player: controls playback (evidence: `core/core-player/src/main/kotlin/com/gamut/core/player/GamutMediaSessionService.kt`)
- Listener → Library and playlists: builds library (evidence: `README.md`)
- Library and playlists → App database: stores library (evidence: `README.md`)
- Listener → Local music: browses device music (evidence: `README.md`)
- Listener → Offline downloads: downloads tracks (evidence: `README.md`)
- Offline downloads → Source resolution: resolves download (evidence: `feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/TrackDownloadManager.kt`)
- Offline downloads → Download index: records downloads (evidence: `feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/TrackDownloadManager.kt`)
- Download service → Offline downloads: observes batch (evidence: `feature/feature-resolver/src/main/kotlin/com/gamut/feature/resolver/DownloadService.kt`)
- Download index → App database: reads database (evidence: `core/core-database/src/main/kotlin/com/gamut/core/database/DownloadIndex.kt`)
- Listener → Account sign-in: signs in optionally (evidence: `README.md`)
- Account sign-in → Cloud sync: authenticates sync
- Cloud sync → Supabase: syncs library (evidence: `README.md`)
- Cloud sync → App database: syncs local data (evidence: `core/core-sync/src/main/kotlin/com/gamut/core/sync/SyncManager.kt`)
- Listener → Storage settings: sets download options (evidence: `README.md`)
