Chơi một số Canon của Pachelbel


29

Xuất đoạn trích sau từ Pachelbel's Canon in D dưới dạng âm thanh:

Canon của Pachelbel ở D

Quy tắc

  • Bất kỳ định dạng / mã hóa nào cũng có thể được sử dụng, miễn là một codec tồn tại trước khi tạo ra thách thức này
  • Bất kỳ nhạc cụ nào (một nhạc cụ thực, tổng hợp MIDI, v.v.) đều có thể được sử dụng
  • Nhịp độ phải là 65 BPM (như được ghi trong bản nhạc) - nếu bạn không thể có được chính xác 65 BPM, bạn có thể sử dụng bất kỳ nhịp độ nào trong phạm vi (bao gồm) 64,75 - 65,25
  • Bản nhạc nằm trong sân hòa nhạc
  • Phải điều chỉnh tính khí bằng nhau (cụ thể là 12-ET với A4 = 440 Hz)

Để tham khảo, đây là một Đoạn trích đoạn sẽ phát đoạn trích:


Đoạn trích đó có thể cạnh tranh khi nó tải xuống từ nơi khác không
Blue

4
@muddyfish Không, bởi vì tìm nạp đầu ra từ nguồn bên ngoài là một lỗ hổng tiêu chuẩn.
Mego

Sẽ xuất ra một tập tin midi thay vì âm thanh được chấp nhận?
DJMcMayhem

@DJMcMayhem Có, các tệp MIDI được chấp nhận.
Mego

Tôi giả sử hợp âm (chỉ) cuối cùng là bắt buộc? Điều đó thực sự cấm các ngôn ngữ không đa âm / API
Level River St

Câu trả lời:


9

JavaScript (ES7), 249 242 241 byte

with(new AudioContext)for(t=i=0;n=parseInt('l43l431db98643o86ogfdbdfdgfdzbdzgigikigfdbzbdv98db9864311480'[i++],36);)with(createOscillator())frequency.value=880*2**(-~-n%20/12),connect(destination),start(t),stop(i>56?t+q*8:t+=n>20?q=6/13:q/2)

Cảm ơn @Neil và @PatrickRoberts vì đã tiết kiệm một số byte!

Giải trình

Ký hiệu được đóng gói thành chuỗi trong đó mỗi ký tự là một ghi chú dưới dạng một chữ số cơ sở 36. Các giá trị lưu ý được xác định theo công thức (19 - pitch) * time + 1pitchlà số semitones ít hơn A5 và time1một semiquaver hoặc 20cho một người ca run. Ở 0cuối dừng forvòng lặp.

Tốc độ là 65,22bpm Chỉnh sửa: chính xác là 65bpm bây giờ, để có thêm 2 byte .

Giải thích / demo này sử dụng Math.powthay vì **tương thích trình duyệt. Nó cũng đặt mức tăng của các bộ dao động để .3hợp âm cuối cùng không làm cho tai bạn bị chảy máu (mức tăng mặc định là 1).

with(new AudioContext)            // use HTML5 audio
  for(                            // iterate through the note pitches and lengths
    t=i=0;                        // t = current time to place the note
    n=parseInt(                   // n = note pitch/length

      // Packed notation string
      'l43l431db98643o86ogfdbdfdgfdzbdzgigikigfdbzbdv98db9864311480'

    [i++],36);
  )
    with(createOscillator())      // create the note oscillator

      // Set the note frequency (using Math.pow for the demo).
      //frequency.value=880*2**(-~-n%20/12),
      frequency.value=880*Math.pow(2,-~-n%20/12),

      // Send the note's sound through the speakers (for the demo, we'll connect it to
      // a gain node so we can reduce the volume).
      //connect(destination),
      connect((g=createGain(),g.gain.value=.3,g.connect(destination),g)),

      start(t),                     // schedule the note to sound
      stop(                         // schedule the end of the note
        i>56?                       // if we are in the final chord
          t+                        //   do not increment the time
            q*8                     //   hard-code the length to a semibreve
        :t+=n>20?q=6/13:q/2         // else update the length based on the note value
      )

Bạn có thể nhấn nút ở trên để kiểm tra nó trong bất kỳ trình duyệt nào hỗ trợ API âm thanh Web HTML5 .


880*2**(-~-n%20/12)sẽ giúp bạn tiết kiệm một vài byte.
Neil

