Відтворити "Taps"


31

Сьогодні, 11 листопада 2015 року, у Сполучених Штатах - День ветеранів . " Taps " - це дзвінок на помилках, який грають на військових похоронах США:

( "Taps" на SoundCloud від vtmiller )

Це проста мелодія, довжиною всього двадцять чотири ноти та використання лише чотирьох різних нот. Ось ноти:

Ноти музики ( джерело )

Виклик

Напишіть програму або функцію, яка відтворює "Taps" або виводить аудіофайл "Taps" у будь-якому поширеному форматі аудіофайлів (наприклад, MP3, WAV, MIDI). Він може відтворюватися на будь-якій клавіші, використовуючи будь-який тип інструменту або звуковий сигнал, доступний для вашої мови. Наприклад, це може звучати як фортепіано замість багла. (Хоча слід використовувати лише один тип інструменту.)

Усі двадцять чотири ноти повинні бути відтворені з точним кроком, тривалістю та інтервалом. Хтось, хто знайомий з "Taps", повинен мати змогу запустити ваш код і легко розпізнати пісню, що відтворюється.

Тривалість мелодії (від початку першої ноти до кінця останньої ноти) повинна становити від 30 до 70 секунд. Можливо, ви можете мати до 5 секунд тиші, заповнивши початок та / або кінець звукового файлу, тому 80-секундний файл є найдовшим дозволеним.

Ви, звичайно, не можете просто завантажити пісню десь в Інтернеті або витягнути її з аудіобібліотеки, яка, як відомо, є зразком. Однак ви можете використовувати аудіобібліотеки, які можуть відтворювати / складати окремі ноти та створювати аудіофайли.

Оцінка балів

Це , тому найкоротша відповідь у байтах виграє. Однак для цього конкретного виклику я закликаю вас не зосереджуватись на кількості байтів, особливо за рахунок якості звуку. Гольфуйте свої матеріали, але дозвольте проявити творчість з вибором інструменту чи методологією виходу звуку. Цей виклик має на меті ставитись до вшанування ветеранів, а не до викривлення ледь впізнаваної версії "Taps".

Зауважте, що ви можете вставляти аудіофайли SoundCloud безпосередньо до публікацій , просто вставивши посилання в порожній рядок. Якщо у вас є обліковий запис SoundCloud, це був би чудовий спосіб поділитися результатами.


Я думаю, ЧакК.
The_Basset_Hound

4
Келвін, якщо ви не заперечуєте, я опублікую декілька гофрованих відповідей у ​​старих БАЗАХ і зроблю пожертву на ветеранську благодійність поза PPCG. Ви надихнули мене на це. До речі, у Великобританії у нас є неділя пам'яті, друга неділя листопада, що означає, що цього року вона була минулою неділею. Один з моїх ранніх спогадів - стоять біля пам’ятника, оточеного маками, де спостерігали 2 хвилини мовчання. Мені було близько 3. Коли я запитав у мами, чому ніхто не розмовляє, вона сказала мені бути спокійною.
Річка Рівня Св.

Чи є правила щодо довжини ферматів?
SirPython

@SirPython Я навіть не знав, що означає цей символ! Як повідомляє en.wikipedia.org/wiki/Fermata, "рівно, скільки часу він проходить, залежить від розсуду виконавця". Використання розсуду на виході не дуже відповідає кодегольфу, тому я грав його як написано. Я бачу, куди ти йдеш, хоча ... Подовження пунктирної другої ноти могло б стиснути пунктирну восьму ноту до шістнадцятої ноти, спростивши все. Але я думаю, що це обман :-)
Level River St

Відповіді:


4

qb64, 100 84 байт

Оновлена ​​версія старої Qbasic, яку можна завантажити за адресою http://www.qb64.net/

Підрахунок виключає пробіли, які не потрібні і лише там, щоб розділити дані на три ноти фрази для наочності.

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

Команди в рядку відтворення

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%

Історія гольфу:

Перший пост: 4/4 час до 4/2 разу, це означає, що у мене є цілі нотатки, але немає шістнадцятого.

Редагувати 1: Ключ змінено з C (діапазон GG) на F (діапазон CC). Тепер мені потрібно лише один раз здійснити зміну октави для високого С, яке відбувається лише один раз, а не всіх низьких G, як раніше.

Позбувшись усіх змін октави, я не думаю, що гольфу більше немає. Їх загалом 20 L, але очевидного способу їх уникнути немає.

Остання фраза (11 символів) така ж, як і перша, але немає можливості двічі вставити її під 11 символів. Повторних даних буде лише 9 символів, якби вихідні L4були усунені (Це видається непотрібним, оскільки довжина нотатки за замовчуванням здається чвертью нотатки, але вона не задокументована, тому я залишив її.)


9

JavaScript, 203 198 196 195 байт

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 байт збережено завдяки Dendrobium та 1 завдяки @PatrickRoberts.

Пояснення

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
      )

Перевірте це тут у браузері! Працює в будь-якому веб-переглядачі, що підтримує HTML5 Web Audio API .


1
-5 байт: c = новий AudioContext (); для (t = i = 0; n = "301093301396202346202346202396331699464390301093" [i ++];) з (c.createOscillator ()) i% 2? L = n / 2: (частота. значення = 392 + n * 44, підключити (c.destination), старт (t + .1), стоп (t + = l))
Dendrobium

Я б сказав, що тривалість (зміна 12 одиниць на 9) неточна; це ще гірше тим, що в пунктирній половині нот є фермати і насправді має бути 12 або довше .
lirtosiast

@ThomasKwa Так, це не ідеально, але вимога повинна бути легко впізнаваною, тому я б сказав, що це проходить. (Також слухайте трек SoundCloud у питанні. Перша пунктирна половина ноти рівно 10/16, тому, якщо ми підемо за цією версією, це досить близько!: P)
користувач81655

8

Математика, 361 287 285 байт

Я пішов на точність тут. Вихід точно такий, як описано в партитурі, зіграний з трубою. Ви можете знайти файл тут .

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

Дякуємо @ MartinBüttner за пропозиції щодо гольфу.


4
Посилання не дозволяє мені почути пісню. Здається, він видалений або не доступний для прослуховування через дозволи.
d0nut

2
Щоб бути додатковим педантичним, ви не брали участь у ферматах!
wchargin

"Тривалість мелодії повинна бути від 30 до 70 секунд." Це трохи коротко за 24 секунди.
Захоплення Кальвіна

4
@ Calvin'sHobbies Зачекайте ... Я все це роблю на рекомендованих 50 BPM ... Я звинувачую вас: |
LegionMammal978

