Spielen Sie "Taps"

31

Heute, am 11. November 2015, ist Veterans Day in den Vereinigten Staaten. " Taps " ist das Signalhorn, das bei US-Militärbestattungen gespielt wird:

( "Taps" auf SoundCloud von vtmiller )

Es ist eine einfache Melodie, die nur vierundzwanzig Noten lang ist und nur vier verschiedene Noten verwendet. Hier ist das Notenblatt:

Taps Noten ( Quelle )

Herausforderung

Schreiben Sie ein Programm oder eine Funktion, die "Taps" abspielt oder eine Audiodatei von "Taps" in einem beliebigen gängigen Audiodateiformat (z. B. MP3, WAV, MIDI) ausgibt. Es kann in jeder Tonart gespielt werden, mit jeder Art von Instrument oder Piepton, die für Ihre Sprache verfügbar sind. Zum Beispiel klingt es wie ein Klavier anstelle eines Signalhorns. (Es sollte jedoch immer nur ein Instrumententyp verwendet werden.)

Alle vierundzwanzig Noten müssen mit genauer Tonhöhe, Dauer und Abstand gespielt werden. Jemand, der mit "Taps" vertraut ist, sollte in der Lage sein, Ihren Code auszuführen und das gespielte Lied leicht zu erkennen.

Die Dauer der Melodie (vom Anfang der ersten bis zum Ende der letzten Note) muss zwischen 30 und 70 Sekunden liegen. Optional können Sie den Anfang und / oder das Ende Ihrer Audiodatei mit einer Pause von bis zu 5 Sekunden füllen, sodass eine 80-Sekunden-Datei die längste zulässige Zeit ist.

Natürlich können Sie den Song nicht einfach irgendwo online herunterladen oder aus einer Audiobibliothek extrahieren, die ihn zufällig als Sample enthält. Sie können jedoch Audiobibliotheken verwenden, mit denen Sie einzelne Noten abspielen / komponieren und Audiodateien erstellen können.

Wertung

Das ist , also gewinnt die kürzeste Antwort in Bytes. Für diese besondere Herausforderung empfehle ich Ihnen jedoch, sich nicht auf Ihre Byteanzahl zu konzentrieren, insbesondere auf Kosten der Klangqualität. Spielen Sie mit Ihren Einsendungen, aber lassen Sie sich bei der Wahl Ihres Instruments oder der Klangausgabemethode kreativ ein. Bei dieser Herausforderung geht es darum, Veteranen zu ehren, und nicht darum, eine kaum wiedererkennbare Version von "Taps" herauszuholen.

Beachten Sie, dass Sie SoundCloud- Audiodateien direkt in Posts einbetten können, indem Sie den Link einfach in eine leere Zeile einfügen. Wenn Sie einen SoundCloud-Account haben, ist dies eine großartige Möglichkeit, Ihre Ausgabe zu teilen.

Calvins Hobbys
quelle
Ich denke ChucK.
The_Basset_Hound
4
Calvin, wenn es Ihnen nichts ausmacht, werde ich ein paar Golf-Antworten in alten BASICs veröffentlichen und eine Spende an eine Veteranen-Wohltätigkeitsorganisation außerhalb von PPCG leisten. Sie haben mich dazu inspiriert. Übrigens haben wir in Großbritannien den Remembrance Sunday, den zweiten Sonntag im November, was bedeutet, dass es in diesem Jahr der letzte Sonntag war. Eine meiner frühesten Erinnerungen ist das Stehen an einem von Mohnblumen umgebenen Denkmal, in dem 2 Minuten Stille beobachtet wurden. Ich war ungefähr 3. Als ich meine Mutter fragte, warum niemand rede, sagte sie mir, ich solle ruhig sein.
Level River St
Gibt es Regeln für die Länge der Fermaten?
SirPython
@ SirPython Ich wusste nicht einmal, was dieses Symbol bedeutet! Laut en.wikipedia.org/wiki/Fermata "Wie lange es genau gehalten wird, liegt im Ermessen des Darstellers." Die Verwendung von Diskretion in der Ausgabe passt nicht wirklich zum Codegolf, also habe ich es so gespielt, wie es geschrieben steht. Ich verstehe, wohin Sie gehen ... Wenn Sie die gepunktete zweite Note verlängern, wird die gepunktete Achtelnote möglicherweise auf eine Sechzehntelnote komprimiert, was die Sache einfacher macht. Aber ich denke, das ist Betrug :-)
Level River St

Antworten:

4

qb64, 100 84 bytes

Aktualisierte Version des alten Qbasic, herunterladbar unter http://www.qb64.net/

Count schließt die Leerzeichen aus, die nicht erforderlich sind und nur dazu dienen, die Daten der Übersichtlichkeit halber in Dreiteilungen aufzuteilen.

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

Befehle in der Abspielzeichenfolge

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%

