File: draw.fs

package info (click to toggle)
snd 25.9-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 44,016 kB
  • sloc: ansic: 291,818; lisp: 260,387; ruby: 71,134; sh: 3,293; fortran: 2,342; csh: 1,062; cpp: 294; makefile: 294; python: 87; xml: 27; javascript: 1
file content (324 lines) | stat: -rw-r--r-- 8,359 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
\ draw.fs -- draw.scm -> draw.fs

\ Author: Michael Scholz <mi-scholz@users.sourceforge.net>
\ Created: 05/12/18 23:36:09
\ Changed: 17/12/02 03:19:40
\
\ @(#)draw.fs	1.20 12/2/17

\ make-current-window-display  ( -- )
\ close-current-window-display ( -- )

require extensions

\ --- inset overall waveform; if click, move to that location ---

#f value current-window-display-is-running \ for prefs

hide
0.20 constant inset-width
0.25 constant inset-height

: update-current-window-location <{ snd -- #f }>
	current-window-display-is-running if
		snd channels 0 ?do
			'inset-envelope snd i channel-property { vals }
			\ set edit-position to impossible value
			vals array? if
				vals 'edit-position -2 array-assoc-set! to vals
			then
		loop
	then
	#f
;

: display-current-window-location <{ snd chn -- }>
	current-window-display-is-running
	snd chn time-graph? && if
		snd chn undef axis-info { axinf }
		axinf 12 array-ref { grf-width }
		inset-width grf-width f* fround->s { width }
		grf-width width - { x-offset }
		axinf 11 array-ref axinf 13 array-ref - { grf-height }
		inset-height grf-height f* fround->s { height }
		axinf 13 array-ref 10 - { chan-offset }
		chan-offset height 2/ + { y-offset }
		snd channel-style channels-separate = if
			chn
		else
			0
		then { grf-chn }
		axinf 19 array-ref { new-peaks }
		snd chn #f framples { frms }
		#f { data0 }
		#f { data1 }
		width  10 >
		height 10 > &&
		frms   0>   &&
		chn 0= snd channel-style channels-superimposed <> || && if
			x-offset chan-offset height + width 2
			snd grf-chn undef #f fill-rectangle drop
			x-offset chan-offset 2 height
			snd grf-chn undef #f fill-rectangle drop
			snd chn right-sample frms f/ width f* fround->s { rx }
			snd chn left-sample  frms f/ width f* fround->s { lx }
			x-offset lx + chan-offset rx lx - 1 max height
			snd grf-chn selection-context #f fill-rectangle drop
			'inset-envelope snd chn channel-property { old-env }
			old-env array? if
				new-peaks not
				old-env 'width array-assoc-ref width = &&
				old-env 'height array-assoc-ref height = &&
				old-env 'y-offset array-assoc-ref y-offset = &&
				old-env 'edit-position array-assoc-ref
				    snd chn edit-position = && if
					old-env 'data0 array-assoc-ref to data0
					old-env 'data1 array-assoc-ref to data1
					#t
				else
					#f
				then
			else
				#f
			then unless	\ else (old-env == #f)
				snd chn current-edit-position 0
				    frms make-graph-data { data }
				\ data may be a vct or a list of two vcts
				data vct? if
					data vct-peak
				else
					data 0 array-ref vct-peak
					data 1 array-ref vct-peak fmax
				then { data-max }
				data-max f0> if
					height data-max f2* f/
				else
					0.0
				then { data-scaler }
				width 2* { new-len }
				data vct? if
					data
				else
					data 0 array-ref
				then length { data-len }
				data-len width f/ fround->s { step }
				data-len width > if
					new-len make-array to data0
					data array? if
						new-len make-array to data1
					then
					0 { idxi }
					0 { idxj }
					data-max fnegate { max-y }
					data-max { min-y }
					0 { stepper }
					begin
						idxi data-len <
						idxj new-len < &&
					while
						data1 if
							max-y data 1 array-ref
							    idxi vct-ref fmax
							    to max-y
							min-y data 0 array-ref
							    idxi vct-ref fmin
							    to min-y
						else
							max-y data idxi vct-ref
							    fmax to max-y
						then
						stepper 1+ to stepper
						stepper step >= if
							data0 idxj x-offset
							    array-set!
							data0 idxj 1+ y-offset
							    max-y data-scaler
							    f* f- fround->s
							    array-set!
							data-max fnegate
							    to max-y
							data1 if
								data1 idxj
								    x-offset
								    array-set!
								data1 idxj 1+
								    y-offset
								    min-y
								    data-scaler
								    f* f-
								    fround->s
								    array-set!
								data-max
								    to min-y
							then
							x-offset 1+ to x-offset
							stepper step -
							    to stepper
							idxj 2 + to idxj
						then
						idxi 1+ to idxi
					repeat
					begin idxj new-len < while
						data0 idxj
						    data0 idxj 2 - array-ref
						    array-set!
						data0 idxj 1+
						    data0 idxj 1 - array-ref
						    array-set!
						data1 if
							data1 idxj 
							    data1 idxj 2 -
							    array-ref
							    array-set!
							data1 idxj 1+
							    data1 idxj 1 -
							    array-ref
							    array-set!
						then
						idxj 2 + to idxj
					repeat
				else
					width data-len f/ fround->s { xstep }
					data-len 2* make-array to data0
					data array? if
						new-len 2* make-array to data1
					then
					0 { idxj }
					x-offset { xj }
					data-len 0 ?do
						data0 idxj xj array-set!
						data1 if
							data0 idxj 1+
							    y-offset
							    data 1 array-ref
							    i vct-ref
							    data-scaler
							    f* f- fround->s
							    array-set!
							data1 idxj
							    xj array-set!
							data1 idxj 1+
							    y-offset
							    data 0 array-ref
							    i vct-ref
							    data-scaler
							    f* f- fround->s
							    array-set!
						else
							data0 idxj 1+
							    y-offset
							    data i vct-ref
							    data-scaler f* f-
							    fround->s array-set!
						then
						idxj 2 + to idxj
						xj xstep + to xj
					loop
				then
				#() 'width width array-assoc-set!
				( vals ) 'height height array-assoc-set!
				( vals ) 'edit-position
				    snd chn edit-position array-assoc-set!
				( vals ) 'data0 data0 array-assoc-set!
				( vals ) 'data1 data1 array-assoc-set!
				( vals ) 'y-offset
				    y-offset array-assoc-set! { vals }
				'inset-envelope vals
				    snd chn set-channel-property drop
			then
			data1 length 2 mod if
				data1 array-pop drop
			then
			data0 snd grf-chn time-graph draw-lines drop
			data1 if
				data1 snd grf-chn time-graph draw-lines drop
			then
		then
	then
;

: click-current-window-location <{ snd chn button state x y axis -- f }>
	current-window-display-is-running
	axis time-graph = && if
		snd chn undef axis-info            { axinf }
		axinf 12 array-ref                 { grf-width }
		inset-width grf-width f* fround->s { width }
		grf-width width -                  { x-offset }
		axinf 11 array-ref axinf 13 array-ref
		    - inset-height f* fround->s    { height }
		axinf 13 array-ref 10 -            { chan-offset }
		width         0>
		x x-offset    >= &&
		x grf-width   <= &&
		y chan-offset >= &&
		y chan-offset height + <= && if
			snd chn #f framples x x-offset f- width f/ f*
			    fround->s { samp }
			snd chn left-sample { ls }
			snd chn right-sample { rs }
			samp snd chn #f set-cursor drop
			samp ls < samp rs > || if
				samp ls rs - 2/ - 0 max
				snd chn #f framples 1- min
				snd chn set-right-sample drop
			then
			snd chn update-time-graph drop
			#t
		else
			#f
		then
	else
		#f
	then
;

: undo-cb { snd chn -- proc; self -- }
	0 proc-create snd , chn ,
 does> { self -- }
	'inset-envelope #f self @ ( snd ) self cell+ @ ( chn )
	    set-channel-property drop
;

: install-current-window-location <{ snd -- }>
	snd channels 0 ?do
		'inset-envelope snd i
		    set-channel-property-save-state-ignore drop
		snd i undo-hook snd i undo-cb add-hook!
	loop
;
set-current

: make-current-window-display ( -- )
	doc" Display in upper right corner the overall current sound \
and where the current window fits in it."
	current-window-display-is-running unless
		#t to current-window-display-is-running
		after-open-hook  <'> install-current-window-location add-hook!
		after-graph-hook <'> display-current-window-location add-hook!
		mouse-click-hook <'> click-current-window-location   add-hook!
		update-hook      <'> update-current-window-location  add-hook!
	then
;

: close-current-window-display ( -- )
	current-window-display-is-running if
		#f to current-window-display-is-running
		after-open-hook <'> install-current-window-location
		    remove-hook! drop
		after-graph-hook <'> display-current-window-location
		    remove-hook! drop
		mouse-click-hook <'> click-current-window-location
		    remove-hook! drop
		update-hook <'> update-current-window-location
		    remove-hook! drop
		sounds each { snd }
			snd channels 0 ?do
				snd i undo-hook <'> undo-cb remove-hook! drop
			loop
		end-each
	then
;

previous

\ draw.fs ends here