キーボードをキーボードにする


10

仕事

ボタンを押すと、キーごとに異なるサウンドを出力するプログラムを作成する必要があります。

使用するキーは次のとおりです。

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

ノートはで始まり、C上の各キーは1つの半音を追加します。

少し簡単にしましょう。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セミトーンずつ増やします。
  • 個々のメモは上に表示されています
  • これはので、最短のコードが勝ちます

これは、最初はここからcaird coinheringaahingの同意を得て取得されました


これをオーディオライブラリのない言語で開くには、3番目の出力形式をお勧めします。標準出力に書き込まれた、オプション2の出力を含むWAVファイルです。これにより、バイナリデータを印刷できる任意の言語のエントリが許可されます。
レイ

回答:


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)

2番目のタスクタイプを選択しました。

ループは各文字を通過し、文字列でこの要素のインデックスを探します。このインデックスは、Low C( '1')から半音上にある数です。所望の周波数の計算は、このによって行われます。

PSこのライブラリはWindowsでのみ機能します。

ovsのおかげで-13バイト。

ジョナサンアランのおかげで-1バイト。


1
これはWindowsでのみ機能することをおそらく言及する必要があります。
完全に人間的な2017年

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

しかし、質問はプログラムを求めました...
Neil A.

0.05許容値は、使用できるようにする必要があります999
ジョナサンアラン2017年


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

文字コードの代わりに入力された実際の文字を受け取るinput要素に依存します。フォーカスは入力ボックスにある必要があります。

オプション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ます。その変数をオブジェクトとは別に宣言するだけの方が短いことがわかったので、それを行いました。
ジャスティンマリナー2017年

記号「$」を入力すると、非常に高い周波数が生成されます。
КириллМалышев

@КириллМалышев良いキャッチ、それは原因.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単位の周波数とミリ秒単位の持続時間を取り込み、その音をその間再生します。

楽しい部分は正しい周波数を理解することでした。ウィキペディアのピアノ鍵盤周波数表と同じページの公式を参照すると、最も短いエンコードはA 1をリファレンスノートとして使用することでした。これは、その周波数が55 Hzの適切なラウンドであるためです。C 1から始めたいので、A 1(13分音符)からC 1(4分音符)に調整する必要があります。これに加えて、InStrインデックスが1つあるという事実が、InStr関数の結果から10を引く理由です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.