Golfgeschichte:

Erster Beitrag: 4/4-mal bis 4/2-mal, dh ich habe ganze Noten, aber keine Sechzehntelnoten.

Edit 1: Schlüssel geändert von C (Bereich GG) zu F (Bereich CC). Jetzt muss ich nur noch einmal eine Oktave wechseln, für das hohe C, das nur einmal vorkommt, und nicht mehr wie bisher für alle niedrigen Gs.

Nachdem ich all diese Oktavenwechsel beseitigt habe, glaube ich nicht, dass es mehr zum Golfen gibt. Es gibt insgesamt 20er Jahre L, aber es gibt keinen offensichtlichen Weg, sie zu vermeiden.

Der letzte Satz (11 Zeichen) ist derselbe wie der erste, aber es gibt keine Möglichkeit, ihn zweimal in weniger als 11 Zeichen einzufügen. Die wiederholten Daten wären nur 9 Zeichen, wenn die Initiale weggelassen würde L4.

Level River St
quelle
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 dank Dendrobium und 1 dank @PatrickRoberts eingespart.

Erläuterung

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
      )

Teste es hier im Browser! Funktioniert mit jedem Browser, der die HTML5-Web-Audio-API unterstützt .

user81655
quelle
1
-5 Bytes: c = neuer AudioContext (); für (t = i = 0; n = "301093301396202346202346202396331699464390301093" [i ++];) mit (c.createOscillator ()) i% 2? L = n / 2: (Frequenz. value = 392 + n * 44, connect (c.destination), start (t + .1), stop (t + = l))
Dendrobium
Ich würde sagen, die Dauer (von 12 auf 9 Einheiten) ist ungenau. es wird durch die Tatsache verschlimmert, dass die gepunkteten Halbtöne Fermaten aufweisen und eigentlich 12 oder länger sein sollten .
Lirtosiast
@ThomasKwa Ja, es ist nicht perfekt, aber die Anforderung ist, leicht erkennbar zu sein, also würde ich sagen, dass es vorbei ist. (Hören Sie sich auch die SoundCloud-Spur in der Frage an. Die erste gepunktete halbe Note ist genau 10/16. Wenn wir uns also an diese Version halten, ist es ziemlich nahe!: P)
user81655
8

Mathematica, 361 287 285 Bytes

Ich habe mich hier um Genauigkeit bemüht. Die Ausgabe erfolgt genau wie in der Partitur beschrieben, mit der Trompete gespielt. Die Datei finden Sie hier .

"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]

Vielen Dank an @ MartinBüttner für die Golfvorschläge.

LegionMammal978
quelle
4
Link erlaubt mir nicht, das Lied zu hören. Es scheint entweder entfernt oder aufgrund von Berechtigungen nicht zum Abhören verfügbar zu sein.
Donnerstag,
2
Um besonders pedantisch zu sein, haben Sie die Fermaten nicht berücksichtigt!
wchargin
"Die Dauer der Melodie muss zwischen 30 und 70 Sekunden liegen." Dies ist mit 24 Sekunden etwas kurz.
Calvins Hobbys
4
@ Calvin'sHobbies Warten Sie ... Ich mache das alles mit den empfohlenen 50 BPM ... Ich beschuldige Sie: |
LegionMammal978
1
%1, %2und %%speichere eigentlich keine Bytes über x="E5"-> x(in der Tat, wenn man sieht, wie oft man sie benutzt, sollte man durch die Verwendung von Variablen ziemlich viel sparen). Dann können Sie Tonnen von Bytes sparen, EmitSount@Sound[SoundNote[#,5/#2,"Trumpet",SoundVolume->#3/17]&@@@{{%%,8,17},{%%,24,20},...}indem Sie die am häufigsten verwendete Notiz verwenden und in speichern %. Und bei 24 Noten könnte es noch kürzer sein, eine flache Liste zu partitionieren:SoundNote[#,5/#2,"Trumpet",SoundVolume->#3/17&@@@{%%,8,17,%%,24,20,%2,2,23,...}~Partition~3
Martin Ender
5

Sonic Pi, 899 Bytes

Das Timing ist ein wenig verschoben, aber ich denke, es ist in Ordnung.

Leicht golfen:

use_synth: Blade
use_synth_defaults sustain: 0.70, release: 0.0
Spielen: G4, Release: 0,05
warte 0,75
Spiel: G4, Sustain: 0,25
warte 0.25
hold = rrand_i (3,4)
Spiel: C5, Sustain: Hold, Release: 0.5
warte halten + 0.5
Spielen: G4, Release: 0,05
warte 0,75
Spiel: C5, Sustain: 0,25
Schlaf 0,25
hold = rrand_i (3,4)
Spiel: E5, Sustain: Hold, Release: 1.25
Schlaf halten + 1,25
spielen: G4
Schlaf 0,70
spielen: C5
Schlaf 0,70
2 mal tun
  Spiel: E5, Sustain: 1, Release: 0,25
  Schlaf 1,25
  spielen: G4
  Schlaf 0,7
  spielen: C5
  Schlaf 0,7
Ende
hold = rrand_i (3,5)
Spielen: E5, Halten: Halten, Loslassen: 0,75
Schlaf halten + 1
Spiel: C5, Release: 0.05
Schlaf 0,75
Spiel: E5, Sustain: 0,25
Schlaf 0,25
Spiel: G5, Sustain: 2,45, Release: 0,05
Schlaf 2.5
Spiel: E5, Sustain: 1, Release: 0,25
Schlaf 1,25
Spiel: C5, Sustain: 1, Release: 0,25
Schlaf 1,25
hold = rrand_i (3,5)
Spiel: G4, Sustain: Hold, Release: 0.5
Schlaf halten + 0,5
Spielen: G4, Release: 0,05
Schlaf 0,75
Spiel: G4, Sustain: 0,25
Schlaf 0,25
hold = rrand_i (3,5)
Spielen: C5, Halten: Halten, Loslassen: 1.5
ashooby
quelle
Ja, jemand, der Sonic Pi verwendet!
Mega Man
Könnte durch Umbenennen von Hold mit h, Ändern von Release: 0.0 auf Release: 0 und Entfernen der Leerzeichen leicht golfen werden.
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)])
costrom
quelle
2

