GUI Piano erstellen [geschlossen]

15

Herausforderung

Erstellen Sie eine GUI-Tastatur mit möglichst wenigen Zeichen.

Beispiel

Da dies eine Aufgabe in einem meiner Kurse war, kann ich den Quellcode nicht anzeigen. Hier ist jedoch ein Screenshot meiner Tastatur.

Klavier

In diesem Beispiel waren meine Tasten vom Typ JButtonund ich habe einen Midi-Synthesizer verwendet, um den Sound zu erzeugen (mit den Standardwerten für die ADSR-Hüllkurve).

Regeln

  • Du dürfen externe Standardbibliotheken verwenden.
  • Sei kreativ mit deinem Sound. Sie können 8-Bit, eine Sitar usw. verwenden.
  • Der Einfachheit halber haben Sie möglicherweise fünf Schlüssel. schwarz und weiß, von C bis E (die ersten fünf Tasten auf meiner Tastatur).
  • Am wichtigsten ist ... präsentieren Sie Ihre Arbeit!

HINWEIS : Je nachdem, mit welcher Sprache Sie arbeiten, kann dies eine ziemlich große Aufgabe sein.

Dies ist meine erste Frage zu SE Code Golf. Wenn etwas unklar ist, fragen Sie bitte nach weiteren Einzelheiten.


BEARBEITEN : Das Fälligkeitsdatum für diese Herausforderung ist der 22.09.12. Wenn Sie eine Antwort nach diesem Datum posten, werde ich sie trotzdem überprüfen (und möglicherweise +1 geben).

rauben
quelle
2
Einschränkungen bezüglich der zu verwendenden Sprache werden hier nicht sehr gern gesehen. Überlegen Sie, ob Sie Ihre Einschränkung fallen lassen oder einen wichtigen Grund nennen sollten.
FUZxxl
1
@FUZxxl Wie im Abschnitt Beispiel angegeben, war dies ein Begriffsprojekt für unsere Java-Klasse. Es wird immer noch als Begriffsprojekt für genau diese Klasse verwendet. Aber ich denke, ich bin nur paranoid, also werde ich die Beschränkungen fallen lassen. Ich denke, Sie meinten, welche Sprachen Sie nicht benutzen sollten ... aber was auch immer, ich habe sie entfernt.
Rob
2
Was sind die Mindestanforderungen an eine "GUI-Tastatur"? Ich schließe aus dem, was bereits vorhanden ist, dass es eine GUI anzeigen und einen Ton erzeugen muss, aber welche Einschränkungen gibt es für: a) den Eingabemechanismus; b) die Schallhülle; c) die verwendete Skala; d) die Genauigkeit der Abstimmung; e) die Proportionen der Schlüssel?
Peter Taylor
2
@ MikeDtrick, das beantwortet 0/5 meiner Fragen. Ich frage nicht, wie Ihre Implementierung funktioniert hat: Ich frage, wie ich herausfinden kann, ob meine (hypothetische) Implementierung ein gültiger Konkurrent ist, da es keinen Sinn macht, einen Eintrag um 20% zu kürzen, wenn dies von einem gültigen Eintrag zu abweicht eine ungültige.
Peter Taylor
1
@MikeDtrick: Sie könnten beispielsweise verlangen, dass die Schaltflächen Pixel für Pixel genau wie in Ihrem Beispiel aussehen. Im anderen Extremfall können Sie jede Anordnung von fünf GUI-Schaltflächen eines beliebigen Typs zulassen.
han

Antworten:

11

Mathematica 319 259 255


Bearbeiten: Die Tasten werden jetzt beim Klicken gedrückt (als Schaltflächen).


Dies spielt die Flügelnoten {"C", "C #", "D", "D #", "E"}, wobei "C" z[n_]die Note in der Mitte C spielt.

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]

Tastatur


Die Tastatur kann mit weniger als dem Doppelten der Zeichen auf 18 Tasten erweitert werden:

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

große Tastatur

DavidC
quelle
1
+1 Ich habe keinen Zweifel daran, dass dies funktionieren wird. Ich wünschte nur, ich könnte damit spielen.
Rob
1
Ich habe eine .cdf-Version der Datei in meiner DropBox unter dropbox.com/sh/m3y0fs0v0nidqt5/UTv_0YGpz5 hinterlassen. Sie können diese mit anderen teilen. Es sollte keine Lizenzprobleme geben, da es für nichtkommerzielle Bildungszwecke verwendet wird. Sie müssen den kostenlosen Wolfram CDF-Player herunterladen, wenn Sie ihn noch nicht haben.
DavidC
David, ich brauche w = {67, 300}dein Ergebnis. Irgendeine Idee, warum der Unterschied? Darf ich diesen Code auch bearbeiten, um ihn zu verkürzen, wenn ich dazu in der Lage bin?
Mr.Wizard
Mr.Wizard. w = {67,300}Funktioniert in Version 9 einwandfrei. Wenn Sie also Änderungen vornehmen oder den Code kürzen möchten, fahren Sie fort. Das Anpassen der Tastengröße war ein Treffer oder ein Fehler. Seltsame Dinge geschahen aus Gründen, die ich nicht erklären kann. (Das Hinzufügen weiterer Schaltflächen wirkt sich beispielsweise auf die Proportionen der ursprünglichen Schaltflächen aus.)
DavidC
10

Webseite (840/796 Zeichen)

>>> Beginnen Sie zu spielen (Internet Explorer wird aus mehreren Gründen nicht unterstützt; Google Chrome und Opera funktionieren am besten.)

Ich könnte es wahrscheinlich etwas kürzer machen, aber es ist ein guter Anfang. Die niedrigere Punktzahl ergibt sich aus dem Ersetzen aller Vorkommen  durch den Buchstaben selbst und dem Entfernen des Schlüsselworts new, wobei die letztere Änderung die Google Chrome-Kompatibilität beeinträchtigt.

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

Speichern Sie diesen Code als Textdatei mit einem Namen, der auf .htm oder .html endet, und öffnen Sie ihn in Chrome oder Opera (Safari funktioniert möglicherweise auch), oder öffnen Sie einfach die JSBin-Seite der Lösung, um die Wiedergabe zu starten. Ich habe den WAV-Datei-Header aus meiner Lösung für das Twinkle-Twinkle-Little-Star- Code-Golf-Problem wiederverwendet .

Ein wichtiges Merkmal ist, dass der Klang mit der Zeit abnimmt. Um dieses Verhalten zu beobachten, halten Sie eine Taste einige Sekunden lang gedrückt und hören Sie zu, was passiert.

Hier ist eine besser lesbare Version des Codes:

<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>
PleaseStand
quelle
1
+1 Funktioniert gut in Firefox 15, obwohl ich ein besser klingendes Instrument gewählt hätte.
DavidC
6

Groovy: 577 (703 mit Leerzeichen)

Die ersten 5 Noten. Andere könnten leicht hinzugefügt werden, es ist etwas dynamisch.

Verdammter Schwung. Wahrscheinlich wäre es mit einer swing lib besser.

Bildbeschreibung hier eingeben

Spielt durch JFugue.

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

Auf groovigen 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
quelle
1

R - 491 Zeichen

Ich bin ein bisschen spät dran, aber ich habe diesen Beitrag erst gestern gesehen.

Funktioniert auf einem Mac, verwendet playRWave und Pakete tuneRund 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))}

Bildbeschreibung hier eingeben

Ungolfed:

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
quelle