# whipper-team/whipper architecture

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

- Interactive diagram: https://gitdiagram.com/whipper-team/whipper
- Repository: https://github.com/whipper-team/whipper

## Overview

Whipper is a command-line Linux CD-DA ripper focused on accurate extraction. The principal workflow is: a user invokes the rip command; Whipper reads disc layout and drive behavior, optionally resolves metadata, extracts and verifies tracks, encodes and names audio files, then records rip results. Separate commands expose drive, offset, image, metadata-lookup, and AccurateRip functions. The README documents additional capabilities such as batch ripping, HTOA, pre-emphasis reporting, and logger plugins. Some subsystem links reflect documented capabilities; sampled excerpts do not establish every internal call.

Main entry points: [`whipper/common/program.py`](https://github.com/whipper-team/whipper/blob/develop/whipper/common/program.py) (Rip coordinator), [`whipper/command/main.py`](https://github.com/whipper-team/whipper/blob/develop/whipper/command/main.py) (CLI dispatcher), [`whipper/common/accurip.py`](https://github.com/whipper-team/whipper/blob/develop/whipper/common/accurip.py) (Checksum logic), [`whipper/program/cdparanoia.py`](https://github.com/whipper-team/whipper/blob/develop/whipper/program/cdparanoia.py) (Audio extraction)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_cli["Command interface"]
  node_entry["CLI dispatcher<br/>[main.py]"]
  node_cdcmd["CD commands<br/>[cd.py]"]
  node_drivecmd["Drive commands<br/>[drive.py]"]
  node_offsetcmd["Offset command<br/>[offset.py]"]
  node_imagecmd["Image command<br/>[image.py]"]
  node_arcmd["AccurateRip command<br/>[accurip.py]"]
  node_mbcmd["Metadata lookup<br/>[mblookup.py]"]
end

subgraph group_disc["Disc analysis"]
  node_config["Configuration<br/>[config.py]"]
  node_drive["Drive handling<br/>[drive.py]"]
  node_toc["Disc table<br/>[table.py]"]
  node_image["Image formats<br/>[image.py]"]
  node_cdrdao["TOC extraction<br/>[cdrdao.py]"]
end

subgraph group_rip["Extraction and output"]
  node_program["Rip coordinator<br/>[program.py]"]
  node_tasks["Task runner<br/>[task.py]"]
  node_reader["Audio extraction<br/>[cdparanoia.py]"]
  node_encoding["Audio encoding<br/>[encode.py]"]
  node_naming["Path templates<br/>[renamer.py]"]
end

subgraph group_verify["Metadata and verification"]
  node_results["Rip results<br/>[result.py]"]
  node_logger["Rip logging<br/>[logger.py]"]
  node_accurip["Checksum logic<br/>[accurip.py]"]
  node_checksum["Checksum extension"]
  node_metadata["MusicBrainz metadata<br/>[mbngs.py]"]
end

node_user(("User"))
node_userdrive(("Optical drive"))
node_musicbrainz(("MusicBrainz service"))
node_arservice(("AccurateRip database"))
node_filesystem[("Audio files")]

node_user -->|"invokes"| node_entry
node_entry -->|"dispatches"| node_cdcmd
node_entry -->|"dispatches"| node_drivecmd
node_entry -->|"dispatches"| node_offsetcmd
node_entry -->|"dispatches"| node_imagecmd
node_entry -->|"dispatches"| node_arcmd
node_entry -->|"dispatches"| node_mbcmd
node_cdcmd -->|"coordinates rip"| node_program
node_program -->|"reads settings"| node_config
node_drivecmd -->|"manages drive"| node_drive
node_offsetcmd -->|"checks offset"| node_drive
node_program -->|"uses drive"| node_drive
node_program -->|"reads TOC"| node_cdrdao
node_cdrdao -->|"reads disc layout"| node_userdrive
node_program -->|"uses disc table"| node_toc
node_imagecmd -->|"handles image"| node_image
node_program -->|"looks up metadata"| node_metadata
node_mbcmd -->|"queries metadata"| node_metadata
node_metadata -->|"queries"| node_musicbrainz
node_program -->|"runs tasks"| node_tasks
node_program -->|"extracts tracks"| node_reader
node_reader -->|"reads audio"| node_userdrive
node_reader -->|"reports progress"| node_tasks
node_program -->|"encodes tracks"| node_encoding
node_program -->|"formats paths"| node_naming
node_encoding -->|"writes audio"| node_filesystem
node_program -->|"verifies tracks"| node_accurip
node_arcmd -->|"checks accuracy"| node_accurip
node_accurip -->|"computes checksum"| node_checksum
node_accurip -->|"compares checksums"| node_arservice
node_program -->|"records outcome"| node_results
node_results -->|"formats log"| node_logger

click node_entry "https://github.com/whipper-team/whipper/blob/develop/whipper/command/main.py"
click node_cdcmd "https://github.com/whipper-team/whipper/blob/develop/whipper/command/cd.py"
click node_drivecmd "https://github.com/whipper-team/whipper/blob/develop/whipper/command/drive.py"
click node_offsetcmd "https://github.com/whipper-team/whipper/blob/develop/whipper/command/offset.py"
click node_imagecmd "https://github.com/whipper-team/whipper/blob/develop/whipper/command/image.py"
click node_arcmd "https://github.com/whipper-team/whipper/blob/develop/whipper/command/accurip.py"
click node_mbcmd "https://github.com/whipper-team/whipper/blob/develop/whipper/command/mblookup.py"
click node_program "https://github.com/whipper-team/whipper/blob/develop/whipper/common/program.py"
click node_config "https://github.com/whipper-team/whipper/blob/develop/whipper/common/config.py"
click node_drive "https://github.com/whipper-team/whipper/blob/develop/whipper/common/drive.py"
click node_toc "https://github.com/whipper-team/whipper/blob/develop/whipper/image/table.py"
click node_image "https://github.com/whipper-team/whipper/blob/develop/whipper/image/image.py"
click node_cdrdao "https://github.com/whipper-team/whipper/blob/develop/whipper/program/cdrdao.py"
click node_tasks "https://github.com/whipper-team/whipper/blob/develop/whipper/extern/task/task.py"
click node_reader "https://github.com/whipper-team/whipper/blob/develop/whipper/program/cdparanoia.py"
click node_encoding "https://github.com/whipper-team/whipper/blob/develop/whipper/common/encode.py"
click node_naming "https://github.com/whipper-team/whipper/blob/develop/whipper/common/renamer.py"
click node_results "https://github.com/whipper-team/whipper/blob/develop/whipper/result/result.py"
click node_logger "https://github.com/whipper-team/whipper/blob/develop/whipper/result/logger.py"
click node_accurip "https://github.com/whipper-team/whipper/blob/develop/whipper/common/accurip.py"
click node_checksum "https://github.com/whipper-team/whipper/blob/develop/src/accuraterip-checksum.c"
click node_metadata "https://github.com/whipper-team/whipper/blob/develop/whipper/common/mbngs.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,node_cdcmd,node_drivecmd,node_offsetcmd,node_imagecmd,node_arcmd,node_mbcmd,node_user toneBlue
class node_config,node_drive,node_toc,node_image,node_cdrdao,node_arservice,node_filesystem toneAmber
class node_program,node_tasks,node_reader,node_encoding,node_naming toneMint
class node_results,node_logger,node_accurip,node_checksum,node_metadata toneRose
class node_userdrive,node_musicbrainz toneIndigo
```

## Components

### Command interface

- [CLI dispatcher](https://github.com/whipper-team/whipper/blob/develop/whipper/command/main.py): `whipper/command/main.py`
- [CD commands](https://github.com/whipper-team/whipper/blob/develop/whipper/command/cd.py): `whipper/command/cd.py`
- [Drive commands](https://github.com/whipper-team/whipper/blob/develop/whipper/command/drive.py): `whipper/command/drive.py`
- [Offset command](https://github.com/whipper-team/whipper/blob/develop/whipper/command/offset.py): `whipper/command/offset.py`
- [Image command](https://github.com/whipper-team/whipper/blob/develop/whipper/command/image.py): `whipper/command/image.py`
- [AccurateRip command](https://github.com/whipper-team/whipper/blob/develop/whipper/command/accurip.py): `whipper/command/accurip.py`
- [Metadata lookup](https://github.com/whipper-team/whipper/blob/develop/whipper/command/mblookup.py): `whipper/command/mblookup.py`

### Disc analysis

- [Configuration](https://github.com/whipper-team/whipper/blob/develop/whipper/common/config.py): `whipper/common/config.py`
- [Drive handling](https://github.com/whipper-team/whipper/blob/develop/whipper/common/drive.py): `whipper/common/drive.py`
- [Disc table](https://github.com/whipper-team/whipper/blob/develop/whipper/image/table.py): `whipper/image/table.py`
- [Image formats](https://github.com/whipper-team/whipper/blob/develop/whipper/image/image.py): `whipper/image/image.py`
- [TOC extraction](https://github.com/whipper-team/whipper/blob/develop/whipper/program/cdrdao.py): `whipper/program/cdrdao.py`

### Extraction and output

- [Rip coordinator](https://github.com/whipper-team/whipper/blob/develop/whipper/common/program.py): `whipper/common/program.py`
- [Task runner](https://github.com/whipper-team/whipper/blob/develop/whipper/extern/task/task.py): `whipper/extern/task/task.py`
- [Audio extraction](https://github.com/whipper-team/whipper/blob/develop/whipper/program/cdparanoia.py): `whipper/program/cdparanoia.py`
- [Audio encoding](https://github.com/whipper-team/whipper/blob/develop/whipper/common/encode.py): `whipper/common/encode.py`
- [Path templates](https://github.com/whipper-team/whipper/blob/develop/whipper/common/renamer.py): `whipper/common/renamer.py`

### Metadata and verification

- [Rip results](https://github.com/whipper-team/whipper/blob/develop/whipper/result/result.py): `whipper/result/result.py`
- [Rip logging](https://github.com/whipper-team/whipper/blob/develop/whipper/result/logger.py): `whipper/result/logger.py`
- [Checksum logic](https://github.com/whipper-team/whipper/blob/develop/whipper/common/accurip.py): `whipper/common/accurip.py`
- [Checksum extension](https://github.com/whipper-team/whipper/blob/develop/src/accuraterip-checksum.c): `src/accuraterip-checksum.c`
- [MusicBrainz metadata](https://github.com/whipper-team/whipper/blob/develop/whipper/common/mbngs.py): `whipper/common/mbngs.py`

### Other components

- **User**
- **Optical drive**
- **MusicBrainz service**
- **AccurateRip database**
- **Audio files**

## Connections

- User → CLI dispatcher: invokes
- CLI dispatcher → CD commands: dispatches
- CLI dispatcher → Drive commands: dispatches
- CLI dispatcher → Offset command: dispatches
- CLI dispatcher → Image command: dispatches
- CLI dispatcher → AccurateRip command: dispatches
- CLI dispatcher → Metadata lookup: dispatches
- CD commands → Rip coordinator: coordinates rip
- Rip coordinator → Configuration: reads settings
- Drive commands → Drive handling: manages drive
- Offset command → Drive handling: checks offset
- Rip coordinator → Drive handling: uses drive
- Rip coordinator → TOC extraction: reads TOC
- TOC extraction → Optical drive: reads disc layout
- Rip coordinator → Disc table: uses disc table
- Image command → Image formats: handles image
- Rip coordinator → MusicBrainz metadata: looks up metadata
- Metadata lookup → MusicBrainz metadata: queries metadata
- MusicBrainz metadata → MusicBrainz service: queries
- Rip coordinator → Task runner: runs tasks
- Rip coordinator → Audio extraction: extracts tracks
- Audio extraction → Optical drive: reads audio
- Audio extraction → Task runner: reports progress
- Rip coordinator → Audio encoding: encodes tracks
- Rip coordinator → Path templates: formats paths
- Audio encoding → Audio files: writes audio
- Rip coordinator → Checksum logic: verifies tracks
- AccurateRip command → Checksum logic: checks accuracy
- Checksum logic → Checksum extension: computes checksum
- Checksum logic → AccurateRip database: compares checksums
- Rip coordinator → Rip results: records outcome
- Rip results → Rip logging: formats log
