blob: 2dc28137d894f2c5513a0eec5423ee9b50c7917b (
plain)
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
|
\ marks.fs -- marks.scm|rb -> marks.fs
\ Author: Michael Scholz <mi-scholz@users.sourceforge.net>
\ Created: 05/12/27 19:22:06
\ Changed: 17/12/02 07:56:15
\
\ @(#)marks.fs 1.28 12/2/17
\ Commentary:
\
\ add-named-mark ( samp name snd chn -- mark )
\ mark-name->id ( name -- m )
\ move-syncd-marks ( sync diff -- )
\ describe-mark ( id -- ary )
\
\ save-mark-properties ( -- )
\ mark-click-info ( id -- #t )
\ marks->string ( snd -- str )
\ Code:
require clm
require examp
<'> integer? alias channel?
\ snd #f: all sounds
\ chn #f: all channels
: marks-length <{ :optional snd #f chn #f edpos #f -- len }>
snd sound? if
chn channel? if
snd chn edpos marks
else
snd chn edpos marks car
then
else
snd chn edpos marks car car
then length
;
: marks? ( :optional snd chn edpos -- f )
marks-length 0>
;
\ from rubber.fs
: add-named-mark { samp name snd chn -- mark }
samp snd chn add-mark { m }
m name set-mark-name drop
m
;
\ mark-name->id is a global version of find-mark
: mark-name->id ( name -- m )
doc" Like find-mark but searche all currently accessible channels."
{ name }
#f \ flag
sounds each { snd }
snd channels 0 ?do
name snd i undef find-mark { m }
m mark? if
drop \ replace #f with mark
m
exit
then
loop
end-each
;
: move-syncd-marks ( sync diff -- )
doc" Move all marks sharing SYNC by DIFF samples."
{ syn diff }
syn syncd-marks each { m }
m undef mark-sample diff + { val }
m val set-mark-sample drop
end-each
;
: describe-mark ( id -- ary )
doc" Return a description of the movements of mark ID over \
the channel's edit history."
{ id }
id <'> mark-home 'no-such-mark nil fth-catch if
sounds each { snd }
snd channels 0 ?do
0 snd i ( chn ) edits each
+
end-each 1+ ( max-edits ) 0 ?do
snd j ( chn ) #f marks { m }
m
id m array-member? && if
#( snd j ( chn ) )
leave
then
loop
loop
end-each
then { mark-setting }
mark-setting array? if
mark-setting 0 array-ref { snd }
mark-setting 1 array-ref { chn }
#( #( 'mark id
'sound snd snd short-file-name
'channel chn ) ) { descr }
0 snd chn edits each
+
end-each 1+ 1 ?do
descr
snd chn i marks id array-member? if
id i mark-sample
else
#f
then array-push drop
loop
descr
else
'no-such-mark #( "%s: %s" get-func-name id ) fth-throw
then
;
\ --- Mark Properties ---
hide
: mark-writeit { mp mhome msamp io -- }
io "\t%S 0 find-sound to snd\n" #( mhome car file-name ) io-write-format
io "\tsnd sound? if\n" io-write
io "\t\t%d snd %d find-mark to mk\n"
#( msamp mhome cadr ) io-write-format
io "\t\tmk mark? if\n" io-write
io "\t\t\tmk %S set-mark-properties drop\n" #( mp ) io-write-format
io "\t\tthen\n" io-write
io "\tthen\n" io-write
;
: save-mark-properties-cb <{ filename -- }>
undef undef undef marks car car cons? if
filename :fam a/o io-open { io }
io "\n\\ from save-mark-properties in %s\n"
#( *filename* ) io-write-format
io "require marks\n\n" io-write
io "let: ( -- )\n" io-write
io "\tnil nil { snd mk }\n" io-write
undef undef undef marks each ( snd-m )
each ( chn-m )
each { m }
m mark-properties { mp }
mp if
m mark-home { mhome }
m undef mark-sample { msamp }
mp mhome msamp io mark-writeit
then
end-each
end-each
end-each
io ";let\n" io-write
io io-close
then
;
set-current
: save-mark-properties ( -- )
doc" Set up an after-save-state-hook \
function to save any mark-properties."
after-save-state-hook <'> save-mark-properties-cb add-hook!
;
previous
: mark-click-info <{ id -- #t }>
doc" A mark-click-hook function that describes a \
mark and its properties.\n\
mark-click-hook <'> mark-click-info add-hook!."
id mark-name { name }
id undef mark-sample { samp }
id mark-home car { snd }
id mark-sync { syn }
id mark-properties { props }
"\n mark id: %s\n\n" #( id ) string-format
make-string-output-port { prt }
name empty? unless
prt " name: %s\n" #( name ) port-puts-format
then
prt " sample: %s (%.3f secs)\n"
#( samp samp snd srate f/ ) port-puts-format
syn if
prt " sync: %s\n" #( syn ) port-puts-format
then
props empty? unless
prt "properties: %s" #( props ) port-puts-format
then
"Mark Info" prt port->string info-dialog drop
#t
;
\ mark-click-hook <'> mark-click-info add-hook!
\ This code saves mark info in the sound file header, and reads it
\ back in when the sound is later reopened.
: marks->string { snd -- str }
"\nrequire marks\n" make-string-output-port { prt }
prt "let: ( -- )\n" port-puts
prt "\t#f { mk }\n" port-puts
snd marks each { chan-marks }
prt "\n\t\\ channel %d\n" #( i ) port-puts-format
chan-marks each { m }
m nil? ?leave
prt "\t%s #f %d %S %d add-mark to mk\n"
#( m undef mark-sample
j ( chn )
m mark-name length 0= if
#f
else
m mark-name
then
m mark-sync ) port-puts-format
m mark-properties { props }
props if
prt "\tmk %S set-mark-properties drop\n"
#( props ) port-puts-format
then
end-each
end-each
prt ";let\n" port-puts
prt port->string
;
0 [if]
output-comment-hook lambda: <{ str -- str' }>
selected-sound marks->string
; add-hook!
after-open-hook lambda: <{ snd -- }>
snd comment ( str ) <'> string-eval #t nil fth-catch if
( str ) drop
then
; add-hook!
[then]
\ marks.fs ends here
|