Créer un piano GUI [fermé]

15

Défi

Créez un clavier GUI avec le moins de caractères possible.

Exemple

Parce que c'était une tâche dans l'un de mes cours, je ne peux pas montrer le code source. Cependant, voici une capture d'écran de mon clavier.

piano

Dans cet exemple, mes touches étaient de type JButtonet j'ai utilisé un synthétiseur Midi pour produire le son (avec les valeurs d'enveloppe ADSR par défaut).

Règles

  • Vous êtes autorisé à utiliser des bibliothèques externes standard.
  • Soyez créatif avec votre son. Vous pouvez utiliser 8 bits, un sitar, etc.
  • Par souci de simplicité, vous pouvez avoir cinq clés; noir et blanc, de C à E (les cinq premières touches de mon clavier).
  • Plus important encore ... présentez votre travail!

AVIS : Selon la langue avec laquelle vous choisissez de travailler, cela peut être une tâche assez importante.

Ceci est ma première question sur SE Code Golf. Si quelque chose n'est pas clair, veuillez demander plus de détails.


EDIT : La date d'échéance pour ce défi sera le 22/09/12. Si vous postez une réponse après cette date, je la regarderai malgré tout (et éventuellement +1).

Rob
la source
2
Les restrictions sur la langue à utiliser ne sont pas très appréciées ici. Envisagez de supprimer votre restriction ou nommez une raison importante.
FUZxxl
1
@FUZxxl Comme indiqué dans la section Exemple, il s'agissait d'un projet de terme pour notre classe Java. Il est toujours utilisé comme un projet de terme pour cette même classe. Mais je suppose que je suis juste paranoïaque alors je vais laisser tomber les restrictions. Je pense que vous vouliez dire quelles langues ne pas utiliser ... mais peu importe, je les ai supprimées.
Rob
2
Quelles sont les exigences minimales pour être considéré comme un "clavier GUI"? Je déduis de ce qui est déjà présent qu'il doit afficher une interface graphique et produire du son, mais quelles sont les restrictions sur: a) le mécanisme d'entrée; b) l'enveloppe sonore; c) l'échelle utilisée; d) la précision de l'accord; e) les proportions des clés?
Peter Taylor
2
@MikeDtrick, qui répond à 0/5 de mes questions. Je ne demande pas comment votre implémentation a fonctionné: je demande comment je peux savoir si mon implémentation (hypothétique) est un concurrent valide, car il est inutile de raccourcir une entrée de 20% si cela le fait passer d'une entrée valide à invalide.
Peter Taylor
1
@MikeDtrick: Par exemple, vous pouvez exiger que les boutons ressemblent exactement à ceux de votre exemple, pixel par pixel. À l'autre extrême, vous pouvez autoriser n'importe quel arrangement de cinq boutons GUI de tout type.
han

Réponses:

11

Mathematica 319 259 255


Modifier: les touches sont désormais enfoncées (sous forme de boutons) lorsque vous cliquez dessus.


Cela jouera les notes de piano à queue {"C", "C #", "D", "D #", "E"}, où "C" est le milieu C. z[n_]joue la note.

