Saldırı, Çürüme, Sürdürme, Serbest Bırakma


47

Ses sentezleyicileri , sesin belirli parametrelerinin (genel ses yüksekliği gibi) zamanla nasıl değiştiğini kontrol etmek için zarf jeneratörleri kullanır. Birçok sentezleyicide, bir zarf Wikipedia'da aşağıdaki şekilde gösterildiği gibi dört parametre ile tanımlanır :

  • Atak zamanı (A) : tuşa ilk basıldığında, sıfırdan başlayarak zarfın maksimum seviyesine ulaşması için geçen süre.
  • Çürüme zamanı (D) : zarfın belirtilen dayanma seviyesine ulaşması için geçen süre.
  • Sustain level (S) : ilk saldırıdan ve çürümeden sonra, tuşa basıldığı sürece korunan seviye.
  • Serbest bırakma süresi (R) : Anahtar serbest bırakıldığında zarfın sıfıra ulaşması için geçen süre.

görüntü tanımını buraya girin

Meydan okuma

Dört, A, D, S, R parametrelerini girin ve zarfı çizin .

Parametreler, 0 ila 127 arasında tam sayı değerleri olacaktır .

Maksimum seviye (saldırı aşamasının sonunda ulaşılan) olduğu varsayılır edilecektir 127 .

Sürdürmek düzeyinde yatay bir parça olduğu kabul edilecektir süresi 64 (bu süre sabit değildir gerçek ses de, ama önemli tutulduğunda zaman miktarı ile belirlenir).

Biçimlendirme ve daha fazla ayrıntı

Çıktı raster veya vektör formatında bir görüntü olmalıdır. Raster ise, poligonal çizgi yatay olarak en az 50 piksel dikey olarak durmalıdır.

Görüntü, standart bir görüntü formatında ya görüntülenebilir ya da bir dosya olarak üretilebilir. Dosya diske yazılabilir veya içeriği STDERR'ye veya fonksiyon dönüş argümanı olarak çıkarılabilir.

Grafik sadece zarfı tanımlayan çokgen çizgiyi içermelidir. Her eksenin ölçeği serbestçe seçilebilir. Eksen çizgileri, sayısal etiketler veya çizgi renkleri gibi diğer elemanlar isteğe bağlıdır.

Giriş araçları ve format her zamanki gibi esnektir . Örneğin, dört sayıyı herhangi bir sırayla veya bunları içeren bir diziyi alabilirsiniz. Bir program veya bir işlev sağlanabilir. Standart boşluklar yasaktır.

Bayt cinsinden en kısa kod kazanır.

Test durumları

Giriş biçiminde [A D S R]. Ölçeğin her şekilde farklı olduğuna dikkat edin (ölçeğin serbestçe seçilebildiği kurala göre)

[15 30 70 40]

görüntü tanımını buraya girin

[64 64 64 64]

görüntü tanımını buraya girin

[0 10 50 80]

görüntü tanımını buraya girin

[0 0 90 80]

görüntü tanımını buraya girin

[5 50 0 0]

görüntü tanımını buraya girin

[5 50 0 80]

görüntü tanımını buraya girin

[24 32 127 48]

görüntü tanımını buraya girin



@Ben Bu referans da amaçlanmıştır :-) Uyku yoksunluğunu seviyorum !
Luis Mendo

Yanıtlar:


7

MATL, 31 22 bayt

Oii64ivYsO127itO5$h&XG

Dört ayrı girişler olarak sipariş Kabul A, D, R,S

MATL Online'da deneyin

açıklama

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

görüntü tanımını buraya girin


43

TikZ, 195 193 181 177 172 167 163 160 159 bayt

Onun yararlı cevap için David Carlisle sayesinde burada

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

Evet, doğru duydunuz TikZ .

açıklama

Bu, amacına ulaşmak için birkaç teknik kullanır. İlk şey girdi. Çoğu kişi L A T E X'in giriş yapabileceğini bilmiyor olabilir. İyi olabilir. Bu komutla sağlanır \typein. Bu derleyiciyi durduracak ve kullanıcıdan değişkene atamak için giriş isteyecektir.

Diğer ana teknik kullanımıdır \def. \defTikz'de saçma güçlüdür. Temel olarak bir kod parçasını tanımlar ve değişkeni çağırdığınız her yere yapıştırır. Bu kodda iki şeyi tanımladık \typein[#1]{}ki değişkenlerimizi golfily olarak atayabilelim ve )--(\a+\dbu kod ungolfed versiyonunda bir kaç kez göründüğü için.

İşte kodun iki sürümü (sarmalayıcı olmadan):

golfed:

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

Ungolfed:

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

Resim:

Doğrudan bir pdf resmini yükleyemediğim ve başka bir formata dönüştüremediğim için çizginin tamamen kaybolmasına neden olduğu görülüyor, işte Önizleme'de açıldığında bir görüntünün nasıl görüneceği gibi görünüyor (bu resim için giriş:) [64 64 64 64]:

Önizleme resmi

Gördüğünüz gibi çok ince. Ancak bir PDF görüntüsü olduğundan ve raster bir görüntünün kalınlık gereksinimlerine uyması gerekmemektedir.


12
TikZ'i o kadar iyi tanıdığınız gerçeğini içtenlikle takdir ediyorum: aklınıza ilk gelen çözüm bu. (Ve eğer değilse, efsanenin hatırlayacağı şey budur)
Sağ Bacak

1
Does not input tikz\begin{document}çalışmak?
7'de ölümle sonuçlandı

5
resimler nasıl? 😉
Sarge Borsch

Bunu gerçekten nasıl yapıyorsunuz? pdflatex adsr.texişe görünmüyor - Bekle, işe yarıyor, etkileşimli girdi isteyeceğini beklemiyordum!
saat

@WheatWizard imagemagick, doğru yaparsanız PDF'yi oldukça iyi dönüştürebilir
Sarge Borsch

20

Python 2, 83 80 79 bayt

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

Çevrimiçi deneyin ( çevrimiçi olduğu için 83 baytlık sürüm)

Tuvalin çalışma şekli nedeniyle bazı çıktıların Biblo kullanılarak tamamen görünmeyebileceğini unutmayın. Daha iyi çalışması için Python'u indirmeniz ve yüklemeniz gerekir.

Ungolfed:

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)

Bu sürüm Biblo'da çalışmaz, çünkü Biblo girdilerin açılmasını desteklemez.


mapPython 2'de kullanabilirsiniz :lambda A,D,S,R:map(goto,[A,A+D,A+D+64,A+D+R+64],[127,S,S,0])
xnor

@xnor Trinket'i alıyorum SuspensionError: Cannot call a function that blocks or suspends here on line undefined in main.py. İşe yaradığını doğruladın mı? Hatanın Biblo’ya özgü olup olmadığından emin değilim.
mbomb007

2.7.12 de benim için çalışıyor.
xnor

@ xnor Mmk, teşekkürler. Skulpt'ta muhtemelen bir sınırlama var.
mbomb007

Skulpt github repo'ya örnek olarak bu programın daha basit bir versiyonunu sundum ve bunun iyi bir keşif olduğunu düşündüler. Umarım düzeltebilirler, ancak "kaplumbağa sprint" hızları yürüyüşe daha çok benziyor.
mbomb007

17

Mathematica, 61 58 bayt

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

Operatördür Transposeve TMathematica tarafından üst simge olarak gösterilir .

Argümanları siparişte alır S, R, A, Dve bir vektör grafik nesnesi döndürür.

Yedi test vakasının tümü için sonuçlar:

görüntü tanımını buraya girin Daha büyük versiyon için tıklayınız.


Bu hızlı oldu!
Luis Mendo,

Bana öğretmek için +1 ListLinePlot:) Ve bir ListStepPlotde var - çok kullanışlı!
Greg Martin

12

R, 66 63 bayt

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

Eksen laboratuarları cumsum(c(0,A,D,64,R))ve c(0,127,S,S,0)ayrıca eksen çizgileri ve sayısal etiketlerle görüntüyü görüntüler .

Tıraş için @Zahiro Mor sayesinde kapalı 3 bayt !

Önceki cevap:

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)) Arsadaki ilk terimi değiştirmek için kullanabilirsiniz . cumsum ile b hile gerekmeyecek ve hala 3 byte tıraş :) 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 bayt

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

Bu, ans (A, D, S, R) olarak adlandırılması gereken "ans" adsız bir işlev verir.


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>

Siparişte bir kerede bir tane alır A, S, D, R.


9

JavaScript (ES6), 114 111 bayt

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>

İçin uygun bir SVG resmi döndürür innerHTML. Geçerli XML için 18 bayt ekleyin.


Rakamın gerçek zamanlı olarak nasıl güncellendiği harika!
Luis Mendo

Bu harika, bir zamanlar SVG sözdizimini öğrenmeliyim. Belki de varsayılan değerlere <input>s?
ETHProductions

@ETHproductions Aklında herhangi bir belirli varsayılan var mı? (Varsayılan ayar aslında ... Neyse ilk grafik tetiklemez göz önüne alındığında)
Neil

Belki de sadece düşünüyordum 64,64,64,64. Normalde varsayılan girdi için doğru çıktıyı
kodlardım

8

Haskell, 112 110 bayt

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]

