Utwórz GUI Piano [zamknięte]

15

Wyzwanie

Utwórz klawiaturę GUI z jak najmniejszą liczbą znaków.

Przykład

Ponieważ było to zadanie na jednym z moich kursów, nie mogę pokazać kodu źródłowego. Oto zrzut ekranu mojej klawiatury.

fortepian

W tym przykładzie moje klucze były typu JButtoni użyłem syntezatora Midi do wytworzenia dźwięku (z domyślnymi wartościami obwiedni ADSR).

Zasady

  • Ci są dopuszczone do korzystania ze standardowych bibliotek zewnętrznych.
  • Bądź kreatywny ze swoim dźwiękiem. Możesz użyć 8-bit, sitar itp.
  • Dla uproszczenia możesz mieć pięć kluczy; czarno-biały, od C do E (pierwsze pięć klawiszy na mojej klawiaturze).
  • Co najważniejsze ... pokaż swoją pracę!

UWAGA : W zależności od języka, z którym chcesz pracować, może to być dość duże zadanie.

To jest moje pierwsze pytanie dotyczące SE Code Golf. Jeśli coś jest niejasne, poproś o dalsze szczegóły.


EDYCJA : Terminem tego wyzwania będzie 9/22/12. Jeśli opublikujesz odpowiedź po tej dacie, przejrzę ją niezależnie (i być może dasz +1).

Obrabować
źródło
2
Ograniczenia dotyczące używania języka nie są tutaj bardzo lubiane. Zastanów się nad usunięciem ograniczenia lub podaj ważny powód.
FUZxxl,
1
@FUZxxl Jak stwierdzono w sekcji Przykład, był to projekt terminowy dla naszej klasy Java. Nadal jest używany jako projekt terminowy dla tej właśnie klasy. Ale przypuszczam, że jestem po prostu paranoikiem, więc zniosę ograniczenia. Myślę, że miałeś na myśli, których języków nie używać ... ale cokolwiek, usunąłem je.
Rob
2
Jakie minimalne wymagania należy uznać za „klawiaturę GUI”? Wnioskuję z tego, co już jest obecne, że musi wyświetlać GUI i generować dźwięk, ale jakie są ograniczenia dotyczące: a) mechanizmu wejściowego; b) obwiednia dźwięku; c) zastosowana skala; d) dokładność strojenia; e) proporcje kluczy?
Peter Taylor,
2
@MikeDtrick, który odpowiada 0/5 moich pytań. Nie pytam, jak działała twoja implementacja: pytam, skąd mam wiedzieć, czy moja (hipotetyczna) implementacja jest ważnym konkurentem, ponieważ nie ma sensu skracać wpisu o 20%, jeśli to czyni go z ważnego wpisu do niepoprawny.
Peter Taylor
1
@MikeDtrick: Na przykład możesz wymagać, aby przyciski wyglądały dokładnie tak, jak w twoim przykładzie, piksel po pikselu. Z drugiej strony możesz zezwolić na dowolne rozmieszczenie pięciu przycisków GUI dowolnego typu.
han

Odpowiedzi:

11

Mathematica 319 259 255


Edycja: klawisze teraz naciskają (jako przyciski) po kliknięciu.


Spowoduje to odtworzenie nut fortepianu {„C”, „C #”, „D”, „D #”, „E”}, gdzie „C” jest środkiem C. z[n_]gra nutę.

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]

klawiatura


Klawiaturę można rozszerzyć do 18 klawiszy, używając mniej niż dwa znaki:

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

duża klawiatura

DavidC
źródło
1
+1 Nie mam wątpliwości, że to zadziała ... Chciałbym po prostu grać.
Rob
1
Zostawiłem wersję pliku .cdf w moim DropBox na dropbox.com/sh/m3y0fs0v0nidqt5/UTv_0YGpz5 Możesz to udostępnić innym. Nie powinno być problemów z licencjonowaniem, ponieważ jest on wykorzystywany do niekomercyjnych celów edukacyjnych. Musisz pobrać darmowy odtwarzacz CDF Wolfram, jeśli jeszcze go nie masz.
DavidC
David, muszę w = {67, 300}uzyskać twój wynik; jakiś pomysł, dlaczego różnica? Czy mogę również edytować ten kod, aby go skrócić, jeśli mogę?
Mr.Wizard
Mr.Wizard. w = {67,300}działa dobrze w wersji 9, więc jeśli chcesz to zmienić lub skrócić kod, przejdź od razu. Dostosowanie rozmiaru przycisku było trafione lub pominięte. Dziwne rzeczy wydarzyły się z powodów, których nie potrafię wyjaśnić. (Na przykład dodanie większej liczby przycisków wpływa na proporcje oryginalnych przycisków.)
DavidC,
10

Strona internetowa (840/796 znaków)

>>> Zacznij grać (Internet Explorer nie jest obsługiwany z wielu powodów; Google Chrome i Opera działają najlepiej).

Prawdopodobnie mógłbym to trochę skrócić, ale to dobry początek. Niższy wynik to zamiana wszystkich wystąpień  na samą postać i usunięcie słowa kluczowegonew , przy czym ta ostatnia zmiana łamie zgodność z 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>

Zapisz ten kod jako plik tekstowy o nazwie kończącej się na .htm lub .html i otwórz go w Chrome lub Operze (Safari może również działać), lub po prostu otwórz stronę JSBin rozwiązania, aby rozpocząć odtwarzanie. Ponownie wykorzystałem nagłówek pliku WAV z mojego rozwiązania do problemu golfowego z kodem Twinkle Twinkle Little Star .

Ważną cechą jest to, że dźwięk z czasem maleje. Aby zaobserwować to zachowanie, spróbuj przytrzymać klawisz przez kilka sekund i słuchać, co się stanie.

Oto bardziej czytelna wersja kodu:

<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>
Proszę wstać
źródło
1
+1 działa dobrze w przeglądarce Firefox 15, chociaż wybrałbym lepiej brzmiący instrument.
DavidC
6

Groovy: 577 (703 z białymi spacjami)

Pierwsze 5 nut. Inne można łatwo dodać, jest to nieco dynamiczne.

Cholerna huśtawka. Prawdopodobnie przy swing swing byłoby lepiej.

wprowadź opis zdjęcia tutaj

Odtwarza przez JFugue.

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

Na 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
źródło
1

R - 491 znaków

Trochę się spóźniłem, ale wczoraj widziałem ten post.

Działa na komputerze Mac, używa playRWave oraz pakietów tuneRi 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))}

wprowadź opis zdjęcia tutaj

Nie golfowany:

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
źródło