@Neil Cảm ơn. Tôi nghi ngờ tôi cũng có thể thoát khỏi -~-bằng cách thay đổi định dạng của gói ghi chú của mình (Công + 1thức chỉ có ở đó vì tôi cần 0dừng forvòng lặp và tôi quá lười để suy nghĩ về nó rất nhiều trước khi tôi đăng).
dùng81655

Tôi thấy điều này sau khi tôi đăng câu trả lời của mình, lol
Patrick Roberts

Bạn có thể lưu một byte khác bằng cách thay thế c=new AudioContext;bằng with(new AudioContext)và loại bỏ hai lần xuất hiện c.trong chương trình.
Patrick Roberts

1
@ kamoroso94 Số. Số mũ có thể là một phân số, vì vậy nếu tôi sử dụng <<nó sẽ chuyển nó thành một số nguyên.
user81655

8

Toán học, 212 152 139 135 byte

{#~(s=##~SoundNote~41&)~1&/@LetterNumber@"uursuursuikmnprsrrnprrfgikigifgiggkiggfdfdbdfgikggkikkmnikmnprsu",{14,18,21}~s~16}~Sound~18.5

Xuất ra một Soundđối tượng phát Canon của Pachelbel trong D khi nhấn nút Play. Nhạc cụ là nhạc cụ MIDI # 41 "violin".

Âm thanh

Nhấp vào đây!

Giải trình

LetterNumber@"uursuursuikmnprsrrnprrfgikigifgiggkiggfdfdbdfgikggkikkmnikmnprsu"

Tìm số chữ cái của mỗi ký tự trong chuỗi ("a" -> 1, "b" -> 2, v.v.), được bọc bằng a List. (Chuỗi này đại diện cho Canon của Pachelbel ở D)

#~(s=##~SoundNote~41&)~1&/@...

Đặt sthành SoundNotechức năng có nhạc cụ là # 41. Đặt thời lượng thành 1 và ánh xạ chức năng đó đến từng thành phần trong List(do đó tạo SoundNotecác đối tượng nguyên thủy).

{14,18,21}~s~16

Làm bộ ba cuối cùng. (Thời lượng 16là để ghi chú cuối cùng dài hơn 16 lần - toàn bộ ghi chú là mười sáu lần một ghi chú thứ mười sáu.)

... ~Sound~18.5

Tạo một Soundvật thể, 18.5dài vài giây (vì nhịp độ là 65 bpm [5 lần đo 4/4 với nhịp độ 65 bpm = khoảng 18,5 giây]).

Phiên bản 126 byte, không cạnh tranh

Sound[{(s=SoundNote)/@LetterNumber@"uursuursuikmnprsrrnprrfgikigifgiggkiggfdfdbdfgikggkikkmnikmnprsu",{14,18,21}~s~16},240/13]

Không cạnh tranh vì đầu ra chứa hai nốt thứ mười sáu thay vì nốt thứ tám và sự phân tách khá đáng chú ý.


14
Thực sự, Mathematica không tích hợp sẵn cho Canon của Pachelbel?
Stewie Griffin

1
@StewieGriffin Chỉ toàn bộ điều có lẽ, và chi phí cắt nó sẽ quá cao.
Mego

@StewieGriffin Đáng ngạc nhiên, nó không.
JungHwan Min

6

Bong bóng , 203 byte

00000000: e002 2800 c35d 0026 9509 6f34 76f2 ffad  ..(..].&..o4v...
00000010: 4150 0893 a735 bd02 a1eb 1237 18fe 5498  AP...5.....7..T.
00000020: 120a 83e1 6662 8a5e 9709 fe8a 3430 0f48  ....fb.^....40.H
00000030: 5008 54af d19a b44f 2be9 fb3b bf9d 206d  P.T....O+..;.. m
00000040: abbf 12f0 2151 6dae 4712 8c18 4d8e f5cd  ....!Qm.G...M...
00000050: eb85 404c 17cd bd5c 2775 38bd eb50 ab88  ..@L...\'u8..P..
00000060: e015 fb7e 4b1e 5ddb 515b 144c fc5e c1be  ...~K.].Q[.L.^..
00000070: 3d5d 20cd e950 4a1d 256e b56e d364 188b  =] ..PJ.%n.n.d..
00000080: 6fa1 afcc 2100 0235 ada0 2f23 411d 95dd  o...!..5../#A...
00000090: 6665 3b45 041d cbe2 8e3b 2456 fb8d 4e4c  fe;E.....;$V..NL
000000a0: 1a7f b814 a6cf 850e 9b6c 9285 3a6f 1ec3  .........l..:o..
000000b0: 02ed 505c 996b eb4d 209c 2776 a8aa 8380  ..P\.k.M .'v....
000000c0: 42cc b779 218e e75e 8000 00              B..y!..^...

