Juega un poco del Canon de Pachelbel


29

Imprima el siguiente extracto del Canon de Pachelbel en D como audio:

Canon de Pachelbel en D

Reglas

  • Se puede usar cualquier formato / codificación, siempre que exista un códec antes de la creación de este desafío
  • Se puede usar cualquier instrumento (un instrumento real, síntesis MIDI, etc.)
  • El tempo debe ser de 65 BPM (como se indica en la partitura): si no puede obtener exactamente 65 BPM, puede usar cualquier tempo dentro del rango (incluido) 64.75 - 65.25
  • La partitura está en concierto
  • Se debe usar la afinación de temperamento igual (específicamente 12-ET con A4 = 440 Hz)

Como referencia, aquí hay un fragmento de pila que reproducirá el extracto:


¿Sería competitivo ese fragmento ya que lo descarga desde otro lugar
Azul

44
@muddyfish No, porque recuperar la salida de una fuente externa es una laguna estándar.
Mego

¿Sería aceptable la salida de un archivo midi en lugar de audio?
DJMcMayhem

@DJMcMayhem Sí, los archivos MIDI son aceptables.
Mego

¿Supongo que el acorde final (solo) se requiere en su totalidad? Que efectivamente prohíbe los lenguajes / API no polifónicos
Level River St

Respuestas:


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)

¡Gracias a @Neil y @PatrickRoberts por algunos ahorros en bytes!

Explicación

La notación está empaquetada en la cadena donde cada carácter es una nota única como base de 36 dígitos. Los valores de las notas están determinados por la fórmula (19 - pitch) * time + 1donde pitches el número de semitonos menor que A5 y timees 1para un semiquaver o 20para un quaver. Al 0final se detiene el forbucle.

El tempo es 65.22bpm Editar: exactamente 65bpm ahora, para 2 bytes más .

Esta explicación / demostración se utiliza en Math.powlugar de **por compatibilidad del navegador. También establece la ganancia de los osciladores para .3que el acorde final no haga sangrar sus oídos (la ganancia predeterminada es 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
      )

Puede presionar el botón de arriba para probarlo en cualquier navegador que admita la API de audio web HTML5 .


880*2**(-~-n%20/12)debería ahorrarte unos pocos bytes.
Neil

@Neil Gracias. Sospecho que también puedo deshacerme de él -~-alterando el formato de mi paquete de notas ( + 1en la fórmula solo está allí porque necesito 0detener el forciclo y era demasiado vago para pensarlo mucho antes de publicar).
user81655

Vi esto después de que publiqué mi respuesta, lol
Patrick Roberts

Puede guardar otro byte mediante la sustitución c=new AudioContext;con with(new AudioContext)y la eliminación de las dos apariciones de c.en el programa.
Patrick Roberts

1
@ kamoroso94 No. El exponente puede ser una fracción, por lo que si lo usara <<, lo convertiría en un número entero.
user81655

8

Mathematica, 212 152 139 135 bytes

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

Emite un Soundobjeto que reproduce el Canon de Pachelbel en D cuando se presiona el botón Reproducir. El instrumento es el instrumento MIDI # 41 "Violín".

El audio

¡Haz click en mi!

Explicación

LetterNumber@"uursuursuikmnprsrrnprrfgikigifgiggkiggfdfdbdfgikggkikkmnikmnprsu"

Encuentre los números de letras de cada carácter en la cadena ("a" -> 1, "b" -> 2, etc.), envueltos con a List. (Esta cadena representa el Canon de Pachelbel en D)

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

Configurado spara SoundNotefuncionar cuyo instrumento es el # 41. Establezca la duración en 1 y asigne esa función a cada elemento en el List(haciendo SoundNoteobjetos primitivos).

{14,18,21}~s~16

Haz la última tríada. (La duración 16está ahí para hacer que la última nota sea 16 veces más larga; una nota completa es dieciseis veces una semicorchea)

... ~Sound~18.5

Haga un Soundobjeto, 18.5segundos de duración (porque el tempo es de 65 bpm [5 medidas de 4/4 con un tempo de 65 bpm = aproximadamente 18.5 segundos]).

Versión de 126 bytes, no competitiva

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

No compite porque la salida contiene dos semicorcheas en lugar de una octava nota, y la separación es bastante notable.


14
¿Realmente, Mathematica no tiene incorporado el Canon de Pachelbel?
Stewie Griffin

1
@StewieGriffin Probablemente solo todo, y el costo de recorte sería demasiado alto.
Mego

@StewieGriffin Sorprendentemente, no lo hace.
JungHwan Min

6

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

Pruébalo en línea!