z@n_ := EmitSound@Sound[SoundNote[n, .3, 1]]; w = {10, 300}; b = {35, 180};
Graphics[Inset[Button["", z[#[[1]]], Background -> If[#[[2]] == w, None, Black], 
ImageSize -> #〚2〛], #〚3〛] & /@ {{"C", w, {-.4, 0}}, {"D", w, {0, 0}}, {"E", w, {.4, 0}}, 
{"C#", b, {-.2, 0.31}}, {"D#", b, {.2, 0.31}}}, PlotRange -> 1]

clavier


Le clavier peut être étendu à 18 touches en utilisant moins du double des caractères:

z@n_ := EmitSound@Sound@SoundNote[n, .3, 1];
w = {"C", "D", "E", "F", "G", "A", "B", "C5", "D5", "E5", "F5"};
b = {"C#", "D#", "", "F#", "G#", "A#", "", "C#5", "D#5"}; i = ImageSize; t = Thread; 
l = List; s = Inset; m = Table; u = Button;
Graphics[Join[t[s[u @@@ t[l["", y /@ w, i -> {5, 350}]] /. y -> z, m[{90 k, 0}, {k, -5, 5}]]], 
Delete[t[s[u @@@ t[l["", y /@ b, Background -> Black, i -> {28, 212}]] /. 
  y -> z, m[{90 k + 45, 220}, {k, -5, 3}]]], {{3}, {7}}]], 
AspectRatio -> .45, PlotRange -> {{-500, 500}, {-610, 610}}, i -> {800, 430}]   

grand clavier

DavidC
la source
1
+1 Je ne doute pas que cela fonctionnera ... J'aimerais juste pouvoir jouer dessus.
Rob
1
J'ai laissé une version .cdf du fichier dans ma DropBox à dropbox.com/sh/m3y0fs0v0nidqt5/UTv_0YGpz5. Vous pouvez le partager avec d'autres. Il ne devrait pas y avoir de problèmes de licence car il est utilisé à des fins éducatives non commerciales. Vous devrez télécharger le lecteur Wolfram CDF gratuit si vous ne l'avez pas déjà.
DavidC
David, j'ai besoin w = {67, 300}d'obtenir votre résultat; une idée pourquoi la différence? De plus, puis-je modifier ce code pour le raccourcir, si j'en suis capable?
Mr.Wizard
Mr.Wizard. w = {67,300}fonctionne très bien sur v. 9 donc si vous voulez le changer, ou d'ailleurs raccourcir le code, allez-y. Le réglage de la taille du bouton a été aléatoire. Des choses étranges se sont produites pour des raisons que je ne peux pas expliquer. (Par exemple, l'ajout de boutons affecte les proportions des boutons d'origine.)
DavidC
10

Page Web (840/796 caractères)

>>> Commencez à jouer (Internet Explorer n'est pas pris en charge pour plusieurs raisons; Google Chrome et Opera fonctionnent mieux.)

Je pourrais probablement raccourcir un peu les choses, mais c'est un bon début. Le score inférieur est après avoir remplacé toutes les occurrences de  par le personnage lui-même et supprimé le mot-clé new, ce dernier modifiant la compatibilité avec Google Chrome.

<style>table{border-collapse:collapse;border-width:1 0;border-style:solid;font-size:64;line-height:2}td{border-style:solid;border-width:0 1}</style><table><td colspan=3 title=0>&nbsp;<td bgcolor=black colspan=2 title=1>&nbsp;<td colspan=2 title=2>&nbsp;<td bgcolor=black colspan=2 title=3>&nbsp;<td colspan=3 title=4>&nbsp;<tr><td colspan=4 title=0>&nbsp;<td colspan=4 title=2>&nbsp;<td colspan=4 title=4>&nbsp;</table><script>for(A=[y=5];y--;){for(s=x=64e3;x--;)s+="~ "[x*(268+17*y)>>13&1];A[y]=new Audio("data:audio/wav;base64,UklGRiXuAgBXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQHuAgCA"+btoa(s))}setInterval("for(y=5;y--;)with(A[y])volume=volume&&Math.exp(-currentTime)",99);onmousedown=function(e){if(z=e.target.title)with(A[z])play(currentTime=0,volume=1)};onmouseup=function(e){if(z=e.target.title)with(A[z])pause(volume=0)}</script>

Enregistrez ce code sous forme de fichier texte avec un nom se terminant par .htm ou .html et ouvrez-le dans Chrome ou Opera (Safari peut également fonctionner), ou ouvrez simplement la page JSBin de la solution pour commencer à jouer. J'ai réutilisé l'en-tête du fichier WAV de ma solution au problème de golf de code Twinkle Twinkle Little Star .

Une caractéristique importante est que le son diminue avec le temps. Pour observer ce comportement, essayez de maintenir une touche enfoncée pendant quelques secondes et écoutez ce qui se passe.

Voici une version plus lisible du code:

<style>
    table {
        border-collapse: collapse;
        border-width: 1 0;
        border-style: solid;
        font-size: 64;
        line-height: 2;
    }

    td {
        border-style: solid;
        border-width: 0 1;
    }
</style>

<table>
        <td colspan=3 title=0>&nbsp;
        <td bgcolor=black colspan=2 title=1>&nbsp;
        <td colspan=2 title=2>&nbsp;
        <td bgcolor=black colspan=2 title=3>&nbsp;
        <td colspan=3 title=4>&nbsp;
    <tr>
        <td colspan=4 title=0>&nbsp;
        <td colspan=4 title=2>&nbsp;
        <td colspan=4 title=4>&nbsp;
</table>

<script>
    for (A = [y = 5]; y--;) {

        for (s = x = 64e3; x--;)
            s += "~ "[x * (268 + 17 * y) >> 13 & 1];

        A[y] = new Audio("data:audio/wav;base64,UklGRiXuAgBXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQHuAgCA" + btoa(s));
    }

    setInterval(function() {
        for (y = 5; y--;)
            with (A[y])
                volume = volume && Math.exp(-currentTime);
    }, 99);

    onmousedown = function(e) {
        if (z = e.target.title)
            with (A[z])
                play(currentTime = 0, volume = 1);
    };

    onmouseup = function(e) { 
        if (z = e.target.title)
            with (A[z])
                pause(volume = 0);
    };
</script>
Veuillez vous lever
la source
1
+1 Fonctionne bien dans Firefox 15, même si j'aurais choisi un meilleur instrument de sondage.
DavidC
6

Groovy: 577 (703 avec des espaces blancs)

Les 5 premières notes. D'autres pourraient être ajoutés facilement, c'est un peu dynamique.

Putain de swing. Avec une balançoire, ce serait probablement mieux.

entrez la description de l'image ici

Joue à travers JFugue.

Sur github: https://github.com/wpiasecki/glissando/blob/master/src/br/glissando/Piano.groovy

Sur groovy 2.0.2

import java.awt.event.*
class Note { def n; boolean s; def p() { new org.jfugue.Player().with {play n;close()}} }
notes=['C','C#','D','D#','E'].inject([]){ l,n -> l<< Note[n:n,s:n=~/#/]}
h=300
l=0
w=60
x=0
new groovy.swing.SwingBuilder().edt {
  frame size:[notes.size()*30+30,h], 
    show:true, 
    defaultCloseOperation:javax.swing.JFrame.EXIT_ON_CLOSE, 
    { l = layeredPane() }
  notes.each { n ->
    C=java.awt.Color
    s=n.s
    p=panel bounds:(s ? [x-15,0,w-30,h-100] : [x,0,w,h]),
      background: s ? C.BLACK : C.WHITE, 
      border: lineBorder(1, color: C.BLACK)
    p.addMouseListener({ if(it.id==MouseEvent.MOUSE_CLICKED)n.p() }as MouseListener)
    if(!s)x+=w
    l.add p,s?0:1
  }
}
Will Lp
la source
1

R - 491 caractères

Je suis un peu en retard mais je viens de voir ce post hier.

Fonctionne sur Mac, utilise playRWave et les packages tuneRet splancs.

a=array
x=c(7,2)
y=c(5,2)
z=c(1,1,3,3)
par(mar=rep(0,4))
plot(NA,xli=c(0,9),yli=c(0,3))
N=list(a(c(0,3,3,2,2,0,0,0,0,z,0),x),a(c(3,6,6,5,5,4,4,3,3,0,0,z,1,1,0),c(9,2)),a(c(6,6,7,7,9,9,6,0,z,0,0),x),a(c(2,4,4,2,2,z,1),y),a(c(5,7,7,5,5,z,1),y))
c=c(NA,NA,NA,1,1)
for(i in 1:5){polygon(N[[i]],c=c[i])}
h=c(261.63,293.66,329.63,277.18,311.13)
library(tuneR)
setWavPlayer("~/Library/Audio/playRwave")
repeat{P=data.frame(locator(1));play(sine(h[sapply(N,function(x)splancs::inout(P,x))],bit=16))}

entrez la description de l'image ici

Non golfé:

par(mar=rep(0,4))
plot(NA,xlim=c(0,9),ylim=c(0,3)) #Create empty plot: due to fuzzy matching of arguments, xlim can be reduced to xli
N=list(array(c(0,3,3,2,2,0,0,0,0,1,1,3,3,0),dim=c(7,2)), #C polygon
       array(c(3,6,6,5,5,4,4,3,3,0,0,1,1,3,3,1,1,0),dim=c(9,2)), #D polygon
       array(c(6,6,7,7,9,9,6,0,1,1,3,3,0,0),dim=c(7,2)), #E polygon
       array(c(2,4,4,2,2,1,1,3,3,1),dim=(5,2)), #Db polygon
       array(c(5,7,7,5,5,1,1,3,3,1),dim=(5,2)))  #Eb polygon
c=c(NA,NA,NA,1,1) #Colors: by default 1 is "black"
for(i in 1:5){polygon(N[[i]],color=c[i])}
h=c(261.63,293.66,329.63,277.18,311.13) #Notes frequency in hertz: C4, D4, E4, Db4 and Eb4
library(tuneR)
setWavPlayer("~/Library/Audio/playRwave") #This can be change to other wav player I think
repeat{
    P=data.frame(locator(1)) #Grab coordinates of selected point
    H=h[sapply(N,function(x)splancs::inout(P,x))] #In which polygon does the selected point belong to, then map it to its ferquency
    s=sine(H,bit=16) #By default create a 1sec note at the given frequency with 44100 sampling rate
    play(s)
    }
plannapus
la source