Skip to content

Repository files navigation

OnionPlayer

A native OPENSTEP 4.2 / NeXTSTEP (i386) GUI MP3 player, written from scratch. It decodes MP3 with libmpg123 linked in-process — not by driving an external mpg123 binary — and plays through the NeXT sound system with a code-only AppKit interface.

Verified on real hardware: an i386 OPENSTEP 4.2 machine with an Ensoniq ES1371 (Creative AudioPCI) sound card driven by the SoundBlaster16PCI DriverKit driver. Every supported sample rate, bit depth, and channel count plays at correct pitch, both at the source rate and at a user-forced output format.

Platform status. OnionPlayer currently runs on OPENSTEP 4.2 for Intel (i386) only — that is the sole configuration it has been built and tested on. The other NeXT architectures (m68k, SPARC, HP PA-RISC) are a future goal, not a supported target yet: the code is portable C / Objective-C, but it has not been compiled or run there, and the prebuilt bundle in dist/ is an i386 Mach-O binary.

Screenshot

OnionPlayer running on OPENSTEP 4.2

The main window with the green LED dot-matrix readout (a scrolling track title over the elapsed/total time), the Output Format panel, and the separate playlist window.

Features

  • In-process libmpg123 decode. The decoder sits behind an AudioDecoder protocol, so FLAC/Ogg back-ends can be added later without touching the engine or UI.
  • Formats: 22.05 / 44.1 / 48 kHz (and the other MPEG rates), 8- and 16-bit, mono and stereo.
  • Output format: automatic or forced. By default the output matches the source; you can also force a rate / bit depth / channel count from the Output Format panel. The ES1371's hardware sample-rate converter plays the forced format natively — useful for lower-powered targets (e.g. m68k) where decoding to a smaller format saves CPU.
  • LED dot-matrix display. A hand-drawn 5×7 dot-matrix panel (no bitmap font) shows two lines: the track title (from the ID3 tag — artist/title — or the filename), which ping-pong scrolls when it is wider than the panel, over the time. Click the panel to toggle the time between elapsed / total and elapsed / remaining. A smaller LED strip shows the live kbps / kHz / channels.
  • VU meter in its own window: stereo vertical LED bars (green → yellow → red) with peak-hold markers, kept in sync with the audio.
  • Transport: play / pause / stop / seek, plus system-volume control.
  • Playlist in a separate window, with previous / next, shuffle and repeat, and automatic advance at end of track.
  • Drag and drop: drop one or more .mp3 files to reset the default playlist and start playing; drop a .m3u or .pls to load it.
  • Playlist files: File ▸ Load / Save / Save As read and write .m3u playlists.
  • Menus: File (playlist load/save), Play (transport), and Window (raise the Main Player, Playlist, VU Meter, or Output Format window).
  • Session persistence: on quit the app remembers the current playlist and which windows were open (and where), and restores them on the next launch. Missing files are dropped from the restored playlist.
  • Real .app bundle that launches from the Workspace and shows its icon (both in the browser and the process dock).

Requirements

  • OPENSTEP 4.2 (i386) / NeXTSTEP.
  • A DriverKit audio driver. Tested with SoundBlaster16PCI (ES1371); any driver that advertises the standard sample rates works, because the player hands the device the audio format directly and lets the hardware's sample-rate converter do the rest.

Install

Installer package (GUI). Unpack dist/OnionPlayer.pkg.tar on the machine and double-click OnionPlayer.pkg — Installer.app opens and installs OnionPlayer.app into /LocalApps:

gnutar xf .../openstep-mp3player/dist/OnionPlayer.pkg.tar
open OnionPlayer.pkg

Plain bundle. Or unpack the .app straight into an apps directory:

cd /LocalApps
gnutar xzf .../openstep-mp3player/dist/OnionPlayer.app.tar.gz

Then double-click OnionPlayer.app in the Workspace, or open /LocalApps/OnionPlayer.app.

Build from source

The build has two steps: build the ported libmpg123 static library, then compile the app against it.

# 1. Build libmpg123 for OPENSTEP cc 2.7.2.1 (produces libmpg123.a)
build/build-libmpg123.sh

# 2. Compile and link the app (run in the persistent build dir):
cc -O -I. -Iinclude -o OnionPlayer \
   src/PlaybackEngine.m src/Mpg123Decoder.m \
   app/OnionApp.m app/DotMatrixView.m app/VUMeterView.m \
   libmpg123.a -lm -framework AppKit -framework Foundation -framework SoundKit \
   -sectcreate __ICON __header app/OnionPlayer.iconheader \
   -sectcreate __ICON app app/OnionPlayer.app/Resources/OnionPlayer.tiff

The two -sectcreate sections are what let the Workspace launch the bundle and render its icon: a tab-separated icon-header binding table in __ICON __header, and the icon TIFF (72 DPI) in __ICON app.

libmpg123 is compiled with OPT_GENERIC and REAL_IS_FLOAT; one file, lfs_wrap.c, must be built at -O0 to dodge a code-generation bug in cc 2.7.2.1 when it joins two long long comparisons with &&/||.

See NOTES.ko.md for the full development log and every trap found along the way, and PLAN.md for the phased plan.

Packaging (.pkg)

To build the OPENSTEP Installer package on the machine, given a built OnionPlayer.app:

sh pkg/build-pkg.sh /LocalApps/OnionPlayer.app dist

It stages the app, runs /NextAdmin/Installer.app/package against pkg/OnionPlayer.info (title, version, /LocalApps default location), and writes OnionPlayer.pkg plus an uncompressed OnionPlayer.pkg.tar for transport.

How it works

  • src/AudioDecoder.h — the decoder protocol (open, format, read, seek, length).
  • src/Mpg123Decoder — the libmpg123 implementation. Output is signed native-endian PCM; the engine byte-swaps 16-bit to big-endian for the NeXT sound system.
  • src/PlaybackEngine — a bounded, streaming engine. A background cthread decodes 0.25 s chunks into a fixed pool of SNDSoundStruct buffers, keeps a few enqueued (SNDStartPlaying, preempt = 0), and paces itself with SNDWait on the oldest outstanding tag. Handles seek / pause / resume / stop and reports the play position.
  • app/OnionApp.m — the code-only AppKit UI (no .nib): menus, the main transport window, playlist window, output-format panel, drag-and-drop, and the session save/restore.
  • app/DotMatrixView — the 5×7 LED dot-matrix view: multi-line text, ping-pong title scroll, and click-to-toggle, drawn with NSRectFill.
  • app/VUMeterView — the stereo vertical LED VU bars. It polls the engine's per-chunk peak level (keyed to the currently-playing chunk, so it stays in sync despite the decode lookahead) on its own ~20 Hz timer, with peak-hold and decay.

License

GPL v2 or later. libmpg123 is LGPL 2.1 (compatible); the port lives under port/, patches/, and build/. The ES1371 sample-rate-converter reference sources consulted during development are BSD/GPL and listed in NOTES.ko.md.

About

Native OPENSTEP 4.2 (i386) GUI MP3 player — libmpg123 linked in-process, code-only AppKit UI. GPL-2.0.

Resources

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages