Toque algumas das músicas de Pachelbel

29

Produza o seguinte trecho da Canon de Pachelbel em D como áudio:

Canon de Pachelbel em D

Regras

  • Qualquer formato / codificação pode ser usado, desde que exista um codec antes da criação deste desafio
  • Qualquer instrumento (um instrumento real, síntese MIDI, etc.) pode ser usado
  • O tempo deve ser de 65 BPM (como indicado na partitura) - se você não conseguir exatamente 65 BPM, poderá usar qualquer tempo dentro do intervalo (inclusive) de 64,75 - 65,25
  • As partituras estão em sintonia
  • É necessário usar o ajuste de temperamento igual (especificamente 12-ET com A4 = 440 Hz)

Para referência, aqui está um snippet de pilha que reproduzirá o trecho:

Mego
fonte
Esse trecho seria competitivo ao baixá-lo de outro lugar?
Blue
4
@muddyfish Não, porque buscar a saída de uma fonte externa é uma brecha padrão.
Mego
Seria aceitável emitir um arquivo midi em vez de áudio?
DJMcMayhem
@DJMcMayhem Sim, arquivos MIDI são aceitáveis.
Mego
Presumo que o acorde final (apenas) seja obrigatório na íntegra? Isso proíbe efetivamente linguagens não-polifônicas / APIs
Level River St

Respostas:

9

JavaScript (ES7), 249 242 241 bytes

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)

Obrigado a @Neil e @PatrickRoberts pela economia de bytes!

Explicação

A notação é compactada na sequência em que cada caractere é uma nota única como um dígito de base 36. Os valores das notas são determinados pela fórmula (19 - pitch) * time + 1onde pitché o número de semitons menor que A5 e timeé 1para um semiquaver ou 20para um quaver. O 0no final interrompe o forloop.

O tempo é 65.22bpm Edit: exatamente 65bpm agora, por mais 2 bytes .

Esta explicação / demonstração usa em Math.powvez de **compatibilidade com o navegador. Também define o ganho dos osciladores para .3que o acorde final não faça seus ouvidos sangrarem (o ganho padrão é 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
      )

Você pode pressionar o botão acima para testá-lo em qualquer navegador que suporte a API de áudio da Web HTML5 .

user81655
fonte
880*2**(-~-n%20/12)você deve economizar alguns bytes.
Neil
@ Neil Obrigado. Eu suspeito que posso me livrar disso -~-também, alterando o formato da embalagem de minhas anotações ( + 1a fórmula está lá apenas porque preciso 0interromper o forciclo e fiquei com preguiça de pensar muito sobre isso antes de postar).
user81655
Vi isso depois que eu postei minha resposta, lol
Patrick Roberts
Você pode salvar outro byte, substituindo c=new AudioContext;com with(new AudioContext)e remover as duas ocorrências de c.no programa.
Patrick Roberts
11
@ kamoroso94 Não. O expoente pode ser uma fração, portanto, se eu o usasse <<, o converteria em um número inteiro.
User81655
8

Mathematica, 212 152 139 139 135 bytes

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

Produz um Soundobjeto que reproduz a Canon de Pachelbel em D quando o botão Play é pressionado. O instrumento é o instrumento MIDI # 41 "Violin".

O áudio

Clique em mim!

Explicação

LetterNumber@"uursuursuikmnprsrrnprrfgikigifgiggkiggfdfdbdfgikggkikkmnikmnprsu"

Encontre os números das letras de cada caractere na sequência ("a" -> 1, "b" -> 2 e assim por diante), agrupada com a List. (Essa string representa o Canon de Pachelbel em D)

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

Defina spara a SoundNotefunção cujo instrumento é # 41. Defina a duração como 1 e mapeie essa função para cada elemento no List(criando SoundNoteobjetos primitivos).

{14,18,21}~s~16

Faça a última tríade. (A duração 16existe para tornar a última nota 16 vezes mais longa - uma nota inteira é dezesseis vezes uma décima sexta nota.)

... ~Sound~18.5

Faça um Soundobjeto com 18.5alguns segundos de duração (porque o tempo é de 65 bpm [5 compassos de 4/4 com tempo de 65 bpm = aproximadamente 18,5 segundos]).

Versão de 126 bytes, não concorrente

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

Não concorrente porque a saída contém duas semicolcheias em vez de uma colcheia e a separação é bastante perceptível.

JungHwan Min
fonte
14
Realmente, o Mathematica não tem um built-in para a Canon de Pachelbel?
Stewie Griffin
11
@ StewieGriffin Apenas a coisa toda provavelmente, e o custo de recorte seria muito alto.
Mego
@StewieGriffin Surpreendentemente, isso não acontece.
JungHwan Min
6

Chiclete , 203 bytes

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!..^...

Experimente online!

Este é um hexdump (reverso com xxd -r) do código fonte. O arquivo MIDI produzido é o seguinte (também um 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  ...@[email protected]_l.B
00000160: 000c 9040 5f6c 8040 000c 903e 5f6c 803e  ...@_l.@...>_l.>
00000170: 000c 9040 5f6c 8040 000c 9042 5f6c 8042  ...@[email protected]_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..`./.
Mego
fonte
6

BBC BASIC, 141 caracteres 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.

Revisado para acomodar o limite de andamento. Atualizará a explicação mais tarde.

BBC BASIC, 123 caracteres ASCII (não-concorrentes como 60BPM)

Faça o download do intérprete em http://www.bbcbasic.co.uk/bbcwin/download.html

Reproduz a música diretamente quando é executada.

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.

Ungolfed

  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

Explicação

jé uma bandeira indicando se estamos nas primeiras 4 barras ou no acorde final. TRUE está -1no BBC BASIC.

A SOUNDdeclaração usa 4 parâmetros:

CANAL: para as 4 primeiras barras, este é o canal 1. Para as 3 notas do acorde na 5ª barra, os números dos canais são 201, 202 e 203 hexadecimais (513.514 e 515 decimais.) Isso significa tocar nos canais 1,2 e 3, o significado 2 inicial toca simultaneamente com 2 notas em outros canais (ou seja, toca um acorde de 3 notas).

VOLUME: Dado como um valor negativo, porque valores positivos representam outros efeitos (envelopes sonoros.). Defina -9 (subirá para -15, mais alto.)

PASSO: Para esta música, varia de D4 = 108 a A5 = 184. Cada passo inteiro é 1/4 de um semitom. Os valores são armazenados como códigos ASCII no intervalo de 54 a 92 e dobrados para gerar novamente o valor correto. As notas 1/8 são armazenadas como notas 1/16 duplicadas. O acorde final é armazenado em 3 arremessos separados e o comprimento da nota varia para a nota inteira, como abaixo.

DURAÇÃO: em 1/20 de segundo. A duração da 1/16 da nota é 5/20 de segundo, portanto 60 1/4 da nota por minuto (a resolução é insuficiente para tornar o andamento mais preciso.) A nota inteira é 5 - (- 75) = 80 unidades (4 segundos ) grandes.

Level River St
fonte
Isso não deveria ser rotulado como não concorrente?
JungHwan Min
@JungHwanMin Para responder ao texto original do seu comentário: O BPM está dentro de 10% de 65. Não há limites na precisão da pergunta. Chamada do OP.
Level River St,
60 bpm é audivelmente diferente de 65 bpm. Permitirei que isso não concorra, pois é uma restrição imposta pelo idioma.
Mego
@Mego Inicialmente, pensei que a BBC Basic contasse 100 centésimos de segundo por padrão, não percebi que era tão grosseira quanto 20 segundos. Eu ajustei meu código para 100, então agora eu posso fazer 65.215BPM, tudo bem? Demorou um pouco mais de mexer, já que toda a nota excede 256/100, então eu tive que tocá-la como duas meias notas. 50 segundos de código seria mais curto, mas 62,5 BPM não é uma grande melhoria.
Level River St
A propósito, houve alguns pequenos erros de transcrição no post original. Pode ser necessário alterar um pouco o seu código. (O código atual tem a versão incorreta) #
7296 JungHwan Min
4

Anterior, 242 bytes

A música é gravada em stdout no formato de um arquivo MIDI. Você precisará redirecionar essa saída para um arquivo .mid para reproduzir o trecho.

<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*,,,

Experimente online! , embora eu ache que atualmente não é possível salvar a saída de forma a manter a integridade binária dos dados.

Explicação

A primeira linha é essencial apenas para um cabeçalho MIDI codificado, que é produzido no início da linha dois. O restante da linha dois codifica a sequência de notas como seus valores MIDI, que são convenientemente ASCII. A terceira linha grava os comandos MIDI para tocar essas notas, com a duração sendo calculada automaticamente (cada nota é um semiquaver, a menos que i% 14 == 0). O acorde final é tratado como um caso especial nas linhas quatro e cinco (já que isso exige que várias teclas sejam pressionadas simultaneamente), e a sexta linha escreve o marcador final final da faixa MIDI.

James Holderness
fonte
4

C, 248 228 210 198 193 191 bytes

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

Isso produz uma sequência de amostras não assinadas de 8 bits destinadas a serem reproduzidas a 8000 amostras por segundo. Se você tiver uma configuração mais antiga do UNIX / Linux, poderá redirecionar a saída para /dev/audio. Em algumas distribuições Linux mais recentes, pode ser necessário canalizar a saída para o player de linha de comando ALSAaplay

teto
fonte
tão maravilhoso. Ótima solução!
Abel Tom
1

SmileBASIC, 115 bytes

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}

Usar um bom instrumento valia 4 bytes extras :)

12Me21
fonte
O que é o instrumento 305?
Pavel
O SmileBASIC possui todos os instrumentos MIDI gerais, mas também possui vários instrumentos não documentados "secretos". Aqui está um exemplo de uma versão muito mais complicada da Canon de Pachelbel tocada usando esse instrumento: dropbox.com/s/wfhr90tdkkji6qy/305.mp3?dl=0
12Me21
0

JavaScript (ES6) usando WAV.js , 325 bytes

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>

Patrick Roberts
fonte