Zmień klawiaturę w klawiaturę


10

Zadanie

Powinieneś napisać program, który po naciśnięciu przycisku emituje inny dźwięk dla każdego klawisza.

Kluczami, których będziesz używać, są:

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

Nuty zaczynają się od, Ca każdy klawisz powyżej dodaje jeden półton.

Pozwólmy ci to jednak nieco ułatwić. Możesz wybrać pomiędzy 2 podobnymi zadaniami,

1) Po naciśnięciu klawisza wypisuje inną nutę, która trwa do momentu naciśnięcia innego klawisza. Ten program działa bez końca

2) Weź ciąg znaków, który zawiera tylko powyższe znaki, które będą generować każdą nutę przez dokładnie 1 sekundę (dozwolona zmiana 0,05 sekundy)

Wejście

  1. Naciśnięcie klawisza
  2. Pojedynczy ciąg zawierający tylko powyższe symbole

Wynik

  1. Pojedyncza nuta, która brzmi do momentu naciśnięcia innego klawisza
  2. Seria notatek, każda o długości 1 sekundy

Notatki

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

Zasady

  • Możesz wybrać pomiędzy zadaniami, ale powiedz, które z nich w odpowiedzi
  • Otrzymujesz ± 0,05 sekundową zmianę w zadaniu 2
  • Każdy symbol zwiększa ton o 1 półton.
  • Poszczególne nuty pokazano powyżej
  • To jest więc wygrywa najkrótszy kod

Zostało to pierwotnie zabrane stąd za zgodą Caira coinheringaahinga


Aby otworzyć to na języki, które nie mają bibliotek audio, polecam trzeci format wyjściowy: plik WAV zawierający wyjście opcji 2, zapisany na standardowe wyjście. Umożliwiłoby to wpisy w dowolnym języku, który może drukować dane binarne.
Ray

Odpowiedzi:


6

Python 3, 154 140 bajtów

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

Wybrałem drugi typ zadania.

Pętla przechodzi przez każdy znak i szuka indeksu tego elementu w ciągu. Ten indeks jest liczbą półtonów w górę od niskiej C („1”). Obliczenie żądanej częstotliwości odbywa się według tego wzoru .

PS Ta biblioteka działa tylko w systemie Windows.

-13 bajtów dzięki ovs.

-1 bajt dzięki Jonathan Allan.


1
Prawdopodobnie powinieneś wspomnieć, że działa to tylko w systemie Windows.
całkowicieludzki

1
Grał w golfa do 141 bajtów:from winsound import* for i in input():Beep(int(65.406*2**('1!2"34$5%6^78*9(0qQwWeErtTyYuiIoOpPasSdDfgGhHjJklLzZxcCvVbBnm'.find(i)/12)),1000)
ov

Ale zadano pytanie o program ...
Neil A.

0.05Tolerancja powinna pozwalają korzystać 999.
Jonathan Allan


3

JavaScript (ES6), 247 lub 230 bajtów

Postanowiłem wypróbować obie opcje.

Zaoszczędź kilka bajtów dzięki @darrylyeo za sugerowanie withinstrukcji.
Podziękowania dla @ Кирилл Малышев za wskazanie problemu z .search().

Opcja 1 - wprowadzanie z klawiatury, 252 246 247 bajtów

_=>{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

Opiera się na elemencie wejściowym odbierającym rzeczywistą wpisaną literę zamiast kodów znaków. Fokus musi być ustawiony na polu wprowadzania.

Opcja 2 - Ciąg wejściowy, 234 229 230 bajtów

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

Po prostu bierze ciąg jako parametr funkcji.

Połączony fragment kodu

Sugeruję obniżenie głośności przy włączonym to, może być głośno. Aby zatrzymać odtwarzanie, fragment wymagał dodania o=do każdego z nich 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>


Możesz umieścić obiekt oscylatora w withzestawieniu, aby 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)))}
odrzucić

1
@darrylyeo Dzięki, zaimplementuję withinstrukcję, ale łamie ostatni bit ( o.r||(o.start(),o.r=1)), ponieważ o.rdo tej pory używałem faktu, który jest niezdefiniowany, ale teraz popełni błąd, ponieważ rnie został zadeklarowany. Okazuje się, że krótsze było po prostu zadeklarowanie tej zmiennej oddzielnie od jakichkolwiek obiektów, więc to zrobiłem.
Justin Mariner

Po wprowadzeniu symbolu „$” powstaje bardzo wysoka częstotliwość.
Кирилл Малышев

@ КириллМалышев Dobry haczyk, bo to .search()traktuje dane wejściowe jako wyrażenie regularne. Przełączono na .indexOf().
Justin Mariner

1

AHK , 130 bajtów

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

Wybrałem opcję 2.

Wyjaśnienie:

Przechowywanie szukanego ciągu jako zmiennej sbyło krótsze niż uniknięcie tego bałaganu bezpośrednio w SoundBeepfunkcji. Musiałem uciec od znaku procentu, ponieważ jest to znak zmiany znaczenia dla nazw zmiennych, ale reszta ciągu jest w porządku.

Domyślnie zmienna 1jest pierwszym parametrem wejściowym. Wpisanie tego do pętli analizowania bez określania separatora spowoduje, że każdy znak w łańcuchu wejściowym będzie analizowany indywidualnie.

SoundBeep przyjmuje częstotliwość w Hz i czas trwania w milisekundach i odtwarza tę nutę tak długo.

Zabawne było ustalenie odpowiednich częstotliwości. Odwołując się do tabeli częstotliwości klawiszy fortepianu z Wikipedii i wzoru na tej samej stronie, znalazłem najkrótsze kodowanie, aby użyć A 1 jako nuty referencyjnej, ponieważ jego częstotliwość to ładna okrągła 55 Hz. Ponieważ chcemy zacząć od C 1 , musimy dostosować z A 1 (trzynasta nuta) do C 1 (czwarta nuta). To, plus fakt, że InStrjest indeksowany jednokrotnie, dlatego odejmujemy 10 od wyniku InStrfunkcji.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.