공격, 부패, 지속, 해제


47

사운드 신시사이저 는 엔벨로프 제너레이터를 사용하여 사운드의 특정 파라미터 (예 : 전체 음량)가 시간에 따라 어떻게 변하는 지 제어합니다. 많은 신디사이저에서 엔벌 로프는 Wikipedia 의 다음 그림과 같이 네 개의 매개 변수로 정의됩니다 .

  • Attack time (A) : 키를 처음 누를 때 엔벨로프가 최대 레벨에 도달하는 데 걸리는 시간입니다 ( 0부터 시작).
  • 부패 시간 (D) : 봉투가 지정된 서스테인 레벨에 도달하는 데 걸린 시간입니다.
  • 서스테인 레벨 (S) : 키를 누르고있는 동안 초기 공격 및 붕괴 후 유지되는 레벨입니다.
  • 릴리스 시간 (R) : 키를 놓을 때 엔벨로프가 0에 도달하는 데 걸린 시간입니다.

여기에 이미지 설명을 입력하십시오

도전

네 개의 매개 변수 A, D, S, R을 입력하고 엔벨로프를 플로팅합니다 .

매개 변수는 0에서 127 사이의 정수 값입니다 .

(공격 단계의 끝에 도달 한) 최대 레벨127 로 가정됩니다 .

서스테인 레벨수평 세그먼트지속 시간이 64 인 것으로 가정합니다 (실제 사운드에서이 지속 시간은 고정되어 있지 않지만 키를 누르고있는 시간에 의해 결정됩니다).

형식 및 세부 사항

출력은 래스터 또는 벡터 형식의 이미지 여야합니다. 래스터 인 경우 다각형 선은 가로로 세로로 최소 50 픽셀을 차지해야합니다.

이미지는 표준 이미지 형식으로 파일로 표시되거나 생성 될 수 있습니다. 파일을 디스크에 쓰거나 정확한 내용을 STDERR 또는 함수 리턴 인수로 출력 할 수 있습니다.

그래프에는 봉투를 정의하는 다각형 선만 포함하면됩니다. 각 축의 스케일을 자유롭게 선택할 수 있습니다. 축선, 숫자 레이블 또는 선 색상과 같은 다른 요소는 선택 사항입니다.

입력 수단과 형식은 평소처럼 유연 합니다. 예를 들어, 4 개의 숫자를 임의의 순서로 또는 숫자를 포함하는 배열을 사용할 수 있습니다. 프로그램이나 기능 을 제공 할 수 있습니다. 표준 허점 은 금지되어 있습니다.

바이트 단위의 최단 코드가 이깁니다.

테스트 사례

입력 형식은입니다 [A D S R]. 스케일은 각 그림에서 다릅니다 (스케일을 자유롭게 선택할 수있는 규칙에 따라).

[15 30 70 40]

여기에 이미지 설명을 입력하십시오

[64 64 64 64]

여기에 이미지 설명을 입력하십시오

[0 10 50 80]

여기에 이미지 설명을 입력하십시오

[0 0 90 80]

여기에 이미지 설명을 입력하십시오

[5 50 0 0]

여기에 이미지 설명을 입력하십시오

[5 50 0 80]

여기에 이미지 설명을 입력하십시오

[24 32 127 48]

여기에 이미지 설명을 입력하십시오


1
나는 타이틀에서 더 많은 시맨틱 한 도전을 기대하고있었습니다 !
Ben

@Ben 그 참조도 의도되었습니다 :-) 나는 수면 박탈을 좋아합니다 !
Luis Mendo

답변:


7

MATL, 31 22 바이트

Oii64ivYsO127itO5$h&XG

네 개의 개별 입력이 같은 주문 수락 A, D, R,S

MATL Online 에서 사용해보십시오

설명

