Crie um GUI Piano [fechado]

15

Desafio

Crie um teclado GUI com o mínimo de caracteres possível.

Exemplo

Como essa foi uma tarefa em um dos meus cursos, não consigo mostrar o código fonte. No entanto, aqui está uma captura de tela do meu teclado.

piano

Neste exemplo, minhas teclas eram do tipo JButtone usei um Midi Synthesizer para produzir o som (com os valores padrão do envelope ADSR).

Regras

  • Você tem permissão para usar bibliotecas externas padrão.
  • Seja criativo com o seu som. Você pode usar 8 bits, uma cítara, etc.
  • Por uma questão de simplicidade, você pode ter cinco chaves; preto e branco, de C a E (as cinco primeiras teclas do meu teclado).
  • Mais importante ... mostre seu trabalho!

AVISO : Dependendo do idioma em que você escolher trabalhar, essa pode ser uma tarefa bastante grande.

Esta é a minha primeira pergunta sobre o SE Code Golf. Se algo não estiver claro, solicite mais detalhes.


EDIT : A data de vencimento para este desafio será 22/09/12. Se você postar uma resposta após essa data, examinarei-a independentemente (e possivelmente a marque com +1).

Roubar
fonte
2
Restrições sobre qual idioma usar não são muito apreciadas aqui. Considere descartar sua restrição ou nomear um motivo importante.
FUZxxl 15/09/12
1
@FUZxxl Conforme declarado na seção Exemplo, este foi um projeto de termo para a nossa classe Java. Ele ainda está sendo usado como um projeto de termo para essa mesma classe. Mas suponho que sou apenas paranóico, então vou abandonar as restrições. Eu acho que você quis dizer quais idiomas não usar ... mas seja o que for, eu os removi.
Rob Rob
2
Quais são os requisitos mínimos para ser considerado um "teclado GUI"? Eu deduzo do que já está presente que deve exibir uma GUI e produzir algum som, mas que restrições existem: a) o mecanismo de entrada; b) o envelope sonoro; c) a balança utilizada; d) a precisão do ajuste; e) as proporções das chaves?
Peter Taylor
2
@MikeDtrick, que responde 0/5 das minhas perguntas. Não estou perguntando como a sua implementação funcionou: estou perguntando como posso saber se minha implementação (hipotética) é um concorrente válido, porque não há sentido em diminuir uma entrada em 20%, se isso o fizer de uma entrada válida para um inválido.
Peter Taylor
1
@MikeDtrick: Por exemplo, você pode exigir que os botões sejam exatamente iguais aos do seu exemplo, pixel por pixel. No outro extremo, você pode permitir qualquer arranjo de cinco botões da GUI de qualquer tipo.
han

Respostas:

11

Mathematica 319 259 255


Editar: As teclas agora pressionam (como botões) quando clicadas.


Isso tocará as notas do piano de cauda {"C", "C #", "D", "D #", "E"}, onde "C" é o meio C. z[n_]toca a nota.

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]

teclado


O teclado pode ser estendido para 18 teclas usando menos que o dobro dos caracteres:

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

teclado grande

DavidC
fonte
1
+1 Não tenho dúvidas de que isso funcionará ... Eu gostaria de poder jogar nele.
Rob Rob
1
Deixei uma versão .cdf do arquivo no meu DropBox em dropbox.com/sh/m3y0fs0v0nidqt5/UTv_0YGpz5. Você pode compartilhar isso com outras pessoas. Não deve haver problemas de licenciamento porque está sendo usado para fins educacionais não comerciais. Você precisará fazer o download gratuito do Wolfram CDF player, se ainda não o tiver.
21812 DavidC
David, preciso w = {67, 300}obter o seu resultado; alguma idéia do porquê da diferença? Além disso, posso editar esse código para reduzi-lo, se eu puder?
precisa saber é o seguinte
Mr.Wizard. w = {67,300}funciona bem na versão 9, portanto, se você quiser alterá-lo ou, nesse caso, encurtar qualquer código, vá em frente. O ajuste do tamanho do botão foi um sucesso ou um fracasso. Coisas estranhas aconteceram por razões que não posso explicar. (Por exemplo, a adição de mais botões afeta as proporções dos botões originais.) #
187
10

Página da Web (840/796 caracteres)

>>> Comece a jogar (o Internet Explorer não é suportado por vários motivos; o Google Chrome e o Opera funcionam melhor.)

Eu provavelmente poderia tornar isso um pouco mais curto, mas é um bom começo. A pontuação mais baixa é depois de substituir todas as ocorrências de  pelo caractere e remover a palavra-chave new, a última alteração quebrando a compatibilidade do 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>

Salve esse código como um arquivo de texto com um nome terminado em .htm ou .html e abra-o no Chrome ou Opera (o Safari também pode funcionar) ou abra a página JSBin da solução para começar a reprodução. Reutilizei o cabeçalho do arquivo WAV da minha solução no problema de golfe com código Twinkle Twinkle Little Star .

Uma característica importante é que o som diminui com o passar do tempo. Para observar esse comportamento, tente manter uma tecla pressionada por alguns segundos e ouvir o que acontece.

Aqui está uma versão mais legível do código:

<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
fonte
1
O +1 funciona bem no Firefox 15, embora eu tivesse escolhido um instrumento com melhor som.
DavidC
6

Groovy: 577 (703 com espaços em branco)

As 5 primeiras notas. Outros podem ser adicionados facilmente, é um pouco dinâmico.

Maldito balanço. Provavelmente com uma lib de swing seria melhor.

insira a descrição da imagem aqui

Reproduz através do JFugue.

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

No 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
fonte
1

R - 491 caracteres

Estou um pouco atrasado, mas acabei de ver este post ontem.

Funciona em um Mac, usa playRWave e pacotes tuneRe 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))}

insira a descrição da imagem aqui

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
fonte