SmileBASIC, 73 Bytes

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

Alle Notizen und Timings sind korrekt. Ich habe eine Trompete benutzt, weil sie MIDI am nächsten kommt

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

12Me21
quelle
1

Powershell, 183 175 159 Bytes

Nostalgie-Trip, wer mag keine Pieptöne ?!

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


Erklärung (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
    )
}


Dies wird in ca. 45 Sekunden abgespielt.

Ich benutze Windows Powershell zum ersten Mal. Tipps zum Golfen sind willkommen.


alte Versionen

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)}
Bassdrop Cumberwubwubwub
quelle
1

BBC Basic, 111

Laden Sie den Interpreter unter http://www.bbcbasic.co.uk/bbcwin/bbcwin.html herunter

Punktzahl schließt Leerzeichen und Zeilenumbrüche aus, die für die Lesbarkeit nicht unbedingt erforderlich sind

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

Ziemlich normale Komprimierung, 1 ASCII-Zeichen pro Note. Parameter von SOUNDsind wie folgt:

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)

Die Reichweite des Songs beträgt 13 Noten, obwohl nur 4 verwendet werden. Um diesen Bereich in den 95-Zahlen-Bereich von druckbarem ASCII zu bringen, musste ich die Dauer in einen ganzzahligen Bereich von 7 drücken und modulo 7 nehmen. Die folgenden Dauern (in Sechzehnteln) werden verwendet (mit Ausnahme von 6, die niemals sind) gebraucht): 1,2,3,4,6,8,12. Um diese Zahlen zu erhalten, bin ich auf die Idee gekommen, 12 durch eine Potenz von sqrt(2)(angenähert durch 1,4) zu teilen und abzuschneiden.

Das SOUND1,0,1,1ist ärgerlich und kostet 12 Bytes. Zwischen Noten gleicher Tonhöhe muss eine Pause eingelegt werden.

Level River St
quelle
1

Ruby + Piepton, 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"}`

Ich habe eine Weile gebraucht, um das zu machen, ich glaube, ich habe das Boot verpasst, aber was auch immer.

fhält die vier verwendeten Frequenzen. nEnthält die fünf verwendeten Notenlängen in Vielfachen von 16.

a="00101...Enthält alle Tonhöhen, gefolgt von allen Notenlängen, als Indexe in die jeweiligen Arrays. lwird dann auf den 24. Index und weiter von gesetzta . Dann wird ein Signaltonbefehl erstellt, indem alle oben genannten Schritte wiederholt und ausgeführt werden

Shelvacu
quelle
0

C - (Roh: 318 | WAV: 437)

8-Bit-Mono-PCM (ohne Vorzeichen) bei 44800 Hz, 33,60 Sekunden.

Die Mezzoforte-, Fortissimo- und Fortedynamik sind etwas künstlerisch umgesetzt. Die Fermaten könnten besser sein.

Code basiert auf unsigned long long8 Oktetten und System 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

Kompiliere und starte mit etwas wie:

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

In -DRAWzu Kompilierung-line für rohe Variante.

Raw Output kann zB mit SoX abgespielt werden playals:

play -c 1 -b 8 -r 44800 -t u8 <file>
       |    |       |       |
       |    |       |       +--- Unsigned 8-bit
       |    |       +----------- Sample rate
       |    +------------------- 8 Bits
       +------------------------ 1 Channel
Runium
quelle