Transformez votre clavier en clavier

10

Tâche

Vous devez écrire un programme qui, lorsqu'un bouton est enfoncé, émet un son différent pour chaque touche.

Les clés que vous utiliserez sont:

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

Les notes commencent à Cet chaque touche ci-dessus ajoute un demi-ton.

Permet de vous faciliter la tâche un peu. Vous pouvez choisir entre 2 tâches similaires,

1) Produisez une note différente lorsqu'une touche est enfoncée et continue jusqu'à ce qu'une autre touche soit enfoncée. Ce programme fonctionne indéfiniment

2) Prenez une chaîne en entrée qui ne contient que les caractères ci-dessus qui produiront chaque note pendant exactement 1 seconde (variation de 0,05 seconde autorisée)

Contribution

  1. Une touche enfoncée
  2. Une seule chaîne contenant uniquement les symboles ci-dessus

Production

  1. Une seule note musicale qui retentit jusqu'à ce qu'une autre touche soit enfoncée
  2. Une série de notes de 1 seconde chacune

Remarques

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

Règles

  • Vous pouvez choisir entre les tâches mais veuillez dire laquelle dans votre réponse
  • Vous obtenez une variation de ± 0,05 seconde dans la tâche 2
  • Chaque symbole incrémente le ton d'un demi-ton.
  • Les notes individuelles sont montrées ci-dessus
  • Ceci est un donc le code le plus court gagne

Cela a été pris à l'origine d' ici avec le consentement de Coinheringaahing

Jonathan Allan
la source
Pour l'ouvrir à des langues qui n'ont pas de bibliothèques audio, je recommande un troisième format de sortie: un fichier WAV contenant l'option 2, écrit sur stdout. Cela permettrait des entrées dans n'importe quelle langue pouvant imprimer des données binaires.
Ray

Réponses:

6

Python 3, 154 140 octets

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

J'ai choisi le deuxième type de tâche.

La boucle passe par chaque caractère et recherche l'index de cet élément dans la chaîne. Cet indice est le nombre de demi-tons à partir de Low C ('1'). Le calcul de la fréquence souhaitée est effectué par cette formule .

PS Cette bibliothèque ne fonctionne que sous Windows.

-13 octets grâce aux ovs.

-1 octet merci à Jonathan Allan.

Кирилл Малышев
la source
1
Vous devez probablement mentionner que cela ne fonctionne que sur Windows.
2017 totalement humain
1
Joué à 141 octets: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
Mais la question demandait un programme ....
Neil A.
La 0.05tolérance devrait vous permettre d'utiliser 999.
Jonathan Allan
3

JavaScript (ES6), 247 ou 230 octets

Décidé d'essayer les deux options.

Enregistré quelques octets grâce à @darrylyeo pour avoir suggéré la withdéclaration.
Merci à @ Кирилл Малышев d'avoir signalé un problème avec .search().

Option 1 - Entrée clavier, 252 246 247 octets

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

Dépend de l'élément d'entrée qui reçoit la lettre typée réelle, au lieu des codes de caractères. Le focus doit être sur la zone de saisie.

Option 2 - Entrée de chaîne, 234 229 230 octets

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

Prend simplement la chaîne comme paramètre de fonction.

Extrait combiné

Je suggère de baisser votre volume en cours d'exécution, cela peut être bruyant. Pour arrêter la lecture, l'extrait de code a dû être ajouté o=à l'intérieur de chacun 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
la source
Vous pouvez mettre l'objet oscillateur dans une withdéclaration pour jouer toutes les instances de o., comme ceci:_=>{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 Merci, implémentera l' withinstruction, mais elle casse le dernier bit ( o.r||(o.start(),o.r=1)) puisque j'utilisais le fait qui o.rest indéfini jusqu'à ce point, mais maintenant il se trompe car rn'a pas été déclaré. Il s'est avéré qu'il était plus court de simplement déclarer cette variable distincte de tout objet, alors je l'ai fait.
Justin Mariner
Lorsque vous entrez le symbole «$», une fréquence très élevée est produite.
Кирилл Малышев
@ КириллМалышев Bonne capture, car la cause .search()traite l'entrée comme une expression régulière. Passé à .indexOf().
Justin Mariner
1

AHK , 130 octets

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

J'ai choisi l'option 2.

Explication:

Stocker la chaîne de recherche en tant que variable sétait plus court que d'échapper directement à ce gâchis dans la SoundBeepfonction. J'ai dû échapper au signe de pourcentage car c'est un caractère d'échappement pour les noms de variable, mais le reste de la chaîne est OK tel quel.

Par défaut, la variable 1est le premier paramètre d'entrée. L'alimentation dans une boucle d'analyse sans spécifier de délimiteur entraînera l'analyse individuelle de chaque caractère de la chaîne d'entrée.

SoundBeep prend une fréquence en Hz et une durée en millisecondes et joue cette note aussi longtemps.

La partie amusante était de trouver les bonnes fréquences. En faisant référence au tableau de fréquence des touches de piano de Wikipedia et à la formule sur la même page, j'ai trouvé que l'encodage le plus court était d'utiliser A 1 comme note de référence car sa fréquence est la belle ronde de 55 Hz. Puisque nous voulons commencer à C 1 , nous devons ajuster de A 1 (la 13e note) à C 1 (la 4e note). Cela, plus le fait qu'il InStrest un indexé, c'est pourquoi nous soustrayons 10 du résultat de la InStrfonction.

Ingénieur Toast
la source