# audio-cassette-simulation

A set of bash scripts that push audio through ffmpeg filter chains to make it sound like it came off a cassette. The processing is the same four things in every profile — tape hiss, wow and flutter as pitch modulation, a bandwidth limit, and equalizer adjustment — with the parameters changed per tape. Prerequisites are bash and an ffmpeg built with libmp3lame.

## Profiles are directories

The repository is organized as one folder per tape, each holding its own pair of scripts, which is the project's whole architecture. There is no profile flag and no shared script; you go into the folder for the tape you want and run what is there.

The six tapes and how the README characterizes them:

- `BASF LH Extra C90` — German ferric tape, moderate hiss and mild flutter
- `Maxell UD C90` — higher-grade ferric, lower hiss and a wider frequency range
- `Sony CHF60 Type I Normal (1978)` — vintage 60-minute normal tape, warm mid-range
- `Sony CHF90 (1978)` — the 90-minute version, with slightly higher tape speed drift
- `TDK D90 (1995-1997)` — late-era Type I, clean with subtle analog character
- `mk60` — Soviet MK-60, high hiss, heavy wow and flutter, aggressive frequency cut

The two Sonys are the interesting pair: same year, same formulation, and the longer tape is thinner, so it wanders more. The MK-60 sits at the other end from the TDK, which is roughly the real spread between a late-90s Japanese Type I and Soviet consumer tape.

## Usage

```
# Convert local audio files (mp3, ogg, m4a, aac)
./convert_cassette_*.sh

# Record a live web stream into segment files
./record_stream_cassette_*.sh [STREAM_URL]
```

Output lands in `./out`. The stream recorder is the less obvious half: it captures a live web stream and cuts it into segment files with the tape profile already applied, which is closer to what taping the radio actually produced than converting a clean file is.

## Limits

The README is the entire documentation. It does not give the filter chain, the noise floor, the modulation depth, or the cutoff frequencies for any profile, so the actual parameter values are only readable in the scripts, and there is no stated way to tune them short of editing. Adding a seventh tape means copying a directory. Nothing here is measured against a real deck or a real tape — the profiles are descriptions turned into filter settings, not captured impulse responses or noise samples, so treat the tape names as flavors rather than emulations. Requiring libmp3lame implies MP3 output, which puts lossy encoding after the analog simulation.

This one is on [[toolbox/watchlist]]: single-author repo, no releases, and the design question of whether the per-directory duplication ever collapses into one script taking a profile argument is unresolved.

Repo: [AARomanov1985/Audio-Cassette-Simulation](https://github.com/AARomanov1985/Audio-Cassette-Simulation), MIT. Star count not recorded at ingest.
