# Play the sound of Pi

Yup, you read the title right. play the sound of pi.

More specifically, for every digit of pi in the first 1000, map it to a musical note and output the resulting melody to a file.

Basically, each digit turns to a note on the C Major scale (basically the normal scale). so 1 turns to Middle C, 2 turns to D4, 3 turns to E4, 9 turns to D5 and so on.

# Rules

• Each note should be exactly 0.5 seconds long.
• The melody should contain the first 1000 digits of pi, including the starting 3.
• 1 to 7 represent Middle C to B4, 8 is C5, 9 is D5 and 0 is E5
• All well supported file formats are allowed, as long as they were created before this challenge.
• There may be no pauses anywhere in the file, including the start and end.
• The instrument played does not matter. It could be a piano, sine wave, anything really, as long as the correct sound is easily hearable.
• It must take no input and produce no output except for the file. Reading from other files is disallowed.
• Standard loopholes are forbidden.

Example mathematica code:

(*please forgive me for this horrible, horrible mess of code*)
digits = RealDigits[Pi, 10, 1000][] /. {0 -> 10};
weights = {0, 2, 4, 5, 7, 9, 11, 12, 14, 16};
melody = {};
For[i = 1, i < 1001, i++, melody = {melody , Sound[SoundNote[weights[[digits[[i]]]], 0.5]]}]
final = Sound[Flatten[melody]];
Export["C:\\Mathematica Shenanigans\\pi.wav", final];


Example melody showing first 100 digits: http://vocaroo.com/i/s0cfEILwYb8M

For your sanity, A table of pitches for each note and what note does each digit represent:

Digit 1: C: 261.63 Hz
Digit 2: D: 293.66 Hz
Digit 3: E: 329.63 Hz
Digit 4: F: 349.23 Hz
Digit 5: G: 392.00 Hz
Digit 6: A: 440.00 Hz
Digit 7: B: 493.88 Hz
Digit 8: C5: 523.25 Hz
Digit 9: D5: 587.33 Hz
Digit 0: E5: 659.25 Hz

• 9 turns to D5 You should clarify that the other notes are in the 4-th octave. Also, in your table does digit 0 come last (E5)? – Luis Mendo Jan 17 '17 at 22:11
• @LuisMendo Yes it does. I'll make these too more clear. – sagiksp Jan 18 '17 at 4:57
• Can we assume 'well supported formats' to mean anything openable by vlc? – Pavel Jan 18 '17 at 6:14
• @Pavel Pretty much – sagiksp Jan 18 '17 at 8:58
• Can I output the note names (e.g. 3.14 --> ECF) if my language does not support sound or writing to sound files? – FinW Jan 18 '17 at 19:42

# Mathematica, 107 87 bytes

Thanks to Martin Ender for saving 20 bytes!

