# papatistos/swhisper architecture

> Architecture diagram of the GitHub repository papatistos/swhisper, 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/papatistos/swhisper
- Repository: https://github.com/papatistos/swhisper

## Overview

swhisper is a Swedish speech transcription and speaker-diarization application. Its principal workflow takes audio through chunking and Whisper transcription, then aligns words with diarization, optionally backfills uncovered speaker turns, and writes transcript formats and statistics. A separate diarization-first mode is documented, alongside VAD, caching, analysis tools, and optional SenseVoice emotion/event recognition. The graph combines sampled call evidence with README-documented capabilities; unsampled subsystem links are omitted where their wiring could not be verified.

Main entry points: [`transcribe.py`](https://github.com/papatistos/swhisper/blob/main/transcribe.py) (Transcription runner), [`diarize/pipeline.py`](https://github.com/papatistos/swhisper/blob/main/diarize/pipeline.py) (Speaker detection), [`transcribe/transcription.py`](https://github.com/papatistos/swhisper/blob/main/transcribe/transcription.py) (Whisper transcription), [`diarize.py`](https://github.com/papatistos/swhisper/blob/main/diarize.py) (Diarization runner)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_transcription["Transcription"]
  node_transcribe_app["Transcription runner<br/>[transcribe.py]"]
  node_audio_processing["Audio processing<br/>[audio_utils.py]"]
  node_vad["Voice activity detection<br/>[ina_vad.py]"]
  node_transcription_engine["Whisper transcription<br/>[transcription.py]"]
  node_diarization_first["Diarization-first mode"]
end

subgraph group_diarization["Diarization"]
  node_diarize_runner["Diarization runner<br/>[diarize.py]"]
  node_diarization_pipeline["Speaker detection<br/>[pipeline.py]"]
  node_alignment["Word-speaker alignment<br/>[pipeline.py]"]
  node_speaker_processing["Speaker processing<br/>[utils.py]"]
  node_backfill["Empty-turn backfill<br/>[diarize.py]"]
  node_cache[("Diarization cache")]
end

subgraph group_outputs["Outputs and analysis"]
  node_output["Transcript formatting<br/>[output.py]"]
  node_stats["Speaker statistics<br/>[output.py]"]
  node_analysis["Results analysis<br/>[analysis.py]"]
  node_transcript_files["Transcript files"]
end

subgraph group_support["Configuration and integrations"]
  node_sensevoice["SenseVoice enrichment"]
  node_transcription_config["Transcription settings<br/>[config.py]"]
  node_diarization_config["Diarization settings<br/>[config.py]"]
  node_path_settings["Path settings<br/>[path_settings.py]"]
end

node_user(("Researcher"))
node_audio["Audio files"]

node_user -->|"provides audio"| node_audio
node_audio -->|"submits audio"| node_transcribe_app
node_transcribe_app -->|"runs transcription"| node_transcription_engine
node_transcription_engine -->|"uses audio tools"| node_audio_processing
node_transcribe_app -.->|"detects speech"| node_vad
node_transcribe_app -->|"starts diarization"| node_diarize_runner
node_diarize_runner -.->|"runs pipeline"| node_diarization_pipeline
node_diarization_pipeline -->|"aligns speakers"| node_alignment
node_alignment -->|"uses processors"| node_speaker_processing
node_alignment -->|"identifies empty turns"| node_backfill
node_backfill -->|"retranscribes turns"| node_transcription_engine
node_diarization_pipeline -.->|"caches results"| node_cache
node_backfill -.->|"enriches segments"| node_sensevoice
node_diarize_runner -.->|"formats transcripts"| node_output
node_output -->|"writes formats"| node_transcript_files
node_output -->|"computes statistics"| node_stats
node_user -.->|"compares results"| node_analysis
node_diarization_first -->|"transcribes segments"| node_transcription_engine
node_diarization_first -->|"runs diarization"| node_diarization_pipeline
node_transcription_config -->|"gets paths"| node_path_settings
node_diarization_config -->|"gets paths"| node_path_settings

click node_transcribe_app "https://github.com/papatistos/swhisper/blob/main/transcribe.py"
click node_audio_processing "https://github.com/papatistos/swhisper/blob/main/transcribe/audio_utils.py"
click node_vad "https://github.com/papatistos/swhisper/blob/main/transcribe/ina_vad.py"
click node_transcription_engine "https://github.com/papatistos/swhisper/blob/main/transcribe/transcription.py"
click node_diarization_first "https://github.com/papatistos/swhisper/blob/main/transcribe/diarization_first.py"
click node_diarize_runner "https://github.com/papatistos/swhisper/blob/main/diarize.py"
click node_diarization_pipeline "https://github.com/papatistos/swhisper/blob/main/diarize/pipeline.py"
click node_alignment "https://github.com/papatistos/swhisper/blob/main/diarize/pipeline.py"
click node_speaker_processing "https://github.com/papatistos/swhisper/blob/main/diarize/utils.py"
click node_backfill "https://github.com/papatistos/swhisper/blob/main/diarize.py"
click node_cache "https://github.com/papatistos/swhisper/blob/main/diarize/diarization_cache.py"
click node_sensevoice "https://github.com/papatistos/swhisper/blob/main/diarize/sensevoice_provider.py"
click node_output "https://github.com/papatistos/swhisper/blob/main/diarize/output.py"
click node_stats "https://github.com/papatistos/swhisper/blob/main/diarize/output.py"
click node_analysis "https://github.com/papatistos/swhisper/blob/main/diarize/analysis.py"
click node_transcription_config "https://github.com/papatistos/swhisper/blob/main/transcribe/config.py"
click node_diarization_config "https://github.com/papatistos/swhisper/blob/main/diarize/config.py"
click node_path_settings "https://github.com/papatistos/swhisper/blob/main/path_settings.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_transcribe_app,node_audio_processing,node_vad,node_transcription_engine,node_diarization_first toneBlue
class node_diarize_runner,node_diarization_pipeline,node_alignment,node_speaker_processing,node_backfill,node_cache toneAmber
class node_output,node_stats,node_analysis,node_transcript_files toneMint
class node_sensevoice,node_transcription_config,node_diarization_config,node_path_settings toneRose
class node_user,node_audio toneIndigo
```

## Components

### Transcription

- [Transcription runner](https://github.com/papatistos/swhisper/blob/main/transcribe.py): `transcribe.py`
- [Audio processing](https://github.com/papatistos/swhisper/blob/main/transcribe/audio_utils.py): `transcribe/audio_utils.py`
- [Voice activity detection](https://github.com/papatistos/swhisper/blob/main/transcribe/ina_vad.py): `transcribe/ina_vad.py`
- [Whisper transcription](https://github.com/papatistos/swhisper/blob/main/transcribe/transcription.py): `transcribe/transcription.py`
- [Diarization-first mode](https://github.com/papatistos/swhisper/blob/main/transcribe/diarization_first.py): `transcribe/diarization_first.py`

### Diarization

- [Diarization runner](https://github.com/papatistos/swhisper/blob/main/diarize.py): `diarize.py`
- [Speaker detection](https://github.com/papatistos/swhisper/blob/main/diarize/pipeline.py): `diarize/pipeline.py`
- [Word-speaker alignment](https://github.com/papatistos/swhisper/blob/main/diarize/pipeline.py): `diarize/pipeline.py`
- [Speaker processing](https://github.com/papatistos/swhisper/blob/main/diarize/utils.py): `diarize/utils.py`
- [Empty-turn backfill](https://github.com/papatistos/swhisper/blob/main/diarize.py): `diarize.py`
- [Diarization cache](https://github.com/papatistos/swhisper/blob/main/diarize/diarization_cache.py): `diarize/diarization_cache.py`

### Outputs and analysis

- [Transcript formatting](https://github.com/papatistos/swhisper/blob/main/diarize/output.py): `diarize/output.py`
- [Speaker statistics](https://github.com/papatistos/swhisper/blob/main/diarize/output.py): `diarize/output.py`
- [Results analysis](https://github.com/papatistos/swhisper/blob/main/diarize/analysis.py): `diarize/analysis.py`
- **Transcript files**

### Configuration and integrations

- [SenseVoice enrichment](https://github.com/papatistos/swhisper/blob/main/diarize/sensevoice_provider.py): `diarize/sensevoice_provider.py`
- [Transcription settings](https://github.com/papatistos/swhisper/blob/main/transcribe/config.py): `transcribe/config.py`
- [Diarization settings](https://github.com/papatistos/swhisper/blob/main/diarize/config.py): `diarize/config.py`
- [Path settings](https://github.com/papatistos/swhisper/blob/main/path_settings.py): `path_settings.py`

### Other components

- **Researcher**
- **Audio files**

## Connections

- Researcher → Audio files: provides audio (evidence: `README.md`)
- Audio files → Transcription runner: submits audio (evidence: `README.md`)
- Transcription runner → Whisper transcription: runs transcription (evidence: `transcribe.py`)
- Whisper transcription → Audio processing: uses audio tools (evidence: `transcribe/transcription.py`)
- Transcription runner → Voice activity detection: detects speech
- Transcription runner → Diarization runner: starts diarization (evidence: `transcribe.py`)
- Diarization runner → Speaker detection: runs pipeline
- Speaker detection → Word-speaker alignment: aligns speakers (evidence: `diarize/pipeline.py`)
- Word-speaker alignment → Speaker processing: uses processors (evidence: `diarize/pipeline.py`)
- Word-speaker alignment → Empty-turn backfill: identifies empty turns (evidence: `diarize.py`)
- Empty-turn backfill → Whisper transcription: retranscribes turns (evidence: `README.md`)
- Speaker detection → Diarization cache: caches results
- Empty-turn backfill → SenseVoice enrichment: enriches segments (evidence: `README.md`)
- Diarization runner → Transcript formatting: formats transcripts (evidence: `README.md`)
- Transcript formatting → Transcript files: writes formats (evidence: `README.md`)
- Transcript formatting → Speaker statistics: computes statistics (evidence: `diarize/output.py`)
- Researcher → Results analysis: compares results (evidence: `README.md`)
- Diarization-first mode → Whisper transcription: transcribes segments (evidence: `transcribe/diarization_first.py`)
- Diarization-first mode → Speaker detection: runs diarization (evidence: `transcribe/diarization_first.py`)
- Transcription settings → Path settings: gets paths (evidence: `transcribe/config.py`)
- Diarization settings → Path settings: gets paths (evidence: `diarize/config.py`)
