Skip to content

Drive sounds re-synthesized from measurements of real Amiga mechanisms#258

Merged
LinuxJedi merged 2 commits into
mainfrom
feature/drive-sound-realism
Jul 23, 2026
Merged

Drive sounds re-synthesized from measurements of real Amiga mechanisms#258
LinuxJedi merged 2 commits into
mainfrom
feature/drive-sound-realism

Conversation

@LinuxJedi

Copy link
Copy Markdown
Owner

The spin noise was already liked; the seek and read noises were not. Rather than copying what other emulators do (sampled sound packs), the synthesis targets were measured from freely licensed recordings of real Amiga drive mechanisms - an A600 Chinon FZ-354 (freesound 628247, CC0, plus 259292 and 39699) and an A500 loading recording - and the voices were rebuilt around the measured numbers. No sample data ships; everything remains cheap deterministic synthesis.

What changed

  • Step clack: low ~300 Hz carriage thump + dominant 1.0-1.2 kHz carriage-resonance ring (real clicks hold ~70% of their energy in the 1-2 kHz octave, 1/e ~3.5 ms) + a weak 1.45x partial carrying the 15-25 ms tail + a 1 ms 2-5 kHz contact tick. Every isolated step (empty-drive poll, track-to-track advance while loading) is followed by two quieter rebound transients ~5/~10 ms behind the impact - real recordings show every lone step as such a cluster.
  • Seek buzz: fast stepping ducks the thump and suppresses the rebounds (the carriage never settles between steps), so the overlapped rings form the measured harmonic comb of the guest's step rate with its envelope at the 1.0-1.4 kHz carriage resonance. Measured seek spectra hold <3% of their energy below 500 Hz.
  • Spin: the hum is now a slightly-inharmonic harmonic stack on ~145 Hz (2nd and 4th partials strongest, matching the measured 145/290/435/577/867 series), and the rumble is a noise pattern hashed from (per-drive seed, revolution index) so it loops exactly once per 200 ms platter revolution - real spin recordings autocorrelate at the revolution lag because the media drags a fixed contact pattern around with it. Two cascaded lowpass poles keep the bed dark.
  • Read: the read-gated hiss layer is removed outright, along with its bus plumbing (set_read_active, the DMA-state feed). On listening review, loading is the step rhythm over the spinning motor, exactly like the reference recordings.

Levels were tuned over three rounds of expert listening feedback (headless --audio-wav A/B renders of a KS1.3 + WB1.3 boot).

Verification

  • New regression tests pin the click's spectral center (Goertzel probes), the rebound clatter, seek-mode suppression, the revolution-locked spin texture (consecutive revolutions must correlate >0.5), the dark motor bed, and the existing idle-exact-silence/volume/headroom contracts.
  • Rendered output cross-checked against the recordings: synthesized seek peaks at 1.16 kHz with 47% of energy in the 1-2 kHz octave (real A600: ~1.3 kHz, 50%); the spin bed reproduces the measured 145/290/436/579 Hz series.
  • DriveSounds is serialized inside Paula, so STATE_VERSION moves 37 -> 38.
  • Full suite green; clippy and fmt clean.

The seek and read noises never sounded like an Amiga; the synthesis
targets are now taken from spectral analysis of freely licensed
recordings of real drive mechanisms (A600 Chinon FZ-354, A500 internal;
no sample data is included, everything stays synthesized):

- A head step is a clack, not a tick: low carriage thump, dominant
  1.0-1.2 kHz carriage ring (70% of a real click's energy sits in the
  1-2 kHz octave), a weak higher partial carrying the 15-25 ms tail,
  and a 1 ms contact tick. Isolated steps (the empty-drive poll, the
  track advance while loading) land with 2 rebound-clatter transients
  ~5/~10 ms behind the impact, the cluster every real recording shows.
- Fast seeks duck the thump and skip the rebounds (the carriage never
  settles), so the overlapped rings form the measured step-rate comb
  peaking at the carriage resonance.
- The spin bed is cyclic, not washy: the hum is a harmonic stack on
  ~145 Hz (2nd and 4th partials strongest, as measured) and the rumble
  is a noise pattern looped exactly once per platter revolution, since
  real spin recordings autocorrelate at the 200 ms revolution lag.
- Reading adds no noise of its own; on listening review the loading
  sound is the step rhythm over the motor, so the read-gated hiss is
  gone along with its bus plumbing.

Regression tests pin the click's spectral center, the rebound clatter,
seek-mode suppression, the revolution-locked spin texture, and that the
motor bed stays dark. DriveSounds' serialized shape changed, so
STATE_VERSION moves to 38.
Copilot AI review requested due to automatic review settings July 22, 2026 21:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Reworks Copperline’s synthesized floppy drive audio to better match measured characteristics of real Amiga mechanisms, while staying fully deterministic and sample-free. This includes reshaping step/seek sounds, making the motor bed revolution-locked, and removing the read/DMA hiss layer and its plumbing.

Changes:

  • Replaced the step “tick” model with a multi-component “clack” (thump/body/ring/tick) including scheduled rebound transients, and seek-mode suppression behavior.
  • Rebuilt motor synthesis as a measured harmonic stack plus revolution-locked rumble texture (with cascaded lowpass filtering).
  • Removed read/DMA hiss (API + bus feed) and bumped savestate format version; updated user docs/config comments accordingly.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/savestate.rs Bumps STATE_VERSION to reflect DriveSounds state/layout changes.
src/drive_sounds.rs Implements the new measured clack/seek and revolution-locked motor synthesis; removes read hiss and adds regression tests.
src/config.rs Updates AudioConfig docs to match the new drive-sound behavior (no read hiss).
src/bus.rs Removes DMA/read feed plumbing for drive sounds and simplifies feed_drive_sounds().
docs/guide/configuration.md Updates configuration guide text to describe the new synthesis model and removal of read noise.
copperline.example.toml Updates example config comments to match the new drive-sound behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/drive_sounds.rs
… Goertzel

The elapsed-samples counter behind the isolated-clack/seek-buzz
classification now advances even while drive sounds are disabled or
muted (Paula mixes every host sample either way), so the first step
after re-enabling classifies against real elapsed time instead of a
counter frozen at the pre-disable value. Regression test covers the
toggle. Also scopes the Goertzel test helper's s0 into the loop, which
--all-targets clippy rejected as a never-read assignment.
@LinuxJedi
LinuxJedi merged commit 147fc70 into main Jul 23, 2026
13 checks passed
@LinuxJedi
LinuxJedi deleted the feature/drive-sound-realism branch July 23, 2026 05:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants