Attack, Decay, Sustain, Release

47

Sound synthesizer menggunakan generator amplop untuk mengontrol bagaimana parameter tertentu dari suara (seperti kenyaringan keseluruhan) berubah seiring waktu. Dalam banyak synthesizer, sebuah amplop didefinisikan oleh empat parameter, seperti diwakili dalam gambar berikut dari Wikipedia :

  • Attack time (A) : waktu yang dibutuhkan amplop untuk mencapai level maksimumnya, mulai dari nol, ketika tombol pertama kali ditekan.
  • Decay time (D) : waktu yang dibutuhkan amplop untuk mencapai level penopang yang ditentukan.
  • Sustain level (S) : level yang dipertahankan, setelah serangan awal dan pembusukan, selama kunci ditekan.
  • Waktu rilis (R) : waktu yang dibutuhkan amplop untuk mencapai nol ketika kunci dilepaskan.

masukkan deskripsi gambar di sini

Tantangan

Masukkan empat parameter A, D, S, R dan plot amplop .

Parameter akan berupa nilai integer dari 0 hingga 127 .

The tingkat maksimum (mencapai pada akhir fase serangan) akan diasumsikan 127 .

The segmen horisontal di mempertahankan tingkat akan diasumsikan memiliki durasi 64 (dalam suara yang sebenarnya durasi ini tidak tetap, tetapi ditentukan oleh jumlah waktu bahwa kunci dipegang).

Format dan detail lebih lanjut

Outputnya harus berupa gambar dalam format raster atau vektor. Jika raster, garis poligonal harus menempati setidaknya 50 piksel secara vertikal.

Gambar dapat ditampilkan atau diproduksi sebagai file dalam format gambar standar. File dapat ditulis ke disk, atau kontennya dapat berupa output, baik ke STDERR atau sebagai argumen pengembalian fungsi.

Grafik hanya perlu berisi garis poligonal yang mendefinisikan amplop. Skala setiap sumbu dapat dipilih secara bebas. Elemen lain seperti garis sumbu, label numerik atau warna garis adalah opsional.

Sarana input dan format fleksibel seperti biasa. Misalnya, Anda dapat mengambil empat angka dalam urutan apa pun, atau array yang mengandungnya. Program atau fungsi dapat disediakan. Celah standar dilarang.

Kode terpendek dalam byte menang.

Uji kasus

Input dalam format [A D S R]. Perhatikan bahwa skala berbeda di setiap gambar (sesuai dengan aturan bahwa skala dapat dipilih secara bebas)

[15 30 70 40]

masukkan deskripsi gambar di sini

[64 64 64 64]

masukkan deskripsi gambar di sini

[0 10 50 80]

masukkan deskripsi gambar di sini

[0 0 90 80]

masukkan deskripsi gambar di sini

[5 50 0 0]

masukkan deskripsi gambar di sini

[5 50 0 80]

masukkan deskripsi gambar di sini

[24 32 127 48]

masukkan deskripsi gambar di sini

Luis Mendo
sumber
1
Saya mengharapkan tantangan yang lebih simian dari judul !
Ben
@ Ben Referensi itu dimaksudkan juga :-) Saya suka kurang tidur !
Luis Mendo

Jawaban:

7

MATL, 31 22 byte

Oii64ivYsO127itO5$h&XG

Menerima empat input terpisah memerintahkan sebagai A, D, R,S

Cobalah di MATL Online

Penjelasan

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

masukkan deskripsi gambar di sini

Suever
sumber
43

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

Terima kasih kepada David Carlisle untuk jawabannya yang bermanfaat di sini

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

Ya, Anda dengar benar TikZ .

Penjelasan

Ini menggunakan beberapa teknik untuk mencapai tujuannya. Yang pertama adalah input. Kebanyakan orang mungkin tidak tahu bahwa L A T E X dapat mengambil input. Yah, bisa. Ini dicapai dengan perintah \typein. Ini akan menghentikan kompiler dan meminta input dari pengguna saat menetapkannya ke variabel.

