Crear un piano GUI [cerrado]

15

Desafío

Cree un teclado GUI con la menor cantidad de caracteres posible.

Ejemplo

Debido a que esta fue una tarea en uno de mis cursos, no puedo mostrar el código fuente. Sin embargo, aquí hay una captura de pantalla de mi teclado.

piano

En este ejemplo, mis teclas eran de tipo JButtony utilicé un sintetizador Midi para producir el sonido (con los valores de envolvente ADSR predeterminados).

Reglas

  • Usted está permitido utilizar librerías externas estándar.
  • Sé creativo con tu sonido. Puedes usar 8 bits, un sitar, etc.
  • Por simplicidad, puede tener cinco llaves; blanco y negro, de C a E (las primeras cinco teclas de mi teclado).
  • Lo más importante ... ¡muestra tu trabajo!

AVISO : Según el idioma con el que elija trabajar, esta puede ser una tarea bastante grande.

Esta es mi primera pregunta sobre SE Code Golf. Si algo no está claro, solicite más detalles.


EDITAR : La fecha de vencimiento para este desafío será el 22/09/12. Si publica una respuesta después de esta fecha, la revisaré independientemente (y posiblemente haga +1).

Robar
fuente
2
Las restricciones sobre qué idioma usar no son muy apreciadas aquí. Considere eliminar su restricción o nombre una razón importante.
FUZxxl
1
@FUZxxl Como se indicó en la sección Ejemplo, este fue un proyecto de término para nuestra clase Java. Todavía se está utilizando como un proyecto de término para esa misma clase. Pero supongo que soy paranoico, así que abandonaré las restricciones. Creo que quisiste decir qué idiomas no usar ... pero lo que sea, los eliminé.
Rob el
2
¿Cuáles son los requisitos mínimos para ser considerado un "teclado GUI"? De lo que ya está presente deduzco que debe mostrar una GUI y producir algo de sonido, pero qué restricciones existen sobre: ​​a) el mecanismo de entrada; b) la envolvente de sonido; c) la escala utilizada; d) la precisión de la afinación; e) las proporciones de las teclas?
Peter Taylor
2
@ MikeDtrick, eso responde 0/5 de mis preguntas. No estoy preguntando cómo funcionó su implementación: estoy preguntando cómo puedo saber si mi implementación (hipotética) es un competidor válido, porque no tiene sentido acortar una entrada en un 20% si hacerlo lo convierte en una entrada válida para uno inválido.
Peter Taylor
1
@ MikeDtrick: Por ejemplo, podría requerir que los botones se vean exactamente como los de su ejemplo, píxel por píxel. En el otro extremo, podría permitir cualquier disposición de cinco botones GUI de cualquier tipo.
han

Respuestas:

11

Mathematica 319 259 255


Editar: las teclas ahora se presionan (como botones) al hacer clic.


Esto tocará las notas de piano de cola {"C", "C #", "D", "D #", "E"}, donde "C" es el medio C. z[n_]toca la 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


El teclado se puede extender a 18 teclas usando menos del doble de los 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
fuente
1
+1 No tengo dudas de que esto funcionará ... Solo desearía poder jugar con eso.
Rob
1
Dejé una versión .cdf del archivo en mi DropBox en dropbox.com/sh/m3y0fs0v0nidqt5/UTv_0YGpz5. Puedes compartir esto con otros. No debería haber problemas de licencia porque se está utilizando con fines educativos no comerciales. Tendrá que descargar el reproductor Wolfram CDF gratuito si aún no lo tiene.
DavidC
David, necesito w = {67, 300}obtener tu resultado; alguna idea de por qué la diferencia? Además, ¿puedo editar este código para acortarlo, si puedo?
Mr.Wizard
Señor mago. w = {67,300}funciona bien en la v. 9, por lo que si desea cambiarlo o, para el caso, acortar cualquiera de los códigos, continúe. El ajuste del tamaño del botón fue impredecible. Cosas extrañas sucedieron por razones que no puedo explicar. (Por ejemplo, agregar más botones afecta las proporciones de los botones originales.)
DavidC
10

Página web (840/796 caracteres)

>>> Comience a jugar (Internet Explorer no es compatible por varias razones; Google Chrome y Opera funcionan mejor).

Probablemente podría hacer esto un poco más corto, pero es un buen comienzo. La puntuación más baja es después de reemplazar todas las apariciones de  con el personaje en sí y eliminar la palabra clave new, este último cambio rompe la compatibilidad de 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>

Guarde este código como un archivo de texto con un nombre que termine en .htm o .html y ábralo en Chrome u Opera (Safari también podría funcionar), o simplemente abra la página JSBin de la solución para comenzar a jugar. Reutilicé el encabezado del archivo WAV de mi solución al problema de golf del código Twinkle Twinkle Little Star .

Una característica importante es que el sonido disminuye a medida que pasa el tiempo. Para observar este comportamiento, intente mantener presionada una tecla durante unos segundos y escuchar lo que sucede.

Aquí hay una versión más legible del 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>
Por favor levantese
fuente
1
+1 Funciona bien en Firefox 15, aunque hubiera elegido un mejor instrumento de sonido.
DavidC
6

Groovy: 577 (703 con espacios en blanco)

Las primeras 5 notas. Otros podrían agregarse fácilmente, es algo dinámico.

Maldito swing. Probablemente con un swing lib sería mejor.

ingrese la descripción de la imagen aquí

Juega a través de JFugue.

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

En 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
fuente
1

R - 491 caracteres

Llego un poco tarde, pero ayer vi esta publicación.

Funciona en una Mac, usa playRWave y paquetes tuneRy 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))}

ingrese la descripción de la imagen aquí

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