Атака, Разложение, Поддержание, Освобождение

47

Звуковые синтезаторы используют генераторы огибающей для управления тем, как определенные параметры звука (например, общая громкость) меняются со временем. Во многих синтезаторах оболочка определяется четырьмя параметрами, как показано на следующем рисунке из Википедии :

  • Время атаки (A) : время, необходимое для того, чтобы конверт достиг максимального уровня, начиная с нуля, при первом нажатии клавиши.
  • Время затухания (D) : время, необходимое конверту для достижения заданного уровня сустейна.
  • Уровень сустейна (S) : уровень, который поддерживается после первоначальной атаки и затухания в течение всего времени нажатия клавиши.
  • Время выпуска (R) : время, необходимое для достижения конвертом нуля при отпускании ключа.

введите описание изображения здесь

Соревнование

Введите четыре параметра A, D, S, R и нанесите огибающую .

Параметры будут целочисленными значениями от 0 до 127 .

Максимальный уровень будет предполагаться (достигнуто в конце фазы атаки) , чтобы быть 127 .

Предполагается, что горизонтальный сегмент на уровне сустейна имеет длительность 64 (в реальном звуке эта длительность не является фиксированной, а определяется количеством времени, в течение которого удерживается клавиша).

Формат и дальнейшие детали

На выходе должно быть изображение в растровом или векторном формате. Если это растр, то полигональная линия должна занимать не менее 50 пикселей по вертикали и по горизонтали.

Изображение может отображаться или создаваться в виде файла в стандартном формате изображения. Файл может быть записан на диск, или его точное содержимое может быть выведено либо в STDERR, либо в качестве аргумента возврата функции.

Граф должен содержать только многоугольную линию, которая определяет оболочку. Масштаб каждой оси может быть выбран произвольно. Другие элементы, такие как оси линий, числовые метки или цвета линий, являются необязательными.

Средства ввода и формат, как обычно, гибки . Например, вы можете взять четыре числа в любом порядке или массив, содержащий их. Программа или функция может быть предоставлена. Стандартные лазейки запрещены.

Самый короткий код в байтах побеждает.

Контрольные примеры

