Сыграйте в канон Пахельбеля

29

В качестве аудио выведите следующую выдержку из канона Пахельбеля в D:

Канон Пачельбеля в D

правила

  • Может использоваться любой формат / кодировка, если кодек существовал до создания этой задачи
  • Можно использовать любой инструмент (настоящий инструмент, синтез MIDI и т. Д.)
  • Темп должен быть 65 ударов в минуту (как указано в нотах) - если вы не можете получить ровно 65 ударов в минуту, вы можете использовать любой темп в пределах (включительно) диапазона 64,75 - 65,25
  • Ноты в концертной подаче
  • Необходимо использовать настройку равного темперамента (в частности, 12-ET с A4 = 440 Гц)

Для справки приведем фрагмент кода, который будет воспроизводить отрывок:

Mego
источник
Будет ли этот фрагмент конкурентоспособным, поскольку он загружает его из других источников
Blue
4
@muddyfish Нет, потому что выборка из внешнего источника - это стандартная лазейка.
Мего
Будет ли приемлем вывод файла MIDI вместо аудио?
DJMcMayhem
@DJMcMayhem Да, MIDI-файлы приемлемы.
Мего
Я предполагаю, что окончательный (только) аккорд требуется полностью? Это эффективно запрещает неполифонические языки / API
Level River St

Ответы:

9

JavaScript (ES7), 249 242 241 байт

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)

Спасибо @Neil и @PatrickRoberts за некоторую экономию байтов!

объяснение

Обозначения упакованы в строку, где каждый символ представляет собой одну заметку в виде базовой цифры 36. Значения записных определяются по формуле , (19 - pitch) * time + 1где pitchесть число полутонов меньше , чем A5 и timeявляется 1для шестнадцатого или 20для дрожи. В 0конце останавливается forцикл.

Темп составляет 65,22 ударов в минуту. Правка: сейчас ровно 65 ударов в минуту, еще на 2 байта .

Это объяснение / демонстрация использует Math.powвместо **совместимости браузера. Он также устанавливает усиление осцилляторов .3так, чтобы финальный аккорд не заставлял ваши уши кровоточить (усиление по умолчанию - 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
      )

Вы можете нажать кнопку выше, чтобы протестировать ее в любом браузере, который поддерживает HTML5 Web Audio API .

user81655
источник
880*2**(-~-n%20/12)должен сэкономить вам несколько байтов.
Нил
@ Нейл Спасибо. Я подозреваю, что могу избавиться и от этого -~-, изменив формат упаковки заметок (+ 1 формула есть только потому, что мне нужно 0остановить forцикл, и мне было лень об этом много думать, прежде чем я отправлю сообщение).
user81655 26.12.16
Увидел это после того, как я опубликовал свой ответ, лол
Патрик Робертс
Вы можете сохранить другие байты, заменяя c=new AudioContext;с with(new AudioContext)и отвернув два вхождения c.в программе.
Патрик Робертс
1
@ kamoroso94 Нет. Экспонента может быть дробной, поэтому, если я использовал << его, он бы к целому числу.
user81655
8

Mathematica, 212 152 139 135 байтов

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

Выводит Soundобъект, который воспроизводит Canon Pachelbel в D при нажатии кнопки Play. Инструмент представляет собой MIDI-инструмент № 41 "Скрипка".

Аудио

Нажми на меня!

объяснение

LetterNumber@"uursuursuikmnprsrrnprrfgikigifgiggkiggfdfdbdfgikggkikkmnikmnprsu"

Найдите буквенные числа каждого символа в строке («a» -> 1, «b» -> 2 и т. Д.), Обернутые символом a List. (Эта строка представляет Канон Пахельбеля в D)

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

Установите sдля SoundNoteфункции, чей инструмент # 41. Установите длительность 1 и отобразите эту функцию на каждый элемент в List(таким образом создавая SoundNoteпримитивные объекты).

{14,18,21}~s~16

Сделайте последнюю триаду. (Продолжительность 16предназначена для того, чтобы сделать последнюю ноту в 16 раз длиннее - целая нота в шестнадцать раз больше шестнадцатой ноты.)

... ~Sound~18.5

Сделайте Soundобъект 18.5длиной в секунды (потому что темп составляет 65 ударов в минуту [5 тактов 4/4 с темпом 65 ударов в минуту = приблизительно 18,5 секунд]).

126-байтовая версия, не конкурирующая

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

Не конкурирует, потому что выходные данные содержат две шестнадцатые ноты вместо восьмой ноты, и разделение весьма заметно.

Юнг Хван Мин
источник
14
В самом деле, Mathematica не имеет встроенного для Canon Pachelbel's?
Стьюи Гриффин
1
@StewieGriffin Только все, вероятно, и стоимость отсечения будет слишком высокой.
Мего
@StewieGriffin Удивительно, но это не так.
JungHwan Мин
6

Bubblegum , 203 байта

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

Попробуйте онлайн!

