@@ -180,35 +180,100 @@ def self.lfo_plot(vg, bb, dat, stroke)
180180 vg . stroke_width 1.0
181181 end
182182
183- def self . env_plot ( vg , bb , dat , stroke , selected )
183+ def self . env_plot ( vg , bb , dat , stroke , selected , emode )
184184 n = dat . length
185+ pts = 32
185186 vg . path do
186187 vg . move_to ( bb . x + bb . w *dat [ 0 ] . x ,
187188 bb . y + bb . h /2 *( 1 -dat [ 0 ] . y ) )
188- ( 0 ...n ) . each do |i |
189- vg . line_to ( bb . x + bb . w *dat [ i ] . x ,
190- bb . y + bb . h /2 *( 1 -dat [ i ] . y ) )
189+
190+ ( 1 ...n ) . each_slice ( 3 ) do |i , j , k |
191+ h = i -1
192+ a = dat [ h ] . y # starting point
193+ b = dat [ i ] . y # bezier control point
194+ c = dat [ j ] . y # bezier control point 2
195+ d = dat [ k ] . y # end point
196+ vg . move_to ( bb . x + bb . w *dat [ i -1 ] . x ,
197+ bb . y + bb . h /2 *( 1 -a ) )
198+ ( 1 ...pts ) . each do |pt |
199+ w2 = pt . to_f /pts . to_f # weight of end point
200+ w1 = 1.0 -w2 # weight of starting point
201+
202+ if ( h ==0 ) # treatment for "first segment linear" in envout_dB for ADSR_dB
203+ case emode
204+ when 1 , 2 # ADSR_lin or ADSR_dB
205+ v1 = ( 10.0 **( ( a ) ) -0.01 ) /0.99
206+ v2 = ( 10.0 **( ( d ) ) -0.01 ) /0.99
207+ rap = v1 + ( v2 - v1 ) * w2
208+ y = ( Math . log10 ( ( rap ) * 0.99 + 0.01 ) )
209+ when 3 # ASR_freqlfo
210+ v1 = ( 2.0 **( 6.0 * a . abs ) -1 )
211+ if ( a <0 )
212+ v1 = -v1
213+ end
214+
215+ v2 = ( 2.0 **( 6.0 * d . abs ) -1 )
216+ if ( c <0 )
217+ v2 = -v2
218+ end
219+
220+ rap = v1 + ( v2 - v1 ) * w2
221+
222+ y = ( rap >=0 ) ? ( ( Math . log ( rap + 1.0 ) / ( 6.0 * Math . log ( 2.0 ) ) ) ) : ( -( Math . log ( 1.0 - rap ) / ( 6.0 * Math . log ( 2.0 ) ) ) )
223+
224+ else # ADSR_filter = 4; ASR_bw = 5;
225+
226+ y = a + ( d - a ) * w2
227+
228+ end
229+
230+ vg . line_to ( bb . x +bb . w *dat [ i -1 ] . x + bb . w *( dat [ k ] . x -dat [ i -1 ] . x ) *w2 ,
231+ bb . y + bb . h /2.0 * ( 1.0 -y ) )
232+
233+ else
234+ vg . line_to ( bb . x +bb . w *dat [ h ] . x + bb . w *( dat [ k ] . x -dat [ h ] . x ) *w2 ,
235+ bb . y + bb . h /2.0 * ( 1.0 -( w1 *w1 *w1 *a + 3 *w1 *w1 *w2 *b + 3 *w1 *w2 *w2 *c + w2 *w2 *w2 *d ) ) )
236+ end
237+ end
238+ vg . line_to ( bb . x + bb . w *dat [ k ] . x ,
239+ bb . y + bb . h /2.0 *( 1.0 -d ) )
240+
191241 end
192242 vg . line_join NVG ::ROUND
193243 vg . stroke_width 2.0
194244 vg . stroke_color stroke
195245 vg . stroke
196246 end
197- vg . stroke_width 1.0
198247
199- sel_color = Theme ::VisualSelect
200- bright = Theme ::VisualBright
201- ( 0 ...n ) . each do |i |
202- xx = bb . x + bb . w *dat [ i ] . x ;
203- yy = bb . y + bb . h /2 *( 1 -dat [ i ] . y ) ;
204- scale = 3
205- vg . stroke_color sel_color if ( selected == i )
206- vg . stroke_color bright if ( selected != i )
207- vg . fill_color Theme ::EnvelopePoint
208- Draw ::WaveForm ::env_marker ( vg , xx , yy , scale )
248+ end
249+
250+ def self . env_draw_markers ( vg , bb , dat , stroke , selected , emode )
251+ n = dat . length
252+ vg . path do
253+ vg . stroke_width 1.0
254+
255+ sel_color = Theme ::VisualSelect
256+ bright = Theme ::VisualBright
257+ bright2 = Theme ::VisualBright2
258+ ( 0 ...n ) . each do |i |
259+ next if ( [ 1 , 2 ] . include? ( i ) )
260+ xx = bb . x + bb . w *dat [ i ] . x ;
261+ yy = bb . y + bb . h /2 *( 1 -dat [ i ] . y ) ;
262+ scale = 3
263+ if ( selected == i )
264+ vg . stroke_color sel_color
265+ elsif ( i % 3 == 0 )
266+ vg . stroke_color bright
267+ else
268+ vg . stroke_color bright2
269+ end
270+ vg . fill_color Theme ::EnvelopePoint
271+ Draw ::WaveForm ::env_marker ( vg , xx , yy , scale )
272+ end
209273 end
210274 end
211275
276+
212277 def self . env_marker ( vg , x , y , scale )
213278 vg . path do
214279 vg . translate ( 0.5 , 0.5 )
@@ -279,7 +344,7 @@ def self.log_y(vg, min, max, bb)
279344 ( 0 ...10 ) . each do |shift |
280345 delta = Math . log ( ( shift +1 ) *1.0 ) /( log10 *( max_ -min_ ) )
281346 dy = bb . h *( base +delta ) ;
282-
347+
283348 next if ( dy < 0 || dy > bb . h )
284349 vg . path do |v |
285350 v . move_to ( bb . x , bb . y +dy ) ;
@@ -362,7 +427,7 @@ def self.linear_y(vg, min, max, bb, thick=1.0, c=40)
362427 med_fill = Theme ::GridLine
363428 light_fill = Theme ::GridLine
364429 c = max
365-
430+
366431 x = ( bb . x ) . floor
367432 y = ( bb . y ) . floor
368433 w = ( bb . w ) . floor
@@ -696,6 +761,40 @@ def self.zipToPos(x,y)
696761 o
697762 end
698763
764+ def self . zipToPosEnv ( x , y , c )
765+ o = [ ]
766+ n = [ x . length , y . length , c . length /2 ] . min
767+ o << Pos . new ( x [ 0 ] , y [ 0 ] )
768+ ( 1 ...n ) . each do |i |
769+ xcp1 = ( x [ i ] +3 *x [ i -1 ] ) /4
770+ ycp1 = ( y [ i ] +3 *y [ i -1 ] ) /4 + 2 *c [ i *2 -1 ]
771+ o << Pos . new ( xcp1 , ycp1 )
772+ xcp2 = ( 3 *x [ i ] +x [ i -1 ] ) /4
773+ ycp2 = ( 3 *y [ i ] +y [ i -1 ] ) /4 + 2 *c [ i *2 ]
774+ o << Pos . new ( xcp2 , ycp2 )
775+
776+ o << Pos . new ( x [ i ] , y [ i ] )
777+ end
778+ o
779+ end
780+
781+ def self . zipToPosCP ( x , y , c )
782+ o = [ ]
783+ n = [ x . length , y . length , c . length /2 ] . min
784+ o << Pos . new ( x [ 0 ] , y [ 0 ] )
785+ ( 1 ...n ) . each do |i |
786+ xcp1 = ( x [ i ] +3 *x [ i -1 ] ) /4
787+ ycp1 = ( y [ i ] +3 *y [ i -1 ] ) /4 + 1 *c [ i *2 -1 ]
788+ o << Pos . new ( xcp1 , ycp1 )
789+ xcp2 = ( 3 *x [ i ] +x [ i -1 ] ) /4
790+ ycp2 = ( 3 *y [ i ] +y [ i -1 ] ) /4 + 1 *c [ i *2 ]
791+ o << Pos . new ( xcp2 , ycp2 )
792+
793+ o << Pos . new ( x [ i ] , y [ i ] )
794+ end
795+ o
796+ end
797+
699798 def self . toPos ( p )
700799 o = [ ]
701800 n = p . length /2
@@ -774,6 +873,7 @@ module Theme
774873
775874 SustainPoint = color ( "005f8a" )
776875 EnvelopePoint = color ( "232c36" )
876+ EnvelopeCPoint = color ( "23362c" )
777877
778878 #Keyboard Widget
779879 KeyWhiteGrad1 = color ( "B0B7C0" )
@@ -790,6 +890,7 @@ module Theme
790890 VisualStroke = color ( "014767" )
791891 VisualLightFill = color ( "014767" , 55 )
792892 VisualBright = color ( "3ac5ec" )
893+ VisualBright2 = color ( "3ac560" )
793894 VisualDim = color ( "143644" )
794895 VisualDimTrans = color ( "143644" , 155 )
795896 VisualSelect = color ( "00ff00" )
0 commit comments