Kullanım örneği: (0#10) 50 80.

adsr zarf

Bu Glosskütüphaneyi kullanır . displayİşlevi, bir pencere (burada: başlıksız pencere (çizdirmek bekliyor ""), boyut 600x300, pozisyon (0,0)masaüstünde), bir arka plan rengi ( red) ve resim cadı kümülatif toplamı sıkıştırma tarafından yapılan yol boyunca bir çizgidir [0,a,d,64,r]= [0,a,a+d,a+d+64,a+d+64+r]olarak x koordinatları ve [0,127,s,s,0]y koordinatları olarak.

Düzenleme: 2 bayt için teşekkürler @xnor!


Yazmak daha kısa olmalıscanl(+)0[a,d,64,r]
xnor

5

İşleme, 134 108 + 14 (çağrı size) = 148 122 bayt

Öncelikle sizeprogramın herhangi bir yerinde bir çağrıya ihtiyacımız var, böylece çıktı pencereye sığacak (varsayılan 100x100'de).

size(400,400);

Ve işte asıl işlev:

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

Gibi ara f(15,20,70,40);

Ekran görüntüsü

15, 20, 70, 40

görüntü


Yeni cevabım, eski cevabımdan daha basit, fakat eski cevabını daha çok seviyorum (daha büyük olsa bile).

Eski cevap (148 bayt)

size(400,400);

ve iki işlev

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

Buna şöyle diyorsunuz f(int_array_containing_values);ve sonuç şöyle görünecek:f(new int[]{15,20,70,40});


4

SmileBASIC, 90 bayt

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, 149 130 bayt

[,$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);

komut satırı argümanlarından girdi alır, görüntüyü (siyah grafik mavi olan PNG) stdout'a yazar. PHP 7.1 veya üstü sürüm gerektirir.

kullanım örneğin

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

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

Eski PHP 4 bayt: Değiştir [,$a,$d,$s,$r]ile list(,$a,$d,$s,$r).


İçeride küçük bir kesik var: imageopenpolygontaban çizgisini gizlemek yerine son poligon çizgisi kanvasın dışına çekiliyor. (y = 127, yalnızca yüksekliği> = 128 olan bir görüntüyü gösterir.)

999 yerine 99 veya 9 renkle daha fazla tasarruf edebilirdim; ama bunlar siyahta görmek oldukça zor. :)


3

Bash + zarafet , 70 bayt

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

Komut dosyası fher bir noktanın koordinatlarını dosyalamak için yazar ve xmgrace (GUI sürümü) dosyayı okur ve arsayı varsayılan olarak satırları kullanarak görüntüler.

Çalıştır :

./plot_ADSR.sh 15 30 70 40

Çıktı: (baskı ekranı)

15 30 70 40

Girdiyi kabul edebiliyorsa, bunun doğrudan bir grace betiği ile yapılabileceğini düşünüyorum, ancak sözdizimini bilmiyorum. Ben içine bakacağım.

Açıklama:

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 bayt

Bu, bu sorulara katılırken dili öğrenmeye çalışmaktan çok uzaktır. Ne yapabileceğimi belirtmekten çekinmeyin.

sabit görüntü

Yoğun:

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

Uncondenced:

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 öyle. Varsayılan olarak 0,0 üst soldur. Her şeyi olabildiğince çabuk tersine çeviriyorum.
kemicofa

1
Ben hiç kod yazmamıştım, bu yüzden bilmiyorum. Buradaki kullanıcılar kodlarını elle girerler, çünkü genel bir minifier'den daha fazla bayt kaydedebilirler. Kötü kodlama uygulamaları ve püf noktaları burada memnuniyetle karşılanmaktadır. Örneğin, yapı nesnelerinin değişkenlerle (l1x, l1y, l1X, l1Y gibi) değiştirilmesi belki de golfçü olur mu?
seshoumara

1
@rugdealer Bu , daha önce görmediyseniz yardımcı olabilir
Luis Mendo,

1
Bağlantınız sayesinde neredeyse 400 bayt kaybettiniz @LuisMendo
kemicofa

1
@rugdealer Vay, bu çok fazla
Luis Mendo

1

dc, 120 bayt

Başlangıçta dc olarak cevap veremeyeceğimi düşünmüştüm, ancak bir vektör görüntünün sözdizimini basmaya izin verildiğini görüyorum.

?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

Kod, her bir noktanın çevrilmiş koordinatlarını hesaplar ve arsa için SVG sözdizimini oluşturur. Bir resim editörü, sol üst köşede orijinli olduğu için , bu durumda 127'den ydeğerleri çıkarmak zorunda kaldım height, böylece görüntü orijin sol alt köşedeymiş gibi gösteriliyordu.

Örnek çalıştır: veya Çevrimiçi Deneyin!

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

Çıktı:

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

Görüntü grafiğini görüntülemek için, bu çıktıyı bir dosyaya kaydedin ve örneğin Gimp ile açın, ya da yukarıda yaptığım gibi bir html sayfasına metni girin.

Açıklama: dc ters-parlatıcıdır d esk C alculator yığın dili

Betik, SVG sözdizimi dizesinin uzunca bir birleşimidir. Anahtar kelime M, koordinat için taşıma ve mevcut konumdan verilen koordinatL için çizgi çekme anlamına gelir .

?                           # 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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.