prints the contents of /dev/urandom to stdout. If you're a level 500 elite hacker like I am, you will note that the cryptographic quality of numbers from /dev/urandom is not the same as numbers from /dev/random. In our case, we don't want this operation to block, so we use /dev/urandom. See 'man 4 random'. (Updated March 6: In addition to the man page, see 1, 2)
Since the output of /dev/urandom is random binary bytes, we can use hexdump to format it into nice integers from 0-255:
The -v flag gets rid of the hexdump's default behaviour of replacing repeated lines with a '*' character. The -e flag uses '/1 "%u\n"' to print out the binary byte as an a formatted decimal number.
These integers in the range of 0-255 are then passed into awk, one line at a time:
The ... part is the following small program:
for (i = 0; i < 1; i+= 0.0001) printf("%08X\n", 100*sin(1382*exp((a[$1 % 8]/12)*log(2))*i))
creates an array 'a' which encodes the relative number of semitones from the base note in a major musical scale. This array is useful in the print statement because the frequency in Hertz of a musical note with equal temperament can be calculated using the following formula: 440 * 2^(semitone distance / 12). 440Hz has arbitrarily been chosen as the reference note, and it represents the frequency of A4.
The for loop then prints formatted 4 byte hexadecimal numbers that represent the amplitude of the sound wave at a given point in time:
100 A scalar multiple used to control the volume.
1382 =~ 440 * 3.14159
exp( Awk doesn't seem to support arbitrary powers, so we use 2^x = e^(x*ln(2))
a[$1 % 8] Pick a semitone at random on the major scale
12 Divide by 12 per the formula
i The counter in the for loop that counts from 0 to 1
The amount of time that each note is played for can be controlled by changing how fast the for loop counts up to 1. This number will also affect the perceived frequency.
The above formula makes a bit more sense if you think about it in the following way. If you did
for (i = 0; i < 1; i+= 0.0001) sin(i * 3.14159);
This will just calculate values on one cycle of a sine curve. If you then multiply 'i' by a frequency X of a musical note, each iteration of the for loop will calculate points on the X cycles of notes of the given frequency so the amplitude will change faster than the original 1 cycle per completion of the for loop.
The next part of the pipe uses xxd to convert the 8 byte hexadecimal values back into binary:
xxd -r -p
Which is then fed into aplay and turned into audible sound:
aplay -c 2 -f S32_LE -r 16000
If you want to make the music sound sad, you can change from the major scale to a minor scale: