Machen Sie Ihre Tastatur zu einer Tastatur

10

Aufgabe

Sie sollten ein Programm schreiben, das beim Drücken einer Taste für jede Taste einen anderen Ton ausgibt.

Die Schlüssel, die Sie verwenden werden, sind:

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

Die Noten beginnen bei Cund jede Taste oben fügt einen Halbton hinzu.

Machen wir es Ihnen allerdings etwas leichter. Sie können zwischen 2 ähnlichen Aufgaben wählen:

1) Geben Sie eine andere Note aus, wenn eine Taste gedrückt wird, die fortgesetzt wird, bis eine andere Taste gedrückt wird. Dieses Programm läuft auf unbestimmte Zeit

2) Nehmen Sie eine Zeichenfolge als Eingabe, die nur die obigen Zeichen enthält, die jede Note genau 1 Sekunde lang ausgeben (Variation von 0,05 Sekunden zulässig).

Eingang

  1. Eine Taste wird gedrückt
  2. Eine einzelne Zeichenfolge, die nur die obigen Symbole enthält

Ausgabe

  1. Eine einzelne Musiknote, die ertönt, bis eine andere Taste gedrückt wird
  2. Eine Reihe von Noten, jede 1 Sekunde lang

Anmerkungen

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

Regeln

  • Sie können zwischen den Aufgaben wählen, aber bitte sagen Sie, welche in Ihrer Antwort
  • In Aufgabe 2 erhalten Sie eine Variation von ± 0,05 Sekunden
  • Jedes Symbol erhöht den Ton um 1 Halbton.
  • Die einzelnen Notizen sind oben dargestellt
  • Dies ist ein so dass der kürzeste Code gewinnt

Dies wurde ursprünglich von hier mit Zustimmung von Caird Coinheringaahing übernommen

Jonathan Allan
quelle
Um dies für Sprachen ohne Audiobibliotheken zu öffnen, empfehle ich ein drittes Ausgabeformat: eine WAV-Datei mit der Ausgabe von Option 2, die in stdout geschrieben wurde. Dies würde Einträge in jeder Sprache ermöglichen, die Binärdaten drucken können.
Ray

Antworten:

6

Python 3, 154 140 Bytes

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

Ich habe den zweiten Aufgabentyp gewählt.

Die Schleife durchläuft jedes Zeichen und sucht in der Zeichenfolge nach dem Index dieses Elements. Dieser Index gibt die Anzahl der Halbtöne ab Low C ('1') an. Die Berechnung der gewünschten Frequenz erfolgt nach dieser Formel .

PS Diese Bibliothek funktioniert nur unter Windows.

-13 Bytes dank Ovs.

-1 Byte danke an Jonathan Allan.

Кирилл Малышев
quelle
1
Sie sollten wahrscheinlich erwähnen, dass dies nur unter Windows funktioniert.
totalmenschlich
1
Golf auf 141 Bytes: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
Aber die Frage nach einem Programm gestellt ...
Neil A.
Die 0.05Toleranz sollte es Ihnen ermöglichen, zu verwenden 999.
Jonathan Allan
3

JavaScript (ES6), 247 oder 230 Byte

Beschlossen, beide Optionen auszuprobieren.

Dank @darrylyeo für das Vorschlagen der withAnweisung wurden einige Bytes gespeichert .
Vielen Dank an @ Кирилл Малышев für den Hinweis auf ein Problem mit .search().

Option 1 - Tastatureingabe, 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

Verlässt sich darauf, dass das Eingabeelement anstelle der Zeichencodes den tatsächlich eingegebenen Buchstaben empfängt. Der Fokus muss auf dem Eingabefeld liegen.

Option 2 - String-Eingabe, 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)}

Nimmt einfach den String als Funktionsparameter.

Kombiniertes Snippet

Ich schlage vor, die Lautstärke zu verringern, da dies laut sein kann. Es kann laut sein. Um die Wiedergabe zu stoppen, musste das Snippet jeweils hinzugefügt o=werden 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
quelle
Sie können das Oszillator-Objekt in eine withAnweisung 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)))}
einfügen
1
@darrylyeo Danke, wird die withAnweisung implementieren , aber sie bricht das letzte Bit ( o.r||(o.start(),o.r=1)), seit ich die Tatsache verwendet habe, o.rdie bis zu diesem Zeitpunkt undefiniert ist, aber jetzt tritt ein Fehler auf, da rsie nicht deklariert wurde. Es stellte sich heraus, dass es kürzer war, diese Variable von Objekten getrennt zu deklarieren, also habe ich das getan.
Justin Mariner
Wenn Sie das Symbol '$' eingeben, wird eine sehr hohe Frequenz erzeugt.
Кирилл Малышев
@ КириллМалышев Guter Fang, das ist, weil .search()die Eingabe als Regex behandelt wird. Umgeschaltet auf .indexOf().
Justin Mariner
1

AHK , 130 Bytes

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

Ich habe Option 2 gewählt.

Erläuterung:

Das Speichern der Suchzeichenfolge als Variable swar kürzer als das direkte Entkommen dieses Durcheinanders in der SoundBeepFunktion. Ich musste das Prozentzeichen maskieren, da dies ein Escapezeichen für Variablennamen ist, aber der Rest der Zeichenfolge ist in Ordnung.

Standardmäßig ist die Variable 1der erste Eingabeparameter. Wenn Sie dies in eine Parsing-Schleife eingeben, ohne ein Trennzeichen anzugeben, wird jedes Zeichen in der Eingabezeichenfolge einzeln analysiert.

SoundBeep Nimmt eine Frequenz in Hz und eine Dauer in Millisekunden auf und spielt diese Note so lange.

Der lustige Teil bestand darin, die richtigen Frequenzen herauszufinden. Unter Bezugnahme auf die Frequenztabelle für Klaviertasten aus Wikipedia und die Formel auf derselben Seite stellte ich fest, dass die kürzeste Codierung darin bestand, A 1 als Referenznote zu verwenden, da die Frequenz die schönen runden 55 Hz beträgt. Da wir bei C 1 beginnen wollen , müssen wir von A 1 (13. Note) auf C 1 (4. Note) einstellen . Aus diesem InStrGrund und der Tatsache, dass es sich um einen Index handelt, subtrahieren wir 10 vom Ergebnis der InStrFunktion.

Ingenieur Toast
quelle