Teknik utama lainnya adalah penggunaan \def. \defdi Tikz sangat kuat. Ini pada dasarnya mendefinisikan sepotong kode dan menempelkannya di mana pun Anda memanggil variabel. Dalam kode ini kita mendefinisikan dua hal \typein[#1]{}sehingga kita dapat menetapkan variabel kita dengan golfily dan )--(\a+\dkarena kode ini muncul beberapa kali dalam versi yang tidak dikenali.

Berikut adalah dua versi kode (tanpa bungkus):

Golf:

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

Tidak Disatukan:

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

Gambar:

Karena saya tidak dapat mengunggah gambar pdf secara langsung, dan mengonversinya ke format lain apa pun tampaknya menyebabkan garis tersebut menghilang sama sekali, inilah yang tampak seperti gambar ketika dibuka di Pratinjau (masukan untuk gambar ini [64 64 64 64]):

Pratinjau gambar

Seperti yang Anda lihat itu sangat tipis. Namun karena ini adalah gambar PDF dan bukan gambar raster tidak harus memenuhi persyaratan ketebalan.

Wisaya Gandum
sumber
12
Saya dengan tulus mengagumi kenyataan bahwa Anda mengenal TikZ dengan sangat baik sehingga ini adalah solusi pertama yang muncul di pikiran Anda. (Dan jika tidak, itulah yang akan diingat legenda)
Kaki Kanan
1
Tidak input tikz\begin{document}bekerja
Fatalkan
5
bagaimana dengan gambar? 😉
Sarge Borsch
Bagaimana Anda membuat ini? pdflatex adsr.texsepertinya tidak berhasil. - Oh, tunggu, itu berhasil, saya hanya tidak berharap itu akan meminta input interaktif!
Berhenti menghidupkan counterclock
@WheatWizard imagemagick dapat mengonversi PDF dengan cukup baik jika Anda melakukannya dengan benar
Sarge Borsch
20

Python 2, 83 80 79 byte

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

Cobalah online (versi 83-byte, karena berjalan online)

Perhatikan bahwa output tertentu mungkin tidak sepenuhnya terlihat menggunakan Trinket, karena cara kanvas bekerja. Anda harus mengunduh dan menginstal Python jika Anda ingin itu berfungsi lebih baik.

Tidak Disatukan:

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)

Versi ini tidak berfungsi di Trinket, karena Trinket tidak mendukung nilai pembongkaran input.

mbomb007
sumber
Anda dapat menggunakan mapdalam Python 2:lambda A,D,S,R:map(goto,[A,A+D,A+D+64,A+D+R+64],[127,S,S,0])
xnor
@xnor saya mendapatkan SuspensionError: Cannot call a function that blocks or suspends here on line undefined in main.pyTrinket. Sudahkah Anda mengonfirmasi bahwa itu berhasil? Saya tidak yakin apakah kesalahannya unik untuk Perhiasan Kecil atau tidak.
mbomb007
Bekerja untuk saya di 2.7.12.
xnor
@ xnor Mmk, terima kasih. Ini mungkin batasan di Skulpt.
mbomb007
Saya mengirimkan versi yang lebih sederhana dari program ini sebagai contoh untuk repo gitub Skulpt, dan mereka pikir itu adalah penemuan yang bagus. Semoga mereka bisa memperbaikinya, tetapi kecepatan "turtle sprint" mereka sepertinya lebih dari sekadar berjalan.
mbomb007
17

Mathematica, 61 58 byte

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

adalah operator untuk Transposedan diterjemahkan sebagai superskrip Toleh Mathematica.

Mengambil argumen dalam urutan S, R, A, Ddan mengembalikan objek grafik vektor.

Hasil untuk semua tujuh kasus uji:

masukkan deskripsi gambar di sini Klik untuk versi yang lebih besar.

Martin Ender
sumber
Itu tadi cepat!
Luis Mendo
+1 untuk mengajari saya ListLinePlot:) Dan ada ListStepPlotjuga — sangat berguna!
Greg Martin
12

R, 66 63 byte

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

Menampilkan gambar, dengan lab sumbu sedang cumsum(c(0,A,D,64,R))dan c(0,127,S,S,0), juga garis sumbu dan label numerik.

Terima kasih kepada @Zahiro Mor karena telah mengurangi 3 byte !

Jawaban sebelumnya:

function(A,D,S,R)plot(c(0,A,A+D,b<-A+D+64,b+R),c(0,127,S,S,0),"l")
Frédéric
sumber
2
Anda dapat menggunakan cumsum(c(0,A,D,64,R)) untuk mengganti istilah pertama dalam plot. dengan cumsum Anda tidak akan memerlukan trik b dan masih mencukur 3 byte :) 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 byte

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

Ini menghasilkan fungsi anonim "ans" yang harus disebut sebagai ans (A, D, S, R).

Lukas K.
sumber
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>

Mengambil input satu per satu secara berurutan A, S, D, R.

Produksi ETH
sumber
9

JavaScript (ES6), 114 111 byte

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>

Mengembalikan gambar SVG yang cocok untuk innerHTML. Tambahkan 18 byte untuk XML yang valid.

Neil
sumber
Sangat bagus bagaimana angka diperbarui secara real time!
Luis Mendo
Ini bagus, saya harus belajar sintaks SVG kapan-kapan. Mungkin menambahkan nilai default ke <input>s?
ETHproduksi
@ ETHproductions Apakah Anda memiliki default tertentu dalam pikiran? (Mengingat bahwa pengaturan default sebenarnya tidak akan memicu grafik awal ...)
Neil
Saya berpikir mungkin adil 64,64,64,64. Biasanya saya akan membuat hardcode output yang benar untuk input default, tapi saya melihat bagaimana itu akan sulit di sini ...
ETHproduksi
8

Haskell, 112 110 byte

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]

