Jadikan keyboard Anda menjadi keyboard

10

Tugas

Anda harus menulis sebuah program yang ketika sebuah tombol ditekan, ia mengeluarkan suara yang berbeda untuk setiap tombol.

Kunci yang akan Anda gunakan adalah:

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

Catatan dimulai pada Cdan setiap tombol di atas menambahkan satu nada semi.

Mari kita membuatnya sedikit lebih mudah bagi Anda. Anda dapat memilih antara 2 tugas serupa,

1) Keluarkan catatan yang berbeda ketika tombol ditekan yang berlanjut sampai tombol lain ditekan. Program ini berjalan tanpa batas

2) Ambil string sebagai input yang hanya berisi karakter di atas yang akan menampilkan setiap nada tepat 1 detik (variasi 0,05 detik diizinkan)

Memasukkan

  1. Sebuah tombol ditekan
  2. Satu string yang hanya berisi simbol di atas

Keluaran

  1. Satu not musik yang berbunyi sampai tombol lain ditekan
  2. Serangkaian catatan, masing-masing berdurasi 1 detik

Catatan

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

Aturan

  • Anda dapat memilih di antara tugas-tugas tetapi tolong katakan yang mana dalam jawaban Anda
  • Anda diberi variasi ± 0,05 detik dalam tugas 2
  • Setiap simbol di sepanjang menambah nada dengan 1 semitone.
  • Catatan individual ditunjukkan di atas
  • Ini adalah sehingga kode terpendek menang

Ini awalnya diambil dari sini dengan persetujuan caird coinheringaahing

Jonathan Allan
sumber
Untuk membuka ini ke bahasa yang tidak memiliki pustaka audio, saya sarankan format output ketiga: file WAV yang berisi opsi 2 output, ditulis ke stdout. Itu akan memungkinkan entri dalam bahasa apa pun yang dapat mencetak data biner.
Ray

Jawaban:

6

Python 3, 154 140 byte

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

Saya memilih jenis tugas kedua.

Loop melewati setiap karakter dan mencari indeks elemen ini dalam string. Indeks ini adalah jumlah semiton dari Rendah C ('1'). Perhitungan frekuensi yang diinginkan dilakukan oleh rumus ini .

PS Perpustakaan ini hanya berfungsi di Windows.

-13 byte berkat ovs.

-1 byte terima kasih kepada Jonathan Allan.

Кирилл Малышев
sumber
1
Anda mungkin harus menyebutkan bahwa ini hanya berfungsi pada Windows.
totallyhuman
1
Ditarik hingga 141 byte: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
Tetapi pertanyaannya meminta sebuah program ....
Neil A.
The 0.05toleransi harus memungkinkan Anda untuk menggunakan 999.
Jonathan Allan
3

JavaScript (ES6), 247 atau 230 byte

Memutuskan untuk mencoba kedua opsi.

Menyimpan beberapa byte, terima kasih kepada @darrylyeo karena menyarankan withpernyataan itu.
Terima kasih kepada @ Кирилл Малышев karena menunjukkan masalah dengan .search().

Opsi 1 - Input Keyboard, 252 246 247 byte

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

Bergantung pada elemen input yang menerima huruf yang diketikkan, bukan kode karakter. Fokus harus ada di kotak input.

Opsi 2 - Input String, 234 229 230 byte

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

Cukup ambil string sebagai parameter fungsi.

Cuplikan Gabungan

Saya sarankan menolak volume Anda menjalankan ini, itu bisa keras. Untuk menghentikan pemutaran, cuplikan harus ditambahkan o=di dalamnya 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>

Justin Mariner
sumber
Anda dapat meletakkan objek osilator dalam withpernyataan untuk menghilangkan semua contoh o., seperti ini:_=>{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 Terima kasih, akan mengimplementasikan withpernyataan itu, tetapi itu memecah bit terakhir ( o.r||(o.start(),o.r=1)) karena saya menggunakan fakta yang o.rtidak terdefinisi sampai saat itu, tetapi sekarang kesalahan keluar karena rbelum dideklarasikan. Ternyata itu lebih pendek untuk hanya menyatakan bahwa variabel terpisah dari objek apa pun, jadi saya melakukan itu.
Justin Mariner
Saat Anda memasukkan simbol '$', frekuensi sangat tinggi dihasilkan.
Кирилл Малышев
@ КириллМалышев Bagus menangkap, itu sebabnya .search()memperlakukan input sebagai regex. Beralih ke .indexOf().
Justin Mariner
1

AHK , 130 byte

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

Saya memilih Opsi 2.

Penjelasan:

Menyimpan string pencarian sebagai variabel slebih pendek daripada melarikan diri dari kekacauan itu langsung dalam SoundBeepfungsi. Saya harus melarikan diri dari tanda persen karena itu adalah karakter pelarian untuk nama-nama variabel tetapi sisa string tidak apa-apa.

Secara default, variabel 1adalah parameter input pertama. Mengumpankan itu ke parsing loop tanpa menentukan pembatas akan menghasilkan setiap karakter dalam string input yang dianalisis secara individual.

SoundBeep mengambil frekuensi dalam Hz dan durasi dalam milidetik dan memainkan catatan itu selama itu.

Bagian yang menyenangkan adalah mencari tahu frekuensi yang tepat. Referensi kunci piano tabel frekuensi dari Wikipedia dan rumus pada halaman yang sama, saya menemukan encoding terpendek adalah menggunakan A 1 sebagai catatan referensi karena frekuensi itu adalah bagus putaran 55 Hz. Karena kita ingin memulai dari C 1 , kita harus menyesuaikan dari A 1 (not ke-13) ke C 1 (not ke-4). Itu, ditambah fakta yang InStrdiindeks satu, itulah sebabnya kami mengurangi 10 dari hasil InStrfungsi.

Toast insinyur
sumber