1+ var attackTime = 0.001
2+ var attackLevel = 1.0 ;
3+ var decayTime = 0.2 ;
4+ var sustainTime = 0.5 ;
5+ var sustainRatio = 0.2 ;
6+ var releaseTime = 0.5 ;
7+ var releaseLevel = 0.0 ;
8+
9+ var attackTimeInput , attackLevelInput ;
10+ var decayTimeInput ;
11+ var sustainTimeInput , sustainRatioInput ;
12+ var releaseTimeInput , releaseLevelInput ;
13+
14+ var maxTime = 1 ;
15+ var maxLevel = 5 ;
16+
17+ var env , osc ;
18+
19+ function setup ( ) {
20+ var cnv = createCanvas ( 500 , 500 ) ;
21+ cnv . mousePressed ( playEnv ) ;
22+
23+ env = new p5 . Env ( ) ;
24+ osc = new p5 . Oscillator ( 'triangle' ) ;
25+ osc . amp ( env ) ;
26+ osc . start ( ) ;
27+ osc . freq ( 440 ) ;
28+
29+ attackTimeInput = createLabeledSlider ( 'Attack time' , 0 , maxTime , attackTime , 20 , 15 ) ;
30+ attackLevelInput = createLabeledSlider ( 'Attack level' , 0 , maxLevel , attackLevel , 20 , 40 ) ;
31+ decayTimeInput = createLabeledSlider ( 'Decay time' , 0 , maxTime , decayTime , 20 , 65 ) ;
32+ sustainTimeInput = createLabeledSlider ( 'Sustain time' , 0 , maxTime , sustainTime , 20 , 90 ) ;
33+ sustainRatioInput = createLabeledSlider ( 'Sustain ratio' , 0 , 1 , sustainRatio , 20 , 115 ) ;
34+ releaseTimeInput = createLabeledSlider ( 'Release time' , 0 , maxTime , releaseTime , 20 , 140 ) ;
35+ releaseLevelInput = createLabeledSlider ( 'Release level' , 0 , maxLevel , 0 , 20 , 165 ) ;
36+ }
37+
38+ function draw ( ) {
39+ background ( 255 ) ;
40+
41+ // Update latest values
42+ attackTime = float ( attackTimeInput . value ( ) ) ;
43+ attackLevel = float ( attackLevelInput . value ( ) ) ;
44+ decayTime = float ( decayTimeInput . value ( ) ) ;
45+ sustainTime = float ( sustainTimeInput . value ( ) ) ;
46+ sustainRatio = float ( sustainRatioInput . value ( ) ) ;
47+ releaseTime = float ( releaseTimeInput . value ( ) ) ;
48+ releaseLevel = float ( releaseLevelInput . value ( ) ) ;
49+
50+ drawADSR ( ) ;
51+
52+ // Text
53+ textAlign ( CENTER ) ;
54+ text ( 'Click anywhere to play' , width / 2 , height / 2 ) ;
55+ }
56+
57+ function playEnv ( ) {
58+ env . set ( attackTime , attackLevel , decayTime , sustainRatio , releaseTime , releaseLevel ) ;
59+ env . play ( osc , 0 , sustainTime ) ;
60+ }
61+
62+ function drawADSR ( ) {
63+ var textPadding = 50 ;
64+ var xScale = ( width - textPadding ) / maxTime / 4 ;
65+ var yScale = ( height - textPadding ) / maxLevel ;
66+ var x , y ;
67+ var shape_color = color ( 30 , 200 , 205 ) ;
68+
69+ fill ( shape_color ) ;
70+ noStroke ( ) ;
71+ textAlign ( LEFT , BOTTOM ) ;
72+
73+ beginShape ( ) ;
74+ // Start
75+ vertex ( 0 , height ) ;
76+ // Attack
77+ x = attackTime * xScale ;
78+ y = height - attackLevel * yScale ;
79+ vertex ( x , y ) ;
80+ fill ( 0 ) ;
81+ text ( "Attack" , x , y ) ;
82+ fill ( shape_color ) ;
83+ // Decay
84+ x = x + decayTime * xScale ;
85+ y = height - ( releaseLevel + sustainRatio * ( attackLevel - releaseLevel ) ) * yScale ;
86+ vertex ( x , y ) ;
87+ fill ( 0 ) ;
88+ text ( "Decay" , x , y ) ;
89+ fill ( shape_color ) ;
90+ // Sustain
91+ x = x + sustainTime * xScale ;
92+ y = y ;
93+ vertex ( x , y ) ;
94+ fill ( 0 ) ;
95+ text ( "Sustain" , x , y ) ;
96+ fill ( shape_color ) ;
97+ // Release
98+ x = x + releaseTime * xScale ;
99+ y = height - releaseLevel * yScale ;
100+ fill ( 0 ) ;
101+ text ( "Release" , x , y ) ;
102+ fill ( shape_color ) ;
103+ vertex ( x , y ) ;
104+ // End
105+ vertex ( width , y ) ;
106+ vertex ( width , height ) ;
107+ endShape ( ) ;
108+ }
109+
110+ function createLabeledSlider ( labelText , minVal , maxVal , initVal , xpos , ypos ) {
111+ var slider = createSlider ( minVal , maxVal , initVal , 0 ) ; // '0' to use continuous
112+ var label = createElement ( "label" , labelText ) ;
113+ var numInput = createInput ( str ( initVal ) , 'number' ) ;
114+
115+ slider . size ( width / 2 ) ;
116+ slider . position ( xpos , ypos ) ;
117+ slider . input ( ( ) => {
118+ numInput . value ( slider . value ( ) ) ;
119+ } ) ;
120+
121+ numInput . size ( width / 8 ) ;
122+ numInput . position ( xpos + slider . size ( ) . width + 10 , ypos ) ;
123+ numInput . input ( ( ) => {
124+ if ( numInput . value ( ) > maxVal ) {
125+ slider . value ( maxVal ) ;
126+ } else if ( numInput . value ( ) < minVal ) {
127+ slider . value ( minVal ) ;
128+ } else {
129+ slider . value ( numInput . value ( ) ) ;
130+ }
131+ } ) ;
132+
133+ label . position ( numInput . position ( ) . x + numInput . size ( ) . width + 10 , ypos + 3 ) ;
134+ return numInput ;
135+ }
0 commit comments