Zagraj w „Taps”

31

Dzisiaj, 11 listopada 2015 r., Jest Dzień Weteranów w Stanach Zjednoczonych. „ Taps ” to hejnał grany na amerykańskich pogrzebach wojskowych:

( „Taps” na SoundCloud z vtmiller )

Jest to prosta melodia, długa tylko na dwadzieścia cztery nuty i wykorzystująca tylko cztery różne nuty. Oto nuty:

Nuty Taps ( źródło )

Wyzwanie

Napisz program lub funkcję, która odtwarza „Taps” lub generuje plik audio „Taps” w dowolnym popularnym formacie pliku audio (np. MP3, WAV, MIDI). Można go odtwarzać dowolnym klawiszem, używając dowolnego rodzaju instrumentu lub sygnału dźwiękowego dostępnego w Twoim języku. Na przykład może to brzmieć jak fortepian zamiast trąbki. (Chociaż nadal należy stosować tylko jeden typ instrumentu.)

Wszystkie dwadzieścia cztery nuty muszą być odtwarzane z dokładną wysokością, czasem trwania i odstępami. Ktoś, kto zna „Taps”, powinien umieć uruchomić kod i łatwo rozpoznać odtwarzany utwór.

Czas trwania melodii (od początku pierwszej nuty do końca ostatniej nuty) musi wynosić od 30 do 70 sekund. Opcjonalnie możesz mieć do 5 sekund ciszy, wypełniając początek i / lub koniec pliku dźwiękowego, więc plik o długości 80 sekund jest najdłuższym dozwolonym.

Oczywiście nie możesz po prostu pobrać utworu w Internecie ani wyodrębnić go z biblioteki audio, która przypadkowo ma go jako próbkę. Możesz jednak korzystać z bibliotek audio, które mogą odtwarzać / komponować pojedyncze nuty i tworzyć pliki audio.

Punktacja

To jest , więc wygrywa najkrótsza odpowiedź w bajtach. Jednak w przypadku tego konkretnego wyzwania zachęcam do nie koncentrowania się na liczbie bajtów, szczególnie kosztem jakości dźwięku. Przeanalizuj swoje zgłoszenia, ale pozwól sobie na kreatywność w wyborze instrumentów lub metodologii wyjścia dźwięku. Wyzwanie to ma na celu uhonorowanie weteranów, a nie wykrzyczenie ledwo rozpoznawalnej wersji „Taps”.

Pamiętaj, że możesz osadzić pliki audio SoundCloud bezpośrednio w postach , wklejając link w pustym wierszu. Jeśli masz konto SoundCloud, byłby to świetny sposób na udostępnienie swoich wyników.

Hobby Calvina
źródło
Myślę, że ChucK.
The_Basset_Hound
4
Calvin, jeśli nie masz nic przeciwko, opublikuję kilka golfowych odpowiedzi w starych językach BASIC i przekażę darowiznę na rzecz organizacji charytatywnej Veterans poza PPCG. Zainspirowałeś mnie do tego. BTW w Wielkiej Brytanii mamy niedzielę Pamięci, drugą niedzielę listopada, co oznacza, że ​​w tym roku była ostatnia niedziela. Jednym z moich najwcześniejszych wspomnień jest pomnik otoczony makami, w którym zachowano 2 minuty ciszy. Miałem około 3 lat. Kiedy zapytałem mamę, dlaczego nikt nie mówi, powiedziała mi, żebym milczał.
Level River St
Czy istnieją jakieś zasady dotyczące długości fermat?
SirPython
@ SirPython Nawet nie wiedziałem, co znaczy ten symbol! Według en.wikipedia.org/wiki/Fermata „Dokładnie, jak długo dłużej będzie on trzymany, zależy od uznania wykonawcy”. Użycie dyskrecji na wyjściu tak naprawdę nie pasuje do codegolfa, więc grałem go tak, jak napisano. Widzę jednak, dokąd zmierzasz ... Wydłużenie kropkowanej drugiej nuty może skompresować kropkowaną ósmą nutę do szesnastej nuty, co upraszcza sprawę. Ale myślę, że to oszustwo :-)
Level River St

Odpowiedzi:

4

qb64, 100 84 bajtów

Zaktualizowana wersja starego Qbasic, do pobrania pod adresem http://www.qb64.net/

Funkcja Count wyklucza spacje, które nie są wymagane, i tylko w celu podzielenia danych na trzynotowe frazy dla zachowania przejrzystości.

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

Polecenia w łańcuchu odtwarzania

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 golfa:

Pierwszy post: od 4/4 do 4/2, co oznacza, że ​​mam kilka całych nut, ale nie mam szesnastych nut.

