เล่นเสียงของ Pi


15

ใช่คุณอ่านชื่อถูกต้อง เล่นเสียงของปี่

โดยเฉพาะอย่างยิ่งสำหรับทุก ๆ ตัวเลขของไพใน 1,000 ครั้งแรกให้แมปโน้ตดนตรีและส่งเมโลดี้ที่เกิดขึ้นไปยังไฟล์

โดยทั่วไปแต่ละหลักจะเปลี่ยนเป็นบันทึกย่อในระดับ C Major (โดยทั่วไปคือระดับปกติ) ดังนั้น 1 ถึงกลาง C 2 หันไป D4, 3 หันไป E4, 9 หันไป D5 และอื่น ๆ

กฎระเบียบ

  • แต่ละโน้ตควรมีความยาว 0.5 วินาที
  • ท่วงทำนองควรมี 1,000 หลักแรกของ pi รวมถึง 3 อันด้วย
  • 1 ถึง 7 แทน Middle C ถึง B4, 8 คือ C5, 9 คือ D5 และ 0 คือ E5
  • อนุญาตให้ใช้รูปแบบไฟล์ที่รองรับได้ทุกรูปแบบตราบใดที่สร้างก่อนความท้าทายนี้
  • อาจไม่มีการหยุดชั่วคราวในไฟล์รวมถึงจุดเริ่มต้นและจุดสิ้นสุด
  • เครื่องดนตรีที่เล่นไม่สำคัญ มันอาจเป็นเปียโนคลื่นไซน์อะไรก็ได้ตราบใดที่เสียงที่ถูกต้องนั้นฟังได้ง่าย
  • ต้องไม่มีการป้อนข้อมูลและไม่สร้างเอาต์พุตยกเว้นไฟล์ ไม่อนุญาตให้อ่านไฟล์อื่น ๆ
  • ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม

ตัวอย่างรหัส mathematica:

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

ตัวอย่างทำนองที่แสดง 100 หลักแรก: http://vocaroo.com/i/s0cfEILwYb8M

เพื่อความมีสติของคุณโต๊ะสำหรับแต่ละโน้ตแต่ละโน้ตและโน้ตแต่ละตัวแสดงถึงอะไร:

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คุณควรชี้แจงว่าบันทึกอื่น ๆ อยู่ใน4ระดับแปดเสียง -th นอกจากนี้ในตารางของคุณมีเลขหลัก0สุดท้าย ( E5) หรือไม่
Luis Mendo เมื่อ

1
@LuisMendo ใช่แล้ว ฉันจะทำให้สิ่งเหล่านี้ชัดเจนยิ่งขึ้น
sagiksp

1
เราสามารถสันนิษฐานว่า
Pavel

@Pavel ค่อนข้างมาก
sagiksp

ฉันสามารถส่งออกชื่อบันทึกย่อ (เช่น 3.14 -> ECF) ได้หรือไม่หากภาษาของฉันไม่รองรับไฟล์เสียงหรือเขียนลงไฟล์เสียง?
FinW

คำตอบ:


10

Mathematica, 107 87 ไบต์

ขอบคุณ Martin Ender ที่ช่วยประหยัด 20 ไบต์!

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

#&@@RealDigits[Pi,10,1000]ให้รายชื่อ 1,000 หลักแรกของπ SoundNote[⌊12Mod[#,10,1]/7⌋-1สร้างหมายเลขพิชที่ถูกต้อง (โดยที่ 0 คือค่ากลาง C โดยค่าเริ่มต้น) จากตัวเลข จากนั้นSoundNote[...,.5]&/@เปลี่ยนชื่อระดับเสียงนั้นเป็นวัตถุเสียงที่มีระยะเวลา 1/2 วินาทีซึ่งรวมSoundอยู่ในตัวอย่างเสียงจริง ในที่สุดการ"t.au"~Export~ส่งออกไปยังไฟล์รูปแบบเสียง Unix ส่วนใหญ่เป็นเพราะนามสกุลเป็นไฟล์ที่สนับสนุนสั้นที่สุด แต่ก็เพราะเราได้ทำให้ชื่อไฟล์เป็นตบหน้า face !

การส่งก่อนหน้า:

"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 ไบต์

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`31415926...20198Lจะผลิต ต่อท้ายจะใช้ในการผลิตไบต์ข้อความช่องสุดท้ายผ่านการทำแผนที่L~ord(i)%29

ส่งออกไฟล์แทร็ก Type 1 Midi หนึ่งไฟล์ซึ่งมีชื่อp.midในไดเรกทอรีทำงานปัจจุบัน

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
ค่อนข้างล่าช้า แต่ถ้าคุณสงสัยว่าสูตรปี่จะใช้มันเป็นรูปแบบที่หลากหลายสูตร 25 ในmathworld.wolfram.com/PiFormulas.html
Samuel Li

6

ขีดข่วน 530 ไบต์

แรงบันดาลใจจากคำตอบของ BookOwl

สาธิตออนไลน์ การเล่นจะเริ่มขึ้นทันทีกดspaceเพื่อหยุดและรีเซ็ต คลิกที่แมวเพื่อเริ่มต้นอีกครั้ง

แก้ไข: golfed ลงเล็กน้อย ผมพบว่าเคล็ดลับการเล่นกอล์ฟบางอย่างเกี่ยวกับวิกิพีเดียอย่างเป็นทางการ

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

กราฟิก:

ใช้เดือย Rabinowitz Wagon เพื่อผลิต 4 หลักต่อครั้ง


3

R, 450 ไบต์

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)

ใช้แพ็คเกจRmpfrเพื่อรับความถูกต้องแม่นยำของตัวเลขไพ ส่งออก.wavไฟล์

เยื้องกับบรรทัดใหม่และความคิดเห็น:

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 ไบต์

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

เวอร์ชันที่ไม่ถูกปรับแต่ง:

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

  }     
}

คำอธิบาย:

  • play(float freq) รูทีนใช้ความถี่เป็นพารามิเตอร์ของโน้ต (ฮาร์ดโค้ด) ที่คุณต้องการเล่นและเก็บคลื่นไซน์ในบัฟเฟอร์
  • ในฟังก์ชั่นf()นี้ฉันเก็บความถี่ที่สอดคล้องกับบันทึกตั้งแต่ C4 ถึง E5 ในnotesอาร์เรย์
  • เก็บpiค่าตามด้วยตัวเลข 1,000 ตัวในบัฟเฟอร์เพื่อทำสิ่งนี้ฉันติดตั้งpiแพ็กเกจบนเครื่องของฉันและใช้popenเพื่ออ่านเอาต์พุตpi 1000และเก็บไว้ในcharบัฟเฟอร์
  • การใช้forลูปและswitchฉันเรียกใช้play()ฟังก์ชั่นในการสร้างบันทึกย่อที่สอดคล้องกับทุกหลักเดียวในpiบัฟเฟอร์ ,

การใช้งาน: ./binary_name.o | aplayบน Linux ดิสทริบิวชันรุ่นล่าสุดในการกระจายแบบเก่าคุณจะเปลี่ยนเส้นทางไปยัง/dev/audio


ขอแนะนำให้เปลี่ยนทั้งกับสิ่งที่ต้องการswitch(foo){...} play(note[(foo-'1')%10])นอกจากนี้อ่านเคล็ดลับสำหรับการเล่นกอล์ฟใน C
ceilingcat
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.