Este es un hexdump (inverso con xxd -r) del código fuente. El archivo MIDI que produce es el siguiente (también un 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 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 el límite de tempo. Se actualizará la explicación más tarde.

BBC BASIC, 123 caracteres ASCII (sin competencia como 60BPM)

Descargue el intérprete en http://www.bbcbasic.co.uk/bbcwin/download.html

Reproduce la canción directamente cuando se ejecuta.

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.

Sin golf

  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

Explicación

jes una bandera que indica si estamos en los primeros 4 compases o en el acorde final. VERDADERO está -1en BBC BASIC.

La SOUNDdeclaración toma 4 parámetros:

CANAL: para las primeras 4 barras, este es el canal 1. Para las 3 notas del acorde en la quinta barra, los números de canal son 201, 202 y 203 hexadecimales (513,514 y 515 decimales). Esto significa tocar en los canales 1,2 y 3, los 2 iniciales significan reproducir simultáneamente con 2 notas en otros canales (es decir, tocar un acorde de 3 notas).

VOLUMEN: Dado como un valor negativo porque los valores positivos representan otros efectos (envolventes de sonido). Establezca en -9 (subirá a -15, que es el más alto).

PITCH: para esta melodía, varía de D4 = 108 a A5 = 184. Cada paso entero es 1/4 de un semitono. Los valores se almacenan como códigos ASCII en el rango de 54 a 92 y se duplican para regenerar el valor correcto. Las notas 1/8 se almacenan como notas 1/16 duplicadas. El acorde final se almacena como 3 tonos separados y la duración de la nota varía a la nota completa como se muestra a continuación.

DURACIÓN: en 1/20 de segundo. La duración de 1/16 de nota es 5/20 de segundo, por lo que 60 1/4 notas por minuto (no hay resolución suficiente para que el tempo sea más preciso). La nota completa es 5 - (- 75) = 80 unidades (4 segundos ) largo.


¿No debería ser etiquetado como no competidor, entonces?
JungHwan Min

@JungHwanMin Para responder el texto original de su comentario: BPM está dentro del 10% de 65. No hay límite en la precisión de la pregunta. La llamada de OP.
Level River St

60 bpm es audiblemente distinto de 65 bpm. Permitiré que esto no compita ya que es una restricción impuesta por el idioma.
Mego

@Mego Inicialmente pensé que BBC Basic contaba en centésimas de segundo por defecto, no me di cuenta de que era tan grosero como 20 segundos de segundo. He ajustado mi código a centésimas, así que ahora puedo hacer 65.215BPM, ¿está bien? Tomó un poco de violín extra ya que toda la nota supera los 256/100, así que tuve que tocarla como dos medias notas. Las centésimas de segundo serían un código más corto, pero 62.5 BPM no es una gran mejora.
Level River St

Por cierto, hubo algunos errores menores de transcripción en la publicación original. Es posible que deba cambiar su código un poco. (El código actual tiene la versión incorrecta)
JungHwan Min

4

Befunge, 242 bytes

La melodía se escribe en stdout en el formato de un archivo MIDI. Tendrá que redirigir esa salida a un archivo .mid para reproducir el extracto.

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

Pruébalo en línea! , aunque no creo que actualmente sea posible guardar la salida de tal manera que conserve la integridad binaria de los datos.

Explicación

La primera línea es esencial solo un encabezado MIDI codificado, que se emite al comienzo de la línea dos. El resto de la línea dos codifica la secuencia de notas como sus valores MIDI, que son convenientemente ASCII. La tercera línea escribe los comandos MIDI para tocar esas notas, y la duración se calcula automáticamente (cada nota es un semicuadro a menos que i% 14 == 0). El acorde final se maneja como un caso especial en las líneas cuatro y cinco (ya que eso requiere que se presionen varias teclas simultáneamente), y la sexta línea escribe el final MIDI final del marcador de pista.


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

Esto produce una secuencia de muestras sin signo de 8 bits destinadas a reproducirse a 8000 muestras por segundo. Si tiene una configuración UNIX / Linux anterior, puede redirigir la salida a /dev/audio. En algunas distribuciones de Linux más nuevas, es posible que deba canalizar la salida al reproductor de línea de comando ALSAaplay


tan genial. ¡Gran solución!
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 un buen instrumento valía 4 bytes adicionales :)


¿Qué es el instrumento 305?
Pavel

SmileBASIC tiene todos los instrumentos MIDI generales, pero también tiene un montón de instrumentos indocumentados "secretos". Aquí hay un ejemplo de una versión mucho más complicada del Canon de Pachelbel jugado con ese 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>

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.