linuxwave turns random bytes into a synthwave track
Generate music from the entropy of Linux 🐧🎵
At a glance
- What is it?
- linuxwave is a small Zig program that reads bytes from /dev/urandom, a file or standard input and turns them into a waveform written as a WAV file. The scale, note frequency, sample rate, channel count and format are all command line flags, so the same entropy produces a chiptune, a calm ambient bed or a boss theme depending on the preset you pick.
- Who is it for?
- Adopt linuxwave when you want a deterministic, dependency free way to turn arbitrary bytes into a playable waveform, for example to generate test audio, placeholder music or ambient sound for a demo, and you are comfortable with a command line tool in Zig. Skip it if you need musically meaningful output, since the mapping from entropy to sound is random by design and no structure, harmony or repetition is produced.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Zig, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Entropy in, waveform out
linuxwave is described in one line: generate music from the entropy of Linux. The mechanism is simple to describe. The program reads random data, maps it onto a musical scale, and writes the result out as a waveform.
The default run reads random data from /dev/urandom to generate a 20-second music composition in the A4 scale and saves it to output.wav. That is the whole program with no arguments, and it produces an actual audio file rather than a MIDI stream, which means anything that plays WAV files can consume it.
The project traces its inspiration to a bash one liner that composed music from /dev/urandom, and to the Hacker News discussion that followed. The difference linuxwave makes is that it is a real program rather than a shell pipeline, and it is written in Zig, so it also serves as a usable Zig package.
For a developer the interesting angle is that the input is not special. Any file can be the source of the randomness, which turns the tool into a general way of mapping arbitrary data onto audio, and the readme points at a community discussion where people have posted the music they generated this way.
Building requires Zig 0.17 and produces one binary
The build instructions are two steps. You clone the repository and build it:
git clone https://github.com/orhun/linuxwave && cd linuxwave/zig build --release=safeThe prerequisite is Zig 0.17, pinned to that version in the instructions. The resulting binary sits at zig-out/bin/linuxwave, and the readme notes that you can also run it directly with zig build run, which is convenient while iterating.
The release safe mode is a deliberate choice for a tool that reads system files. It keeps runtime safety checks on in the optimised build, which costs some speed and buys protection against out of bounds access while parsing input.
There is a second way to consume the project. The readme states that if you want to use linuxwave in your Zig project as a package, the API documentation is published alongside the project, so the same waveform generation is available as a library call rather than only as a command. That makes the tool usable inside a larger Zig program that already has a stream of bytes to turn into sound.
The options decide what the noise sounds like
The command line interface is where the character comes from. The options list starts like this:
Options:
-s, --scale <SCALE> Sets the musical scale [default: 0,2,3,5,7,8,10,12]
-n, --note <HZ> Sets the frequency of the note [default: 440 (A4)]
-r, --rate <HZ> Sets the sample rate [default: 24000]
-c, --channels <NUM> Sets the number of channels [default: 1]
-f, --format <FORMAT> SThe scale is given as semitone offsets, with the default being the major scale across an octave and a bit, and the note flag sets the base frequency, 440 Hz being A4. Everything else follows from those two: the sample rate, the number of channels and the sample format.
The examples show how far the same input can be pushed. A blues scale at 220 Hz gives a different colour from the default, and the note frequency acts as a master pitch, so setting it to 261.63 Hz moves the whole piece to C.
The format flag is worth understanding. The preset examples use values such as S32_LE and U8, so the output is a raw PCM file with a chosen bit depth and endianness rather than a container. That gives control, and it also means a consumer expecting a conventional 16 bit PCM stereo file has to be told which format it is getting.
Files, stdin and stdout all work as endpoints
The input side is not restricted to random data. Any file can be read, and the readme gives a concrete example that turns the build file of the project itself into ten seconds of music in C major:
linuxwave -i build.zig -n 261.63 -d 10 -o music.wavStandard input works as well, by passing a dash as the input, so the tool can sit in a pipeline:
cat README.md | linuxwave -i -And output can be directed to standard output with a dash too:
linuxwave -o - > output.wavThe most useful combination is piping straight into a player, which the readme demonstrates with mpv:
linuxwave -o - | mpv -That means you can hear the result without writing a file, which is the fastest loop for trying out different scales. It also means the tool composes well with other command line programs, since both ends of the pipeline are ordinary file descriptors.
Presets show the range from chiptune to ambient
The preset examples in the readme are effectively a set of recipes, and they double as documentation for the flags. A calming track uses a low sample rate and a 32-bit little-endian signed integer format:
linuxwave -r 2000 -f S32_LE -o calm.wavA chiptune uses the familiar 44100 Hz sample rate, stereo output and an 8-bit unsigned integer format:
linuxwave -r 44100 -f U8 -c 2 -o chiptune.wavA boss stage theme shrinks the scale to a few notes and lowers the note frequency to 60 Hz while raising the volume:
linuxwave -s 0,7,1 -n 60 -v 65 -o boss.wavAnd a spooky low fidelity variant drops the sample rate to 1000 Hz and opens it up to four channels:
linuxwave -s 0,1,5,3 -n 100 -r 1000 -v 55 -c 4 -o spooky_manor.wavThe pattern behind them is clear. Small scale, low note and high volume give a bass heavy, sparse result, while a wide scale at a low sample rate gives a washed out, atmospheric texture. Contributors are invited to submit their own presets as pull requests, and the project also links a discussion thread where the community has posted the tracks they generated.
Packaging for Arch, Void, Docker and signed release tarballs
linuxwave is distributed in several ways, which says something about how the author expects it to be used.
Arch Linux carries it in the community repository, installed with:
pacman -S linuxwaveVoid Linux has it in the official package repository, installed with:
xbps-install linuxwavePre-compiled binaries for different targets are on the releases page, and the readme states they are produced by a Continuous Deployment workflow. Release tarballs are signed with a specific PGP key, which is worth noting because it lets a user verify what they downloaded rather than trusting the download channel alone.
Docker images are built automatically and published to two registries, Docker Hub and the GitHub Container Registry. The usage command writes output.wav into the current working directory:
docker run --rm -v "$(pwd)":/app "orhunp/linuxwave:${TAG:-latest}"The volume mount is what makes that work, since the container writes the file and the host sees it. Custom images can be built from the Dockerfile in the repository with:
docker build -t linuxwave .The Docker image compiles in one builder stage and runs as a non root user
The Dockerfile in the repository is short and shows the project's priorities. The builder stage uses the Zig 0.17.0 image, installs git, copies the source and runs the release build:
FROM eloitor/zig:0.17.0 AS builder
RUN apk update
RUN apk add --no-cache git
WORKDIR /app
COPY . .
RUN zig build --release=safe
FROM alpine:3.8
WORKDIR /app
COPY --from=builder /app/zig-out/bin/linuxwave /usr/local/bin
RUN touch output.wav && \
chown 1000:1000 output.wav
USER 1000:1000
ENTRYPOINT [ "linuxwave" ]The final stage keeps only the compiled binary on a small Alpine base, and the entrypoint is the program itself, which is why the docker run command in the readme takes no command of its own.
Two details are notable. The image creates an output.wav file and gives it to user 1000 so the non-root user can write to it inside the mounted volume, which is what stops the container from failing with a permission error when it saves the result. And the final base is alpine:3.8, which is a long retired Alpine release, so anyone building images from this Dockerfile for a current environment should update that base themselves.
Outside the container the project also carries the usual packaging artefacts for a command line tool: a man/ directory, a release.sh script, a Dockerfile, build.zig and build.zig.zon, a CHANGELOG.md, a SECURITY.md and a code of conduct.
Editorial conclusion
Adopt linuxwave when you want a deterministic, dependency free way to turn arbitrary bytes into a playable waveform, for example to generate test audio, placeholder music or ambient sound for a demo, and you are comfortable with a command line tool in Zig. Skip it if you need musically meaningful output, since the mapping from entropy to sound is random by design and no structure, harmony or repetition is produced. Before you use it, build it with zig build --release=safe, check the default scale and note values in the options list, and confirm that the -f format flag matches what your player expects, since the default is not the usual 16 bit PCM a stereo player assumes.
Frequently asked questions
What does linuxwave do?
It reads random data, by default from /dev/urandom, and turns it into a waveform written as a WAV file. The default run produces a 20-second composition in the A4 scale saved to output.wav.
How do I build linuxwave from source?
You need Zig 0.17. Clone the repository and run zig build --release=safe. The binary is then at zig-out/bin/linuxwave, and zig build run executes it directly.
Can linuxwave read from a file or standard input?
Yes. The -i flag selects the input, so you can point it at a file such as build.zig or pass a dash to read from standard input, for example cat README.md | linuxwave -i -. Output can be sent to standard output the same way with -o -.
Which flags control the sound of linuxwave?
The scale is set with -s, the base note frequency with -n, the sample rate with -r, the channel count with -c and the sample format with -f, plus volume with -v and duration with -d. The defaults are the scale 0,2,3,5,7,8,10,12, note 440 Hz for A4, sample rate 24000 and one channel.
How is linuxwave packaged and distributed?
It is in the Arch Linux community repository and the official Void Linux repository, pre-compiled binaries are published on the releases page with PGP signed tarballs, and Docker images are built automatically for Docker Hub and the GitHub Container Registry. The licence is MIT and the latest release is v0.4.0.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/orhun-linuxwave)Was this useful?