Ввод в формате [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

Принимает четыре отдельных входа заказан как 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

введите описание изображения здесь

Suever
источник
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. \defв тикзе это абсурдно мощно. По сути, он определяет кусок кода и вставляет его везде, где вы вызываете переменную. В этом коде мы определяем две вещи, \typein[#1]{}так что мы можем назначить наши переменные по-гольфистски, и )--(\a+\dпотому что этот код появляется несколько раз в неуправляемой версии.

Вот две версии кода (без оболочки):

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

Образ:

Поскольку я не могу загрузить изображение в формате PDF напрямую, и преобразование его в любой другой формат, по-видимому, приводит к тому, что строка полностью исчезает, вот как может выглядеть изображение при открытии в Preview (вход для этого изображения [64 64 64 64]):

Предварительный просмотр изображения

Как видите, он очень тонкий. Однако, поскольку это изображение PDF, а не растровое изображение, оно не должно соответствовать требованиям по толщине.

Мастер пшеницы
источник
12
Я искренне восхищаюсь тем, что вы так хорошо знаете TikZ, что это первое решение, которое приходит вам в голову. (А если это не так, легенда запомнит это)
Правая нога
1
Не input tikz\begin{document}работает?
Роковая
5
как насчет фотографий? S
Sarge Borsch
Как вы на самом деле сделать это? 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, если вы хотите, чтобы он работал лучше.

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)

Эта версия не работает в Trinket, потому что Trinket не поддерживает распаковку значений ввода.

mbomb007
источник
Вы можете использовать mapв 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 Я вхожу в Брелок SuspensionError: Cannot call a function that blocks or suspends here on line undefined in main.py. Вы подтвердили, что это работает? Я не уверен, является ли ошибка уникальной для Брелка или нет.
mbomb007
У меня работает в 2.7.12.
xnor
@xnor Ммк, спасибо. Это, вероятно, ограничение в Skulpt.
mbomb007
Я представил более простую версию этой программы в качестве примера для репозитория Skulpt github, и они подумали, что это хорошая находка. Надеюсь, им удастся это исправить, но темп их "черепашьего бега" кажется скорее прогулкой.
mbomb007
17

Mathematica, 61 58 байт

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

является оператором для Transposeи представляется как верхний индекс TMathematica.

Принимает аргументы в порядке S, R, A, Dи возвращает объект векторной графики.

Результаты для всех семи тестовых случаев:

введите описание изображения здесь Нажмите для увеличения версии.

Мартин Эндер
источник
Это было быстро!
Луис Мендо
+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 и все равно function(A,D,S,R)plot(cumsum(c(0,A,D,64,R)),c(0,127,S,S,0),"l")
побрейте
11

Matlab, 50 байтов

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

Это дает анонимную функцию «ans», которая должна называться ans (A, D, S, R).

Лукас К.
источник
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>

Принимает ввод по одному в заказе A, S, D, R.

ETHproductions
источник
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. Добавьте 18 байтов для правильного XML.

Нил
источник
Здорово, как фигура обновляется в реальном времени!
Луис Мендо
Это здорово, я должен когда-нибудь изучить синтаксис 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.

конверт адср

Это использует Glossбиблиотеку. displayФункция ожидает окно замышляет (здесь: окно без заголовка ( ""), размера 600x300, положение (0,0)на рабочем столе), цвет фона ( red) и изображение ведьму является линией , вдоль пути , сделанного проносясь кумулятивной суммы [0,a,d,64,r]= [0,a,a+d,a+d+64,a+d+64+r]как координаты х и [0,127,s,s,0]в качестве координат у.

Редактировать: Спасибо @xnor за 2 байта!

Ними
источник
Должно быть короче, чтобы написатьscanl(+)0[a,d,64,r]
xnor
5

Обработка, 134 108 + 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);

и две функции

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

Kritixi Lithos
источник
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
12Me21
источник
4

PHP, 149 130 байт

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

+4 байта для старого PHP: заменить [,$a,$d,$s,$r]на list(,$a,$d,$s,$r).


Там есть небольшой хак: вместо того, imageopenpolygonчтобы скрывать базовую линию, завершающая линия многоугольника рисуется вне холста. (y = 127 будет отображаться только на изображении с высотой> = 128.)

Я мог бы сохранить больше с цветом 99 или 9 вместо 999; но это довольно трудно увидеть на черном. :)

Titus
источник
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 (версия с графическим интерфейсом) считывает файл и отображает график с использованием линий по умолчанию.

Выполнить :

./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
seshoumara
источник
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)}

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)
}
Kemicofa поддерживает Монику
источник
@ LuisMendo это так. По умолчанию 0,0 слева вверху. Я переверну все, как только смогу.
Kemicofa поддерживает Монику
1
Я никогда не кодировал в го, поэтому я не знаю. Пользователи здесь обрабатывают свой код вручную, потому что они могут сэкономить больше байтов, чем общий минификатор. Плохие методы кодирования и приемы приветствуются здесь. Например, не будет ли замена объектов struct переменными (такими как l1x, l1y, l1X, l1Y) более привлекательной?
Сешумара
1
@rugdealer Это может помочь, если вы еще не видели
Луис Мендо
1
Потерял почти 400 байт благодаря вашей ссылке @LuisMendo
kemicofa поддерживает Monica
1
@rugdealer Вау, это много \ o /
Луис Мендо
1

постоянный ток, 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 для графика. Поскольку редактор изображений имеет начало координат в верхнем левом углу, мне пришлось вычесть yзначения из height127 в этом случае, чтобы изображение отображалось так, как если бы источник находился в нижнем левом углу.

Запустите пример: или попробуйте онлайн!

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 является обратным для ногтей д ESK с 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
seshoumara
источник