アタック、ディケイ、サステイン、リリース


47

サウンドシンセサイザーは、エンベロープジェネレーターを使用して、サウンドの特定のパラメーター(全体的なラウドネスなど)の経時変化を制御します。多くのシンセサイザーでは、Wikipediaの次の図に示すように、エンベロープは4つのパラメーターによって定義されます。

  • 攻撃時間(A):キーが最初に押されたときに、エンベロープがゼロから開始して最大レベルに達するまでにかかった時間。
  • 減衰時間(D):エンベロープが指定された持続レベルに達するまでにかかった時間。
  • 持続レベル(S):最初の攻撃と減衰の後、キーが押されている限り維持されるレベル。
  • リリース時間(R):キーがリリースされたときにエンベロープがゼロに達するまでにかかった時間。

ここに画像の説明を入力してください

挑戦

4つのパラメーター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]

ここに画像の説明を入力してください



@Benその参照も意図されていました:-)私は睡眠不足が大好きです!
ルイスメンドー

回答:


7

MATL、31 22バイト

Oii64ivYsO127itO5$h&XG

よう命じた4つの別々の入力を受け付けADRS

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バイト

ここで役立つ回答をしてくれたDavid Carlisleに感謝します。

\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が非ゴルフバージョンで多くの時間を示すため、2つのことを定義します。

コードの2つのバージョン(ラッパーなし)は次のとおりです。

ゴルフ:

\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のボルシチ

これを実際にどのようにレンダリングしますか?pdflatex adsr.tex動作しないようです。—ああ、それは機能します。インタラクティブな入力を要求するとは思っていませんでした!
反時計回りに回転するのをやめた

@WheatWizard imagemagickは、PDFを適切に変換すれば、かなり適切に変換できます
Sarge Borsch

20

Python 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の動作を改善するには、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はTrinket に乗ります。動作することを確認しましたか?エラーがTrinketに固有のものかどうかはわかりません。
mbomb007

2.7.12で動作します。
XNOR

@xnor Mmk、ありがとう。これはおそらくSkulptの制限です。
mbomb007

Skulpt githubリポジトリの例として、このプログラムのより簡単なバージョンを提出しましたが、彼らはそれが素晴らしい発見だと考えました。彼らがそれを修正できることを願っていますが、彼らの「カメの短距離走」のペースはもっと歩いているようです。
mbomb007

17

Mathematica、61 58バイト

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

はの演算子でTransposeありT、Mathematicaによって上付き文字としてレンダリングされます。

引数を順番S, R, A, Dに受け取り、ベクトルグラフィックスオブジェクトを返します。

7つのテストケースすべての結果:

ここに画像の説明を入力してください クリックして拡大版をご覧ください。


早かった!
ルイスメンドー

教えてくれて+1 ListLinePlot:)またListStepPlot、便利な機能もあります!
グレッグマーティン

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)、軸線と数値ラベルとともに画像を表示します。

@Zahiro Morに3バイトを削ってくれてありがとう!

前の答え:

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

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

順番に1つずつ入力しますA, S, D, R


9

JavaScript(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バイトを追加します。


図がリアルタイムで更新されるのは素晴らしいことです!
ルイスメンドー

これは素晴らしいことです。いつかSVG構文を学ぶ必要があります。おそらくデフォルト値を<input>sに追加しますか?
ETHproductions

@ETHproductions特定のデフォルトを念頭に置いていましたか?(デフォルトを設定しても実際には初期グラフがトリガーされないことを考えると...)
ニール

たぶんただ考えていた64,64,64,64。通常、私は、デフォルトの入力に対して正しい出力をハードコーディングしたいが、それは...ここには難しいだろうどのように私は見る
ETHproductions

8

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

adsrエンベロープ

これはGlossライブラリを使用します。display関数のプロットに窓期待(ここで:タイトルせずにウィンドウを("")、サイズ600x300、位置(0,0)デスクトップ上)、背景色(red)と画像魔女は、累積和ジッピング製パスに沿った線である[0,a,d,64,r]=の[0,a,a+d,a+d+64,a+d+64+r]ようにx座標および[0,127,s,s,0]y座標として。

編集:2バイトありがとう@xnor!


書き込みに短くする必要がありますscanl(+)0[a,d,64,r]
XNOR

5

処理中、134108 + 14(呼び出しsize)= 148 122バイト

最初に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);

そして2つの機能

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)をstdoutに書き込みます。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

Go、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は左上です。私はできるだけ早くすべてを逆にします。
ケミコファ

1
goでコーディングしたことはないので、わかりません。ここのユーザーは、一般的なミニファイアーよりも多くのバイトを節約できるため、コードを手動で操作します。ここでは、不適切なコーディングの手法とトリックを歓迎します。たとえば、structオブジェクトを変数(l1x、l1y、l1X、l1Yなど)で置き換えるとゴルファーになりませんか?
seshoumara

1
@rugdealer これは、あなたがそれを見たことがない場合に役立つかもしれません
ルイスメンドー

1
リンクのおかげでほぼ400バイトが失われました@LuisMendo
kemicofa

1
@rugdealerうわー、それはたくさん\ o /
ルイスメンドー

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逆ポーランドでD ESK 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.