# prosincerity/ghostwriter architecture

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

- Interactive diagram: https://gitdiagram.com/prosincerity/ghostwriter
- Repository: https://github.com/prosincerity/ghostwriter

## Overview

Ghostwriter is an offline-first Android songwriting app. The main workflow is: a writer opens or creates a project, edits and saves lyrics, optionally imports a beat, then plays it while exploring its waveform and placing timeline markers. MainActivity routes between the home, editor, settings, and about screens; EditorScreen coordinates project persistence and beat preparation. The graph also shows lyric backups and waveform processing/cache as distinct internal responsibilities. Source excerpts are partial, so some UI-to-storage wiring and documented-but-unsampled details are intentionally omitted.

Main entry points: [`app/src/main/java/com/prosincerity/ghostwriter/ui/screens/EditorScreen.kt`](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/screens/EditorScreen.kt) (Lyrics editor), [`app/src/main/java/com/prosincerity/ghostwriter/data/ProjectStorage.kt`](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/data/ProjectStorage.kt) (Project operations), [`app/src/main/java/com/prosincerity/ghostwriter/MainActivity.kt`](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/MainActivity.kt) (App navigation), [`app/src/main/java/com/prosincerity/ghostwriter/media/BeatPlayer.kt`](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/media/BeatPlayer.kt) (Beat playback)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_navigation["App navigation"]
  node_activity["App navigation<br/>[MainActivity.kt]"]
  node_home["Project home<br/>[HomeScreen.kt]"]
  node_settings["Settings<br/>[SettingsScreen.kt]"]
  node_about["About<br/>[AboutScreen.kt]"]
end

subgraph group_writing["Songwriting workspace"]
  node_editor["Lyrics editor<br/>[EditorScreen.kt]"]
  node_notepad["Lyrics notepad<br/>[LyricsNotepad.kt]"]
  node_projectinfo["Project details"]
  node_markerui["Marker dialogs"]
end

subgraph group_audio["Beat and waveform"]
  node_beatplayer["Beat playback<br/>[BeatPlayer.kt]"]
  node_beatpanel["Beat controls<br/>[BeatPlayerPanel.kt]"]
  node_playbackcontrols["Playback controls"]
  node_waveview["Waveform timeline<br/>[WaveformView.kt]"]
  node_waveextract["Waveform extraction"]
  node_viewport["Waveform viewport"]
end

subgraph group_persistence["Project persistence"]
  node_projectstorage["Project operations<br/>[ProjectStorage.kt]"]
  node_lyricsstorage["Lyrics backups"]
  node_metadata["Project metadata<br/>[ProjectMetadata.kt]"]
  node_settingsdata["App settings<br/>[Settings.kt]"]
  node_wavecache["Waveform cache<br/>[WaveformCache.kt]"]
end

node_writer(("Writer"))
node_filesystem[("Local files")]
node_androidmedia["Android media APIs"]
node_audioimport["Audio file picker"]

node_writer -->|"opens app"| node_activity
node_activity -->|"shows home"| node_home
node_activity -->|"opens project"| node_editor
node_activity -->|"opens settings"| node_settings
node_activity -->|"opens about"| node_about
node_home -->|"manages projects"| node_projectstorage
node_editor -->|"loads project"| node_projectstorage
node_editor -->|"controls playback"| node_beatplayer
node_editor -->|"prepares waveform"| node_waveextract
node_editor -->|"selects beat"| node_audioimport
node_notepad -->|"edits lyrics"| node_editor
node_projectinfo -->|"edits details"| node_editor
node_markerui -->|"edits markers"| node_editor
node_beatpanel -->|"controls playback"| node_beatplayer
node_beatpanel -->|"shows timeline"| node_waveview
node_playbackcontrols -->|"controls playback"| node_beatplayer
node_waveview -->|"updates viewport"| node_viewport
node_projectstorage -->|"loads and saves"| node_lyricsstorage
node_projectstorage -->|"reads and writes"| node_metadata
node_projectstorage -->|"manages cache"| node_wavecache
node_lyricsstorage -->|"reads and writes"| node_filesystem
node_metadata -->|"reads and writes"| node_filesystem
node_settings -->|"accesses settings"| node_settingsdata
node_settingsdata -->|"persists settings"| node_filesystem
node_projectstorage -->|"stores projects"| node_filesystem
node_waveextract -->|"decodes audio"| node_androidmedia
node_beatplayer -->|"plays audio"| node_androidmedia
node_waveextract -->|"caches samples"| node_wavecache