"t.au"~Export~Sound[SoundNote[⌊12Mod[#,10,1]/7⌋-1,.5]&/@#&@@RealDigits[Pi,10,1000]]


#&@@RealDigits[Pi,10,1000] gives the list of the first 1000 digits of π. SoundNote[⌊12Mod[#,10,1]/7⌋-1 produces the correct pitch number (where 0 is middle C by default) from a digit. Then SoundNote[...,.5]&/@ turns that pitch name into a sound object of duration 1/2 second, which Sound gathers into an actual audio snippet. Finally "t.au"~Export~ exports to a Unix Audio Format file, mostly because the extension is the shortest supported one, but also because we get to make the filename a slap in the face to π!

Previous submission:

"t.au"~Export~Sound[StringSplit["E5 C D E F G A B C5 D5"][[#+1]]~SoundNote~.5&/@#&@@RealDigits[Pi,10,1000]]


# Python 2, 182 bytes

x=p=6637
while~-p:x=p/2*x/p+2*10**999;p-=2
s="MThd\0\0\0\6\0\1\0\1\342\4MTrk\0\0\13\301\0\220"
for i inx:s+="JHGECA@><L\260"[~ord(i)%29]+'{<'
open('p.mid','w').write(s+"\0\377/\0")


x will produce 31415926...20198L. The trailing L is used to produce the final channel message byte, via the mapping ~ord(i)%29.

Outputs a single track Type 1 Midi file, named p.mid to the current working directory.

0000: 4d 54 68 64 00 00 00 06  MThd....  # Midi header, 6 bytes to follow
0008: 00 01 00 01              ....      # Type 1, 1 track
000c: e2 04                    â.        # (-)30 ticks per beat, 4 beats per second

000e: 4d 54 72 6b 00 00 0b c1  MTrk...Á  # Track header, 3009 bytes to follow
0016: 00 90 40 7b              ..@{      # Wait  0 ticks, play E4 (3), 97% volume
001a: 3c 3c 7b                 <<{       # Wait 60 ticks, play C4 (1), 97% volume
001d: 3c 41 7b                 <A{       # Wait 60 ticks, play F4 (4), 97% volume
0020: 3c 3c 7b                 <<{       # Wait 60 ticks, play C4 (1), 97% volume
0023: 3c 43 7b                 <C{       # Wait 60 ticks, play G4 (5), 97% volume
...
0bcf: 3c b0 7b 3c              <°{<      # Wait 60 ticks, all notes off
0bd3: 00 ff 2f 00              .ÿ/.      # End of track marker


# Scratch, 530 bytes

Online Demonstration. Playback will begin immediately, press space to stop and reset. Click the cat to start again.

Edit: golfed down slightly. I found some golfing tips on the official wiki.

when gf clicked
set[c v]to[4e3
repeat(c
end
repeat(250
set[b v]to(c
set[h v]to((d)mod(1e4
change[c v]by(-16
repeat(b
set[d v]to(((d)*(b))+((1e4)*(item(b)of[f v
set[g v]to(((2)*(b))-(1
replace item(b)of[f v]with((d)mod(g
set[d v]to(((d)-((d)mod(g)))/(g
change[b v]by(-1
end
change[h v]by(((d)-((d)mod(1e4)))/(1e4
repeat(4
set[h v]to(((h)-((h)mod(10)))/(10
end
repeat(4
say(item(last v)of[a v
play note((round((((item(last v)of[a v])-(1))mod(10))*(1.78)))+(60))for(0.5)beats
delete(last v)of[a v


Graphical: Uses the Rabinowitz Wagon spigot to produce 4 digits at a time.

# R, 450 bytes

N=261.63*(2^(1/12))^c(16,0,2,4,5,7,9,11,12,14);S=44100;s=unlist(sapply(el(strsplit(as(Rmpfr::Const("pi",1e5),"character"),""))[c(1,3:1001)],function(x)sin(0:(0.5*S-1)*pi*2*N[(x:1)+1]/S)));c=32767*s/max(abs(s));a=file("p.wav","wb");v=writeChar;w=function(x,z)writeBin(as.integer(x),a,z,e="little");v("RIFF",a,4,NULL);w(36+S*10,4);v("WAVEfmt ",a,8,NULL);w(16,4);w(c(1,1),2);w(S*1:2,4);w(c(2,16),2);v("data",a,4,NULL);w(2*length(s),4);w(c,2);close(a)


Uses package Rmpfr to get the correct precision on pi digits. Outputs a .wav file.

Indented, with new lines and comments:

N=261.63*(2^(1/12))^c(16,0,2,4,5,7,9,11,12,14) # Frequency of each notes
S=44100 #Sampling rate
s=unlist(sapply(el(strsplit(
as(Rmpfr::Const("pi",1e5),"character"), #get pi correct digits as a character string
""))[c(1,3:1001)], #Grabs first 1000 digits
function(x)sin(0:(0.5*S-1)*pi*2*N[(x:1)+1]/S))) #Wave function
c=32767*s/max(abs(s)) #Normalize to range [-32767;32767] as per wav 16-bit standard
a=file("p.wav","wb")
v=writeChar
w=function(x,z)writeBin(as.integer(x),a,z,e="little")
v("RIFF",a,4,NULL)     #ChunkID
w(36+S*10,4)           #Chunksize
v("WAVEfmt ",a,8,NULL) #Format, followed by SubChunk1ID
w(16,4)                #SubChunk1Size
w(c(1,1),2)            #AudioFormat & NumChannels
w(S*1:2,4)             #SampleRate & ByteRate
w(c(2,16),2)           #BlockAlign & BitsPerSample
v("data",a,4,NULL)     #SubChunk2ID
w(2*length(s),4)       #Subchunk2Size
w(c,2)                 #Actual data
close(a)


## C (gcc) 572 bytes

p(float f){i;char b;p=3.14;for(i= 0;i<5000;i++){b[i]=35*sin(f*(2*p*i)/10000);putchar(b[i]);}} f(){i;FILE *f;char p;float n;n= 261.63;for(i=1;i<=6;i++){if(i==3)n[i]=349.23;else n[i]=1.12231*n[i-1];}for(i=7;i<=9;i++)n[i]=2*n[i-7];f=popen("pi 1000","r");fgets(p,sizeof(p)-1,f);for(i=0;i<999;i++){switch(p[i]){case'1':p(n);break;case'2':p(n);break;case'3':p(n);break;case'4':p(n);break;case'5':p(n);break;case'6':p(n);break;case'7':p(n);break;case'8':p(n);break;case'9':p(n);break;case'0':p(n);break;default:p(n);break;}}}


Ungolfed version:

void play(float freq)
{
char buffer;
float pi=3.14;
for(int i = 0; i<5000; i++)
{
buffer[i] = 35*sin(freq*(2*pi*i)/10000 );
putchar(buffer[i]);
}
}

void f()
{
FILE *fp;
char pi;
float note;
note= 261.63;

for(int i=1;i<=6;i++)
{
if(i==3)
note[i]=349.23;
else
note[i]=1.12231*note[i-1];
}

for(int i=7;i<=9;i++)
note[i]=2*note[i-7];

fp=popen("pi 1000","r" );
fgets(pi, sizeof(pi)-1, fp);

for(int i=0;i<1001;i++)
{
switch(pi[i])
{
case '1': play(note);break;
case '2': play(note);break;
case '3': play(note);break;
case '4': play(note);break;
case '5': play(note);break;
case '6': play(note);break;
case '7': play(note);break;
case '8': play(note);break;
case '9': play(note);break;
case '0': play(note);break;
default : play(note);break;
}

}
}


Explanation:

• play(float freq) routine takes in the frequency as a parameter of the note (hardcoded) you want to play and stores a sine wave in a buffer.
• In the function f(), i stored the frequencies corresponding to notes ranging from C4 to E5 in a notes array.
• Store the pi value followed by 1000 digits in a buffer.In order to do this, I installed the pi package on my machine, and used popen to read the output of pi 1000 and store it in a char buffer.
• Using a for loop and switch I called the play() function to produce notes that correspond to every single digit in the pi buffer. ,

Usage: ./binary_name.o | aplay on modern Linux distributions, on older distributions you would redirect it to /dev/audio

• Suggest replacing the entire switch(foo){...} with something like play(note[(foo-'1')%10]). Also, read tips for golfing in C – ceilingcat Feb 8 '17 at 7:48