Сделайте вашу клавиатуру в клавиатуру

10

задача

Вы должны написать программу, которая при нажатии кнопки выводит различный звук для каждой клавиши.

Ключи, которые вы будете использовать:

1!2"34$5%6^78*9(0qQwWeErtTyYuiIoOpPasSdDfgGhHjJklLzZxcCvVbBnm

Примечания начинаются с, Cи каждая клавиша выше добавляет один полутон.

Позволяет сделать это немного легче для вас, хотя. Вы можете выбрать между 2 одинаковыми задачами,

1) Выводит другую ноту при нажатии клавиши, которая продолжается до нажатия другой клавиши. Эта программа работает бесконечно

2) Возьмите строку в качестве входных данных, которая содержит только символы выше, которые будут выводить каждую ноту ровно в течение 1 секунды (допускается изменение 0,05 секунды)

вход

  1. Нажатие клавиши
  2. Одна строка, содержащая только символы выше

Вывод

  1. Отдельная музыкальная нота, которая звучит до нажатия другой клавиши
  2. Серия заметок, каждая длиной 1 секунда

Ноты

Letter | Note
-------+-------
   1   |  C
   !   |  C#
   2   |  D
   "   |  D#
   3   |  E
   4   |  F
   $   |  F#
   5   |  G
   %   |  G#
   6   |  A
   ^   |  A#
   7   |  B
   8   |  C
   *   |  C#
   9   |  D
   (   |  D#
   0   |  E
   q   |  F
   Q   |  F#
   w   |  G
   W   |  G#
   e   |  A
   E   |  A#
   r   |  B
   t   |  C    <-- middle C
   T   |  C#
   y   |  D
   Y   |  D#
   u   |  E
   i   |  F
   I   |  F#
   o   |  G
   O   |  G#
   p   |  A
   P   |  A#
   a   |  B
   s   |  C
   S   |  C#
   d   |  D
   D   |  D#
   f   |  E
   g   |  F
   G   |  F#
   h   |  G
   H   |  G#
   j   |  A
   J   |  A#
   k   |  B
   l   |  C
   L   |  C#
   z   |  D
   Z   |  D#
   x   |  E
   c   |  F
   C   |  F#
   v   |  G
   V   |  G#
   b   |  A
   B   |  A#
   n   |  B
   m   |  C

правила

  • Вы можете выбирать между задачами, но, пожалуйста, укажите, какой из них в вашем ответе
  • Вам дается отклонение в задании 2 ± 0,05 секунды
  • Каждый символ вдоль увеличивает тон на 1 полутон.
  • Отдельные заметки показаны выше
  • Это поэтому выигрывает самый короткий код

Первоначально это было взято из здесь с Кэрд coinheringaahing в согласии

Джонатан Аллан
источник
Чтобы открыть это для языков, у которых нет аудиобиблиотек, я рекомендую третий выходной формат: WAV-файл, содержащий выходные данные варианта 2, записанные в stdout. Это позволило бы записи на любом языке, который может печатать двоичные данные.
Рэй

Ответы:

6

Python 3, 154 140 байт

from winsound import*
for i in input():Beep(int(65.406*2**('1!2"34$5%6^78*9(0qQwWeErtTyYuiIoOpPasSdDfgGhHjJklLzZxcCvVbBnm'.find(i)/12)),999)

Я выбрал второй тип задачи.

Цикл проходит через каждый символ и ищет индекс этого элемента в строке. Этот индекс представляет собой число полутонов вверх от низкого C ('1'). Расчет желаемой частоты производится по этой формуле .

PS Эта библиотека работает только в Windows.

-13 байт благодаря овс.

-1 байт благодаря Джонатану Аллану.

Кирилл Малышев
источник
1
Вы, вероятно, должны упомянуть, что это работает только на Windows.
полностью человек
1
Golfed до 141 байт:from winsound import* for i in input():Beep(int(65.406*2**('1!2"34$5%6^78*9(0qQwWeErtTyYuiIoOpPasSdDfgGhHjJklLzZxcCvVbBnm'.find(i)/12)),1000)
овс
Но вопрос, заданный для программы ....
Нил А.
0.05Допуск должен позволить вам использовать 999.
Джонатан Аллан
3

JavaScript (ES6), 247 или 230 байт

Решили опробовать оба варианта.

Сохранено несколько байтов, спасибо @darrylyeo за предложение with.
Спасибо @ Кирилл Малышев за указание на проблему с .search().

Вариант 1 - ввод с клавиатуры, 252 246 247 байт

_=>{c=new AudioContext;q=1;with(c.createOscillator())connect(c.destination),I.oninput=_=>(~(i='1!2"34$5%6^78*9(0qQwWeErtTyYuiIoOpPasSdDfgGhHjJklLzZxcCvVbBnm'.indexOf(I.value,I.value=""))&&(frequency.value=65.4*2**(i/12),q&&start(q=0)))}
<input id=I

Полагается на элемент ввода, получающий введенную букву вместо кодов символов. Фокус должен быть на поле ввода.

Вариант 2 - строковый ввод, 234 229 230 байтов

s=>{c=new AudioContext;with(c.createOscillator())connect(c.destination),[...s].map((c,i)=>frequency.setValueAtTime(65.4*2**('1!2"34$5%6^78*9(0qQwWeErtTyYuiIoOpPasSdDfgGhHjJklLzZxcCvVbBnm'.indexOf(c)/12),i)),start(),stop(s.length)}

Просто принимает строку в качестве параметра функции.

Комбинированный фрагмент

Я предлагаю убавить громкость при этом, это может быть громко. Чтобы остановить воспроизведение, сниппет требовал добавления o=внутри каждого with(c.createOscillator()).

f= // keyboard input
_=>{c=new AudioContext;q=1;with(o=c.createOscillator())connect(c.destination),I.oninput=_=>(~(i='1!2"34$5%6^78*9(0qQwWeErtTyYuiIoOpPasSdDfgGhHjJklLzZxcCvVbBnm'.indexOf(I.value,I.value=""))&&(frequency.value=65.4*2**(i/12),q&&start(q=0)))}

g= // string input
s=>{c=new AudioContext;with(o=c.createOscillator())connect(c.destination),[...s].map((c,i)=>frequency.setValueAtTime(65.4*2**('1!2"34$5%6^78*9(0qQwWeErtTyYuiIoOpPasSdDfgGhHjJklLzZxcCvVbBnm'.indexOf(c)/12),i)),start(),stop(s.length)}

swap=_=>{keyboard=!keyboard;A.innerHTML=keyboard?"Keyboard":"String";S.style.display=keyboard?"none":"inline";window.c&&c.close();window.o&&o.stop();keyboard?f():I.oninput=null;I.value="";}
keyboard=0;
swap();
<span id="A"></span> Input:<br>
<input id="I">
<button id="S" onclick="g(I.value)">Run</button><br>
<button onclick="swap()">Swap</button>

Джастин Маринер
источник
Вы можете поместить объект осциллятора в withоператор, чтобы исключить все случаи o., например:_=>{c=new AudioContext;with(c.createOscillator())connect(c.destination),I.oninput=_=>(~(i='1!2"34$5%6^78*9(0qQwWeErtTyYuiIoOpPasSdDfgGhHjJklLzZxcCvVbBnm'.search(I.value,I.value=""))&&(frequency.value=65.4*2**(i/12),r||(start(),r=1)))}
darrylyeo
1
@darrylyeo Спасибо, мы реализуем withоператор, но он прерывает последний бит ( o.r||(o.start(),o.r=1)), так как я использовал тот факт, который o.rне определен до этого момента, но теперь он выдает ошибки, так rкак не был объявлен. Оказалось, что было короче просто объявить эту переменную отдельно от любых объектов, поэтому я сделал это.
Джастин Маринер
Когда вы вводите символ «$», получается очень высокая частота.
Кирилл Малышев
@ КириллМалышев Хороший улов, потому что .search()обрабатывает ввод как регулярное выражение. Перешел на .indexOf().
Джастин Маринер
1

AHK , 130 байт

s=1!2"34$5`%6^78*9(0qQwWeErtTyYuiIoOpPasSdDfgGhHjJklLzZxcCvVbBnm
Loop,Parse,1
SoundBeep,55*2**((InStr(s,A_LoopField,1)-10)/12),999

Я выбрал вариант 2.

Объяснение:

Хранение строки поиска в качестве переменной sбыло короче, чем выход из этого беспорядка непосредственно вSoundBeep функции. Мне пришлось экранировать знак процента, так как это escape-символ для имен переменных, но остальная часть строки в порядке, как есть.

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

SoundBeep принимает частоту в Гц и длительность в миллисекундах и воспроизводит эту ноту в течение этого времени.

Самое интересное было выяснить правильные частоты. Ссылаясь на таблицу частот клавиш пианино из Википедии и формулу на той же странице, я обнаружил, что самое короткое кодирование - это использование A 1 в качестве справочной информации, потому что его частота - хороший круговой 55 Гц. Поскольку мы хотим начать с C 1 , нам нужно перейти от A 1 (13-я нота) к C 1 (4-я нота). Это, плюс тот факт, что InStrэто одноиндексное, - вот почему мы вычитаем 10 из результата InStrфункции.

Инженер Тост
источник