Pi sesini çal


15

Evet, başlığı doğru okudun. pi sesi çalmak.

Daha spesifik olarak, ilk 1000'deki her pi basamağı için bir nota eşleyin ve ortaya çıkan melodiyi bir dosyaya çıkarın.

Temel olarak, her basamak C Major ölçeğinde (temelde normal ölçek) bir nota dönüşür. böylece 1 Orta C'ye, 2 D4'e, 3 E4'e, 9 D5'e vb.

kurallar

  • Her nota tam olarak 0,5 saniye uzunluğunda olmalıdır.
  • Melodi, başlangıç ​​3 dahil olmak üzere ilk 1000 haneyi içermelidir.
  • 1 ila 7 Orta C ila B4'ü temsil eder, 8 C5, 9 D5 ve 0 E5'tir
  • Bu meydan okumadan önce oluşturulduğu sürece, iyi desteklenen tüm dosya biçimlerine izin verilir.
  • Başlangıç ​​ve bitiş de dahil olmak üzere dosyanın hiçbir yerinde duraklama olmayabilir.
  • Çalınan enstrüman önemli değil. Doğru ses kolayca ısıtılabildiği sürece bir piyano, sinüs dalgası, gerçekten herhangi bir şey olabilir.
  • Dosya dışında herhangi bir girdi almamalı ve çıktı üretmemelidir. Diğer dosyalardan okumaya izin verilmiyor.
  • Standart boşluklar yasaktır.

Örnek matematik kodu:

(*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];

İlk 100 rakamı gösteren örnek melodi: http://vocaroo.com/i/s0cfEILwYb8M

Akıl sağlığınız için, her nota için bir perde tablosu ve her rakamın hangi notayı temsil ettiği:

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

5
9 D5'e döner. Diğer notaların 4oktav içinde olduğunu açıklığa kavuşturmalısınız . Ayrıca, tablonuzda rakam 0son ( E5) geliyor?
Luis Mendo

1
@LuisMendo Evet öyle. Bunları çok daha açıklığa kavuşturacağım.
sagiksp

1
Vlc tarafından açılabilecek bir şey anlamına gelen 'iyi desteklenen formatlar' olduğunu varsayabilir miyiz?
Pavel

@Pavel Oldukça
sagiksp

Dilim ses veya ses dosyalarına yazmayı desteklemiyorsa not adlarını (ör. 3.14 -> ECF) verebilir miyim?
FinW

Yanıtlar:


10

Mathematica, 107 87 bayt

Martin Ender'e 20 bayt kazandığı için teşekkürler!

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

#&@@RealDigits[Pi,10,1000]1000 'nin ilk 1000 rakamının listesini verir. SoundNote[⌊12Mod[#,10,1]/7⌋-1bir basamaktan doğru adım sayısını (burada varsayılan olarak 0 orta C'dir) üretir. Ardından SoundNote[...,.5]&/@bu ses perdesi adını 1/2 saniyelik bir ses nesnesine Sounddönüştürür ve bu gerçek bir ses parçacığına dönüşür. En sonunda"t.au"~Export~ olarak bir Unix Ses Biçimi dosyasına aktarılır, çünkü çoğunlukla uzantı desteklenen en kısa dosyadır, aynı zamanda dosya adını yüze bir tokat haline getireceğimiz için π !

Önceki gönderim:

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

10

Python 2, 182 bayt

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`üretecek 31415926...20198L. SondakiL nokta, eşleme yoluyla son kanal mesaj baytını üretmek için kullanılır~ord(i)%29 .

p.midGeçerli çalışma dizinine adlı tek bir parça Tür 1 Midi dosyası çıktılar .

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

1
Oldukça geç, ancak hangi pi formülünün kullanıldığını merak ediyorsanız, mathworld.wolfram.com/PiFormulas.html adresindeki Formula 25'te bir varyasyon .
Samuel Li

6

Kaşımak , 530 bayt

BookOwl'un cevabından ilham aldı .

Çevrimiçi Gösteri . Oynatma hemen başlar, spacedurdurmak ve sıfırlamak için tuşuna basın . Tekrar başlamak için kediyi tıklayın.

Düzenleme: hafifçe aşağı golf. Resmi wiki'de bazı golf ipuçları buldum .

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

Grafiksel:

Bir seferde 4 basamak üretmek için Rabinowitz Wagon spigotunu kullanır.


3

R, 450 bayt

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)

RmpfrPi basamaklarında doğru hassasiyeti elde etmek için paketi kullanır . Çıkışlar a.wav dosya .

Girintili, yeni satırlar ve yorumlar:

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)

0

C (gcc) 572 bayt

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;}}}

Ungolfed sürümü:

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;
    }

  }     
}

Açıklama:

  • play(float freq) rutin frekansı çalmak istediğiniz notanın (sabit kodlu) bir parametresi olarak alır ve bir sinüs dalgasını bir arabellekte saklar.
  • Fonksiyonda f(), C4'ten E5'e kadar olan notlara karşılık gelen frekansları birnotes dizide .
  • Mağaza pibunun için buffer.In amacıyla 1000 basamağı takip değerini, ben yüklü pibenim makinede paketi ve kullanılan popençıktısını okumak için pi 1000ve a depolarchar tampon.
  • Bir fordöngü kullanarak ve arabellekteki her bir basamağa karşılık gelen notlar üretmek switchiçin play()işlevi çağırdım pi. ,

Kullanımı: ./binary_name.o | aplayModern Linux dağıtımlarında, daha eski dağıtımlarda,/dev/audio


Tümünün yerine switch(foo){...}benzer bir şey koymanızı öneririz play(note[(foo-'1')%10]). Ayrıca, C golf için ipuçlarını
ceilingcat
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.