키보드를 키보드로 만드십시오


10

직무

버튼을 누르면 각 키마다 다른 소리를 출력하는 프로그램을 작성해야합니다.

사용할 키는 다음과 같습니다.

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

음표가 시작되고 C위의 각 키는 하나의 반음을 추가합니다.

그래도 조금 더 쉽게 만들 수 있습니다. 두 가지 유사한 작업 중에서 선택할 수 있습니다.

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 반음 씩 증가시킵니다.
  • 개별 메모는 위에 표시되어 있습니다
  • 이것은 이므로 가장 짧은 코드가 승리합니다.

이것은 원래 caird coinheringaahing의 동의로 여기 에서 가져 왔습니다.


오디오 라이브러리가없는 언어로이를 열려면 세 번째 출력 형식 인 stdout에 작성된 옵션 2 출력을 포함하는 WAV 파일을 사용하는 것이 좋습니다. 그러면 이진 데이터를 인쇄 할 수있는 모든 언어의 항목이 허용됩니다.
Ray

답변:


6

파이썬 3, 154140 바이트

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

두 번째 작업 유형을 선택했습니다.

루프는 각 문자를 통과하고 문자열에서이 요소의 색인을 찾습니다. 이 지수는 Low C ( '1')의 반음 수입니다. 원하는 주파수 계산은이 공식으로 이루어집니다 .

PS이 라이브러리 는 Windows에서만 작동합니다.

ovs 덕분에 -13 바이트

Jonathan Allan 덕분에 -1 바이트.


1
아마도 이것이 Windows에서만 작동한다는 것을 언급해야 할 것입니다.
전적으로 휴먼

1
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)
골프

그러나 질문은 프로그램을 요청했다 ....
Neil A.

0.05허용 오차는 사용할 수 있도록해야한다 999.
Jonathan Allan


3

JavaScript (ES6), 247 또는 230 바이트

두 가지 옵션을 모두 사용하기로 결정했습니다.

with문장 을 제안한 @darrylyeo 덕분에 몇 바이트를 절약했습니다 .
문제를 지적 해 주신 @ Кирилл Малышев에게 감사합니다 .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.rr선언되지 않았 으므로 오류가 발생합니다 . 변수를 객체와 별도로 선언하는 것이 더 짧았습니다. 그래서 그렇게했습니다.
저스틴 마리너

'$'기호를 입력하면 매우 높은 주파수가 생성됩니다.
Кирилл Малышев

@ КириллМалышев 잘 잡습니다 .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함수 에서 직접 해당 혼란을 피하는 것보다 짧았습니다 . 변수 이름의 이스케이프 문자이므로 백분율 기호를 이스케이프 처리해야했지만 나머지 문자열은 그대로 괜찮습니다.

기본적으로 변수 1는 첫 번째 입력 매개 변수입니다. 구분자를 지정하지 않고 파싱 루프에 입력하면 입력 문자열의 각 문자가 개별적으로 분석됩니다.

SoundBeep Hz 단위의 주파수와 밀리 초 단위의 지속 시간을 취하여 그 음을 오랫동안 연주합니다.

재미있는 부분은 올바른 주파수를 알아내는 것이 었습니다. Wikipedia 의 피아노 키 주파수 표 와 같은 페이지의 수식을 참조하면 가장 짧은 인코딩은 주파수가 55Hz의 멋진 라운드이기 때문에 A 1 을 참조 메모로 사용하는 것으로 나타났습니다 . C 1 에서 시작하고 싶기 때문에 A 1 (13 번째 음표)에서 C 1 (4 번째 음표)로 조정해야합니다. 즉, InStr1- 인덱스 라는 사실 은 InStr함수 의 결과에서 10을 빼는 이유 입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.