Edycja 1: Zmieniono klucz z C (zakres GG) na F (zakres CC). Teraz muszę tylko raz zmienić oktawę, dla wysokiego C, które występuje tylko raz, zamiast wszystkich niskich G jak poprzednio.

Po wyeliminowaniu wszystkich tych zmian oktaw, nie sądzę, aby było więcej do golfa. Istnieje w sumie 20 L, ale nie ma oczywistego sposobu na ich uniknięcie.

Ostatnia fraza (11 znaków) jest taka sama jak pierwsza, ale nie ma możliwości dwukrotnego wstawienia jej poniżej 11 znaków. Powtarzane dane miałyby tylko 9 znaków, gdyby inicjał L4został wyeliminowany (Wydaje się to niepotrzebne, ponieważ domyślna długość nuty wydaje się ćwierćnuta, ale nie jest udokumentowana, więc zostawiłem ją.)

Level River St
źródło
9

JavaScript, 203 198 196 195 bajtów

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 bajtów zapisanych dzięki Dendrobium i 1 dzięki @PatrickRoberts.

Wyjaśnienie

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
      )

Przetestuj to tutaj w przeglądarce! Działa w każdej przeglądarce obsługującej HTML5 Web Audio API .

użytkownik 81655
źródło
1
-5 bajtów: c = nowy AudioContext (); dla (t = i = 0; n = "301093301396202346202346202396331699464390301093" [i ++];) z (c.createOscillator ()) i% 2? L = n / 2: (częstotliwość. wartość = 392 + n * 44, podłącz (c. cel), start (t + .1), stop (t + = l))
Dendrobium
Powiedziałbym, że czas trwania (zmiana 12 jednostek na 9) jest niedokładny; pogarsza to fakt, że kropkowane półnuty mają fermaty i naprawdę powinny mieć 12 lub więcej .
lirtosiast
@ThomasKwa Tak, to nie jest idealne, ale wymaganie jest łatwe do rozpoznania, więc powiedziałbym, że mija. (Posłuchaj także ścieżki SoundCloud w pytaniu, pierwsza kropkowana półnuta ma dokładnie 10 / 16ths, więc jeśli przechodzimy przez tę wersję, jest dość blisko!: P)
user81655
8

Mathematica, 361 287 285 bajtów

Poszedłem tutaj po dokładność. Wyjście jest dokładnie takie, jak opisano w partyturze, granej na trąbce. Plik można znaleźć tutaj .

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

Dzięki @ MartinBüttner za sugestie dotyczące gry w golfa.