0   % Push a literal 0 to the stack
ii  % Grab the first two inputs
64  % Push the number literal 64 to the stack
i   % Grab the third input
v   % Vertically concatenate all values
Ys  % Compute the cumulative sum
0   % Push the number literal 0 to the stack
127 % Push the number literal 127 to the stack
i   % Grab the fourth input
t   % Duplicate the fourth input
O   % Push the number literal 0 to the stack
5$h % Concatenate the last 5 elements on the stack
&XG % Plot the result using the first array as x and second array as y

여기에 이미지 설명을 입력하십시오


43

TikZ, 195 193 181 177 172 167 163 160 159 바이트

자신의 도움이 대답 데이비드 칼라일 덕분에 여기

\documentclass[tikz]{standalone}\begin{document}\tikz\def~#1{\typein[#1];}~\a~\s~\d~\r\def\u{)--(\a+\d}\draw(,)--(\a,127\u,\s\u+64,\s\u+\r+64,);\end{document}

네, 당신은 바로 TikZ 를 들었습니다 .

설명

목표를 달성하기 위해 몇 가지 기술을 사용합니다. 첫 번째는 입력입니다. 대부분의 사람들은 L A T E X가 입력을받을 수 있다는 것을 모릅니다 . 잘 할 수 있습니다. 이것은 명령으로 달성됩니다 \typein. 이것은 컴파일러를 정지시키고 변수에 할당 할 때 사용자의 입력을 요청합니다.

