Tạo một GUI Piano [đã đóng]


15

Thử thách

Tạo Bàn phím GUI với càng ít ký tự càng tốt.

Thí dụ

Bởi vì đây là một bài tập trong một trong các khóa học của tôi, tôi không thể hiển thị mã nguồn. Tuy nhiên, đây là một ảnh chụp màn hình bàn phím của tôi.

đàn piano

Trong ví dụ này, các phím của tôi thuộc loại JButtonvà tôi đã sử dụng Bộ tổng hợp Midi để tạo ra âm thanh (với các giá trị phong bì ADSR mặc định).

Quy tắc

  • Bạn được phép sử dụng các thư viện bên ngoài tiêu chuẩn.
  • Hãy sáng tạo với âm thanh của bạn. Bạn có thể sử dụng 8 bit, sitar, v.v.
  • Để đơn giản, bạn có thể có năm khóa; đen trắng, từ C đến E (năm phím đầu tiên trên bàn phím của tôi).
  • Quan trọng nhất là ... giới thiệu công việc của bạn!

THÔNG BÁO : Tùy thuộc vào ngôn ngữ bạn chọn để làm việc với, đây có thể là một nhiệm vụ khá lớn.

Đây là câu hỏi đầu tiên của tôi về SE Code Golf. Nếu bất cứ điều gì không rõ ràng, xin vui lòng hỏi thêm chi tiết.


EDIT : Ngày đáo hạn cho thử thách này sẽ là 22/9/12. Nếu bạn đăng câu trả lời sau ngày này, tôi sẽ xem xét nó bất kể (và có thể +1 nó).


2
Những hạn chế về ngôn ngữ sử dụng không được yêu thích nhiều ở đây. Xem xét bỏ hạn chế của bạn hoặc đặt tên cho một lý do quan trọng.
FUZxxl

1
@FUZxxl Như đã nêu trong phần Ví dụ, đây là một dự án thuật ngữ cho lớp Java của chúng tôi. Nó vẫn đang được sử dụng như một dự án hạn cho chính lớp đó. Nhưng tôi cho rằng tôi chỉ bị hoang tưởng nên sẽ bỏ các hạn chế. Tôi nghĩ bạn có nghĩa là ngôn ngữ nào không được sử dụng ... nhưng bất cứ điều gì, tôi đã loại bỏ chúng.
Cướp

2
Các yêu cầu tối thiểu để được coi là "bàn phím GUI" là gì? Tôi suy luận từ những gì đã có là nó phải hiển thị GUI và tạo ra một số âm thanh, nhưng có những hạn chế nào đối với: a) cơ chế đầu vào; b) đường bao âm thanh; c) thang đo được sử dụng; d) độ chính xác của điều chỉnh; e) tỷ lệ của các phím?
Peter Taylor

2
@MikeDtrick, câu trả lời 0/5 câu hỏi của tôi. Tôi không hỏi cách triển khai của bạn hoạt động như thế nào một không hợp lệ.
Peter Taylor

1
@MikeDtrick: Ví dụ: bạn có thể yêu cầu các nút trông giống hệt như các nút trong ví dụ của bạn, pixel theo pixel. Ở một thái cực khác, bạn có thể cho phép sắp xếp năm nút GUI thuộc bất kỳ loại nào.
han

Câu trả lời:


11

Toán học 319 259 255


Chỉnh sửa: Phím bây giờ ấn xuống (dưới dạng nút) khi nhấp vào.


Điều này sẽ phát các nốt grand piano {"C", "C #", "D", "D #", "E"}, trong đó "C" là giữa C. z[n_]chơi nốt.

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]

bàn phím


Bàn phím có thể được mở rộng thành 18 phím bằng cách sử dụng ít hơn gấp đôi ký tự:

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

bàn phím lớn


1
+1 Tôi không nghi ngờ gì trong đầu rằng nó sẽ hoạt động ... Tôi chỉ ước mình có thể chơi trên đó.
Cướp

1
Tôi đã để lại phiên bản .cdf của tệp trong DropBox của mình tại dropbox.com/sh/m3y0fs0v0nidqt5/UTv_0YGpz5 Bạn có thể chia sẻ tệp này với người khác. Không nên có vấn đề cấp phép vì nó đang được sử dụng cho mục đích giáo dục, phi thương mại. Bạn sẽ cần tải xuống trình phát CDF Wolfram miễn phí nếu bạn chưa có.
DavidC

David, tôi cần w = {67, 300}nhận được kết quả của bạn; Bất cứ ý tưởng tại sao sự khác biệt? Ngoài ra, tôi có thể chỉnh sửa mã này để rút ngắn nó, nếu tôi có thể?
Mr.Wizard

Ông thằn lằn. w = {67,300}hoạt động tốt trên câu 9, vì vậy nếu bạn muốn thay đổi nó, hoặc cho vấn đề đó, hãy rút ngắn bất kỳ mã nào, đi thẳng về phía trước. Điều chỉnh kích thước nút bị nhấn hoặc bỏ lỡ. Những điều kỳ lạ đã xảy ra vì những lý do tôi không thể giải thích. (Ví dụ: việc thêm nhiều nút ảnh hưởng đến tỷ lệ của các nút gốc.)
DavidC

10

Trang web (840/796 ký tự)

>>> Bắt đầu chơi (Internet Explorer không được hỗ trợ vì nhiều lý do; Google Chrome và Opera hoạt động tốt nhất.)

Tôi có lẽ có thể làm điều này ngắn hơn một chút, nhưng nó là một khởi đầu tốt. Điểm thấp hơn là sau khi thay thế tất cả các lần xuất hiện  bằng chính ký tự đó và xóa từ khóa new, thay đổi sau sẽ phá vỡ tính tương thích của 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>

Lưu mã này dưới dạng tệp văn bản có tên kết thúc bằng .htm hoặc .html và mở nó trong Chrome hoặc Opera (Safari cũng có thể hoạt động) hoặc chỉ cần mở trang JSBin của giải pháp để bắt đầu chơi. Tôi đã sử dụng lại tiêu đề tệp WAV từ giải pháp của mình cho vấn đề golf mã Twinkle Twinkle Little Star .

Một tính năng quan trọng là âm thanh giảm dần khi thời gian trôi qua. Để quan sát hành vi này, hãy thử giữ một phím trong vài giây và lắng nghe những gì xảy ra.

Đây là một phiên bản dễ đọc hơn của mã:

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

1
+1 Hoạt động tốt trong Firefox 15, mặc dù tôi đã chọn một công cụ âm thanh tốt hơn.
DavidC

6

Groovy: 577 (703 với khoảng trắng)

5 lưu ý đầu tiên. Những người khác có thể được thêm dễ dàng, nó hơi năng động.

Xích đu chết tiệt. Có lẽ với một lib lib nó sẽ tốt hơn.

nhập mô tả hình ảnh ở đây

Chơi qua JFugue.

Trên github: https://github.com/wpiasecki/glissando/blob/master/src/br/glissando/Piano.groovy

Trên 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
  }
}

1

R - 491 ký tự

Tôi hơi muộn nhưng tôi mới thấy bài này ngày hôm qua.

Hoạt động trên máy Mac, sử dụng playRWave và các gói tuneRsplancs.

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

nhập mô tả hình ảnh ở đây

Ung dung:

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)
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.