LegionMammal978
źródło
4
Link nie pozwala mi usłyszeć piosenki. Wygląda na to, że został usunięty lub nie jest dostępny do słuchania z powodu uprawnień.
d0nut
2
Żeby być wyjątkowo pedantycznym, nie uwzględniłeś fermy!
wchargin
„Czas trwania melodii musi wynosić od 30 do 70 sekund.” To trochę za krótko na 24 sekundy.
Calvin's Hobbies,
4
@ Calvin'sHobbies Czekaj ... Robię to wszystko przy zalecanych 50 BPM ... Obwiniam cię: |
LegionMammal978,
1
%1, %2i %%tak naprawdę nie zapisuj żadnych bajtów ponad x="E5"- x(w rzeczywistości, biorąc pod uwagę, jak często ich używasz, powinieneś sporo zaoszczędzić, używając zmiennych). Następnie możesz zaoszczędzić mnóstwo bajtów, używając EmitSount@Sound[SoundNote[#,5/#2,"Trumpet",SoundVolume->#3/17]&@@@{{%%,8,17},{%%,24,20},...}i przechowując najczęściej używaną notatkę w %. Przy 24 notatkach dzielenie płaskiej listy może być jeszcze krótsze:SoundNote[#,5/#2,"Trumpet",SoundVolume->#3/17&@@@{%%,8,17,%%,24,20,%2,2,23,...}~Partition~3
Martin Ender
5

Sonic Pi, 899 bajtów

Czas jest trochę opóźniony, ale myślę, że jest w porządku.

Lekko golfa:

use_synth: blade
use_synth_defaults sustain: 0.70, wydanie: 0.0
zagraj: G4, wydanie: 0,05
poczekaj 0,75
zagraj: G4, podtrzymaj: 0,25
poczekaj 0,25
przytrzymaj = rrand_i (3,4)
zagraj: C5, podtrzymaj: przytrzymaj, zwolnij: 0,5
poczekaj przytrzymaj + 0,5
zagraj: G4, wydanie: 0,05
poczekaj 0,75
zagraj: C5, podtrzymaj: 0,25
spać 0,25
przytrzymaj = rrand_i (3,4)
zagraj: E5, podtrzymaj: przytrzymaj, zwolnij: 1.25
wstrzymanie snu + 1,25
zagraj: G4
spać 0,70
grać: C5
spać 0,70
2. razy
  zagraj: E5, podtrzymaj: 1, zwolnij: 0,25
  spać 1,25
  zagraj: G4
  spać 0,7
  grać: C5
  spać 0,7
koniec
przytrzymaj = rrand_i (3,5)
zagraj: E5, podtrzymaj: przytrzymaj, zwolnij: 0,75
wstrzymanie snu + 1
zagraj: C5, wydanie: 0,05
spać 0,75
zagraj: E5, podtrzymaj: 0,25
spać 0,25
zagraj: G5, podtrzymanie: 2,45, wydanie: 0,05
spać 2.5
zagraj: E5, podtrzymaj: 1, zwolnij: 0,25
spać 1,25
zagraj: C5, podtrzymaj: 1, zwolnij: 0,25
spać 1,25
przytrzymaj = rrand_i (3,5)
zagraj: G4, podtrzymaj: przytrzymaj, zwolnij: 0,5
wstrzymanie snu + 0,5
zagraj: G4, wydanie: 0,05
spać 0,75
zagraj: G4, podtrzymaj: 0,25
spać 0,25
przytrzymaj = rrand_i (3,5)
zagraj: C5, podtrzymaj: przytrzymaj, zwolnij: 1.5
ashooby
źródło
Tak, ktoś używa Sonic Pi!
Mega Man
Można go nieco pograć w golfa poprzez zmianę nazwy blokady na h, zmianę zwolnienia: 0,0 na zwolnienie: 0 i usunięcie spacji.
Mega Man
4

MATLAB, 338 327 262 258 230 bajtów

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
źródło
2

SmileBASIC, 73 bajty

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

Wszystkie nuty i czasy są prawidłowe. Użyłem trąbki, ponieważ jest to najbliższa rzecz w MIDI

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

12Me21
źródło
1

PowerShell, 183 175 159 bajtów

Nostalgia trip, kto nie lubi dźwięków ?!

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


Objaśnienie (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
    )
}


Gra rozpocznie się za około 45 sekund.

Po raz pierwszy korzystam z Windows PowerShell, wszelkie wskazówki dotyczące gry w golfa są mile widziane.


Stare wersje

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
źródło
1

BBC Basic, 111

Pobierz tłumacza na http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

Wynik wyklucza białe znaki i znaki nowej linii, które nie są niezbędne i zostały dodane do czytelności

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

Dość standardowa kompresja, 1 znak ASCII na nutę. Parametry SOUNDsą następujące:

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)

Zakres utworu wynosi 13 nut, mimo że używane są tylko 4. Aby wprowadzić ten zakres do 95-liczbowego zakresu drukowalnego ASCII, musiałem ścisnąć czas trwania do zakresu liczb całkowitych 7 i przyjąć go modulo 7. Zastosowano następujące czasy trwania (w szesnastych) (z wyjątkiem 6, które nigdy nie jest używane): 1,2,3,4,6,8,12. Aby uzyskać te liczby, wpadłem na pomysł podzielenia 12 przez potęgę sqrt(2)(przybliżoną przez 1,4) i obcięcia.

SOUND1,0,1,1Jest kłopot, kosztuje 12 bajtów. Konieczne jest zapewnienie przerwy między nutami o identycznej wysokości.

Level River St
źródło
1

Rubin + dźwięk, 178 bajtów

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"}`

Chwilę mi to zajęło, myślę, że tęskniłem za łodzią, ale cokolwiek.

futrzymuje cztery używane częstotliwości. nzawiera pięć używanych długości nut w wielokrotności 16 nut.

a="00101...przechowuje wszystkie wysokości nut, a następnie wszystkie długości nut, jako indeksy do odpowiednich tablic. ljest następnie ustawiany na 24. wskaźnik i później a. Następnie konstruuje się sygnał dźwiękowy poprzez iterację wszystkich powyższych elementów i wykonuje się

Shelvacu
źródło
0

C - (Raw: 318 | WAV: 437)

8-bitowy (niepodpisany) mono PCM przy 44800 Hz, 33,60 sekundy.

Dynamika mezzo forte, fortissimo i forte została nieco artystycznie zaimplementowana. Fermaty mogłyby być lepsze.

Kod polega na tym, unsigned long longże ma 8 oktetów, a system jest małym endianem.

#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

Skompiluj i uruchom z czymś takim jak:

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

Dodaj -DRAWdo linii kompilacji dla surowego wariantu.

Surowe dane wyjściowe można odtwarzać np. W SoX playjako:

play -c 1 -b 8 -r 44800 -t u8 <file>
       |    |       |       |
       |    |       |       +--- Unsigned 8-bit
       |    |       +----------- Sample rate
       |    +------------------- 8 Bits
       +------------------------ 1 Channel
Runium
źródło