다른 주요 기술은의 사용입니다 \def. \defTikz에서는 터무니없이 강력합니다. 본질적으로 코드 조각을 정의하고 변수를 호출하는 모든 곳에 붙여 넣습니다. 이 코드에서는 \typein[#1]{}변수를 골고루 할당 할 수 있도록이 두 가지를 정의 )--(\a+\d하고이 코드는 ungolfed 버전에서 여러 번 표시되기 때문입니다.

다음은 래퍼없이 두 가지 버전의 코드입니다.

골프 :

\documentclass[tikz]{standalone}\begin{document}\tikz\def~#1{\typein[#1];}~\a~\s~\d~\r\def\u{)--(\a+\d}\draw(,)--(\a,127\u,\s\u+64,\s\u+\r+64,);\end{document}

언 골프 드 :

\typein[\a]{}\typein[\s]{}\typein[\d]{}\typein[\r]{}\draw(0,0)--(\a,127)--(\a+\d,)--(\a+\d+64,)--(\a+\d+\r+64,0);

영상:

pdf 이미지를 직접 업로드 할 수 없으며 다른 형식으로 변환하면 선이 완전히 사라지는 것처럼 보이므로 미리보기에서 열면 이미지가 어떻게 보일 수 있습니다 (이 이미지의 입력은 [64 64 64 64]) :

미리보기 이미지

보시다시피 매우 얇습니다. 그러나 래스터 이미지가 아닌 PDF 이미지이므로 두께 요구 사항을 준수하지 않아도됩니다.


12
TikZ를 잘 알고 있다는 사실에 진심으로 감탄합니다. (그리고 그것이 아니라면, 그것이 전설이 기억할 것입니다)
오른쪽 다리

1
input tikz\begin{document}작동 하지 않습니까?
페이탈 라이즈

5
사진은 어때요? 😉
Sarge Borsch

실제로 이것을 어떻게 렌더링합니까? pdflatex adsr.tex작동하지 않는 것 같습니다. — 아 잠깐만 요, 작동합니다. 대화식 입력을 요청할 것으로 기대하지 않았습니다!
반 시계 회전을 중단

@WheatWizard ImageMagick이 합리적으로 잘 당신이 그것을 바로 할 경우 PDF로 변환 할 수 있습니다
사지 (Sarge) 러시아 식 수프의 일종

20

파이썬 2, 83 80 79 바이트

from turtle import*
def f(A,D,S,R):X=A+D+64;map(goto,[A,A+D,X,X+R],[127,S,S,0])

온라인으로 시도하십시오 (83 바이트 버전, 온라인으로 실행되므로)

캔버스가 작동하는 방식으로 인해 Trinket을 사용하여 특정 출력이 완전히 표시되지 않을 수 있습니다. 더 잘 작동하려면 Python을 다운로드하여 설치해야합니다.

언 골프 드 :

from turtle import*
A,D,S,R=input()
goto(A,127)
goto(A+D,S)
goto(A+D+64,S)
goto(A+D+64+R,0)

Trinket은 입력 값 압축 풀기를 지원하지 않기 때문에 Trinket에서는 작동하지 않습니다.


mapPython 2에서 사용할 수 있습니다 :lambda A,D,S,R:map(goto,[A,A+D,A+D+64,A+D+R+64],[127,S,S,0])
xnor

@xnor 나는 SuspensionError: Cannot call a function that blocks or suspends here on line undefined in main.py악세사리를 타. 작동하는지 확인 했습니까? 오류가 악세사리에 고유한지 확실하지 않습니다.
mbomb007

2.7.12에서 저에게 효과적입니다.
xnor

@xnor Mmk, 감사합니다. Skulpt의 제한 사항 일 수 있습니다.
mbomb007

나는이 프로그램의 간단한 버전을 Skulpt github 저장소에 예제로 제출했으며, 그것이 좋은 발견이라고 생각했습니다. 그들이 그것을 고칠 수 있기를 바라지 만, 그들의 "거북이 질주"의 속도는 더 걷는 것 같습니다.
mbomb007

17

매스 매 티카, 61 58 바이트

ListLinePlot[{Accumulate@{0,##3,64,#2},{0,127,#,#,0}}]&

Mathematica 의 연산자이며 Transpose위 첨자 T로 렌더링됩니다 .

순서대로 인수를 가져와 S, R, A, D벡터 그래픽스 객체를 반환합니다.

7 가지 테스트 사례 모두에 대한 결과 :

여기에 이미지 설명을 입력하십시오 더 큰 버전을 보려면 클릭하십시오.


그것은 빠르다!
Luis Mendo

가르쳐 주셔서 +1 ListLinePlot:) 그리고 ListStepPlot아주 유용합니다!
Greg Martin

12

R, 66 63 바이트

function(A,D,S,R)plot(cumsum(c(0,A,D,64,R)),c(0,127,S,S,0),"l")

축선 및 숫자 레이블 cumsum(c(0,A,D,64,R))과 함께 축 랩이있는 이미지를 표시합니다 c(0,127,S,S,0).

3 바이트 를 줄인 @Zahiro Mor에게 감사 합니다 !

이전 답변 :

function(A,D,S,R)plot(c(0,A,A+D,b<-A+D+64,b+R),c(0,127,S,S,0),"l")

2
cumsum(c(0,A,D,64,R)) 도표에서 첫 번째 항을 바꾸는 데 사용할 수 있습니다 . cumsum으로 당신은 b 트릭을 필요로하지 않고 여전히 3 바이트를 면도합니다 :) function(A,D,S,R)plot(cumsum(c(0,A,D,64,R)),c(0,127,S,S,0),"l")
Zahiro Mor

11

Matlab, 50 바이트

@(A,D,S,R)plot(cumsum([0,A,D,64,R]),[0,127,S,S,0])

이는 ans (A, D, S, R)로 호출되어야하는 익명 함수 "ans"를 생성합니다.


9

자바 스크립트 (ES6) + HTML, 126 + 23 = 149

c=O.getContext`2d`;c.moveTo(a=0,z=O.height=128);g=(y,x=prompt())=>c.lineTo(a+=+x,y)||g;g(0)(s=z+~prompt())(s,64)(z);c.stroke()
<canvas id=O width=512>

순서대로 한 번에 하나씩 입력을 A, S, D, R받습니다.


9

자바 스크립트 (ES6) 114 111 바이트

f=(a,d,s,r)=>`<svg width=446 height=128><path stroke=red fill=none d=M0,127L${a},0l${d},${127-s}h64l${r},${s}>`
<div oninput=o.innerHTML=f(a.value,d.value,s.value,r.value)><input type=number value=0 min=0 max=127 id=a><input type=number value=63 min=0 max=127 id=d><input type=number value=127 min=0 max=127 id=s><input type=number value=0 min=0 max=127 id=r><div id=o><svg width=446 height=128><path stroke=red fill=none d=M0,127L0,0l63,0h64l0,127 /></svg>

에 적합한 SVG 이미지를 반환합니다 innerHTML. 유효한 XML에 18 바이트를 추가하십시오.


수치가 실시간으로 업데이트되는 방법이 훌륭합니다!
Luis Mendo

이것은 훌륭합니다. 언제나 SVG 구문을 배워야합니다. 아마도 <input>s 에 기본값을 추가 합니까?
ETHproductions

@ETHproductions 특정 기본값을 염두에 두셨습니까? (어쨌든 기본값을 설정해도 실제로 초기 그래프가 트리거되지는 않습니다 ...)
Neil

아마 그냥 생각하고 있었다 64,64,64,64. 일반적으로 기본 입력에 대한 올바른 출력을 하드 코딩했지만 여기에서 어떻게 어려운지 알 수 있습니다 ...
ETHproductions

8

하스켈 112 110 바이트

import Graphics.Gloss
(a#d)s r=display(InWindow""(600,300)(0,0))red$line$zip(scanl(+)0[a,d,64,r])[0,127,s,s,0]

사용 예 : (0#10) 50 80.

광고주 봉투

이것은 Gloss라이브러리를 사용합니다 . display함수는 윈도우 (여기서는 타이틀없이 윈도우 (음모 기대 "") 크기 600x300 위치 (0,0)위젯), 배경색 ( red) 및 포토 마녀하는 단계의 누적 합계 압축에 의해 상기 경로를 따라 라인 [0,a,d,64,r]=를 [0,a,a+d,a+d+64,a+d+64+r]는 AS x 좌표 및 [0,127,s,s,0]y 좌표

편집 : 2 바이트에 대한 @xnor 감사합니다!


작성 시간이 더 짧아야 함scanl(+)0[a,d,64,r]
xnor

5

처리 중, 134108 + 14 (call to size) = 148122 바이트

먼저 size프로그램의 어딘가에 대한 호출이 필요 하므로 출력이 창에 맞습니다 (기본값 : 100x100).

size(400,400);

그리고 실제 기능은 다음과 같습니다.

void g(int a,int b,int c,int d){line(0,127,a,0);line(a,0,b+=a,c=127-c);line(b,c,b+=64,c);line(b,c,b+d,127);}

처럼 불러 f(15,20,70,40);

스크린 샷

15, 20, 70, 40

영상


내 새로운 답변은 이전 답변보다 더 간단하지만 더 오래된 답변을 더 좋아합니다.

기존 답변 (148 바이트)

size(400,400);

그리고 두 기능

void f(int[]v){translate(0,127);l(v[0],-127);l(v[1],127-v[2]);l(64,0);l(v[3],v[2]);}void l(int x,int y){line(0,0,x,y);translate(x,y);}

그것을 호출 f(int_array_containing_values);하면 결과는 다음과 같습니다.f(new int[]{15,20,70,40});


4

SmileBASIC, 90 바이트

INPUT A,D,S,R
B=A+D+64W=#Y-S
GLINE.,#Y,A,0GLINE A,0,A+D,W
GLINE A+D,W,B,W
GLINE B,W,B+R,#Y

4

PHP, 149130 바이트

[,$a,$d,$s,$r]=$argv;imagepolygon($i=imagecreatetruecolor(446,127),[0,127,$a,0,$d+=$a,$s,$d+=64,$s,$d+$r,127],5,999);imagepng($i);

명령 행 인수에서 입력을 가져오고 이미지 (흑백에 파란색이 파란색 인 PNG)를 표준 출력에 씁니다. PHP 7.1 이상이 필요합니다.

사용법 예

# any OS with ImageMagick:
php -r '<code>' <parameters> | display

# linux with feh:
php -r '<code>' <parameters> | feh

오래된 PHP를위한 4 개 바이트 : 교체 [,$a,$d,$s,$r]와 함께 list(,$a,$d,$s,$r).


거기에는 작은 해킹이 있습니다. imageopenpolygon기준선을 숨기기 위해 사용 하는 대신 마무리 다각형 선이 캔버스 외부에 그려집니다. (y = 127은 높이가 128보다 큰 이미지에만 표시됩니다.)

999 대신 색상 99 또는 9로 더 많이 절약 할 수있었습니다. 그러나 그들은 검은 색으로보기가 꽤 어렵습니다. :)


3

Bash + grace , 70 바이트

t=$[$1+$2]
echo "0 0
$1 127
$t $3
$[t+64] $3
$[t+64+$4] 0">f
xmgrace f

스크립트는 f각 점의 좌표 를 파일에 기록 하고 xmgrace (GUI 버전)는 파일을 읽고 기본적으로 선을 사용하여 플롯을 표시합니다.

실행 :

./plot_ADSR.sh 15 30 70 40

출력 : (인쇄 화면)

15 30 70 40

입력을 수락 할 수 있다면 유예 스크립트로 직접 수행 할 수 있다고 생각하지만 구문에 익숙하지 않습니다. 내가 살펴볼 게

설명:

t=$[$1+$2]          # store the value of (A+D) for later usage
echo "0 0           # start writing the coordinates to file "f", first the origin
$1 127              # then (A, 127)
$t $3               # then (A + D, S)
$[t+64] $3          # then (A + D + 64, S)
$[t+64+$4] 0">f     # then (A + D + 64 + R, 0)
xmgrace f           # call xmgrace to plot the generated XY file

2

이동, 947 915 506 바이트

이 질문에 참여하면서 언어를 배우려고 노력하는 것은 최적화와는 거리가 멀다. 내가 할 수있는 일을 자유롭게 지적하십시오.

고정 이미지

응축 :

package main;import (."os";."image";k"image/png";c"image/color";."strconv";."math");func main(){g:=NewRGBA(Rect(0,0,127*4,127));a,_:=ParseFloat(Args[1],4);d,_:=ParseFloat(Args[2],4);s,_:=ParseFloat(Args[3],4);r,_:=ParseFloat(Args[4],4);z:=[5][]float64{{0,0},{a,127},{a+d,s},{a+d+64,s},{a+d+64+r,0}};for i:=1;i<len(z);i++{v,w,x,y:=z[i-1][0],z[i-1][1],z[i][0],z[i][1];m:=(y-w)/(x-v);t:=y-m*x;for v<=x{g.Set(int(Ceil(v)),127-int(Ceil(w)),c.RGBA{0,0,0,255});v+=.01;w=m*v+t}};f,_:=Create("o.png");k.Encode(f,g)}

비 응축 :

package main

import (
    ."os"
    ."image"
    k"image/png"
    c"image/color"
    ."strconv"
    ."math"
    "fmt"
)

func main(){
    g := NewRGBA(Rect(0, 0, 127*4, 127))

    a, _ := ParseFloat(Args[1], 4)
    d, _ := ParseFloat(Args[2], 4)
    s, _ := ParseFloat(Args[3], 4)
    r, _ := ParseFloat(Args[4], 4)

    z := [5][]float64{{0,0},{a,127},{a+d,s},{a+d+64,s},{a+d+64+r,0}}
    for i:=1;i<len(z);i++{
        v,w,x,y:=z[i-1][0],z[i-1][1],z[i][0],z[i][1]
        m:=(y-w)/(x-v)
        t:=y-m*x
        for v<=x{
            g.Set(int(Ceil(v)),127-int(Ceil(w)), c.RGBA{0,0,0,255})
            v+=.01
            w=m*v+t
        }
    }
    f,_:=Create("o.png")
    k.Encode(f,g)
}

@LuisMendo입니다. 기본적으로 0,0이 왼쪽 상단입니다. 최대한 빨리 모든 것을 뒤집어 놓을 것이다.
kemicofa

1
나는 코드를 작성하지 않았으므로 몰라요. 여기서 사용자는 일반 축소 기보다 더 많은 바이트를 절약 할 수 있으므로 코드를 수동으로 골라냅니다. 나쁜 코딩 관행과 트릭을 환영합니다. 예를 들어 구조체 객체를 변수 (예 : l1x, l1y, l1X, l1Y)로 바꾸는 것이 골퍼가 아닐까요?
seshoumara

1
@rugdealer 이것은 당신이 그것을 보지 못한 경우에 도움 될 수 있습니다
Luis Mendo

1
당신의 연결 @LuisMendo 거의 400 바이트 감사를 분실
kemicofa

1
@rugdealer 와우, 그건 정말 \ o /
Luis Mendo

1

dc, 120 바이트

처음에는 dc에서 대답 할 수 없다고 생각했지만 벡터 이미지의 구문을 인쇄하는 것이 허용됩니다.

?sR127r-sS[<svg><path d="M0 127 L]nrdn[ 0 L]n+dn32PlSn[ L]n64+dn32PlSn[ L]nlR+n[ 127" fill="none" stroke="red"/></svg>]p

이 코드는 각 점의 변환 된 좌표를 계산하고 플롯에 대한 SVG 구문을 생성합니다. 이미지 편집기는 왼쪽 상단에 원점 이 있으므로이 경우 127에서 y값 을 빼야 height이미지가 원점이 왼쪽 하단에있는 것처럼 표시됩니다.

예제를 실행하십시오 : 또는 온라인으로 사용해보십시오!

dc -f plot_ADSR.dc <<< "15 30 70 40"

산출:

<svg><path d="M0 127 L15 0 L45 57 L109 57 L149 127" fill="none" stroke="red"/></svg>

이미지 플롯을 표시하려면 정확한 출력을 파일로 저장하고 예를 들어 Gimp로 열거 나 위에서와 같이 html 페이지에 텍스트를 입력하십시오.

설명 : dc 역방향 폴란드어 인 차원 스크 C의 alculator 스택 언어

이 스크립트는 SVG 구문 문자열을 오랫동안 연결 한 것입니다. 키워드는 M의미 좌표로 이동 하고 L의미 좌표 부여에 현재 위치에서 선 그리기 .

?                           # read input (in reverse order by default). Stack: RSDA
sR                          # pop top value, store it in register 'R'. Stack: SDA
127r-sS                     # push 127, swap top 2 values, pop them and push
                            #subtracting result, save it to 'S', pop it. Stack: DA
[<svg><path d="M0 127 L]n   # [..]n print string (push then pop). Stack: unchanged
rdn                         # swap, duplicate top, print (A) and pop it. Stack: AD
[ 0 L]n                     # printing
+dn                         # pop top 2 values, push addition result, duplicate it,
                            #print and pop it. Stack: (A+D)
32P                         # print a space
lSn                         # push value from register 'S', print and pop it.
                            #Stack: unchanged
[ L]n                       # printing
64+dn                       # push 64, pop top 2 values, push addition result,
                            #duplicate it, print and pop it. Stack: (A+D+64)
32PlSn[ L]n                 # print space, print register 'S', more printing
lR+n                        #push value from register 'R', pop top 2 values, push
                            #addition result, print it and pop it. Stack: empty
[ 127" fill="none" stroke="red"/></svg>]p   # printing
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.