SlopAY is a mostly vibe-coded AY player in C. It includes a Z80 emulator and support for loading AY files, rendering audio in real time on macOS, exporting to WAV or MIDI, and printing a piano roll of the notes being played. On other POSIX systems it runs headless unless writing WAV output.
Supported formats and platforms:
- ZX Spectrum 48K: beeper-only tracks
- ZX Spectrum 128K: AY chip tracks, and hybrid tracks combining AY with beeper
- Amstrad CPC: AY chip tracks (with configurable interrupt rates)
The player supports beeper mixing with configurable volume and mix mode.
MIDIAY is a companion tool that provides an interactive shell for controlling the AY chip via MIDI input on macOS.
Note: This is new code largely vibrated into existence to test my AY emulator, so it may be rough around the edges. The MIDIAY tool is macOS-only due to its use of CoreMIDI/CoreAudio.
The project builds two executables:
SlopAY(POSIX; real-time playback on macOS, headless elsewhere, WAV/MIDI export available)MIDIAY(macOS only)
Shared shortcut conventions:
h: helpv: volumex: stereo moder: reverbe: echo
SlopAY [-V] [-v <percent>] [-b <percent>] [-m <mode>] [-x <mode>] [-P <machine>] [-I <50|300>] [-r <Hz>] [-p] [-s <song>] [-t <seconds>] [-w <file.wav>] [-M <file.mid>] [-B <channel>] <ay_file>
-v, --volume <percent>: master output volume for AY + beeper (0-100, default 100)-b, --beeper-volume <percent>,--beeper <percent>: relative beeper level before master scaling (0-100, default 50)-m, --beeper-mix <mode>,--mix <mode>: beeper mix mode (addorduck, defaultadd)-x, --stereo-mode <mode>: stereo mode (mono,abc, oracb, defaultabc)-P, --machine <machine>: timing profile (spectrumorcpc, defaultspectrum)-I, --cpc-rate <50|300>: CPC interrupt-rate override (used only with-P cpc, default50)-r, --sample-rate <Hz>: audio sample rate (8000-192000, default 44100)-p, --piano-roll: print per-frame AY/Beeper notes-s, --song <song>: 0-based song index from the AY file; if omitted, SlopAY plays songs sequentially starting from the file's first-song index-t, --time <seconds>: max playback time (0uses song length)-w, --wav <file.wav>: write WAV instead of speaker output (requires finite duration from song length or-t); in sequential mode this writes per-song files as<name>-sN.ext-M, --midi <file.mid>: export AY + beeper notes to MIDI (requires finite duration from song length or-t); in sequential mode this writes per-song files as<name>-sN.ext-B, --midi-beeper-channel <0-15>: MIDI channel used for beeper notes in--midiexport (default3)-V, --version: show program version-h, --help: show command help
Beeper effective level is (-v / 100) * (-b / 100). For example, -v 80 -b 50 yields an effective beeper level of 40%.
Both AY unipolar output and beeper output are DC-blocked in the render path to reduce DC bias in playback/export.
Examples:
Intended use: Play the full AY file in default sequential mode (first song, then the next).
SlopAY ProjectAY/Spectrum/Demos/example.ay
Intended use: Export every song in sequence to WAV files without overwriting previous songs.
SlopAY -t 60 -w out.wav ProjectAY/Spectrum/Games/example.ay
Expected output files:
out-s0.wav
out-s1.wav
...
Intended use: Export one selected song to a single WAV file.
SlopAY -s 1 -t 60 -w out.wav ProjectAY/Spectrum/Games/example.ay
Intended use: Export every song in sequence to per-song MIDI files.
SlopAY -t 90 -M out.mid ProjectAY/Spectrum/Demos/example.ay
Expected output files:
out-s0.mid
out-s1.mid
...
Intended use: Export one selected song to MIDI with a custom beeper channel.
SlopAY -s 0 -t 90 -M out.mid -B 10 ProjectAY/Spectrum/Demos/example.ay
Intended use: Inspect note activity frame-by-frame with the piano roll.
SlopAY -p -s 0 -t 5 ProjectAY/Spectrum/Demos/example.ay
Example piano roll output:
[PR 000123] A=C5 B=E4 C=--- BEEP=---
[PR 000124] A=C5 B=E4 C=G3 BEEP=A4
[PR 000125] A=NOISE B=--- C=--- BEEP=---
Intended use: Compare stereo layouts and platform timing profiles.
SlopAY -x acb -t 30 -w out-acb.wav ProjectAY/Spectrum/Games/example.ay
SlopAY -P cpc -t 30 -w out-cpc.wav ProjectAY/CPC/Games/example.ay
SlopAY -P cpc -I 50 -t 30 -w out-cpc-50hz.wav ProjectAY/CPC/Games/example.ay
SlopAY -r 48000 -t 60 -w out-48khz.wav ProjectAY/Spectrum/Games/example.ay
MIDIAY
MIDIAY starts an interactive shell with CoreMIDI/CoreAudio input and AY control commands.
MIDIAY remains macOS-only. On other POSIX systems, SlopAY can still be used for headless piano-roll inspection and
WAV/MIDI export.
<reg> <value>: write AY register directly (reg0–15, value0–255)p,play: enter play mode (see below)h,help: print the command help tablec,chord: toggle chord mode (shared with play mode and MIDI input)m,chord-type: cycle chord type (maj→min→sus4→sus2→dim→aug→5)s,envelope-shape: cycle envelope shapeo,envelope-period: cycle envelope periodv <0-100>,volume <0-100>: set master volume percentg <0-127>,channel-volume <0-127>: set channel volume (MIDI scale)u <A|B|C|0|1|2> <0|1>,envelope <A|B|C|0|1|2> <0|1>: disable/enable envelope control for one AY channelr,reverb: cycle reverb delayr 0,reverb 0: disable reverbe,echo: cycle echo delaye 0,echo 0: disable echox,stereo-mode,stereo: cycle stereo mode (mono→abc→acb).,stop: stop all notesq,quit: quit
Play mode accepts single-keypress note input without requiring Enter.
Key layout (one octave, matches a physical keyboard row):
W E T Y U
A S D F G H J
C D E F G A B
Controls:
A S D F G H J: play C D E F G A BW E T Y U: play the adjacent sharps (C♯ D♯ F♯ G♯ A♯)Z/X: octave down / upC: toggle three-note chord mode on/offM: cycle chord type (maj/min/sus4/sus2/dim/aug/5)V: toggle arpeggiator on/offK/L: slower / faster arpeggiator step speed[/]: shorten / lengthen note hold time (50 ms steps, range 50–2000 ms, default 200 ms)Space: stop all current notes immediatelyQ: return to command mode
Chord mode/type are global and shared across command mode, play mode, and MIDI input. Arpeggiator mode/speed are also shared with MIDI input.
https://worldofspectrum.org/projectay/gdmusic.htm
The source code in this repository is licensed under the MIT License. See LICENSE for the full text.