Contoh penggunaan: (0#10) 50 80.

amplop adsr

Ini menggunakan Glossperpustakaan. The displayFungsi mengharapkan jendela untuk plot di (di sini: jendela tanpa judul ( ""), ukuran 600x300, posisi (0,0)pada desktop), warna background ( red) dan gambar penyihir garis sepanjang jalan yang dibuat oleh zipping jumlah kumulatif [0,a,d,64,r]= [0,a,a+d,a+d+64,a+d+64+r]sebagai x koordinat dan [0,127,s,s,0]sebagai koordinat y.

Sunting: Terima kasih @xnor untuk 2 byte!

nimi
sumber
Harus lebih pendek untuk menulisscanl(+)0[a,d,64,r]
xnor
5

Memproses, 134 108 + 14 (panggil ke size) = 148 122 byte

Pertama-tama kita perlu panggilan ke sizesuatu tempat dalam program sehingga output akan muat di jendela (default pada 100x100).

size(400,400);

Dan inilah fungsi sebenarnya:

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

Sebut saja seperti f(15,20,70,40);

Tangkapan layar

15, 20, 70, 40

gambar


Jawaban saya yang lebih baru lebih mudah daripada jawaban yang lebih tua, tetapi saya lebih suka yang lebih tua (meskipun lebih besar).

Jawaban lama (148 byte)

size(400,400);

dan dua fungsi

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

Sebut seperti f(int_array_containing_values);dan hasilnya akan terlihat seperti:f(new int[]{15,20,70,40});

Kritixi Lithos
sumber
4

SmileBASIC, 90 byte

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
12Me21
sumber
4

PHP, 149 130 byte

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

mengambil input dari argumen baris perintah, menulis gambar (PNG dengan grafik biru hitam) ke stdout. Membutuhkan PHP 7.1 atau lebih baru.

penggunaan misalnya

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

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

+4 byte untuk PHP yang lebih lama: Ganti [,$a,$d,$s,$r]dengan list(,$a,$d,$s,$r).


Ada retasan kecil di sana: alih-alih menggunakan imageopenpolygonuntuk menyembunyikan garis dasar, garis akhir poligon diambil di luar kanvas. (y = 127 hanya akan ditampilkan pada gambar dengan tinggi> = 128.)

Saya bisa menyimpan lebih banyak dengan warna 99 atau 9 bukannya 999; tapi itu cukup sulit untuk dilihat pada warna hitam. :)

Titus
sumber
3

Bash + grace , 70 byte

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

Script menulis untuk mengarsipkan fkoordinat setiap titik, dan xmgrace (versi GUI) membaca file dan menampilkan plot menggunakan garis secara default.

Jalankan :

./plot_ADSR.sh 15 30 70 40

Output: (layar cetak)

15 30 70 40

Saya pikir ini bisa dilakukan secara langsung oleh skrip anugerah, jika dapat menerima input, tapi saya tidak terbiasa dengan sintaksnya. Saya akan memeriksanya.

Penjelasan:

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
seshoumara
sumber
2

Pergi, 947 915 506 byte

Ini masih jauh dari optimal, mencoba mempelajari bahasa sambil berpartisipasi dalam pertanyaan-pertanyaan ini. Jangan ragu untuk menunjukkan apa yang bisa saya lakukan.

gambar tetap

Kental:

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

Tanpa syarat:

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)
}
kemicofa
sumber
@LuisMendo itu. Secara default 0,0 adalah kiri atas. Aku akan membalikkan semuanya secepat mungkin.
kemicofa
1
Saya tidak pernah membuat kode, jadi saya tidak tahu. Pengguna di sini mem-golf-kan kodenya secara manual karena mereka dapat menyimpan lebih banyak byte daripada minifier umum. Praktek dan trik pengkodean yang buruk disambut di sini. Sebagai contoh, tidak akan mengganti objek struct dengan variabel (seperti l1x, l1y, l1X, l1Y) menjadi golfier mungkin?
seshoumara
1
@rugdealer Ini dapat membantu, jika Anda belum melihatnya
Luis Mendo
1
Kehilangan hampir 400 byte berkat tautan Anda @LuisMendo
kemicofa
1
@rugdealer Wow, itu banyak \ o /
Luis Mendo
1

dc, 120 byte

Awalnya saya pikir saya tidak bisa menjawab dalam dc, tetapi saya melihat bahwa mencetak sintaks dari gambar vektor diperbolehkan.

?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

Kode menghitung koordinat yang diterjemahkan dari setiap titik dan menghasilkan sintaks SVG untuk plot. Karena editor gambar memiliki asal di sudut kiri atas, saya harus mengurangi ynilai dari height, 127 dalam kasus ini, sehingga gambar ditampilkan seolah-olah asal di sudut kiri bawah.

Jalankan contoh: atau Cobalah Online!

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

Keluaran:

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

Untuk menampilkan plot gambar, simpan output yang tepat ke file dan buka dengan Gimp, misalnya, atau masukkan teks dalam halaman html seperti yang saya lakukan di atas.

Penjelasan: dc adalah reverse-polish d esk c alculator bahasa tumpukan

Script ini merupakan rangkaian panjang dari sintaksis SVG. Kata kunci Mberarti pindah untuk berkoordinasi dan Lsingkatan dari garis tarik dari posisi saat ini ke koordinat yang diberikan .

?                           # 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
seshoumara
sumber