Juega "Taps"


31

Hoy, 11 de noviembre de 2015, es el Día de los Veteranos en los Estados Unidos. " Taps " es la llamada de corneta que se toca en los funerales militares de los Estados Unidos:

( "Taps" en SoundCloud de vtmiller )

Es una melodía simple, solo tiene veinticuatro notas y usa solo cuatro notas diferentes. Aquí está la partitura:

Taps partituras ( fuente )

Reto

Escriba un programa o función que reproduzca "Taps" o genere un archivo de audio de "Taps" en cualquier formato de archivo de audio común (por ejemplo, MP3, WAV, MIDI). Puede reproducirse en cualquier tecla, utilizando cualquier tipo de instrumento o pitido disponible para su idioma. Por ejemplo, puede sonar como un piano en lugar de una corneta. (Aunque todavía solo debe usarse un tipo de instrumento).

Las veinticuatro notas se deben tocar con tono, duración y espaciado precisos. Alguien que esté familiarizado con "Taps" debería poder ejecutar su código y reconocer fácilmente la canción que se está reproduciendo.

La duración de la melodía (desde el comienzo de la primera nota hasta el final de la última nota) debe estar entre 30 y 70 segundos. Opcionalmente, puede tener hasta 5 segundos de silencio rellenando el inicio y / o el final de su archivo de sonido, por lo que un archivo de 80 segundos es el más largo permitido.

Por supuesto, no puede simplemente descargar la canción en línea en algún lugar o extraerla de una biblioteca de audio que la tenga como muestra. Sin embargo, puede usar bibliotecas de audio que puedan reproducir / componer notas individuales y crear archivos de audio.

Tanteo

Este es el , por lo que gana la respuesta más corta en bytes. Sin embargo, para este desafío en particular, le animo a que no se concentre en el recuento de bytes, especialmente a expensas de la calidad del sonido. Golf sus presentaciones pero permítase ser creativo con su elección de instrumento o metodología de salida de sonido. Este desafío está destinado a honrar a los veteranos, no a gritar una versión apenas reconocible de "Taps".

Tenga en cuenta que puede incrustar archivos de audio SoundCloud directamente en publicaciones simplemente pegando el enlace en una línea vacía. Si tiene una cuenta de SoundCloud, esta sería una excelente manera de compartir su salida.


Estoy pensando en ChucK.
The_Basset_Hound

44
Calvin, si no te importa, publicaré un par de respuestas de golf en viejos BASIC y haré una donación a una organización benéfica para veteranos fuera de PPCG. Me has inspirado para hacer eso. Por cierto, en el Reino Unido tenemos el Domingo de Recuerdo, el segundo domingo de noviembre, lo que significa que este año fue el domingo pasado. Uno de mis primeros recuerdos está de pie junto a un monumento rodeado de amapolas donde se observaron 2 minutos de silencio. Tenía unos 3 años. Cuando le pregunté a mi madre por qué nadie hablaba, me dijo que me callara.
Level River St

¿Hay alguna regla para la longitud de las fermatas?
SirPython

@SirPython ¡Ni siquiera sabía qué significaba ese símbolo! De acuerdo con en.wikipedia.org/wiki/Fermata "Exactamente cuánto tiempo se mantiene depende de la discreción del artista intérprete o ejecutante". Usar discreción en la salida realmente no encaja con codegolf, así que lo jugué tal como está escrito. Sin embargo, veo a dónde vas ... Alargar la segunda nota punteada podría comprimir la octava nota punteada hasta una decimosexta nota, simplificando las cosas. Pero creo que eso es trampa :-)
Level River St

Respuestas:


4

qb64, 100 84 bytes

Versión actualizada del antiguo Qbasic, descargable en http://www.qb64.net/

El recuento excluye los espacios, que no son obligatorios y solo están allí para dividir los datos en frases de tres notas para mayor claridad.

PLAY"T99L4C.L8CL1F. L4C.L8FL1A. L4CFL2A L4CFL2A L4CFL1A. L4F.L8AL1>C< L2AFL1C. L4C.L8CL1F."

Comandos en la cadena de reproducción

T99     set tempo to 99 quarter notes per minute (default is 120, only just too short)
CDEFGAB play notes in the current octave
><      up or down one octave
Lx      following notes are of note of 1/x duration
.       extend previous note duration by 50%

Historia del golf:

Primera publicación: 4/4 veces a 4/2 veces, lo que significa que tengo algunas notas completas, pero no dieciséis notas.

Edición 1: La clave cambió de C (rango GG) a F (rango CC). Ahora solo tengo que realizar un cambio de octava una vez, para la C alta, que solo ocurre una vez, en lugar de todas las G bajas como antes.

Después de deshacerme de todos esos cambios de octava, no creo que haya más golf. Hay un total de 20 L, pero no hay una forma obvia de evitarlos.

La última frase (11 caracteres) es la misma que la primera, pero no hay forma de insertarla dos veces en menos de 11 caracteres. Los datos repetidos serían de solo 9 caracteres si L4se eliminaran las iniciales (parece innecesario ya que la longitud de la nota predeterminada parece ser un cuarto de nota, pero no está documentada, así que la dejé).


9

JavaScript, 203 198 196 195 bytes

with(new AudioContext)for(t=i=0;n="301093301396202346202346202396331699464390301093"[i++];)with(createOscillator())i%2?l=n/2:(frequency.value=392+n*44,connect(destination),start(t+.1),stop(t+=l))

5 bytes guardados gracias a Dendrobium y 1 gracias a @PatrickRoberts.

Explicación

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=                        // n = note pitch (or temporarily length)

    // This string contains the values of each note alternating between length and pitch
    //     (l1, p1, l2, p2, etc...)
    // Length value is in 16th notes (1 = 1/16th note, 2 = 1/8th, etc...)
    //     The longer notes are limited to 9 but I think it still sounds OK
    // Pitch value 0 = G4, 3 = C5, 6 = E5, 9 = G5 (multiples of 3 saves 1 byte)
    "301093301396202346202346202396331699464390301093"

  [i++];)
    with(createOscillator())  // create the note oscillator
      i%2?                    // alternate between length and pitch characters
        l=n/2                 // l = length (stored for use in the next iteration)
                              // dividing it by 2 sets the speed to 60 beats per minute
                              //     and casts it to a number
      :(
        frequency.value=392   // base note = G5 (392hz)
          +n*44,              // there is (conveniently) roughly 132hz between each note
        connect(destination), // send the note's sound through the speakers
        start(t               // schedule the note to sound
          +.1),               // short delay to distinguish two notes of the same pitch
        stop(t+=l)            // schedule the end of the note and increment the time
      )

¡Pruébalo aquí en el navegador! Funciona en cualquier navegador que admita la API de audio web HTML5 .


1
-5 bytes: c = nuevo AudioContext (); para (t = i = 0; n = "301093301396202346202346202396331699464390301093" [i ++];) con (c.createOscillator ()) i% 2? L = n / 2: (frecuencia. valor = 392 + n * 44, conectar (c. destino), iniciar (t + .1), detener (t + = l))
Dendrobium

Yo diría que la duración (cambiar 12 unidades a 9) es imprecisa; empeora por el hecho de que las medias notas punteadas tienen fermatas y realmente deberían ser 12 o más .
lirtosiast

@ThomasKwa Sí, no es perfecto, pero el requisito es ser fácilmente reconocible, así que diría que pasa. (También escuche la pista de SoundCloud en la pregunta, la primera media nota punteada es exactamente 10/16, así que si vamos por esa versión, ¡está bastante cerca!: P)
user81655

8

Mathematica, 361 287 285 bytes

Fui por la precisión aquí. La salida es exactamente como se describe en la partitura, tocada con la trompeta. Puedes encontrar el archivo aquí .

"G"
e="E5";c="C5";EmitSound@Sound[SoundNote[#,5/#2,"Trumpet",SoundVolume->#3/17]&@@@{%,8,17,%,24,20,c,2,23,%,8,26,c,24,29,e,2,32,%,12,35,c,12,38,e,6,41,%,12,44,c,12,47,e,6,50,%,12,53,c,12,56,e,2,59,c,8,62,e,24,65,"G5",3,68,e,6,170/3,c,6,136/3,%,2,34,%,8,34,%,24,34,c,2,34}~Partition~3]

Gracias a @ MartinBüttner por las sugerencias de golf.


44
Link no me permite escuchar la canción. Parece que se eliminó o no está disponible para escuchar debido a los permisos.
d0nut

2
Para ser más pedante, ¡no tomaste en cuenta las fermatas!
wchargin

"La duración de la melodía debe ser entre 30 y 70 segundos". Esto es un poco corto a los 24 segundos.
Aficiones de Calvin

44
@ Calvin'sHobbies Espera ... Estoy haciendo todo esto a los 50 BPM recomendados ... Te culpo: |
LegionMammal978

1
%1, %2y %%no guarde ningún byte sobre x="E5"-> x(de hecho, al ver la frecuencia con la que los usa, debería ahorrar bastante usando variables). Luego puede guardar toneladas de bytes usando EmitSount@Sound[SoundNote[#,5/#2,"Trumpet",SoundVolume->#3/17]&@@@{{%%,8,17},{%%,24,20},...}y almacenando la nota más utilizada %. Y a las 24 notas, podría ser más corto aún dividir una lista plana:SoundNote[#,5/#2,"Trumpet",SoundVolume->#3/17&@@@{%%,8,17,%%,24,20,%2,2,23,...}~Partition~3
Martin Ender

5

Sonic Pi, 899 bytes

El tiempo está un poco apagado, pero creo que está bien.

Ligeramente golfizado:

use_synth: cuchilla
use_synth_defaults sustain: 0.70, lanzamiento: 0.0
jugar: G4, lanzamiento: 0.05
espera 0,75
jugar: G4, sostener: 0.25
espera 0.25
mantener = rrand_i (3,4)
reproducir: C5, sostener: mantener, liberar: 0.5
espera espera + 0.5
jugar: G4, lanzamiento: 0.05
espera 0,75
jugar: C5, sostener: 0.25
dormir 0.25
mantener = rrand_i (3,4)
reproducir: E5, sostener: mantener, liberar: 1.25
dormir espera + 1,25
jugar: G4
dormir 0,70
jugar: C5
dormir 0,70
2. veces hacer
  Reproducir: E5, sostener: 1, liberar: 0.25
  dormir 1.25
  jugar: G4
  dormir 0.7
  jugar: C5
  dormir 0.7
fin
mantener = rrand_i (3,5)
reproducir: E5, sostener: mantener, liberar: 0.75
dormir espera + 1
jugar: C5, lanzamiento: 0.05
dormir 0.75
jugar: E5, sostener: 0.25
dormir 0.25
jugar: G5, sostener: 2.45, lanzamiento: 0.05
dormir 2.5
Reproducir: E5, sostener: 1, liberar: 0.25
dormir 1.25
reproducir: C5, sostener: 1, liberar: 0.25
dormir 1.25
mantener = rrand_i (3,5)
reproducir: G4, sostener: mantener, liberar: 0.5
dormir espera + 0.5
jugar: G4, lanzamiento: 0.05
dormir 0.75
jugar: G4, sostener: 0.25
dormir 0.25
mantener = rrand_i (3,5)
reproducir: C5, sostener: mantener, liberar: 1.5

Sí, alguien usando Sonic Pi!
Mega Man

Podría jugarse un poco al cambiar el nombre de la retención con h, cambiar la versión: 0.0 a la versión: 0 y eliminar los espacios.
Mega Man

4

MATLAB, 338 327 262 258 230 bytes

o=@(L,f)sin(pi*.11*2^(f/12))*(1:600*L))
sound([o(3,-1) o(1,-1) o(12,2) o(3,-1) o(1,2) o(12,4) o(2,-1) o(2,2) o(4,4) o(2,-1) o(2,2) o(4,4) o(2,-1) o(2,2) o(12,4) o(3,2) o(1,4) o(8,6) o(4,4) o(4,2) o(12,-1) o(3,-1) o(1,-1) o(12,4)])

2

SmileBASIC, 73 bytes

BGMPLAY"@56T50L2.G8.G16B+G8.<C16E>[G8<C8E4>]2G8<C8EC8.E16G2E4C4>GG8.G16B+

Todas las notas y tiempos son correctos. Usé una trompeta porque es lo más parecido en MIDI

<audio autoplay controls src="//12me21.github.io/resources/taps.mp3"></audio>


1

Powershell, 183 175 159 bytes

Viaje de nostalgia, ¿a quién no le gustan los pitidos?

foreach($i in 0..23){[console]::beep((196,262,330,392)[(001012012012012123210001-split'')[$i]],(3,1,12,3,1,12,2,2,4,2,2,4,2,2,12,3,1,8,4,4,12,3,1,12)[$i]*400)}


Explicación (sortof)

foreach($i in 0..23) { # foreach loop which ranges from 0 to 23
    [console]::beep( # [console]::beep(Pitch, Duration)
        (196,262,330,392) # the notes in Hertz
            [ # select which note to use
                (001012012012012123210001-split'') # -split '' creates an array of [0,0,1,0,1 ...], spaces can be omitted
                [$i] # select the n-th element
            ],
        (3,1,12,3,1,12,2,2,4,2,2,4,2,2,12,3,1,8,4,4,12,3,1,12) # array of durations
        [$i]*400 # duration in milliseconds * 400
    )
}


Esto se reproducirá en unos 45 segundos.

Esta es la primera vez que uso el Powershell de Windows, cualquier consejo sobre el golf es bueno.


versiones antiguas

175

foreach($i in(0..23)){[console]::beep((196,262,330,392)[(0,0,1,0,1,2,0,1,2,0,1,2,0,1,2,1,2,3,2,1,0,0,0,1)[$i]],(3,1,12,3,1,12,2,2,4,2,2,4,2,2,12,3,1,8,4,4,12,3,1,12)[$i]*400)}

183

$d=3,1,12,3,1,12,2,2,4,2,2,4,2,2,12,3,1,8,4,4,12,3,1,12;$n=0,0,1,0,1,2,0,1,2,0,1,2,0,1,2,1,2,3,2,1,0,0,0,1;foreach($i in(0..23)){[console]::beep((196,262,330,392)[$n[$i]],$d[$i]*400)}

1

BBC Basic, 111

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

La puntuación excluye espacios en blanco y líneas nuevas, que no son esenciales y se agregan para facilitar la lectura

FORk=1TO24
  x=ASC(MID$("')F'Lb(Ke(Ke(KbJhxeI#')F",k))
  SOUND1,-9,x DIV7*4+60,INT(12/1.4^(x MOD7))*5
  SOUND1,0,1,1
NEXT

Compresión bastante estándar, 1 carácter ASCII por nota. Los parámetros de SOUNDson los siguientes:

Channel (always 1 for the purposes of this challenge)
Amplitude (negative for on, 0 for off, positive is an envelope index)
Pitch (in increments of 1/4 semitone, with middle C at 100)
Duration (20ths of a second)

El rango de la canción es de 13 notas, aunque solo se usan 4. Para obtener este rango en el rango de 95 números de ASCII imprimible, tuve que reducir la duración a un rango entero de 7 y tomar el módulo 7. Se usan las siguientes duraciones (en dieciseisavos) (con la excepción de 6, que nunca es utilizado): 1,2,3,4,6,8,12. Para producir estos números, me topé con la idea de dividir 12 por una potencia de sqrt(2)(aproximadamente 1,4) y truncar.

El SOUND1,0,1,1es una molestia, que cuesta 12 bytes. Es necesario proporcionar una pausa entre notas de tono idéntico.


1

Ruby + pitido, 178 bytes

f=[260,346,416,499]
n=[12,*1..4]
l=(a="001012012012012123210001310310224224220318440310".chars.map(&:to_i))[24..-1]
`beep#{24.times.map{|i|" -f#{f[a[i]]} -l#{n[l[i]]}00"}*" -n"}`

Me tomó un tiempo hacer esto, creo que perdí el bote, pero lo que sea.

fcontiene las cuatro frecuencias utilizadas. ncontiene las cinco longitudes de nota utilizadas, en múltiplos de notas 16.

a="00101...contiene todos los tonos de nota seguidos de todas las longitudes de nota, como índices en las matrices respectivas. lluego se establece en el índice 24 y en adelante a. Luego, se construye un comando de pitido iterando a través de todo lo anterior y se ejecuta


0

C - (Sin procesar: 318 | WAV: 437)

PCM mono de 8 bits (sin signo) a 44800 Hz, 33,60 segundos.

Las dinámicas mezzo forte, fortissimo y forte se implementan de manera artística. Las fermatas podrían ser mejores.

El código se basa en unsigned long longser 8 octetos y el sistema little endian.

#include<stdio.h>
#include<math.h>
#ifdef RAW
main(){unsigned long long D[]={0x422422c13c13,0xc13c44813c22},X[]={27863,37193,46860,55727},O=0x406e64924910,i=0,j;float Z,A,U=40,P;for(;i<24;D[i++/12]>>=4){Z=X[O&3]/1e6;P=0;O>>=2;A=i>18?--U:i<14?U+i/2:U+30;for(j=(D[i/12]&15)*13440;j;A-=--j<7e3&&A>0?.01:0)putchar(A*sin(P+=Z)+128);}}
#else
main(){unsigned long long D[]={0x422422c13c13,0xc13c44813c22},X[]={27863,37193,46860,55727},O=0x406e64924910,i=0,j;float Z,A,U=40,P;int W[]={0x46464952,1570852,0x45564157,544501094,16,65537,44800,44800,524289,0x61746164,1505280};fwrite(W,4,11,stdout);for(;i<24;D[i++/12]>>=4){Z=X[O&3]/1e6;P=0;O>>=2;A=i>18?--U:i<14?U+i/2:U+30;for(j=(D[i/12]&15)*13440;j;A-=--j<7e3&&A>0?.01:0)putchar(A*sin(P+=Z)+128);}}
#endif

Compila y ejecuta con algo como:

gcc -std=c99 -o taps taps.c -lm
./taps > taps.wav
play taps.wav

Agregar -DRAWa la línea de compilación para la variante sin procesar.

La salida sin formato se puede reproducir con, por ejemplo, SoX playcomo:

play -c 1 -b 8 -r 44800 -t u8 <file>
       |    |       |       |
       |    |       |       +--- Unsigned 8-bit
       |    |       +----------- Sample rate
       |    +------------------- 8 Bits
       +------------------------ 1 Channel
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.