click node_activity "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/MainActivity.kt"
click node_home "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/screens/HomeScreen.kt"
click node_settings "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/screens/SettingsScreen.kt"
click node_about "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/screens/AboutScreen.kt"
click node_editor "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/screens/EditorScreen.kt"
click node_notepad "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/components/LyricsNotepad.kt"
click node_projectinfo "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/screens/ProjectInfoDialog.kt"
click node_markerui "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/screens/EditorMarkerDialogs.kt"
click node_projectstorage "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/data/ProjectStorage.kt"
click node_lyricsstorage "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/data/ProjectLyricsStorage.kt"
click node_metadata "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/data/ProjectMetadata.kt"
click node_settingsdata "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/data/Settings.kt"
click node_beatplayer "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/media/BeatPlayer.kt"
click node_beatpanel "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/components/BeatPlayerPanel.kt"
click node_playbackcontrols "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/components/BeatPlaybackControls.kt"
click node_waveview "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/components/WaveformView.kt"
click node_waveextract "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/logic/WaveformExtractor.kt"
click node_viewport "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/logic/WaveformViewport.kt"
click node_wavecache "https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/data/WaveformCache.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_activity,node_home,node_settings,node_about toneBlue
class node_editor,node_notepad,node_projectinfo,node_markerui,node_filesystem toneAmber
class node_beatplayer,node_beatpanel,node_playbackcontrols,node_waveview,node_waveextract,node_viewport,node_androidmedia toneMint
class node_projectstorage,node_lyricsstorage,node_metadata,node_settingsdata,node_wavecache toneRose
class node_writer,node_audioimport toneIndigo
```

## Components

### App navigation

- [App navigation](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/MainActivity.kt): `app/src/main/java/com/prosincerity/ghostwriter/MainActivity.kt`
- [Project home](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/screens/HomeScreen.kt): `app/src/main/java/com/prosincerity/ghostwriter/ui/screens/HomeScreen.kt`
- [Settings](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/screens/SettingsScreen.kt): `app/src/main/java/com/prosincerity/ghostwriter/ui/screens/SettingsScreen.kt`
- [About](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/screens/AboutScreen.kt): `app/src/main/java/com/prosincerity/ghostwriter/ui/screens/AboutScreen.kt`

### Songwriting workspace

- [Lyrics editor](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/screens/EditorScreen.kt): `app/src/main/java/com/prosincerity/ghostwriter/ui/screens/EditorScreen.kt`
- [Lyrics notepad](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/components/LyricsNotepad.kt): `app/src/main/java/com/prosincerity/ghostwriter/ui/components/LyricsNotepad.kt`
- [Project details](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/screens/ProjectInfoDialog.kt): `app/src/main/java/com/prosincerity/ghostwriter/ui/screens/ProjectInfoDialog.kt`
- [Marker dialogs](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/screens/EditorMarkerDialogs.kt): `app/src/main/java/com/prosincerity/ghostwriter/ui/screens/EditorMarkerDialogs.kt`

### Beat and waveform

- [Beat playback](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/media/BeatPlayer.kt): `app/src/main/java/com/prosincerity/ghostwriter/media/BeatPlayer.kt`
- [Beat controls](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/components/BeatPlayerPanel.kt): `app/src/main/java/com/prosincerity/ghostwriter/ui/components/BeatPlayerPanel.kt`
- [Playback controls](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/components/BeatPlaybackControls.kt): `app/src/main/java/com/prosincerity/ghostwriter/ui/components/BeatPlaybackControls.kt`
- [Waveform timeline](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/ui/components/WaveformView.kt): `app/src/main/java/com/prosincerity/ghostwriter/ui/components/WaveformView.kt`
- [Waveform extraction](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/logic/WaveformExtractor.kt): `app/src/main/java/com/prosincerity/ghostwriter/logic/WaveformExtractor.kt`
- [Waveform viewport](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/logic/WaveformViewport.kt): `app/src/main/java/com/prosincerity/ghostwriter/logic/WaveformViewport.kt`

### Project persistence

- [Project operations](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/data/ProjectStorage.kt): `app/src/main/java/com/prosincerity/ghostwriter/data/ProjectStorage.kt`
- [Lyrics backups](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/data/ProjectLyricsStorage.kt): `app/src/main/java/com/prosincerity/ghostwriter/data/ProjectLyricsStorage.kt`
- [Project metadata](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/data/ProjectMetadata.kt): `app/src/main/java/com/prosincerity/ghostwriter/data/ProjectMetadata.kt`
- [App settings](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/data/Settings.kt): `app/src/main/java/com/prosincerity/ghostwriter/data/Settings.kt`
- [Waveform cache](https://github.com/prosincerity/ghostwriter/blob/main/app/src/main/java/com/prosincerity/ghostwriter/data/WaveformCache.kt): `app/src/main/java/com/prosincerity/ghostwriter/data/WaveformCache.kt`

### Other components

- **Writer**
- **Local files**
- **Android media APIs**
- **Audio file picker**

## Connections

- Writer → App navigation: opens app
- App navigation → Project home: shows home
- App navigation → Lyrics editor: opens project
- App navigation → Settings: opens settings
- App navigation → About: opens about
- Project home → Project operations: manages projects
- Lyrics editor → Project operations: loads project
- Lyrics editor → Beat playback: controls playback
- Lyrics editor → Waveform extraction: prepares waveform
- Lyrics editor → Audio file picker: selects beat
- Lyrics notepad → Lyrics editor: edits lyrics
- Project details → Lyrics editor: edits details
- Marker dialogs → Lyrics editor: edits markers
- Beat controls → Beat playback: controls playback
- Beat controls → Waveform timeline: shows timeline
- Playback controls → Beat playback: controls playback
- Waveform timeline → Waveform viewport: updates viewport
- Project operations → Lyrics backups: loads and saves
- Project operations → Project metadata: reads and writes
- Project operations → Waveform cache: manages cache
- Lyrics backups → Local files: reads and writes
- Project metadata → Local files: reads and writes
- Settings → App settings: accesses settings
- App settings → Local files: persists settings
- Project operations → Local files: stores projects
- Waveform extraction → Android media APIs: decodes audio
- Beat playback → Android media APIs: plays audio
- Waveform extraction → Waveform cache: caches samples
