Trasforma la tua tastiera in una tastiera


10

Compito

Si dovrebbe scrivere un programma che quando si preme un pulsante, emette un suono diverso per ciascun tasto.

Le chiavi che userete sono:

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

Le note iniziano alle Ce ogni tasto sopra aggiunge un semitono.

Permettiamo tuttavia di renderti leggermente più semplice. Puoi scegliere tra 2 attività simili,

1) Emette una nota diversa quando viene premuto un tasto che continua fino a quando non viene premuto un altro tasto. Questo programma funziona a tempo indeterminato

2) Prendi una stringa come input che contiene solo i caratteri sopra che genereranno ogni nota esattamente per 1 secondo (è consentita una variazione di 0,05 secondi)

Ingresso

  1. È stato premuto un tasto
  2. Una singola stringa contenente solo i simboli sopra

Produzione

  1. Una singola nota musicale che suona fino a quando non viene premuto un altro tasto
  2. Una serie di note, ciascuna lunga 1 secondo

Appunti

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

Regole

  • È possibile scegliere tra le attività ma si prega di dire quale nella risposta
  • Viene assegnata una variazione di ± 0,05 secondi nell'attività 2
  • Ogni simbolo lungo aumenta il tono di 1 semitono.
  • Le singole note sono mostrate sopra
  • Questo è un quindi vince il codice più breve

Questo è stato originariamente preso da qui con il consenso di coinheringaahing


Per aprirlo a lingue che non dispongono di librerie audio, consiglio un terzo formato di output: un file WAV contenente l'opzione 2 output, scritto su stdout. Ciò consentirebbe voci in qualsiasi lingua in grado di stampare dati binari.
Ray

Risposte:


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)

Ho scelto il secondo tipo di attività.

Il ciclo passa attraverso ogni carattere e cerca l'indice di questo elemento nella stringa. Questo indice è il numero di semitoni in alto da Low C ('1'). Il calcolo della frequenza desiderata viene effettuato con questa formula .

PS Questa libreria funziona solo in Windows.

-13 byte grazie agli ovs.

-1 byte grazie a Jonathan Allan.


1
Probabilmente dovresti menzionare che questo funziona solo su Windows.
totalmente umano il

1
Golfato a 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

Ma la domanda ha richiesto un programma ....
Neil A.

La 0.05tolleranza dovrebbe permetterti di usare 999.
Jonathan Allan,


3

JavaScript (ES6), 247 o 230 byte

Ho deciso di provare entrambe le opzioni.

Risparmio di pochi byte grazie a @darrylyeo per aver suggerito l' withaffermazione.
Grazie a @ Кирилл Малышев per aver segnalato un problema con .search().

Opzione 1 - Input da tastiera, 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

Si basa sull'elemento di input che riceve la lettera effettivamente digitata, anziché i codici carattere. Il focus deve essere sulla casella di input.

Opzione 2 - Input stringa, 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)}

Prende semplicemente la stringa come parametro della funzione.

Snippet combinato

Suggerisco di abbassare il volume eseguendo questo, può essere rumoroso. Per interrompere la riproduzione, è necessario aggiungere lo snippet o=all'interno di ciascuno 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>


È possibile inserire l'oggetto oscillatore in una withdichiarazione per eseguire il golf di tutte le istanze di o., in questo modo:_=>{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 Grazie, implementerò l' withaffermazione, ma rompe l'ultimo bit ( o.r||(o.start(),o.r=1)) poiché stavo usando il fatto che o.rnon è stato definito fino a quel punto, ma ora si interrompe poiché rnon è stato dichiarato. Si è scoperto che era più breve dichiarare quella variabile separata da qualsiasi oggetto, quindi l'ho fatto.
Justin Mariner,

Quando si inserisce il simbolo '$', viene prodotta una frequenza molto alta.
Кирилл Малышев,

@ КириллМалышев Buona cattura, che causa .search()considera l'input come regex. Passato a .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

Ho scelto l'opzione 2.

Spiegazione:

Memorizzare la stringa di ricerca come variabile sera più breve di sfuggire a quel casino direttamente nella SoundBeepfunzione. Ho dovuto sfuggire al segno di percentuale poiché si tratta di un carattere di escape per i nomi delle variabili, ma il resto della stringa è OK così com'è.

Per impostazione predefinita, la variabile 1è il primo parametro di input. Inserendolo in un ciclo di analisi senza specificare un delimitatore, ciascun carattere della stringa di input verrà analizzato individualmente.

SoundBeep accetta una frequenza in Hz e una durata in millisecondi e suona quella nota per così tanto tempo.

La parte divertente era capire le frequenze giuste. Facendo riferimento alla tabella delle frequenze dei tasti del piano di Wikipedia e alla formula nella stessa pagina, ho scoperto che la codifica più breve era usare A 1 come nota di riferimento perché la sua frequenza è il bel giro di 55 Hz. Dato che vogliamo iniziare da C 1 , dobbiamo regolare da A 1 (la 13a nota) a C 1 (la 4a nota). Questo, oltre al fatto che InStrè un indice, è il motivo per cui sottraggiamo 10 dal risultato della InStrfunzione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.