Это hexdump (обратный с xxd -r) исходного кода. MIDI-файл, который он создает, выглядит следующим образом (также 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..`./.
Mego
источник
6

BBC BASIC, 141 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.

Пересмотрено с учетом ограничения по темпу. Обновлю объяснение позже.

BBC BASIC, 123 символа ASCII (неконкурирует как 60BPM)

Скачать переводчик можно по адресу http://www.bbcbasic.co.uk/bbcwin/download.html.

Воспроизведение песни непосредственно при запуске.

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.

Ungolfed

  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

объяснение

jфлаг, указывающий, находимся ли мы в первых 4 тактах или в финальном аккорде. ИСТИНА -1в BBC BASIC.

SOUNDОператор принимает 4 параметра:

КАНАЛ: для первых 4 тактов это канал 1. Для 3-х нот аккорда в 5-м такте номера каналов равны 201, 202 и 203 шестнадцатеричным (513,514 и 515 десятичных.) Это означает, что играть на каналах 1,2 и 3, начальное значение 2 означает одновременное воспроизведение 2 нот на других каналах (т. Е. Воспроизведение аккорда 3 нот).

ОБЪЕМ: Задано как отрицательное значение, потому что положительные значения представляют другие эффекты (звуковые огибающие.). Установите на -9 (будет до -15, что является самым громким.)

PITCH: для этой мелодии диапазон от D4 = 108 до A5 = 184. Каждый целочисленный шаг составляет 1/4 полутона. Значения сохраняются в виде кодов ASCII в диапазоне от 54 до 92 и дублируются для восстановления правильного значения. 1/8 примечания сохраняются как дубликаты 1/16 примечания. Финальный аккорд сохраняется в виде трех отдельных тонов, а длина ноты варьируется до всей ноты, как показано ниже.

ПРОДОЛЖИТЕЛЬНОСТЬ: в 1/20 секунды. Длительность 1/16 ноты составляет 5/20 секунды, поэтому 60 1/4 ноты в минуту (недостаточно разрешения, чтобы сделать темп более точным.) Вся нота составляет 5 - (- 75) = 80 единиц (4 секунды). ) длинная.

Уровень реки St
источник
Разве это не должно быть помечено как не конкурирующее?
JungHwan Мин
@JungHwanMin Чтобы ответить на оригинальный текст вашего комментария: BPM находится в пределах 10% от 65. Нет никаких ограничений в точности в вопросе. Вызов ОП.
Уровень Река St
60 ударов в минуту слышно отличается от 65 ударов в минуту. Я позволю этому быть неконкурентным, так как это ограничение наложено языком.
Мего
@Mego Сначала я думал, что BBC Basic по умолчанию считается в сотых долях секунды, я не понимал, что это грубая цифра в 20 долей секунды. Я изменил свой код до 100-х, так что теперь я могу делать 65.215BPM, это нормально? Потребовалось немного больше возиться, так как вся нота превышает 256/100, поэтому мне пришлось разыграть ее как две ноты. 50-е секунды были бы более коротким кодом, но 62.5BPM - не так уж и много улучшений.
Уровень Река St
Кстати, в оригинальном посте были незначительные ошибки транскрипции. Возможно, вам придется немного изменить свой код. (Текущий код имеет неправильную версию)
JungHwan Мин
4

Befunge, 242 байта

Мелодия записывается на стандартный вывод в формате файла MIDI. Вам нужно будет перенаправить этот вывод в файл .mid , чтобы воспроизвести отрывок.

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

Попробуйте онлайн! Хотя я не думаю, что в настоящее время возможно сохранить вывод таким образом, чтобы он сохранял двоичную целостность данных.

объяснение

Первая строка важна только для жестко закодированного MIDI-заголовка, который выводится в начале второй строки. Оставшаяся часть второй строки кодирует последовательность нот как их значения MIDI, которые обычно являются ASCII. В третьей строке записываются MIDI-команды для воспроизведения этих нот, причем длительность вычисляется автоматически (каждая нота является полуквалом, если только i% 14 == 0). Последний аккорд обрабатывается как особый случай в строках 4 и 5 (так как для этого требуется одновременное нажатие нескольких клавиш), а в шестой строке записывается окончательный маркер конца MIDI-трека.

Джеймс Холдернесс
источник
4

C 248 228 210 198 193 191 байт

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

В результате получается последовательность из 8-битных беззнаковых сэмплов, предназначенная для воспроизведения со скоростью 8000 сэмплов в секунду. Если у вас более старая установка UNIX / Linux, вы можете перенаправить вывод в/dev/audio . В некоторых новых дистрибутивах Linux вам может потребоваться передать вывод в проигрыватель командной строки ALSAaplay

ceilingcat
источник
так круто. Отличное решение!
Абель Том
1

SmileBASIC, 115 байт

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}

Использование хорошего инструмента стоило 4 дополнительных байта :)

12Me21
источник
Что за инструмент 305?
Павел
В SmileBASIC есть все основные MIDI-инструменты, но есть и «секретные» недокументированные инструменты. Вот пример гораздо более сложной версии Canon Пачелбеля,
12Me21
0

JavaScript (ES6) с использованием WAV.js , 325 байт

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>

Патрик Робертс
источник