Hãy thử trực tuyến!

Đây là một hexdump (đảo ngược với xxd -r) của mã nguồn. Tệp MIDI mà nó tạo ra như sau (cũng là một hexdump):

00000000: 4d54 6864 0000 0006 0001 0002 01e0 4d54  MThd..........MT
00000010: 726b 0000 0019 00ff 5902 0200 00ff 5804  rk......Y.....X.
00000020: 0402 1808 00ff 5103 0e15 c500 ff2f 004d  ......Q....../.M
00000030: 5472 6b00 0001 f200 c000 00ff 0405 5069  Trk...........Pi
00000040: 616e 6f00 9051 5f81 5880 5100 1890 4e5f  ano..Q_.X.Q...N_
00000050: 6c80 4e00 0c90 4f5f 6c80 4f00 0c90 515f  l.N...O_l.O...Q_
00000060: 8158 8051 0018 904e 5f6c 804e 000c 904f  .X.Q...N_l.N...O
00000070: 5f6c 804f 000c 9051 5f6c 8051 000c 9045  _l.O...Q_l.Q...E
00000080: 5f6c 8045 000c 9047 5f6c 8047 000c 9049  _l.E...G_l.G...I
00000090: 5f6c 8049 000c 904a 5f6c 804a 000c 904c  _l.I...J_l.J...L
000000a0: 5f6c 804c 000c 904e 5f6c 804e 000c 904f  _l.L...N_l.N...O
000000b0: 5f6c 804f 000c 904e 5f81 5880 4e00 1890  _l.O...N_.X.N...
000000c0: 4a5f 6c80 4a00 0c90 4c5f 6c80 4c00 0c90  J_l.J...L_l.L...
000000d0: 4e5f 8158 804e 0018 9042 5f6c 8042 000c  N_.X.N...B_l.B..
000000e0: 9043 5f6c 8043 000c 9045 5f6c 8045 000c  .C_l.C...E_l.E..
000000f0: 9047 5f6c 8047 000c 9045 5f6c 8045 000c  .G_l.G...E_l.E..
00000100: 9043 5f6c 8043 000c 9045 5f6c 8045 000c  .C_l.C...E_l.E..
00000110: 9042 5f6c 8042 000c 9043 5f6c 8043 000c  .B_l.B...C_l.C..
00000120: 9045 5f6c 8045 000c 9043 5f81 5880 4300  .E_l.E...C_.X.C.
00000130: 1890 475f 6c80 4700 0c90 455f 6c80 4500  ..G_l.G...E_l.E.
00000140: 0c90 435f 8158 8043 0018 9042 5f6c 8042  ..C_.X.C...B_l.B
00000150: 000c 9040 5f6c 8040 000c 9042 5f6c 8042  ...@_l.@...B_l.B
00000160: 000c 9040 5f6c 8040 000c 903e 5f6c 803e  ...@_l.@...>_l.>
00000170: 000c 9040 5f6c 8040 000c 9042 5f6c 8042  ...@_l.@...B_l.B
00000180: 000c 9043 5f6c 8043 000c 9045 5f6c 8045  ...C_l.C...E_l.E
00000190: 000c 9047 5f6c 8047 000c 9043 5f81 5880  ...G_l.G...C_.X.
000001a0: 4300 1890 475f 6c80 4700 0c90 455f 6c80  C...G_l.G...E_l.
000001b0: 4500 0c90 475f 8158 8047 0018 9049 5f6c  E...G_.X.G...I_l
000001c0: 8049 000c 904a 5f6c 804a 000c 9045 5f6c  .I...J_l.J...E_l
000001d0: 8045 000c 9047 5f6c 8047 000c 9049 5f6c  .E...G_l.G...I_l
000001e0: 8049 000c 904a 5f6c 804a 000c 904c 5f6c  .I...J_l.J...L_l
000001f0: 804c 000c 904e 5f6c 804e 000c 904f 5f6c  .L...N_l.N...O_l
00000200: 804f 000c 9051 5f6c 8051 000c 904a 5f00  .O...Q_l.Q...J_.
00000210: 904e 5f00 9051 5f8e 4c80 4a00 0080 4e00  .N_..Q_.L.J...N.
00000220: 0080 5100 8360 ff2f 00                   ..Q..`./.

6

BBC BASIC, 141 ký tự ASCII (65.217BPM)

*TEMPO1
F.i=2TO71j=i>65SOUND1-j*(479+i/2),-9,ASCM." \\VX\\VX\DHLNRVXVVNRVV>@DHD@D>@D@@HD@@>:>:6:>@DH@@HDHHLNLDHLNRVXNNVV\\",i)*2,23-j*161N.

Sửa đổi để giới hạn chỗ ở trên nhịp độ. Sẽ cập nhật giải thích sau.

BBC BASIC, 123 ký tự ASCII (không phải là 60BPM)

Tải xuống thông dịch viên tại http://www.bbcbasic.co.uk/bbcwin/doad.html

Phát bài hát trực tiếp khi chạy.

F.i=1TO67j=i>64SOUND1-j*(447+i),-9,ASCM."\\VX\\VX\DHLNRVXVVNRVV>@DHD@D>@D@@HD@@>:>:6:>@DH@@HDHHLNLDHLNRVXNV\",i)*2,5-j*75N.

Bị đánh cắp

  FOR i = 1 TO 67
    j = i > 64: REM j=0 for the first four bars composed of 16th notes, j=-1 for the final chord (whole note)
    SOUND 1 - j * (447 + i), -9, ASC(MID$("\\VX\\VX\DHLNRVXVVNRVV>@DHD@D>@D@@HD@@>:>:6:>@DH@@HDHHLNLDHLNRVXNV\", i)) * 2, 5 - j * 75
  NEXT i

Giải trình

jlà một lá cờ cho biết chúng ta đang ở trong 4 thanh đầu tiên hay hợp âm cuối cùng. TRUE là -1trong BBC BASIC.

Câu SOUNDlệnh có 4 tham số:

KÊNH: đối với 4 thanh đầu tiên, đây là kênh 1. Đối với 3 nốt của hợp âm trong thanh thứ 5, các số kênh là 201, 202 và 203 hex (513,514 và 515 thập phân.) Điều này có nghĩa là phát trên các kênh 1,2 và 3, 2 nghĩa ban đầu chơi đồng thời với 2 nốt trên các kênh khác (tức là chơi hợp âm 3 nốt).

TÍNH NĂNG: Được đưa ra dưới dạng giá trị âm vì giá trị dương biểu thị các hiệu ứng khác (phong bì âm thanh.). Đặt ở -9 (sẽ tăng lên -15, mức lớn nhất.)

PITCH: Đối với giai điệu này, dao động từ D4 = 108 đến A5 = 184. Mỗi bước nguyên là 1/4 của một nửa cung. Các giá trị được lưu trữ dưới dạng mã ASCII trong phạm vi 54 đến 92 và nhân đôi để tạo lại giá trị chính xác. Ghi chú 1/8 được lưu trữ dưới dạng trùng lặp 1/16 ghi chú. Hợp âm cuối cùng được lưu trữ dưới dạng 3 nốt riêng biệt và độ dài nốt khác nhau cho toàn bộ nốt như bên dưới.

THỜI GIAN: trong 1/20 của một giây. Thời lượng của ghi chú 1/16 là 5/20 giây nên 60 1/4 ghi chú mỗi phút (không đủ độ phân giải để làm cho nhịp độ chính xác hơn.) Toàn bộ ghi chú là 5 - (- 75) = 80 đơn vị (4 giây ) Dài.


Điều này không nên được dán nhãn không cạnh tranh, sau đó?
JungHwan tối

@JungHwanMin Để trả lời văn bản gốc của bình luận của bạn: BPM nằm trong 10% của 65. Không có ràng buộc nào về độ chính xác trong câu hỏi. Cuộc gọi của OP.
Cấp sông St

60 bpm khác biệt rõ rệt với 65 bpm. Tôi sẽ cho phép điều này không cạnh tranh vì đó là một hạn chế do ngôn ngữ áp đặt.
Mego

@Mego Ban đầu tôi nghĩ BBC Basic được tính theo 100 giây trong một giây theo mặc định, tôi không nhận ra nó thô như 20 giây. Tôi đã điều chỉnh mã của mình thành 100, vì vậy bây giờ tôi có thể thực hiện 65.215BPM, điều đó có ổn không? Phải mất thêm một chút nữa khi toàn bộ nốt nhạc vượt quá 256/100 nên tôi phải chơi nó như hai nốt nhạc. 50 giây sẽ là mã ngắn hơn nhưng 62,5BPM không có nhiều cải tiến.
Cấp sông St

Nhân tiện, có một số lỗi sao chép nhỏ trong bài viết gốc. Bạn có thể cần thay đổi mã của mình một chút. (Mã hiện tại có phiên bản sai)
JungHwan Min

4

Befunge, 242 byte

Giai điệu được ghi vào thiết bị xuất chuẩn ở định dạng của tệp MIDI. Bạn sẽ cần chuyển hướng đầu ra đó sang tệp .mid để phát đoạn trích.

<v:"MThd"0006000101"MTrk"001+"~e"0*3"UQ"30*5"-\"9
v>9#:-#,_0"QONLJIGEJIGEGCGECB@>@B@BCEGCECBECEGECBNLJNONLJIGEQONQONQ"0\:
_v#:\%+77+1,"@",\,*8*82,+3*4!*-3::\,"@",:,*:*62,1
v>"QNJQNJ"0\:
_v#:\+1,"@",\,-**82/3\*:*62:,+!\**97!-3::\
@>,\"/U"3*,,,

Hãy thử trực tuyến! , mặc dù tôi không nghĩ hiện tại có thể lưu đầu ra theo cách nó sẽ giữ được tính toàn vẹn nhị phân của dữ liệu.

Giải trình

Dòng đầu tiên rất cần thiết chỉ là một tiêu đề MIDI được mã hóa cứng, là đầu ra ở đầu dòng hai. Phần còn lại của dòng hai mã hóa chuỗi các ghi chú dưới dạng các giá trị MIDI của chúng, là ASCII thuận tiện. Dòng thứ ba viết ra các lệnh MIDI để phát các ghi chú đó, với thời lượng được tính toán tự động (mỗi ghi chú là một bán nguyệt trừ khi tôi% 14 == 0). Hợp âm cuối cùng được xử lý như một trường hợp đặc biệt trên các dòng bốn và năm (vì điều đó đòi hỏi phải nhấn đồng thời nhiều phím) và dòng thứ sáu viết ra điểm cuối MIDI cuối cùng của điểm đánh dấu.


4

C, 248 228 210 198 193 191 byte

#define y(x)cos(.346*t*exp(x/17.))
d=1846,t;main(c){for(;t++<d*80;putchar(c=((t<d*64?y(("TTQRTTQRTHJLMOQRQQMOQQEFHJHFHEFHFFJHFFECECACEFHJFFJHJJLMHJLMOQRT"[t/d]-72)):y(12)+y(9)+y(5))+3)*42));}

Điều này tạo ra một chuỗi gồm 8 mẫu không dấu dự định được phát ở mức 8000 mẫu mỗi giây. Nếu bạn có thiết lập UNIX / Linux cũ hơn, bạn có thể chuyển hướng đầu ra /dev/audio. Trên một số bản phân phối Linux mới hơn, bạn có thể phải chuyển đầu ra sang trình phát dòng lệnh ALSAaplay


rất tuyệt vời. Giải pháp tuyệt vời!
Abel Tom

1

SmileBASIC, 115 byte

BGMPLAY"@305T65L16[A8F+G]2A{r}F#8>F#GABAGAF#GAG8BAG8F#EF#EDEF#GABG8BAB8<C#D{r}AA1:1[R1]4F#1:2[R1]4D1{r=>AB<C#DEF#G}

Sử dụng một nhạc cụ đẹp có giá trị thêm 4 byte :)


Nhạc cụ gì 305?
Pavel

SmileBASIC có tất cả các nhạc cụ MIDI nói chung, nhưng cũng có một loạt các nhạc cụ "bí mật" không có giấy tờ. Đây là một ví dụ về phiên bản phức tạp hơn nhiều của Canon của Pachelbel được chơi bằng nhạc cụ đó: dropbox.com/s/wfhr90tdkkji6qy/305.mp3?dl=0
12Me21

0

JavaScript (ES6) bằng WAV.js , 325 byte

w=new WAV();w.addProgression(btoa9‘¹9‘¹8€¹‘9‘¹‘y‘9‘y¸€x¸x€8¸€8¸888¸€x¸€8€xù€xù‘y9`.replace(/[CF]./g,'$&#').split(/(?=[A-G])/g).map((f=t=>n=>({note:n,time:t}))(15/65)));['D5','F5#','A5'].map(n=>w.addNote(f(48/13)(n),.3,[],1,1));new Audio(URL.createObjectURL(w.toBlob())).play()
<script src="https://cdn.rawgit.com/patrickroberts/3b065ab94ce5094baacf45ed23e2a16e/raw/9c367e292fbee8341e1019d0d5953a2234449882/wav.babel.js"></script>

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.