1
%1, %2і %%насправді не зберігайте жодних байтів над x="E5"-> x(адже, бачачи, як часто ви їх використовуєте, ви насправді повинні економити досить багато, використовуючи змінні). Тоді ви можете зберегти тонни байтів, використовуючи EmitSount@Sound[SoundNote[#,5/#2,"Trumpet",SoundVolume->#3/17]&@@@{{%%,8,17},{%%,24,20},...}та зберігаючи найпоширенішу примітку в %. І в 24 ноти може бути коротше все-таки розділити плоский список:SoundNote[#,5/#2,"Trumpet",SoundVolume->#3/17&@@@{%%,8,17,%%,24,20,%2,2,23,...}~Partition~3
Мартін Ендер

5

Sonic Pi, 899 байт

Час трохи пройшов, але я думаю, що це нормально.

Легко гольф:

use_synth: клинок
use_synth_defaults підтримує: 0,70, реліз: 0,0
гра: G4, реліз: 0,05
зачекайте 0,75
гра: G4, підтримка: 0,25
чекати 0,25
утримувати = rrand_i (3,4)
грати: C5, підтримувати: утримувати, випускати: 0,5
очікування затримки + 0,5
гра: G4, реліз: 0,05
зачекайте 0,75
гра: C5, підтримка: 0,25
сон 0,25
утримувати = rrand_i (3,4)
грати: E5, підтримувати: утримувати, випускати: 1,25
затримка сну + 1,25
грати: G4
сон 0.70
гра: C5
сон 0.70
2.часи робити
  гра: E5, підтримка: 1, випуск: 0,25
  сон 1,25
  грати: G4
  сон 0,7
  гра: C5
  сон 0,7
кінець
hold = rrand_i (3,5)
грати: E5, підтримувати: утримувати, випускати: 0,75
затримка сну + 1
відтворення: C5, реліз: 0,05
сон 0,75
гра: E5, підтримка: 0,25
сон 0,25
гра: G5, підтримка: 2,45, реліз: 0,05
сон 2.5
гра: E5, підтримка: 1, випуск: 0,25
сон 1,25
гра: C5, підтримка: 1, реліз: 0,25
сон 1,25
hold = rrand_i (3,5)
грати: G4, підтримувати: утримувати, випускати: 0,5
затримка сну + 0,5
гра: G4, реліз: 0,05
сон 0,75
гра: G4, підтримка: 0,25
сон 0,25
hold = rrand_i (3,5)
грати: C5, підтримувати: утримувати, випускати: 1.5

Так, хтось із Sonic Pi!
Mega Man

Можливо, трохи перетягнути гольф, перейменувавши утримування на h, змінивши випуск: 0.0 на випуск: 0 та видаливши пробіли.
Mega Man

4

MATLAB, 338 327 262 258 230 байт

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 байти

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

Усі нотатки та таймінги є правильними. Я використовував трубу, тому що це найближча річ у MIDI

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


1

Powershell, 183 175 159 байт

Подорож у ностальгії, хто не любить звукових сигналів ?!

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


Пояснення (сортоф)

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


Це відбудеться приблизно за 45 секунд.

Це вперше я використовую Powershell Windows, будь-які поради щодо гольфу - це веломе.


Старі версії

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

Завантажте перекладача за посиланням http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

Оцінка виключає пробіли та нові рядки, які не є істотними та додаються для читабельності

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

Досить стандартне стиснення, 1 символ ASCII на ноту. Параметри таких SOUNDє:

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)

Діапазон пісні - 13 нот, хоча використовуються лише 4. Щоб перевести цей діапазон у діапазон 95 друкованих ASCII, мені довелося вичавити тривалість у цілий діапазон 7 і взяти його за модулем 7. Використовуються наступні тривалості (у шістнадцятих) (за винятком 6, які ніколи використано): 1,2,3,4,6,8,12. Для отримання цих чисел я потрапив на ідею ділити 12 на потужність sqrt(2)(приблизну 1.4) і обрізати.

Це SOUND1,0,1,1роздратування, вартість якого становить 12 байт. Необхідно передбачити паузу між нотами однакової висоти.


1

Ruby + звуковий сигнал, 178 байт

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

Мені довелося деякий час зробити це, я думаю, я пропустив човен, але що б там не було.

fвміщує чотири використовувані частоти. nмістить п'ять використаних довжин нот, кратних 16-й нотах.

a="00101...містить усі шаги нот, а потім усі довжини нот, як індекси у відповідних масивах. lПотім встановлюється до 24-го індексу і далі a. Тоді команда звукового сигналу будується шляхом ітерації через усе вищезазначене і виконується


0

C - (Raw: 318 | WAV: 437)

8-бітний (без підпису) моно PCM при 44800 Гц, 33,60 секунди.

Динаміка mezzo forte, fortissimo та forte дещо художньо реалізована. Фермати могли бути кращими.

Код покладається на unsigned long long8 октетів і на систему мало ендіан.

#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

Компілюйте та запустіть щось подібне:

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

Додати -DRAWдо рядка-компілятора для необробленого варіанту.

Сирий вихід може програватися, наприклад, SoX playяк:

play -c 1 -b 8 -r 44800 -t u8 <file>
       |    |       |       |
       |    |       |       +--- Unsigned 8-bit
       |    |       +----------- Sample rate
       |    +------------------- 8 Bits
       +------------------------ 1 Channel
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.