Jouez le son de Pi

15

Oui, vous avez bien lu le titre. jouer le son de pi.

Plus spécifiquement, pour chaque chiffre de pi dans les 1000 premiers, mappez-le sur une note de musique et sortez la mélodie résultante dans un fichier.

Fondamentalement, chaque chiffre se transforme en une note sur l'échelle de do majeur (essentiellement l'échelle normale). donc 1 tour au milieu C, 2 tours au D4, 3 tours au E4, 9 tours au D5 et ainsi de suite.

Règles

  • Chaque note doit durer exactement 0,5 seconde.
  • La mélodie doit contenir les 1000 premiers chiffres de pi, y compris les 3 premiers.
  • 1 à 7 représente le milieu C à B4, 8 est C5, 9 est D5 et 0 est E5
  • Tous les formats de fichiers bien pris en charge sont autorisés, tant qu'ils ont été créés avant ce défi.
  • Il ne peut y avoir de pause nulle part dans le fichier, y compris le début et la fin.
  • L'instrument joué n'a pas d'importance. Ce pourrait être un piano, une onde sinusoïdale, n'importe quoi vraiment, tant que le son correct est facilement audible.
  • Il ne doit prendre aucune entrée et ne produire aucune sortie à l'exception du fichier. La lecture à partir d'autres fichiers n'est pas autorisée.
  • Les failles standard sont interdites.

Exemple de code mathématique:

(*please forgive me for this horrible, horrible mess of code*)
digits = RealDigits[Pi, 10, 1000][[1]] /. {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];

Exemple de mélodie montrant les 100 premiers chiffres: http://vocaroo.com/i/s0cfEILwYb8M

Pour votre santé mentale, un tableau des hauteurs pour chaque note et quelle note chaque chiffre représente:

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
sagiksp
la source
5
9 transforme en D5 Vous devez préciser que les autres notes sont dans la 4-ième octave. De plus, dans votre tableau, le chiffre 0vient-il en dernier ( E5)?
Luis Mendo
1
@LuisMendo Oui, c'est le cas. Je vais aussi les clarifier.
sagiksp
1
Pouvons-nous supposer que les «formats bien pris en charge» signifient quelque chose pouvant être ouvert par vlc?
Pavel
@Pavel Pretty much
sagiksp
Puis-je sortir les noms des notes (par exemple 3.14 -> ECF) si ma langue ne prend pas en charge le son ou l'écriture dans des fichiers audio?
Fin le

Réponses:

10

Mathematica, 107 87 octets

Merci à Martin Ender d'avoir économisé 20 octets!

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

#&@@RealDigits[Pi,10,1000]donne la liste des 1000 premiers chiffres de π. SoundNote[⌊12Mod[#,10,1]/7⌋-1produit le numéro de hauteur correct (où 0 est le milieu C par défaut) à partir d'un chiffre. SoundNote[...,.5]&/@Transforme ensuite ce nom de hauteur en un objet sonore d'une durée de 1/2 seconde, qui se Soundrassemble en un véritable extrait audio. Enfin, "t.au"~Export~exporte vers un fichier au format audio Unix, principalement parce que l'extension est la plus courte prise en charge, mais aussi parce que nous arrivons à faire du nom de fichier une gifle en face à π !

Soumission précédente:

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

Python 2, 182 octets

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 in`x`:s+="JHGECA@><L\260"[~ord(i)%29]+'{<'
open('p.mid','w').write(s+"\0\377/\0")

`x`va produire 31415926...20198L. La fin Lest utilisée pour produire l'octet de message de canal final, via le mappage ~ord(i)%29.

Génère un fichier Midi Type 1 à piste unique, nommé p.middans le répertoire de travail actuel.

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
primo
la source
1
Assez tard, mais si vous vous demandez quelle formule pi est utilisée, c'est une variation de la formule 25 sur mathworld.wolfram.com/PiFormulas.html .
Samuel Li
6

Scratch , 530 octets

Inspiré par la réponse de BookOwl .

Démonstration en ligne . La lecture commencera immédiatement, appuyez sur spacepour arrêter et réinitialiser. Cliquez sur le chat pour recommencer.

Edit: légèrement golfé. J'ai trouvé quelques astuces de golf sur le wiki officiel .

when gf clicked
set[c v]to[4e3
repeat(c
add[2e3]to[f v
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
add((h)mod(10))to[a v
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

Graphique:

Utilise l'embout Rabinowitz Wagon pour produire 4 chiffres à la fois.

primo
la source
3

R, 450 octets

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]+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)

Utilise le package Rmpfrpour obtenir la précision correcte sur les chiffres pi. Sort un .wavfichier.

En retrait, avec de nouvelles lignes et commentaires:

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]+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)
plannapus
la source
0

C (gcc) 572 octets

p(float f){i;char b[10000];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[1001];float n[10];n[0]= 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[0]);break;case'2':p(n[1]);break;case'3':p(n[2]);break;case'4':p(n[3]);break;case'5':p(n[4]);break;case'6':p(n[5]);break;case'7':p(n[6]);break;case'8':p(n[7]);break;case'9':p(n[8]);break;case'0':p(n[9]);break;default:p(n[0]);break;}}}

Version non golfée:

void play(float freq)
{
    char buffer[10000];
    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[1001];
    float note[10];
    note[0]= 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[0]);break;
        case '2': play(note[1]);break;
        case '3': play(note[2]);break;
        case '4': play(note[3]);break;
        case '5': play(note[4]);break;
        case '6': play(note[5]);break; 
        case '7': play(note[6]);break;
        case '8': play(note[7]);break;
        case '9': play(note[8]);break;
        case '0': play(note[9]);break;
        default : play(note[0]);break;
    }

  }     
}

Explication:

  • play(float freq) la routine prend la fréquence comme paramètre de la note (codée en dur) que vous voulez jouer et stocke une onde sinusoïdale dans un tampon.
  • Dans la fonction f(), j'ai stocké les fréquences correspondant aux notes allant de C4 à E5 dans un notestableau.
  • Stocker la pivaleur suivie de 1000 chiffres dans un tampon.Pour ce faire, j'ai installé le pipackage sur ma machine, et utilisé popenpour lire la sortie de pi 1000et le stocker dans un chartampon.
  • À l'aide d'une forboucle, switchj'ai appelé la play()fonction pour produire des notes qui correspondent à chaque chiffre du pitampon. ,

Utilisation: ./binary_name.o | aplaysur les distributions Linux modernes, sur les distributions plus anciennes, vous le redirigeriez vers/dev/audio

Abel Tom
la source
Suggérez de remplacer le tout switch(foo){...}par quelque chose comme play(note[(foo-'1')%10]). Lisez également les conseils pour jouer au golf en C
plafond le