1 #include "snd.h"
2 #include "clm-strings.h"
3 #include "sndlib-strings.h"
4 #include "clm2xen.h"
5 
6 
7 #if HAVE_RUBY
8   #define TO_GVAR_NAME(Str) xen_scheme_global_variable_to_ruby(Str)
9 #else
10   #define TO_GVAR_NAME(Str) Str
11 #endif
12 
13 
remove_temp_files(chan_info * cp)14 static void remove_temp_files(chan_info *cp)
15 {
16   free_sound_list(cp);
17   delete_any_remaining_mix_temp_files_at_exit(cp);
18 }
19 
20 
save_peak_env_info(chan_info * cp)21 static void save_peak_env_info(chan_info *cp)
22 {
23   write_peak_env_info_file(cp); /* this returns bool, but for_each_chan wants void */
24 }
25 
26 
27 static Xen exit_hook;
28 static Xen before_exit_hook;
29 
snd_exit_cleanly(bool force_exit)30 bool snd_exit_cleanly(bool force_exit)
31 {
32   Xen res = Xen_false;
33   ss->exiting = true; /* if segfault during exit code, don't try to restart at event loop! */
34 
35   /* before-exit-hook can cancel the exit, whereas exit-hook can't */
36   if (Xen_hook_has_list(before_exit_hook))
37     res = run_or_hook(before_exit_hook,
38 		      Xen_empty_list,
39 		      S_before_exit_hook);
40   if ((Xen_is_true(res)) && (!force_exit)) return(false); /* does it make any sense to call this hook if we're forced to exit anyway? */
41 
42 #if (!USE_NO_GUI)
43   if (ask_about_unsaved_edits(ss))
44     {
45       int i;
46       bool found_saver = false;
47       for (i = 0; i < ss->max_sounds; i++)
48 	{
49 	  snd_info *sp;
50 	  sp = ss->sounds[i];
51 	  if ((sp) &&
52 	      (sp->inuse == SOUND_NORMAL) &&
53 	      (has_unsaved_edits(sp)))
54 	    {
55 	      found_saver = true;
56 	      save_edits_now(sp);
57 	    }
58 	}
59       if (found_saver) return(false);
60     }
61 #endif
62 
63   if (peak_env_dir(ss))
64     for_each_chan(save_peak_env_info);
65 
66   if (Xen_hook_has_list(exit_hook))
67     run_hook(exit_hook,
68 	     Xen_empty_list,
69 	     S_exit_hook);
70 
71   if (ss->file_monitor_ok)
72     cleanup_file_monitor();
73 
74   cleanup_dac();
75   for_each_normal_chan(remove_temp_files);
76   cleanup_region_temp_files();
77   forget_temps();
78   return(true);
79 }
80 
81 
sound_not_current(snd_info * sp)82 void sound_not_current(snd_info *sp)
83 {
84   /* check for change in update status */
85   bool needs_update;
86   if (ss->file_monitor_ok) return;
87   needs_update = (file_write_date(sp->filename) != sp->write_date);
88   if (needs_update != sp->need_update)
89     {
90       sp->need_update = needs_update;
91       if (needs_update)
92 	{
93 	  if (auto_update(ss))
94 	    snd_update(sp); /* will stop bomb via need_update flag */
95 	  else start_bomb(sp);
96 	}
97       else stop_bomb(sp);
98     }
99 }
100 
101 
102 
103 
104 /* ---------------- save sound state (options, or entire state) ---------------- */
105 
fneq(mus_float_t a,mus_float_t b)106 static bool fneq(mus_float_t a, mus_float_t b)
107 {
108   /* floating point != replacement */
109   return(fabs(a - b) > .00001);
110 }
111 
112 
cursor_style_name(cursor_style_t style)113 static const char *cursor_style_name(cursor_style_t style)
114 {
115   switch (style)
116     {
117     case CURSOR_CROSS: return(TO_VAR_NAME(S_cursor_cross));
118     case CURSOR_LINE:  return(TO_VAR_NAME(S_cursor_line));
119     default: /* proc?? */ return(TO_VAR_NAME(S_cursor_cross));
120     }
121 }
122 
123 
show_axes2string(show_axes_t ax)124 static const char *show_axes2string(show_axes_t ax)
125 {
126   switch (ax)
127     {
128     case SHOW_NO_AXES:           return(TO_VAR_NAME(S_show_no_axes));
129     case SHOW_X_AXIS:            return(TO_VAR_NAME(S_show_x_axis));
130     case SHOW_X_AXIS_UNLABELLED: return(TO_VAR_NAME(S_show_x_axis_unlabelled));
131     case SHOW_ALL_AXES:          return(TO_VAR_NAME(S_show_all_axes));
132     case SHOW_BARE_X_AXIS:       return(TO_VAR_NAME(S_show_bare_x_axis));
133     default:                     return(TO_VAR_NAME(S_show_all_axes_unlabelled));
134     }
135 }
136 
137 
zoom_focus_style_name(zoom_focus_t choice)138 static const char *zoom_focus_style_name(zoom_focus_t choice)
139 {
140   switch (choice)
141     {
142     case ZOOM_FOCUS_LEFT:   return(TO_VAR_NAME(S_zoom_focus_left));
143     case ZOOM_FOCUS_RIGHT:  return(TO_VAR_NAME(S_zoom_focus_right));
144     case ZOOM_FOCUS_MIDDLE: return(TO_VAR_NAME(S_zoom_focus_middle));
145       /* proc?? */
146     default:                return(TO_VAR_NAME(S_zoom_focus_active));
147     }
148 }
149 
150 
transform_normalization_name(fft_normalize_t choice)151 static const char *transform_normalization_name(fft_normalize_t choice)
152 {
153   switch (choice)
154     {
155     case DONT_NORMALIZE:      return(TO_VAR_NAME(S_dont_normalize));
156     case NORMALIZE_BY_CHANNEL:return(TO_VAR_NAME(S_normalize_by_channel));
157     case NORMALIZE_BY_SOUND:  return(TO_VAR_NAME(S_normalize_by_sound));
158     case NORMALIZE_GLOBALLY:  return(TO_VAR_NAME(S_normalize_globally));
159     default:                  return(TO_VAR_NAME(S_normalize_by_channel));
160     }
161 }
162 
163 
graph_style_name(graph_style_t choice)164 static const char *graph_style_name(graph_style_t choice)
165 {
166   switch (choice)
167     {
168     case GRAPH_DOTS:           return(TO_VAR_NAME(S_graph_dots));
169     case GRAPH_DOTS_AND_LINES: return(TO_VAR_NAME(S_graph_dots_and_lines));
170     case GRAPH_LOLLIPOPS:      return(TO_VAR_NAME(S_graph_lollipops));
171     case GRAPH_FILLED:         return(TO_VAR_NAME(S_graph_filled));
172     case GRAPH_LINES:
173     default:                   return(TO_VAR_NAME(S_graph_lines));
174     }
175 }
176 
177 
transform_graph_type_name(graph_type_t choice)178 static const char *transform_graph_type_name(graph_type_t choice)
179 {
180   switch (choice)
181     {
182     case GRAPH_AS_SONOGRAM:    return(TO_VAR_NAME(S_graph_as_sonogram));
183     case GRAPH_AS_SPECTROGRAM: return(TO_VAR_NAME(S_graph_as_spectrogram));
184     default:                   return(TO_VAR_NAME(S_graph_once));
185     }
186 }
187 
188 
time_graph_type_name(graph_type_t choice)189 static const char *time_graph_type_name(graph_type_t choice)
190 {
191   switch (choice)
192     {
193     case GRAPH_AS_WAVOGRAM: return(TO_VAR_NAME(S_graph_as_wavogram));
194     default:                return(TO_VAR_NAME(S_graph_once));
195     }
196 }
197 
198 
x_axis_style_name(x_axis_style_t choice)199 static const char *x_axis_style_name(x_axis_style_t choice)
200 {
201   switch (choice)
202     {
203     case X_AXIS_AS_CLOCK:      return(TO_VAR_NAME(S_x_axis_as_clock));
204     case X_AXIS_IN_SAMPLES:    return(TO_VAR_NAME(S_x_axis_in_samples));
205     case X_AXIS_AS_PERCENTAGE: return(TO_VAR_NAME(S_x_axis_as_percentage));
206     case X_AXIS_IN_BEATS:      return(TO_VAR_NAME(S_x_axis_in_beats));
207     case X_AXIS_IN_MEASURES:   return(TO_VAR_NAME(S_x_axis_in_measures));
208     default:                   return(TO_VAR_NAME(S_x_axis_in_seconds));
209     }
210 }
211 
212 
speed_control_style_name(speed_style_t choice)213 static const char *speed_control_style_name(speed_style_t choice)
214 {
215   switch (choice)
216     {
217     case SPEED_CONTROL_AS_RATIO:    return(TO_VAR_NAME(S_speed_control_as_ratio));
218     case SPEED_CONTROL_AS_SEMITONE: return(TO_VAR_NAME(S_speed_control_as_semitone));
219     default:                        return(TO_VAR_NAME(S_speed_control_as_float));
220     }
221 }
222 
223 
channel_style_name(channel_style_t choice)224 static const char *channel_style_name(channel_style_t choice)
225 {
226   switch (choice)
227     {
228     case CHANNELS_COMBINED:     return(TO_VAR_NAME(S_channels_combined));
229     case CHANNELS_SUPERIMPOSED: return(TO_VAR_NAME(S_channels_superimposed));
230     default:                    return(TO_VAR_NAME(S_channels_separate));
231     }
232 }
233 
234 
sync_style_name(sync_style_t choice)235 static const char *sync_style_name(sync_style_t choice)
236 {
237   switch (choice)
238     {
239     case SYNC_NONE: return(TO_VAR_NAME(S_sync_none));
240     case SYNC_ALL:  return(TO_VAR_NAME(S_sync_all));
241     default:        return(TO_VAR_NAME(S_sync_by_sound));
242     }
243 }
244 
245 
enved_target_name(enved_target_t choice)246 static const char *enved_target_name(enved_target_t choice)
247 {
248   switch (choice)
249     {
250     case ENVED_SPECTRUM: return(TO_VAR_NAME(S_enved_spectrum));
251     case ENVED_SRATE:    return(TO_VAR_NAME(S_enved_srate));
252     default:             return(TO_VAR_NAME(S_enved_amplitude));
253     }
254 }
255 
256 
b2s(bool val)257 static const char *b2s(bool val) {return((val) ? (char *)PROC_TRUE : (char *)PROC_FALSE);} /* cast needed by g++ > 3.4 */
258 
259 #if (!USE_NO_GUI)
260 static char *colvarname = NULL;
colormap_variable_name(int col)261 static char *colormap_variable_name(int col)
262 {
263   if (colvarname) free(colvarname);
264   colvarname = (char *)calloc(64, sizeof(char));
265   snprintf(colvarname, 64, "%s-colormap", colormap_name(col));
266   return(colvarname);
267 }
268 #endif
269 
270 
271 #define white_space "      "
272 static bool b_ok = false;
273 
274 
275 #if HAVE_RUBY
pss_ss(FILE * fd,const char * name,const char * val)276 static void pss_ss(FILE *fd, const char *name, const char *val) {fprintf(fd, "set_%s(%s)\n", to_proc_name(name), val);}
pss_sq(FILE * fd,const char * name,const char * val)277 static void pss_sq(FILE *fd, const char *name, const char *val) {fprintf(fd, "set_%s(\"%s\")\n", to_proc_name(name), val);}
pss_sd(FILE * fd,const char * name,int val)278 static void pss_sd(FILE *fd, const char *name, int val)   {fprintf(fd, "set_%s(%d)\n", to_proc_name(name), val);}
pss_sod(FILE * fd,const char * name,mus_long_t val)279 static void pss_sod(FILE *fd, const char *name, mus_long_t val)   {fprintf(fd, "set_%s(%" print_mus_long ")\n", to_proc_name(name), val);}
pss_sf(FILE * fd,const char * name,mus_float_t val)280 static void pss_sf(FILE *fd, const char *name, mus_float_t val) {fprintf(fd, "set_%s(%.4f)\n", to_proc_name(name), val);}
281 
pss_sl(FILE * fd,const char * name,mus_float_t val1,mus_float_t val2)282 static void pss_sl(FILE *fd, const char *name, mus_float_t val1, mus_float_t val2)
283   {fprintf(fd, "set_%s([%f, %f])\n", to_proc_name(name), val1, val2);}
284 
psp_ss(FILE * fd,const char * name,const char * val)285 static void psp_ss(FILE *fd, const char *name, const char *val) {fprintf(fd, "%sset_%s(%s, sfile)\n", white_space, to_proc_name(name), val);}
psp_sd(FILE * fd,const char * name,int val)286 static void psp_sd(FILE *fd, const char *name, int val)   {fprintf(fd, "%sset_%s(%d, sfile)\n", white_space, to_proc_name(name), val);}
psp_sf(FILE * fd,const char * name,mus_float_t val)287 static void psp_sf(FILE *fd, const char *name, mus_float_t val) {fprintf(fd, "%sset_%s(%.4f, sfile)\n", white_space, to_proc_name(name), val);}
288 
psp_sl(FILE * fd,const char * name,mus_float_t val1,mus_float_t val2)289 static void psp_sl(FILE *fd, const char *name, mus_float_t val1, mus_float_t val2)
290   {fprintf(fd, "%sset_%s([%f, %f], sfile)\n", white_space, to_proc_name(name), val1, val2);}
291 
pcp_ss(FILE * fd,const char * name,const char * val,int chan)292 static void pcp_ss(FILE *fd, const char *name, const char *val, int chan)
293   {fprintf(fd, "%sset_%s(%s, sfile, %d)\n", white_space, to_proc_name(name), val, chan);}
294 
pcp_sss(FILE * fd,const char * name,const char * val,int chan,const char * grf)295 static void pcp_sss(FILE *fd, const char *name, const char *val, int chan, const char *grf)
296   {fprintf(fd, "%sset_%s(\"%s\", sfile, %d, %s)\n", white_space, to_proc_name(name), val, chan, TO_VAR_NAME(grf));}
297 
pcp_sd(FILE * fd,const char * name,int val,int chan)298 static void pcp_sd(FILE *fd, const char *name, int val, int chan)
299   {fprintf(fd, "%sset_%s(%d, sfile, %d)\n", white_space, to_proc_name(name), val, chan);}
300 
pcp_sod(FILE * fd,const char * name,mus_long_t val,int chan)301 static void pcp_sod(FILE *fd, const char *name, mus_long_t val, int chan)
302   {fprintf(fd, "%sset_%s(%" print_mus_long ", sfile, %d)\n", white_space, to_proc_name(name), val, chan);}
303 
pcp_sf(FILE * fd,const char * name,mus_float_t val,int chan)304 static void pcp_sf(FILE *fd, const char *name, mus_float_t val, int chan)
305   {fprintf(fd, "%sset_%s(%.4f, sfile, %d)\n", white_space, to_proc_name(name), val, chan);}
306 
pcp_sl(FILE * fd,const char * name,mus_float_t val1,mus_float_t val2,int chan)307 static void pcp_sl(FILE *fd, const char *name, mus_float_t val1, mus_float_t val2, int chan)
308   {fprintf(fd, "%sset_%s([%f, %f], sfile, %d)\n", white_space, to_proc_name(name), val1, val2, chan);}
309 #endif
310 
311 
312 #if HAVE_FORTH
pss_ss(FILE * fd,const char * name,const char * val)313 static void pss_ss(FILE *fd, const char *name, const char *val) {fprintf(fd, "%s set-%s drop\n", val, name);}
pss_sq(FILE * fd,const char * name,const char * val)314 static void pss_sq(FILE *fd, const char *name, const char *val) {fprintf(fd, "\"%s\" set-%s drop\n", val, name);}
pss_sd(FILE * fd,const char * name,int val)315 static void pss_sd(FILE *fd, const char *name, int val)   {fprintf(fd, "%d set-%s drop\n", val, name);}
pss_sod(FILE * fd,const char * name,mus_long_t val)316 static void pss_sod(FILE *fd, const char *name, mus_long_t val)   {fprintf(fd, "%" print_mus_long " set-%s drop\n", val, name);}
pss_sf(FILE * fd,const char * name,mus_float_t val)317 static void pss_sf(FILE *fd, const char *name, mus_float_t val) {fprintf(fd, "%.4f set-%s drop\n", val, name);}
pss_sl(FILE * fd,const char * name,mus_float_t val1,mus_float_t val2)318 static void pss_sl(FILE *fd, const char *name, mus_float_t val1, mus_float_t val2)
319 {fprintf(fd, "%s'( %f %f ) set-%s drop\n", white_space, val1, val2, name);}
320 
psp_ss(FILE * fd,const char * name,const char * val)321 static void psp_ss(FILE *fd, const char *name, const char *val) {fprintf(fd, "%s%s sfile set-%s drop\n", white_space, val, name);}
psp_sd(FILE * fd,const char * name,int val)322 static void psp_sd(FILE *fd, const char *name, int val)   {fprintf(fd, "%s%d sfile set-%s drop\n", white_space, val, name);}
psp_sf(FILE * fd,const char * name,mus_float_t val)323 static void psp_sf(FILE *fd, const char *name, mus_float_t val) {fprintf(fd, "%s%.4f sfile set-%s drop\n", white_space, val, name);}
324 
psp_sl(FILE * fd,const char * name,mus_float_t val1,mus_float_t val2)325 static void psp_sl(FILE *fd, const char *name, mus_float_t val1, mus_float_t val2)
326   {fprintf(fd, "%s'( %f %f ) sfile set-%s drop\n", white_space, val1, val2, name);}
327 
pcp_ss(FILE * fd,const char * name,const char * val,int chan)328 static void pcp_ss(FILE *fd, const char *name, const char *val, int chan)
329   {fprintf(fd, "%s%s sfile %d set-%s drop\n", white_space, val, chan, name);}
330 
pcp_sss(FILE * fd,const char * name,const char * val,int chan,const char * grf)331 static void pcp_sss(FILE *fd, const char *name, const char *val, int chan, const char *grf)
332   {fprintf(fd, "%s\"%s\" sfile %d %s set-%s drop\n", white_space, val, chan, grf, name);}
333 
pcp_sd(FILE * fd,const char * name,int val,int chan)334 static void pcp_sd(FILE *fd, const char *name, int val, int chan)
335   {fprintf(fd, "%s%d sfile %d set-%s drop\n", white_space, val, chan, name);}
336 
pcp_sod(FILE * fd,const char * name,mus_long_t val,int chan)337 static void pcp_sod(FILE *fd, const char *name, mus_long_t val, int chan)
338   {fprintf(fd, "%s%" print_mus_long " sfile %d set-%s drop\n", white_space, val, chan, name);}
339 
pcp_sf(FILE * fd,const char * name,mus_float_t val,int chan)340 static void pcp_sf(FILE *fd, const char *name, mus_float_t val, int chan)
341   {fprintf(fd, "%s%.4f sfile %d set-%s drop\n", white_space, val, chan, name);}
342 
pcp_sl(FILE * fd,const char * name,mus_float_t val1,mus_float_t val2,int chan)343 static void pcp_sl(FILE *fd, const char *name, mus_float_t val1, mus_float_t val2, int chan)
344   {fprintf(fd, "%s'( %f %f ) sfile %d set-%s drop\n", white_space, val1, val2, chan, name);}
345 #endif
346 
347 
348 #if HAVE_SCHEME || (!HAVE_EXTENSION_LANGUAGE)
pss_ss(FILE * fd,const char * name,const char * val)349 static void pss_ss(FILE *fd, const char *name, const char *val) {fprintf(fd, "(set! (%s) %s)\n", name, val);}
pss_sq(FILE * fd,const char * name,const char * val)350 static void pss_sq(FILE *fd, const char *name, const char *val) {fprintf(fd, "(set! (%s) \"%s\")\n", name, val);}
pss_sd(FILE * fd,const char * name,int val)351 static void pss_sd(FILE *fd, const char *name, int val)   {fprintf(fd, "(set! (%s) %d)\n", name, val);}
pss_sod(FILE * fd,const char * name,mus_long_t val)352 static void pss_sod(FILE *fd, const char *name, mus_long_t val)   {fprintf(fd, "(set! (%s) %" print_mus_long ")\n", name, val);}
pss_sf(FILE * fd,const char * name,mus_float_t val)353 static void pss_sf(FILE *fd, const char *name, mus_float_t val) {fprintf(fd, "(set! (%s) %.4f)\n", name, val);}
pss_sl(FILE * fd,const char * name,mus_float_t val1,mus_float_t val2)354 static void pss_sl(FILE *fd, const char *name, mus_float_t val1, mus_float_t val2) {fprintf(fd, "(set! (%s) (list %f %f))\n", name, val1, val2);}
355 
psp_ss(FILE * fd,const char * name,const char * val)356 static void psp_ss(FILE *fd, const char *name, const char *val)
357   {b_ok = true; fprintf(fd, "%s(set! (%s sfile) %s)\n", white_space, name, val);}
358 
psp_sd(FILE * fd,const char * name,int val)359 static void psp_sd(FILE *fd, const char *name, int val)
360   {b_ok = true; fprintf(fd, "%s(set! (%s sfile) %d)\n", white_space, name, val);}
361 
psp_sf(FILE * fd,const char * name,mus_float_t val)362 static void psp_sf(FILE *fd, const char *name, mus_float_t val)
363   {b_ok = true; fprintf(fd, "%s(set! (%s sfile) %.4f)\n", white_space, name, val);}
364 
psp_sl(FILE * fd,const char * name,mus_float_t val1,mus_float_t val2)365 static void psp_sl(FILE *fd, const char *name, mus_float_t val1, mus_float_t val2)
366   {b_ok = true; fprintf(fd, "%s(set! (%s sfile) (list %f %f))\n", white_space, name, val1, val2);}
367 
pcp_ss(FILE * fd,const char * name,const char * val,int chan)368 static void pcp_ss(FILE *fd, const char *name, const char *val, int chan)
369   {b_ok = true; fprintf(fd, "%s(set! (%s sfile %d) %s)\n", white_space, name, chan, val);}
370 
pcp_sss(FILE * fd,const char * name,const char * val,int chan,const char * grf)371 static void pcp_sss(FILE *fd, const char *name, const char *val, int chan, const char *grf)
372   {b_ok = true; fprintf(fd, "%s(set! (%s sfile %d %s) \"%s\")\n", white_space, name, chan, grf, val);}
373 
pcp_sd(FILE * fd,const char * name,int val,int chan)374 static void pcp_sd(FILE *fd, const char *name, int val, int chan)
375   {b_ok = true; fprintf(fd, "%s(set! (%s sfile %d) %d)\n", white_space, name, chan, val);}
376 
pcp_sod(FILE * fd,const char * name,mus_long_t val,int chan)377 static void pcp_sod(FILE *fd, const char *name, mus_long_t val, int chan)
378   {b_ok = true; fprintf(fd, "%s(set! (%s sfile %d) %" print_mus_long ")\n", white_space, name, chan, val);}
379 
pcp_sf(FILE * fd,const char * name,mus_float_t val,int chan)380 static void pcp_sf(FILE *fd, const char *name, mus_float_t val, int chan)
381   {b_ok = true; fprintf(fd, "%s(set! (%s sfile %d) %.4f)\n", white_space, name, chan, val);}
382 
pcp_sl(FILE * fd,const char * name,mus_float_t val1,mus_float_t val2,int chan)383 static void pcp_sl(FILE *fd, const char *name, mus_float_t val1, mus_float_t val2, int chan)
384   {b_ok = true; fprintf(fd, "%s(set! (%s sfile %d) (list %f %f))\n", white_space, name, chan, val1, val2);}
385 #endif
386 
387 
save_options(FILE * fd)388 static void save_options(FILE *fd)
389 {
390   fprintf(fd, "\n%s Snd %s (%s) options saved %s\n", Xen_comment_mark, SND_VERSION, SND_DATE, snd_local_time());
391 
392   if (transform_size(ss) != DEFAULT_TRANSFORM_SIZE) pss_sod(fd, S_transform_size, transform_size(ss));
393   if (fft_window(ss) != DEFAULT_FFT_WINDOW) pss_ss(fd, S_fft_window, TO_VAR_NAME(mus_fft_window_xen_name(fft_window(ss))));
394   if (transform_graph_type(ss) != DEFAULT_TRANSFORM_GRAPH_TYPE) pss_ss(fd, S_transform_graph_type, transform_graph_type_name(transform_graph_type(ss)));
395   if (time_graph_type(ss) != DEFAULT_TIME_GRAPH_TYPE) pss_ss(fd, S_time_graph_type, time_graph_type_name(time_graph_type(ss)));
396   if (x_axis_style(ss) != DEFAULT_X_AXIS_STYLE) pss_ss(fd, S_x_axis_style, x_axis_style_name(x_axis_style(ss)));
397   if (fneq(beats_per_minute(ss), DEFAULT_BEATS_PER_MINUTE)) pss_sf(fd, S_beats_per_minute, beats_per_minute(ss));
398   if (beats_per_measure(ss) != DEFAULT_BEATS_PER_MEASURE) pss_sd(fd, S_beats_per_measure, beats_per_measure(ss));
399   if (graph_style(ss) != DEFAULT_GRAPH_STYLE) pss_ss(fd, S_graph_style, graph_style_name(graph_style(ss)));
400   if (region_graph_style(ss) != DEFAULT_GRAPH_STYLE) pss_ss(fd, S_region_graph_style, graph_style_name(region_graph_style(ss)));
401   if (channel_style(ss) != DEFAULT_CHANNEL_STYLE) pss_ss(fd, S_channel_style, channel_style_name(channel_style(ss)));
402   if (sync_style(ss) != DEFAULT_SYNC_STYLE) pss_ss(fd, S_sync_style, sync_style_name(sync_style(ss)));
403   if (enved_target(ss) != DEFAULT_ENVED_TARGET) pss_ss(fd, S_enved_target, enved_target_name(enved_target(ss)));
404   if (transform_type(ss) != DEFAULT_TRANSFORM_TYPE) pss_ss(fd, S_transform_type, TO_VAR_NAME(transform_program_name(transform_type(ss))));
405   if (zoom_focus_style(ss) != ZOOM_FOCUS_ACTIVE) pss_ss(fd, S_zoom_focus_style, zoom_focus_style_name(zoom_focus_style(ss)));
406   if (transform_normalization(ss) != DEFAULT_TRANSFORM_NORMALIZATION) pss_ss(fd, S_transform_normalization, transform_normalization_name(transform_normalization(ss)));
407   if (with_file_monitor(ss) != DEFAULT_WITH_FILE_MONITOR) pss_ss(fd, S_with_file_monitor, b2s(with_file_monitor(ss)));
408   if (just_sounds(ss) != DEFAULT_JUST_SOUNDS) pss_ss(fd, S_just_sounds, b2s(just_sounds(ss)));
409   if (play_arrow_size(ss) != DEFAULT_PLAY_ARROW_SIZE) pss_sd(fd, S_play_arrow_size, play_arrow_size(ss));
410   if (show_selection_transform(ss) != DEFAULT_SHOW_SELECTION_TRANSFORM) pss_ss(fd, S_show_selection_transform, b2s(show_selection_transform(ss)));
411   if (with_gl(ss) != DEFAULT_WITH_GL) pss_ss(fd, S_with_gl, b2s(with_gl(ss)));
412   if (with_mix_tags(ss) != DEFAULT_WITH_MIX_TAGS) pss_ss(fd, S_with_mix_tags, b2s(with_mix_tags(ss)));
413   if (with_relative_panes(ss) != DEFAULT_WITH_RELATIVE_PANES) pss_ss(fd, S_with_relative_panes, b2s(with_relative_panes(ss)));
414   if (sinc_width(ss) != DEFAULT_SINC_WIDTH) pss_sd(fd, S_sinc_width, sinc_width(ss));
415   if (ss->init_window_width != DEFAULT_INIT_WINDOW_WIDTH) pss_sd(fd, S_window_width, ss->init_window_width);
416   if (ss->init_window_height != DEFAULT_INIT_WINDOW_HEIGHT) pss_sd(fd, S_window_height, ss->init_window_height);
417   if (ss->init_window_x != DEFAULT_INIT_WINDOW_X) pss_sd(fd, S_window_x, ss->init_window_x);
418   if (ss->init_window_y != DEFAULT_INIT_WINDOW_Y) pss_sd(fd, S_window_y, ss->init_window_y);
419   if (default_output_chans(ss) != DEFAULT_OUTPUT_CHANS) pss_sd(fd, S_default_output_chans, default_output_chans(ss));
420   if (default_output_srate(ss) != DEFAULT_OUTPUT_SRATE) pss_sd(fd, S_default_output_srate, default_output_srate(ss));
421   if (default_output_header_type(ss) != DEFAULT_OUTPUT_HEADER_TYPE)
422     pss_ss(fd, S_default_output_header_type, mus_header_type_to_string(default_output_header_type(ss)));
423   if (default_output_sample_type(ss) != DEFAULT_OUTPUT_SAMPLE_TYPE)
424     pss_ss(fd, S_default_output_sample_type, mus_sample_type_to_string(default_output_sample_type(ss)));
425   if (auto_resize(ss) != DEFAULT_AUTO_RESIZE) pss_ss(fd, S_auto_resize, b2s(auto_resize(ss)));
426   if (graphs_horizontal(ss) != DEFAULT_GRAPHS_HORIZONTAL) pss_ss(fd, S_graphs_horizontal, b2s(graphs_horizontal(ss)));
427   if (auto_update(ss) != DEFAULT_AUTO_UPDATE) pss_ss(fd, S_auto_update, b2s(auto_update(ss)));
428   if (color_inverted(ss) != DEFAULT_COLOR_INVERTED) pss_ss(fd, S_color_inverted, b2s(color_inverted(ss)));
429   if (zero_pad(ss) != DEFAULT_ZERO_PAD) pss_sd(fd, S_zero_pad, zero_pad(ss));
430   if (ask_before_overwrite(ss) != DEFAULT_ASK_BEFORE_OVERWRITE) pss_ss(fd, S_ask_before_overwrite, b2s(ask_before_overwrite(ss)));
431   if (with_toolbar(ss) != DEFAULT_WITH_TOOLBAR) pss_ss(fd, S_with_toolbar, b2s(with_toolbar(ss)));
432   if (with_tooltips(ss) != DEFAULT_WITH_TOOLTIPS) pss_ss(fd, S_with_tooltips, b2s(with_tooltips(ss)));
433   if (with_menu_icons(ss) != DEFAULT_WITH_MENU_ICONS) pss_ss(fd, S_with_menu_icons, b2s(with_menu_icons(ss)));
434   if (remember_sound_state(ss) != DEFAULT_REMEMBER_SOUND_STATE) pss_ss(fd, S_remember_sound_state, b2s(remember_sound_state(ss)));
435   if (ask_about_unsaved_edits(ss) != DEFAULT_ASK_ABOUT_UNSAVED_EDITS) pss_ss(fd, S_ask_about_unsaved_edits, b2s(ask_about_unsaved_edits(ss)));
436   if (save_as_dialog_src(ss) != DEFAULT_SAVE_AS_DIALOG_SRC) pss_ss(fd, S_save_as_dialog_src, b2s(save_as_dialog_src(ss)));
437   if (save_as_dialog_auto_comment(ss) != DEFAULT_SAVE_AS_DIALOG_AUTO_COMMENT) pss_ss(fd, S_save_as_dialog_auto_comment, b2s(save_as_dialog_auto_comment(ss)));
438   if (show_full_duration(ss) != DEFAULT_SHOW_FULL_DURATION) pss_ss(fd, S_show_full_duration, b2s(show_full_duration(ss)));
439   if (show_full_range(ss) != DEFAULT_SHOW_FULL_RANGE) pss_ss(fd, S_show_full_range, b2s(show_full_range(ss)));
440   if (fneq(initial_beg(ss), DEFAULT_INITIAL_BEG)) pss_sf(fd, S_initial_beg, initial_beg(ss));
441   if (fneq(initial_dur(ss), DEFAULT_INITIAL_DUR)) pss_sf(fd, S_initial_dur, initial_dur(ss));
442   if (dac_combines_channels(ss) != DEFAULT_DAC_COMBINES_CHANNELS) pss_ss(fd, S_dac_combines_channels, b2s(dac_combines_channels(ss)));
443   if (wavo_hop(ss) != DEFAULT_WAVO_HOP) pss_sd(fd, S_wavo_hop, wavo_hop(ss));
444   if (wavo_trace(ss) != DEFAULT_WAVO_TRACE) pss_sd(fd, S_wavo_trace, wavo_trace(ss));
445   if (spectro_hop(ss) != DEFAULT_SPECTRO_HOP) pss_sd(fd, S_spectro_hop, spectro_hop(ss));
446 #if (!USE_NO_GUI)
447   if ((color_map(ss) != DEFAULT_COLOR_MAP) && (color_map(ss) <= 15)) pss_ss(fd, S_colormap, TO_GVAR_NAME(colormap_variable_name(color_map(ss))));
448   if (color_map_size(ss) != DEFAULT_COLOR_MAP_SIZE) pss_sd(fd, S_colormap_size, color_map_size(ss));
449 #endif
450   if (wavelet_type(ss) != DEFAULT_WAVELET_TYPE) pss_sd(fd, S_wavelet_type, wavelet_type(ss));
451   if (cursor_style(ss) != DEFAULT_CURSOR_STYLE) pss_ss(fd, S_cursor_style, cursor_style_name(cursor_style(ss)));
452   if (tracking_cursor_style(ss) != DEFAULT_TRACKING_CURSOR_STYLE) pss_ss(fd, S_tracking_cursor_style, cursor_style_name(tracking_cursor_style(ss)));
453   if (cursor_size(ss) != DEFAULT_CURSOR_SIZE) pss_sd(fd, S_cursor_size, cursor_size(ss));
454   if (dot_size(ss) != DEFAULT_DOT_SIZE) pss_sd(fd, S_dot_size, dot_size(ss));
455   if (dac_size(ss) != DEFAULT_DAC_SIZE) pss_sd(fd, S_dac_size, dac_size(ss));
456   if (selection_creates_region(ss) != DEFAULT_SELECTION_CREATES_REGION) pss_ss(fd, S_selection_creates_region, b2s(selection_creates_region(ss)));
457   if (enved_filter_order(ss) != DEFAULT_ENVED_FILTER_ORDER) pss_sd(fd, S_enved_filter_order, enved_filter_order(ss));
458   if (max_transform_peaks(ss) != DEFAULT_MAX_TRANSFORM_PEAKS) pss_sd(fd, S_max_transform_peaks, max_transform_peaks(ss));
459   if (max_regions(ss) != DEFAULT_MAX_REGIONS) pss_sd(fd, S_max_regions, max_regions(ss));
460   if (fneq(auto_update_interval(ss), DEFAULT_AUTO_UPDATE_INTERVAL)) pss_sf(fd, S_auto_update_interval, auto_update_interval(ss));
461   if (fneq(cursor_update_interval(ss), DEFAULT_CURSOR_UPDATE_INTERVAL)) pss_sf(fd, S_cursor_update_interval, cursor_update_interval(ss));
462   if (cursor_location_offset(ss) != DEFAULT_CURSOR_LOCATION_OFFSET) pss_sd(fd, S_cursor_location_offset, cursor_location_offset(ss));
463   if (with_verbose_cursor(ss) != DEFAULT_WITH_VERBOSE_CURSOR) pss_ss(fd, S_with_verbose_cursor, b2s(with_verbose_cursor(ss)));
464   if (with_inset_graph(ss) != DEFAULT_WITH_INSET_GRAPH) pss_ss(fd, S_with_inset_graph, b2s(with_inset_graph(ss)));
465   if (with_interrupts(ss) != DEFAULT_WITH_INTERRUPTS) pss_ss(fd, S_with_interrupts, b2s(with_interrupts(ss)));
466   if (with_smpte_label(ss) != DEFAULT_WITH_SMPTE_LABEL) pss_ss(fd, S_with_smpte_label, b2s(with_smpte_label(ss)));
467   if (with_pointer_focus(ss) != DEFAULT_WITH_POINTER_FOCUS) pss_ss(fd, S_with_pointer_focus, b2s(with_pointer_focus(ss)));
468   if (show_indices(ss) != DEFAULT_SHOW_INDICES) pss_ss(fd, S_show_indices, b2s(show_indices(ss)));
469   if (show_transform_peaks(ss) != DEFAULT_SHOW_TRANSFORM_PEAKS) pss_ss(fd, S_show_transform_peaks, b2s(show_transform_peaks(ss)));
470   if (show_y_zero(ss) != DEFAULT_SHOW_Y_ZERO) pss_ss(fd, S_show_y_zero, b2s(show_y_zero(ss)));
471   if (show_grid(ss) != DEFAULT_SHOW_GRID) pss_ss(fd, S_show_grid, b2s((bool)show_grid(ss)));
472   if (fneq(grid_density(ss), DEFAULT_GRID_DENSITY)) pss_sf(fd, S_grid_density, grid_density(ss));
473   if (show_sonogram_cursor(ss) != DEFAULT_SHOW_SONOGRAM_CURSOR) pss_ss(fd, S_show_sonogram_cursor, b2s(show_sonogram_cursor(ss)));
474   if (show_axes(ss) != DEFAULT_SHOW_AXES) pss_ss(fd, S_show_axes, show_axes2string(show_axes(ss)));
475   if (show_marks(ss) != DEFAULT_SHOW_MARKS) pss_ss(fd, S_show_marks, b2s(show_marks(ss)));
476   if (clipping(ss) != DEFAULT_CLIPPING) pss_ss(fd, S_clipping, b2s(clipping(ss)));
477 #if USE_MOTIF
478   if (view_files_sort(ss) != DEFAULT_VIEW_FILES_SORT) pss_sd(fd, S_view_files_sort, view_files_sort(ss));
479 #endif
480   if (fft_log_magnitude(ss) != DEFAULT_FFT_LOG_MAGNITUDE) pss_ss(fd, S_fft_log_magnitude, b2s(fft_log_magnitude(ss)));
481   if (fft_log_frequency(ss) != DEFAULT_FFT_LOG_FREQUENCY) pss_ss(fd, S_fft_log_frequency, b2s(fft_log_frequency(ss)));
482   if (fft_with_phases(ss) != DEFAULT_FFT_WITH_PHASES) pss_ss(fd, S_fft_with_phases, b2s(fft_with_phases(ss)));
483   if (print_length(ss) != DEFAULT_PRINT_LENGTH) pss_sd(fd, S_print_length, print_length(ss));
484   if (show_mix_waveforms(ss) != DEFAULT_SHOW_MIX_WAVEFORMS) pss_ss(fd, S_show_mix_waveforms, b2s(show_mix_waveforms(ss)));
485   if (mix_waveform_height(ss) != DEFAULT_MIX_WAVEFORM_HEIGHT) pss_sd(fd, S_mix_waveform_height, mix_waveform_height(ss));
486   if (mix_tag_height(ss) != DEFAULT_MIX_TAG_HEIGHT) pss_sd(fd, S_mix_tag_height, mix_tag_height(ss));
487   if (mix_tag_width(ss) != DEFAULT_MIX_TAG_WIDTH) pss_sd(fd, S_mix_tag_width, mix_tag_width(ss));
488   if (mark_tag_height(ss) != DEFAULT_MARK_TAG_HEIGHT) pss_sd(fd, S_mark_tag_height, mark_tag_height(ss));
489   if (mark_tag_width(ss) != DEFAULT_MARK_TAG_WIDTH) pss_sd(fd, S_mark_tag_width, mark_tag_width(ss));
490   if (enved_with_wave(ss) != DEFAULT_ENVED_WITH_WAVE) pss_ss(fd, S_enved_with_wave, b2s(enved_with_wave(ss)));
491   if (enved_in_dB(ss) != DEFAULT_ENVED_IN_DB) pss_ss(fd, S_enved_in_dB, b2s(enved_in_dB(ss)));
492   if (enved_clipping(ss) != DEFAULT_ENVED_CLIPPING) pss_ss(fd, S_enved_clipping, b2s(enved_clipping(ss)));
493   if (enved_style(ss) == ENVELOPE_EXPONENTIAL) pss_ss(fd, S_enved_style, TO_VAR_NAME(S_envelope_exponential));
494 
495   if ((!tiny_font(ss)) || (!(mus_strcmp(tiny_font(ss), DEFAULT_TINY_FONT)))) pss_sq(fd, S_tiny_font, tiny_font(ss));
496   if ((!peaks_font(ss)) || (!(mus_strcmp(peaks_font(ss), DEFAULT_PEAKS_FONT)))) pss_sq(fd, S_peaks_font, peaks_font(ss));
497   if ((!bold_peaks_font(ss)) || (!(mus_strcmp(bold_peaks_font(ss), DEFAULT_BOLD_PEAKS_FONT)))) pss_sq(fd, S_bold_peaks_font, bold_peaks_font(ss));
498   if ((!axis_label_font(ss)) || (!(mus_strcmp(axis_label_font(ss), DEFAULT_AXIS_LABEL_FONT)))) pss_sq(fd, S_axis_label_font, axis_label_font(ss));
499   if ((!axis_numbers_font(ss)) || (!(mus_strcmp(axis_numbers_font(ss), DEFAULT_AXIS_NUMBERS_FONT)))) pss_sq(fd, S_axis_numbers_font, axis_numbers_font(ss));
500   if (listener_font(ss))
501     pss_sq(fd, S_listener_font, listener_font(ss));
502   if (listener_is_visible())
503     pss_ss(fd, S_show_listener, b2s(true));
504 
505 #if USE_MOTIF
506   if (in_graph_cursor(ss) != DEFAULT_GRAPH_CURSOR)
507     pss_sd(fd, S_graph_cursor, in_graph_cursor(ss));
508 #endif
509 
510   save_added_sound_file_extensions(fd);
511   save_added_source_file_extensions(fd);
512 
513   if (save_state_file(ss))
514     pss_sq(fd, S_save_state_file, save_state_file(ss));
515   if (peak_env_dir(ss)) pss_sq(fd, S_peak_env_dir, peak_env_dir(ss));
516   if (temp_dir(ss)) pss_sq(fd, S_temp_dir, temp_dir(ss));
517   if (save_dir(ss)) pss_sq(fd, S_save_dir, save_dir(ss));
518   if (open_file_dialog_directory(ss)) pss_sq(fd, S_open_file_dialog_directory, open_file_dialog_directory(ss));
519   if (ladspa_dir(ss)) pss_sq(fd, S_ladspa_dir, ladspa_dir(ss));
520   if ((eps_file(ss)) && (!(mus_strcmp(eps_file(ss), DEFAULT_EPS_FILE)))) pss_sq(fd, S_eps_file, eps_file(ss));
521   if ((listener_prompt(ss)) && (!(mus_strcmp(listener_prompt(ss), DEFAULT_LISTENER_PROMPT)))) pss_sq(fd, S_listener_prompt, listener_prompt(ss));
522   if ((html_program(ss)) && (!(mus_strcmp(html_program(ss), DEFAULT_HTML_PROGRAM)))) pss_sq(fd, S_html_program, html_program(ss));
523   if (html_dir(ss)) pss_sq(fd, S_html_dir, html_dir(ss));
524 
525   if (fneq(fft_window_alpha(ss), DEFAULT_FFT_WINDOW_ALPHA)) pss_sf(fd, S_fft_window_alpha, fft_window_alpha(ss));
526   if (fneq(fft_window_beta(ss), DEFAULT_FFT_WINDOW_BETA)) pss_sf(fd, S_fft_window_beta, fft_window_beta(ss));
527   if (fneq(min_dB(ss), DEFAULT_MIN_DB)) pss_sf(fd, S_min_dB, min_dB(ss));
528   if (fneq(log_freq_start(ss), DEFAULT_LOG_FREQ_START)) pss_sf(fd, S_log_freq_start, log_freq_start(ss));
529   if (fneq(color_cutoff(ss), DEFAULT_COLOR_CUTOFF)) pss_sf(fd, S_color_cutoff, color_cutoff(ss));
530   if (fneq(color_scale(ss), DEFAULT_COLOR_SCALE)) pss_sf(fd, S_color_scale, color_scale(ss));
531   if (fneq(spectro_x_scale(ss), DEFAULT_SPECTRO_X_SCALE)) pss_sf(fd, S_spectro_x_scale, spectro_x_scale(ss));
532   if (fneq(spectro_y_scale(ss), DEFAULT_SPECTRO_Y_SCALE)) pss_sf(fd, S_spectro_y_scale, spectro_y_scale(ss));
533   if (fneq(spectro_z_scale(ss), DEFAULT_SPECTRO_Z_SCALE)) pss_sf(fd, S_spectro_z_scale, spectro_z_scale(ss));
534   if (fneq(spectro_z_angle(ss), DEFAULT_SPECTRO_Z_ANGLE)) pss_sf(fd, S_spectro_z_angle, spectro_z_angle(ss));
535   if (fneq(spectro_x_angle(ss), DEFAULT_SPECTRO_X_ANGLE)) pss_sf(fd, S_spectro_x_angle, spectro_x_angle(ss));
536   if (fneq(spectro_y_angle(ss), DEFAULT_SPECTRO_Y_ANGLE)) pss_sf(fd, S_spectro_y_angle, spectro_y_angle(ss));
537   if (fneq(spectrum_end(ss), DEFAULT_SPECTRUM_END)) pss_sf(fd, S_spectrum_end, spectrum_end(ss));
538   if (fneq(spectrum_start(ss), DEFAULT_SPECTRUM_START)) pss_sf(fd, S_spectrum_start, spectrum_start(ss));
539   if (fneq(enved_base(ss), DEFAULT_ENVED_BASE)) pss_sf(fd, S_enved_base, enved_base(ss));
540   if (fneq(enved_power(ss), DEFAULT_ENVED_POWER)) pss_sf(fd, S_enved_power, enved_power(ss));
541   if (fneq(eps_bottom_margin(ss), DEFAULT_EPS_BOTTOM_MARGIN)) pss_sf(fd, S_eps_bottom_margin, eps_bottom_margin(ss));
542   if (fneq(eps_left_margin(ss), DEFAULT_EPS_LEFT_MARGIN)) pss_sf(fd, S_eps_left_margin, eps_left_margin(ss));
543   if (fneq(eps_size(ss), DEFAULT_EPS_SIZE)) pss_sf(fd, S_eps_size, eps_size(ss));
544 
545   if ((fneq(contrast_control_min(ss), DEFAULT_CONTRAST_CONTROL_MIN)) ||
546       (fneq(contrast_control_max(ss), DEFAULT_CONTRAST_CONTROL_MAX)))
547     pss_sl(fd, S_contrast_control_bounds, contrast_control_min(ss), contrast_control_max(ss));
548   if (fneq(contrast_control_amp(ss), DEFAULT_CONTRAST_CONTROL_AMP)) pss_sf(fd, S_contrast_control_amp, contrast_control_amp(ss));
549   if ((fneq(expand_control_min(ss), DEFAULT_EXPAND_CONTROL_MIN)) ||
550       (fneq(expand_control_max(ss), DEFAULT_EXPAND_CONTROL_MAX)))
551     pss_sl(fd, S_expand_control_bounds, expand_control_min(ss), expand_control_max(ss));
552   if (fneq(expand_control_ramp(ss), DEFAULT_EXPAND_CONTROL_RAMP)) pss_sf(fd, S_expand_control_ramp, expand_control_ramp(ss));
553   if (fneq(expand_control_hop(ss), DEFAULT_EXPAND_CONTROL_HOP)) pss_sf(fd, S_expand_control_hop, expand_control_hop(ss));
554   if (fneq(expand_control_jitter(ss), DEFAULT_EXPAND_CONTROL_JITTER)) pss_sf(fd, S_expand_control_jitter, expand_control_jitter(ss));
555   if (fneq(expand_control_length(ss), DEFAULT_EXPAND_CONTROL_LENGTH)) pss_sf(fd, S_expand_control_length, expand_control_length(ss));
556   if (speed_control_tones(ss) != DEFAULT_SPEED_CONTROL_TONES) pss_sd(fd, S_speed_control_tones, speed_control_tones(ss));
557   if (speed_control_style(ss) != DEFAULT_SPEED_CONTROL_STYLE) pss_ss(fd, S_speed_control_style, speed_control_style_name(speed_control_style(ss)));
558   if ((fneq(speed_control_min(ss), DEFAULT_SPEED_CONTROL_MIN)) ||
559       (fneq(speed_control_max(ss), DEFAULT_SPEED_CONTROL_MAX)))
560     pss_sl(fd, S_speed_control_bounds, speed_control_min(ss), speed_control_max(ss));
561   if ((fneq(reverb_control_scale_min(ss), DEFAULT_REVERB_CONTROL_SCALE_MIN)) ||
562       (fneq(reverb_control_scale_max(ss), DEFAULT_REVERB_CONTROL_SCALE_MAX)))
563     pss_sl(fd, S_reverb_control_scale_bounds, reverb_control_scale_min(ss), reverb_control_scale_max(ss));
564   if ((fneq(reverb_control_length_min(ss), DEFAULT_REVERB_CONTROL_LENGTH_MIN)) ||
565       (fneq(reverb_control_length_max(ss), DEFAULT_REVERB_CONTROL_LENGTH_MAX)))
566     pss_sl(fd, S_reverb_control_length_bounds, reverb_control_length_min(ss), reverb_control_length_max(ss));
567   if (fneq(reverb_control_feedback(ss), DEFAULT_REVERB_CONTROL_FEEDBACK)) pss_sf(fd, S_reverb_control_feedback, reverb_control_feedback(ss));
568   if (fneq(reverb_control_lowpass(ss), DEFAULT_REVERB_CONTROL_LOWPASS)) pss_sf(fd, S_reverb_control_lowpass, reverb_control_lowpass(ss));
569   if (fneq(reverb_control_decay(ss), DEFAULT_REVERB_CONTROL_DECAY)) pss_sf(fd, S_reverb_control_decay, reverb_control_decay(ss));
570   if ((fneq(amp_control_min(ss), DEFAULT_AMP_CONTROL_MIN)) ||
571       (fneq(amp_control_max(ss), DEFAULT_AMP_CONTROL_MAX)))
572     pss_sl(fd, S_amp_control_bounds, amp_control_min(ss), amp_control_max(ss));
573   if (filter_control_order(ss) != DEFAULT_FILTER_CONTROL_ORDER) pss_sd(fd, S_filter_control_order, filter_control_order(ss));
574   if (filter_control_in_dB(ss) != DEFAULT_FILTER_CONTROL_IN_DB) pss_ss(fd, S_filter_control_in_dB, b2s(filter_control_in_dB(ss)));
575   if (filter_control_in_hz(ss) != DEFAULT_FILTER_CONTROL_IN_HZ) pss_ss(fd, S_filter_control_in_hz, b2s(filter_control_in_hz(ss)));
576   if (with_tracking_cursor(ss) != DEFAULT_WITH_TRACKING_CURSOR) pss_sd(fd, S_with_tracking_cursor, (int)with_tracking_cursor(ss));
577   if (in_show_controls(ss) != DEFAULT_SHOW_CONTROLS) pss_ss(fd, S_show_controls, b2s(in_show_controls(ss)));
578 
579   save_colors(fd);
580 
581   if (fneq(mus_srate(), MUS_DEFAULT_SAMPLING_RATE)) pss_sf(fd, S_mus_srate, mus_srate());
582   if (mus_file_buffer_size() != MUS_DEFAULT_FILE_BUFFER_SIZE) pss_sd(fd, S_mus_file_buffer_size, mus_file_buffer_size());
583   if (mus_array_print_length() != MUS_DEFAULT_ARRAY_PRINT_LENGTH) pss_sd(fd, S_mus_array_print_length, mus_array_print_length());
584   if (clm_default_table_size_c() != MUS_CLM_DEFAULT_TABLE_SIZE) pss_sod(fd, S_clm_table_size, clm_default_table_size_c());
585 
586   {
587     int srate = 0, chans = 0;
588     mus_sample_t samp_type = MUS_UNKNOWN_SAMPLE;
589     mus_header_raw_defaults(&srate, &chans, &samp_type);
590     if ((chans != 2) ||
591 	(srate != 44100) ||
592 	(samp_type != MUS_BSHORT))
593       {
594 #if HAVE_SCHEME
595 	fprintf(fd, "(set! (mus-header-raw-defaults) (list %d %d %s))\n",
596 		srate,
597 		chans,
598 		mus_sample_type_to_string(samp_type));
599 #endif
600 #if HAVE_RUBY
601 	fprintf(fd, "set_mus_header_raw_defaults([%d, %d, %s])\n",
602 		srate,
603 		chans,
604 		mus_sample_type_to_string(samp_type));
605 #endif
606 #if HAVE_FORTH
607 	fprintf(fd, "'( %d %d %s ) set-mus-header-raw-defaults drop\n",
608 		srate,
609 		chans,
610 		mus_sample_type_to_string(samp_type));
611 #endif
612       }
613   }
614 
615   fprintf(fd, "%s end of snd options\n", Xen_comment_mark);
616 }
617 
618 
619 /* next two are for the help menu */
620 
global_control_panel_state(void)621 void global_control_panel_state(void)
622 {
623   char *buf;
624   snd_help_append("\n\nCurrent control panel defaults:\n\n");
625   buf = (char *)calloc(1024, sizeof(char));
626   snprintf(buf, 1024, "amp bounds: %.3f to %.3f\n",
627 	       amp_control_min(ss), amp_control_max(ss));
628   snd_help_append(buf);
629   snprintf(buf, 1024, "speed bounds: %.3f to %.3f, tones: %d, style: %s\n",
630 	       speed_control_min(ss), speed_control_max(ss),
631 	       speed_control_tones(ss),
632 	       speed_control_style_name(speed_control_style(ss)));
633   snd_help_append(buf);
634   snprintf(buf, 1024, "expand bounds: %.3f to %.3f, ramp: %.3f, hop: %.3f, length: %.3f, jitter: %.3f\n",
635 	       expand_control_min(ss), expand_control_max(ss),
636 	       expand_control_ramp(ss), expand_control_hop(ss), expand_control_length(ss), expand_control_jitter(ss));
637   snd_help_append(buf);
638   snprintf(buf, 1024, "contrast bounds: %.3f to %.3f, amp: %.3f\n",
639 	       contrast_control_min(ss), contrast_control_max(ss),
640 	       contrast_control_amp(ss));
641   snd_help_append(buf);
642   snprintf(buf, 1024, "reverb scale: %.3f to %.3f, length: %.3f to %.3f, feedbacl: %.3f, lowpass: %.3f, decay: %.3f\n",
643 	       reverb_control_scale_min(ss), reverb_control_scale_max(ss),
644 	       reverb_control_length_min(ss), reverb_control_length_max(ss),
645 	       reverb_control_feedback(ss), reverb_control_lowpass(ss), reverb_control_decay(ss));
646   snd_help_append(buf);
647   snprintf(buf, 1024, "filter order: %d, in dB: %s, in Hz: %s\n",
648 	       filter_control_order(ss),
649 	       b2s(filter_control_in_dB(ss)),
650 	       b2s(filter_control_in_hz(ss)));
651   snd_help_append(buf);
652   snd_help_back_to_top();
653   free(buf);
654 }
655 
656 
global_fft_state(void)657 void global_fft_state(void)
658 {
659   char *buf;
660   snd_help_append("\n\nCurrent FFT defaults:\n\n");
661   buf = (char *)calloc(1024, sizeof(char));
662   snprintf(buf, 1024, "fft size: %" print_mus_long "\n    type: %s\n    window: %s (alpha: %.3f, beta: %.3f)\n",
663 	       transform_size(ss),
664 	       TO_VAR_NAME(transform_program_name(transform_type(ss))),
665 	       TO_VAR_NAME(mus_fft_window_xen_name(fft_window(ss))),
666 	       fft_window_alpha(ss),
667 	       fft_window_beta(ss));
668   snd_help_append(buf);
669   snprintf(buf, 1024, "    graph-type: %s\n    show-peaks: %s (max: %d)\n    show-selection-fft: %s\n",
670 	       transform_graph_type_name(transform_graph_type(ss)),
671 	       b2s(show_transform_peaks(ss)),
672 	       max_transform_peaks(ss),
673 	       b2s(show_selection_transform(ss)));
674   snd_help_append(buf);
675   snprintf(buf, 1024, "    log freq: %s (start: %.3f)\n    dB: %s, min-dB: %.3f\n    normalization: %s\n",
676 	       b2s(fft_log_frequency(ss)),
677 	       log_freq_start(ss),
678 	       b2s(fft_log_magnitude(ss)),
679 	       min_dB(ss),
680 	       transform_normalization_name(transform_normalization(ss)));
681   snd_help_append(buf);
682   snd_help_back_to_top();
683   free(buf);
684 }
685 
686 
687 #if HAVE_SCHEME
688 
689 static void set_print_lengths(int len);
690 
save_property_list(FILE * fd,Xen property_list,int chan,int edpos)691 static void save_property_list(FILE *fd, Xen property_list, int chan, int edpos)
692 {
693   Xen ignore_list;
694   int old_print_length, old_vct_print_length;
695   s7_int old_s7_print_length;
696 
697   old_s7_print_length = s7_integer(s7_let_field_ref(s7, s7_make_symbol(s7, "print-length")));
698   old_vct_print_length = mus_vct_print_length();
699   old_print_length = print_length(ss);
700 
701   /* make sure we don't truncate vector output with "..." */
702   set_print_lengths(1000000); /* this sets all three lengths */
703 
704   ignore_list = Xen_assoc(C_string_to_Xen_symbol("save-state-ignore"), property_list);
705 
706   if (!(Xen_is_list(ignore_list)))
707     {
708       char *temp = NULL;
709       if (chan == -1)
710 	fprintf(fd, "%s(set! (%s sfile) \'%s)\n", white_space, S_sound_properties, temp = Xen_object_to_C_string(property_list));
711       else
712 	{
713 	  if (edpos == -1)
714 	    fprintf(fd, "%s(set! (%s sfile %d) \'%s)\n", white_space, S_channel_properties, chan, temp = Xen_object_to_C_string(property_list));
715 	  else fprintf(fd, "%s(set! (%s sfile %d %d) \'%s)\n", white_space, S_edit_properties, chan, edpos, temp = Xen_object_to_C_string(property_list));
716 	}
717       if (temp) free(temp);
718     }
719   else
720     {
721       Xen new_properties = Xen_empty_list;
722       int i, property_len, gc_loc;
723       gc_loc = snd_protect(new_properties);
724       property_len = Xen_list_length(property_list);
725       for (i = 0; i < property_len; i++)
726 	{
727 	  Xen property;
728 	  property = Xen_list_ref(property_list, i);
729 	  if (Xen_is_false(Xen_member(Xen_car(property), ignore_list)))
730 	    new_properties = Xen_cons(property, new_properties);
731 	}
732       if (!(Xen_is_null(new_properties)))
733 	{
734 	  char *temp = NULL;
735 	  if (chan == -1)
736 	    fprintf(fd, "%s(set! (%s sfile) \'%s)\n", white_space, S_sound_properties, temp = Xen_object_to_C_string(new_properties));
737 	  else
738 	    {
739 	      if (edpos == -1)
740 		fprintf(fd, "%s(set! (%s sfile %d) \'%s)\n", white_space, S_channel_properties, chan, temp = Xen_object_to_C_string(new_properties));
741 	      else fprintf(fd, "%s(set! (%s sfile %d %d) \'%s)\n", white_space, S_edit_properties, chan, edpos, temp = Xen_object_to_C_string(new_properties));
742 	    }
743 	  if (temp) free(temp);
744 	}
745       snd_unprotect_at(gc_loc);
746     }
747 
748   /* restore the various print lengths */
749   set_print_length(old_print_length);
750   mus_vct_set_print_length(old_vct_print_length);
751   s7_let_field_set(s7, s7_make_symbol(s7, "print-length"), s7_make_integer(s7, old_s7_print_length));
752 }
753 #endif
754 
755 
756 #if HAVE_RUBY
save_property_list(FILE * fd,Xen property_list,int chan,int edpos)757 static void save_property_list(FILE *fd, Xen property_list, int chan, int edpos)
758 {
759   Xen ignore_list;
760   ignore_list = rb_ary_assoc(property_list, C_string_to_Xen_symbol("save_state_ignore"));
761   if (!(Xen_is_vector(ignore_list)))
762     {
763       if (chan == -1)
764 	fprintf(fd, "%sset_%s(%s, sfile)\n", white_space, to_proc_name(S_sound_properties), Xen_object_to_C_string(property_list));
765       else
766 	{
767 	  if (edpos == -1)
768 	    fprintf(fd, "%sset_%s(%s, sfile, %d)\n", white_space, to_proc_name(S_channel_properties), Xen_object_to_C_string(property_list), chan);
769 	  else fprintf(fd, "%sset_%s(%s, sfile, %d, %d)\n", white_space, to_proc_name(S_edit_properties), Xen_object_to_C_string(property_list), chan, edpos);
770 	}
771     }
772   else
773     {
774       Xen ignore_vec, new_properties = Xen_empty_list;
775       int i, property_len, gc_loc;
776       gc_loc = snd_protect(new_properties);
777       property_len = Xen_list_length(property_list);
778       ignore_vec = Xen_vector_ref(ignore_list, 1);
779       if (Xen_is_vector(ignore_vec))
780 	{
781 	  for (i = 0; i < property_len; i++)
782 	    {
783 	      Xen property;
784 	      property = Xen_list_ref(property_list, i);
785 	      if (Xen_is_false(rb_ary_includes(ignore_vec, Xen_car(property))))
786 		new_properties = Xen_cons(property, new_properties);
787 	    }
788 	}
789       else
790 	{
791 	  for (i = 0; i < property_len; i++)
792 	  new_properties = Xen_cons(Xen_list_ref(property_list, i), new_properties);
793 	}
794       if (!(Xen_is_null(new_properties)))
795 	{
796 	  if (chan == -1)
797 	    fprintf(fd, "%sset_%s(%s, sfile)\n", white_space, to_proc_name(S_sound_properties), Xen_object_to_C_string(new_properties));
798 	  else
799 	    {
800 	      if (edpos == -1)
801 		fprintf(fd, "%sset_%s(%s, sfile, %d)\n", white_space, to_proc_name(S_channel_properties), Xen_object_to_C_string(new_properties), chan);
802 	      else fprintf(fd, "%sset_%s(%s, sfile, %d, %d)\n", white_space, to_proc_name(S_edit_properties), Xen_object_to_C_string(new_properties), chan, edpos);
803 	    }
804 	}
805       snd_unprotect_at(gc_loc);
806     }
807 }
808 #endif
809 
810 
811 #if HAVE_FORTH
save_property_list(FILE * fd,Xen property_list,int chan,int edpos)812 static void save_property_list(FILE *fd, Xen property_list, int chan, int edpos)
813 {
814   Xen ignore_list;
815   ignore_list = Xen_assoc(C_string_to_Xen_symbol("save-state-ignore"), property_list);
816   if (!(Xen_is_list(ignore_list)))
817     {
818       if (chan == -1)
819 	fprintf(fd, "%s%s sfile set-%s drop\n", white_space, fth_to_c_dump(property_list), S_sound_properties);
820       else
821 	{
822 	  if (edpos == -1)
823 	    fprintf(fd, "%s%s sfile %d set-%s drop\n", white_space, fth_to_c_dump(property_list), chan, S_channel_properties);
824 	  else fprintf(fd, "%s%s sfile %d %d set-%s drop\n", white_space, fth_to_c_dump(property_list), chan, edpos, S_edit_properties);
825 	}
826     }
827   else
828     {
829       Xen new_properties = Xen_empty_list;
830       int i, property_len, gc_loc;
831       gc_loc = snd_protect(new_properties);
832       property_len = Xen_list_length(property_list);
833       for (i = 0; i < property_len; i++)
834 	{
835 	  Xen property;
836 	  property = Xen_list_ref(property_list, i);
837 	  if (Xen_is_false(Xen_member(Xen_car(property), ignore_list)))
838 	    new_properties = Xen_cons(property, new_properties);
839 	}
840       if (!(Xen_is_null(new_properties)))
841 	{
842 	  if (chan == -1)
843 	    fprintf(fd, "%s%s sfile set-%s drop\n", white_space, fth_to_c_dump(new_properties), S_sound_properties);
844 	  else
845 	    {
846 	      if (edpos == -1)
847 		fprintf(fd, "%s%s sfile %d set-%s drop\n", white_space, fth_to_c_dump(new_properties), chan, S_channel_properties);
848 	      else fprintf(fd, "%s%s sfile %d %d set-%s drop\n", white_space, fth_to_c_dump(new_properties), chan, edpos, S_edit_properties);
849 	    }
850 	}
851       snd_unprotect_at(gc_loc);
852     }
853 }
854 #endif
855 
856 
857 #if (!HAVE_EXTENSION_LANGUAGE)
save_property_list(FILE * fd,Xen property_list,int chan,int edpos)858 static void save_property_list(FILE *fd, Xen property_list, int chan, int edpos) {}
859 #endif
860 
861 
check_selection(FILE * fd,chan_info * cp)862 static void check_selection(FILE *fd, chan_info *cp)
863 {
864   if (selection_is_active_in_channel(cp))
865     {
866       mus_long_t beg, end;
867       beg = selection_beg(cp);
868       end = selection_end(cp);
869       pcp_ss(fd, S_selection_member, b2s(true), cp->chan);
870       pcp_sod(fd, S_selection_position, beg, cp->chan);
871       pcp_sod(fd, S_selection_framples, end - beg + 1, cp->chan);
872     }
873 }
874 
875 
find_sound_nth(snd_info * nsp)876 static int find_sound_nth(snd_info *nsp)
877 {
878   int i, which = 0;
879   for (i = 0; i < nsp->index; i++)
880     {
881       snd_info *sp;
882       sp = ss->sounds[i];
883       if ((sp) && (sp->inuse == SOUND_NORMAL))
884 	if ((mus_strcmp(nsp->short_filename, sp->short_filename)) ||
885 	    (mus_strcmp(nsp->filename, sp->filename)))
886 	  which++;
887     }
888   return(which);
889 }
890 
891 
open_save_sound_block(snd_info * sp,FILE * fd,bool with_nth)892 void open_save_sound_block(snd_info *sp, FILE *fd, bool with_nth)
893 {
894   /* here we have to use the 'nth' arg to find_sound -- it should return #f if such an 'nth' case is not found,
895    *   so that we can tell when to open another view on a given file
896    */
897 #if HAVE_RUBY
898   fprintf(fd, "begin\n  sfile = %s(\"%s\", %d)\n  if (sfile == false)\n    sfile = %s(\"%s\")\n  end\n",
899 	  to_proc_name(S_find_sound),
900 	  sp->short_filename,
901 	  (with_nth) ? find_sound_nth(sp) : 0,
902 	  to_proc_name((sp->user_read_only == FILE_READ_ONLY) ? S_view_sound : S_open_sound),
903 	  sp->filename);
904 
905 #endif
906 #if HAVE_SCHEME
907   fprintf(fd, "(let* ((sfile (or (%s \"%s\" %d) (%s \"%s\")))\n"
908               "       (-env- (curlet)))\n"
909               "  (if sfile\n"
910               "    (begin\n"
911               "      (define (-mix-selection- beg pos len snd chn sel-chn start-chn)\n"
912               "        (do ((ch start-chn (+ ch 1)))\n"
913               "            ((> ch sel-chn))\n"
914               "          (set! (selection-member? snd ch) #t)\n"
915               "          (set! (selection-position snd ch) pos)\n"
916               "          (set! (selection-framples snd ch) len))\n"
917               "        (mix-selection beg snd chn sel-chn))\n",
918 	  S_find_sound,
919 	  sp->short_filename, /* short filename ok because find-sound searches for that name as well as the full filename */
920 	  (with_nth) ? find_sound_nth(sp) : 0,
921 	  (sp->user_read_only == FILE_READ_ONLY) ? S_view_sound : S_open_sound,
922 	  sp->filename);
923 #endif
924 #if HAVE_FORTH
925   fprintf(fd, "\"%s\" %d %s to sfile\nsfile false? [if] \"%s\" %s to sfile [then]\n",
926 	  sp->short_filename,
927 	  (with_nth) ? find_sound_nth(sp) : 0,
928 	  S_find_sound,
929 	  sp->filename,
930 	  (sp->user_read_only == FILE_READ_ONLY) ? S_view_sound : S_open_sound);
931 #endif
932 }
933 
934 
close_save_sound_block(FILE * fd,bool need_f)935 void close_save_sound_block(FILE *fd, bool need_f)
936 {
937 #if HAVE_RUBY
938   fprintf(fd, "end\n");
939 #endif
940 #if HAVE_SCHEME
941   if (need_f)
942     fprintf(fd, "      #f)))\n"); /* avoid empty begin if no field was output */
943   else fprintf(fd, "      )))\n");
944 #endif
945 #if HAVE_FORTH
946   fprintf(fd, "\n");
947 #endif
948 }
949 
950 
is_default_envelope(env * e)951 static bool is_default_envelope(env *e)
952 {
953   return((e) &&
954 	 (e->pts == 2) &&
955 	 (e->base == 1.0) &&
956 	 (e->data[0] == 0.0) &&
957 	 (e->data[1] == 1.0) &&
958 	 (e->data[2] == 1.0) &&
959 	 (e->data[3] == 1.0));
960 }
961 
962 
save_sound_state(snd_info * sp,void * ptr)963 void save_sound_state(snd_info *sp, void *ptr)
964 {
965   /* called only after the global settings have been established, so here we can't use the DEFAULT_* macros that are ambiguous */
966   int chan;
967   FILE *fd;
968   chan_info *cp;
969   fd = (FILE *)ptr;
970   open_save_sound_block(sp, fd, true);
971   b_ok = false;
972   if (sp->sync != DEFAULT_SYNC) psp_sd(fd, S_sync, sp->sync);
973   if (sp->contrast_control_on != DEFAULT_CONTRAST_CONTROL_ON) psp_ss(fd, S_contrast_control_on, b2s(sp->contrast_control_on));
974   if (fneq(sp->contrast_control, DEFAULT_CONTRAST_CONTROL)) psp_sf(fd, S_contrast_control, sp->contrast_control);
975   if ((fneq(sp->contrast_control_min, DEFAULT_CONTRAST_CONTROL_MIN)) ||
976       (fneq(sp->contrast_control_max, DEFAULT_CONTRAST_CONTROL_MAX)))
977     psp_sl(fd, S_contrast_control_bounds, sp->contrast_control_min, sp->contrast_control_max);
978   if (fneq(sp->contrast_control_amp, DEFAULT_CONTRAST_CONTROL_AMP)) psp_sf(fd, S_contrast_control_amp, sp->contrast_control_amp);
979   if (sp->expand_control_on != DEFAULT_EXPAND_CONTROL_ON) psp_ss(fd, S_expand_control_on, b2s(sp->expand_control_on));
980   if (fneq(sp->expand_control, DEFAULT_EXPAND_CONTROL)) psp_sf(fd, S_expand_control, sp->expand_control);
981   if ((fneq(sp->expand_control_min, DEFAULT_EXPAND_CONTROL_MIN)) ||
982       (fneq(sp->expand_control_max, DEFAULT_EXPAND_CONTROL_MAX)))
983     psp_sl(fd, S_expand_control_bounds, sp->expand_control_min, sp->expand_control_max);
984   if (fneq(sp->expand_control_ramp, DEFAULT_EXPAND_CONTROL_RAMP)) psp_sf(fd, S_expand_control_ramp, sp->expand_control_ramp);
985   if (fneq(sp->expand_control_hop, DEFAULT_EXPAND_CONTROL_HOP)) psp_sf(fd, S_expand_control_hop, sp->expand_control_hop);
986   if (fneq(sp->expand_control_jitter, DEFAULT_EXPAND_CONTROL_JITTER)) psp_sf(fd, S_expand_control_jitter, sp->expand_control_jitter);
987   if (fneq(sp->expand_control_length, DEFAULT_EXPAND_CONTROL_LENGTH)) psp_sf(fd, S_expand_control_length, sp->expand_control_length);
988   if (sp->speed_control_tones != DEFAULT_SPEED_CONTROL_TONES) psp_sd(fd, S_speed_control_tones, sp->speed_control_tones);
989   if (sp->speed_control_style != DEFAULT_SPEED_CONTROL_STYLE) psp_ss(fd, S_speed_control_style, speed_control_style_name(sp->speed_control_style));
990   if (fneq(sp->speed_control, DEFAULT_SPEED_CONTROL))
991     {
992 #if XEN_HAVE_RATIOS
993       if (sp->speed_control_style == SPEED_CONTROL_AS_RATIO)
994 	{
995 	  /* no ratios in Ruby */
996 #if HAVE_FORTH
997 	  fprintf(fd, "%s%d/%d set-%s drop\n", white_space,
998                   sp->speed_control_numerator * sp->speed_control_direction,
999                   sp->speed_control_denominator, S_speed_control);
1000 #else
1001 	  fprintf(fd, "%s(set! (%s sfile) %d/%d)\n", white_space, S_speed_control,
1002                   sp->speed_control_numerator * sp->speed_control_direction,
1003                   sp->speed_control_denominator);
1004 #endif
1005 	}
1006       else
1007 #endif
1008       psp_sf(fd, S_speed_control, sp->speed_control * sp->speed_control_direction);
1009     }
1010   if ((fneq(sp->speed_control_min, DEFAULT_SPEED_CONTROL_MIN)) ||
1011       (fneq(sp->speed_control_max, DEFAULT_SPEED_CONTROL_MAX)))
1012     psp_sl(fd, S_speed_control_bounds, sp->speed_control_min, sp->speed_control_max);
1013   if (sp->reverb_control_on != DEFAULT_REVERB_CONTROL_ON) psp_ss(fd, S_reverb_control_on, b2s(sp->reverb_control_on));
1014   if (fneq(sp->reverb_control_scale, DEFAULT_REVERB_CONTROL_SCALE)) psp_sf(fd, S_reverb_control_scale, sp->reverb_control_scale);
1015   if ((fneq(sp->reverb_control_scale_min, DEFAULT_REVERB_CONTROL_SCALE_MIN)) ||
1016       (fneq(sp->reverb_control_scale_max, DEFAULT_REVERB_CONTROL_SCALE_MAX)))
1017     psp_sl(fd, S_reverb_control_scale_bounds, sp->reverb_control_scale_min, sp->reverb_control_scale_max);
1018   if (fneq(sp->reverb_control_length, DEFAULT_REVERB_CONTROL_LENGTH)) psp_sf(fd, S_reverb_control_length, sp->reverb_control_length);
1019   if ((fneq(sp->reverb_control_length_min, DEFAULT_REVERB_CONTROL_LENGTH_MIN)) ||
1020       (fneq(sp->reverb_control_length_max, DEFAULT_REVERB_CONTROL_LENGTH_MAX)))
1021     psp_sl(fd, S_reverb_control_length_bounds, sp->reverb_control_length_min, sp->reverb_control_length_max);
1022   if (fneq(sp->reverb_control_feedback, DEFAULT_REVERB_CONTROL_FEEDBACK)) psp_sf(fd, S_reverb_control_feedback, sp->reverb_control_feedback);
1023   if (fneq(sp->reverb_control_lowpass, DEFAULT_REVERB_CONTROL_LOWPASS)) psp_sf(fd, S_reverb_control_lowpass, sp->reverb_control_lowpass);
1024   if (fneq(sp->reverb_control_decay, DEFAULT_REVERB_CONTROL_DECAY)) psp_sf(fd, S_reverb_control_decay, sp->reverb_control_decay);
1025   if (fneq(sp->amp_control, DEFAULT_AMP_CONTROL)) psp_sf(fd, S_amp_control, sp->amp_control);
1026   if ((fneq(sp->amp_control_min, DEFAULT_AMP_CONTROL_MIN)) ||
1027       (fneq(sp->amp_control_max, DEFAULT_AMP_CONTROL_MAX)))
1028     psp_sl(fd, S_amp_control_bounds, sp->amp_control_min, sp->amp_control_max);
1029   if (sp->filter_control_on != DEFAULT_FILTER_CONTROL_ON) psp_ss(fd, S_filter_control_on, b2s(sp->filter_control_on));
1030   if (sp->filter_control_order != DEFAULT_FILTER_CONTROL_ORDER) psp_sd(fd, S_filter_control_order, sp->filter_control_order);
1031   if (sp->filter_control_in_dB != DEFAULT_FILTER_CONTROL_IN_DB) psp_ss(fd, S_filter_control_in_dB, b2s(sp->filter_control_in_dB));
1032   if (sp->filter_control_in_hz != DEFAULT_FILTER_CONTROL_IN_HZ) psp_ss(fd, S_filter_control_in_hz, b2s(sp->filter_control_in_hz));
1033   if ((sp->filter_control_envelope) && (!(is_default_envelope(sp->filter_control_envelope))))
1034     {
1035       char *tmpstr = NULL;
1036       psp_ss(fd, S_filter_control_envelope, tmpstr = env_to_string(sp->filter_control_envelope));
1037       if (tmpstr) free(tmpstr);
1038     }
1039 
1040   if ((Xen_is_vector(sp->properties)) &&
1041       (Xen_is_list(Xen_vector_ref(sp->properties, 0))) &&
1042       (!(Xen_is_null(Xen_vector_ref(sp->properties, 0)))))
1043     {
1044       save_property_list(fd, Xen_vector_ref(sp->properties, 0), -1, -1); /* sound-properties */
1045     }
1046   for (chan = 0; chan < (int)sp->nchans; chan++)
1047     {
1048       axis_info *ap;
1049 
1050       cp = sp->chans[chan];
1051       if ((!cp) || (!cp->edits) || (!cp->sounds)) break;
1052       ap = cp->axis;
1053       if (!(cp->graph_time_on)) pcp_ss(fd, S_time_graph_on, b2s(cp->graph_time_on), chan);
1054       if (cp->graph_transform_on) pcp_ss(fd, S_transform_graph_on, b2s(cp->graph_transform_on), chan);
1055       if (cp->graph_lisp_on) pcp_ss(fd, S_lisp_graph_on, b2s(cp->graph_lisp_on), chan);
1056       if (ap)
1057 	{
1058 	  if (((ap->x0 != 0.0) || (ap->x1 != 0.1)) && (ap->x1 > .0005)) pcp_sl(fd, S_x_bounds, ap->x0, ap->x1, chan);
1059 	  if ((ap->y0 != -1.0) || (ap->y1 != 1.0)) pcp_sl(fd, S_y_bounds, ap->y0, ap->y1, chan);
1060 	}
1061       if (cp->cursor_size != DEFAULT_CURSOR_SIZE) pcp_sd(fd, S_cursor_size, cp->cursor_size, chan);
1062       if (cp->cursor_style != DEFAULT_CURSOR_STYLE) pcp_ss(fd, S_cursor_style, cursor_style_name(cp->cursor_style), chan);
1063       if (cp->tracking_cursor_style != DEFAULT_TRACKING_CURSOR_STYLE) pcp_ss(fd, S_tracking_cursor_style, cursor_style_name(cp->tracking_cursor_style), chan);
1064       if (cp->show_marks != show_marks(ss)) pcp_ss(fd, S_show_marks, b2s(cp->show_marks), chan);
1065       if (cp->show_y_zero != show_y_zero(ss)) pcp_ss(fd, S_show_y_zero, b2s(cp->show_y_zero), chan);
1066       if (cp->show_grid != show_grid(ss)) pcp_ss(fd, S_show_grid, b2s((bool)(cp->show_grid)), chan);
1067       if (cp->show_sonogram_cursor != show_sonogram_cursor(ss)) pcp_ss(fd, S_show_sonogram_cursor, b2s(cp->show_sonogram_cursor), chan);
1068       if (cp->wavo_hop != wavo_hop(ss)) pcp_sd(fd, S_wavo_hop, cp->wavo_hop, chan);
1069       if (cp->wavo_trace != wavo_trace(ss)) pcp_sd(fd, S_wavo_trace, cp->wavo_trace, chan);
1070       if (cp->max_transform_peaks != max_transform_peaks(ss)) pcp_sd(fd, S_max_transform_peaks, cp->max_transform_peaks, chan);
1071       if (cp->show_transform_peaks != show_transform_peaks(ss)) pcp_ss(fd, S_show_transform_peaks, b2s(cp->show_transform_peaks), chan);
1072       if (cp->fft_log_frequency != fft_log_frequency(ss)) pcp_ss(fd, S_fft_log_frequency, b2s(cp->fft_log_frequency), chan);
1073       if (cp->fft_log_magnitude != fft_log_magnitude(ss)) pcp_ss(fd, S_fft_log_magnitude, b2s(cp->fft_log_magnitude), chan);
1074       if (cp->fft_with_phases != fft_with_phases(ss)) pcp_ss(fd, S_fft_with_phases, b2s(cp->fft_with_phases), chan);
1075       if (cp->with_verbose_cursor != with_verbose_cursor(ss)) pcp_ss(fd, S_with_verbose_cursor, b2s(cp->with_verbose_cursor), chan);
1076       if (cp->zero_pad != zero_pad(ss)) pcp_sd(fd, S_zero_pad, cp->zero_pad, chan);
1077       if (cp->wavelet_type != wavelet_type(ss)) pcp_sd(fd, S_wavelet_type, cp->wavelet_type, chan);
1078       if (fneq(cp->min_dB, min_dB(ss))) pcp_sf(fd, S_min_dB, cp->min_dB, chan);
1079       if (fneq(cp->spectro_x_angle, spectro_x_angle(ss))) pcp_sf(fd, S_spectro_x_angle, cp->spectro_x_angle, chan);
1080       if (fneq(cp->spectro_y_angle, spectro_y_angle(ss))) pcp_sf(fd, S_spectro_y_angle, cp->spectro_y_angle, chan);
1081       if (fneq(cp->spectro_z_angle, spectro_z_angle(ss))) pcp_sf(fd, S_spectro_z_angle, cp->spectro_z_angle, chan);
1082       if (fneq(cp->spectro_x_scale, spectro_x_scale(ss))) pcp_sf(fd, S_spectro_x_scale, cp->spectro_x_scale, chan);
1083       if (fneq(cp->spectro_y_scale, spectro_y_scale(ss))) pcp_sf(fd, S_spectro_y_scale, cp->spectro_y_scale, chan);
1084       if (fneq(cp->spectro_z_scale, spectro_z_scale(ss))) pcp_sf(fd, S_spectro_z_scale, cp->spectro_z_scale, chan);
1085       if (fneq(cp->spectrum_end, spectrum_end(ss))) pcp_sf(fd, S_spectrum_end, cp->spectrum_end, chan);
1086       if (fneq(cp->spectrum_start, spectrum_start(ss))) pcp_sf(fd, S_spectrum_start, cp->spectrum_start, chan);
1087       if (fneq(cp->fft_window_alpha, fft_window_alpha(ss))) pcp_sf(fd, S_fft_window_alpha, cp->fft_window_alpha, chan);
1088       if (fneq(cp->fft_window_beta, fft_window_beta(ss))) pcp_sf(fd, S_fft_window_beta, cp->fft_window_beta, chan);
1089       if (cp->spectro_hop != spectro_hop(ss)) pcp_sd(fd, S_spectro_hop, cp->spectro_hop, chan);
1090       if (cp->transform_size != transform_size(ss)) pcp_sod(fd, S_transform_size, cp->transform_size, chan);
1091       if (cp->transform_graph_type != transform_graph_type(ss))
1092 	pcp_ss(fd, S_transform_graph_type, transform_graph_type_name(cp->transform_graph_type), chan);
1093       if (cp->time_graph_type != time_graph_type(ss)) pcp_ss(fd, S_time_graph_type, time_graph_type_name(cp->time_graph_type), chan);
1094       if (cp->fft_window != fft_window(ss)) pcp_ss(fd, S_fft_window, TO_VAR_NAME(mus_fft_window_xen_name(cp->fft_window)), chan);
1095       if (cp->transform_type != transform_type(ss)) pcp_ss(fd, S_transform_type, TO_VAR_NAME(transform_program_name(cp->transform_type)), chan);
1096       /* this is assuming the added transform definition (if any) can be found -- maybe not a good idea */
1097       if (cp->transform_normalization != transform_normalization(ss))
1098 	pcp_ss(fd, S_transform_normalization, transform_normalization_name(cp->transform_normalization), chan);
1099       if (cp->time_graph_style != graph_style(ss)) pcp_ss(fd, S_time_graph_style, graph_style_name(cp->time_graph_style), chan);
1100       if (cp->lisp_graph_style != graph_style(ss)) pcp_ss(fd, S_lisp_graph_style, graph_style_name(cp->lisp_graph_style), chan);
1101       if (cp->transform_graph_style != graph_style(ss)) pcp_ss(fd, S_transform_graph_style, graph_style_name(cp->transform_graph_style), chan);
1102       if (cp->show_mix_waveforms != show_mix_waveforms(ss)) pcp_ss(fd, S_show_mix_waveforms, b2s(cp->show_mix_waveforms), chan);
1103       if (cp->dot_size != dot_size(ss)) pcp_sd(fd, S_dot_size, cp->dot_size, chan);
1104       if (fneq(cp->grid_density, grid_density(ss))) pcp_sf(fd, S_grid_density, cp->grid_density, chan);
1105       if (cp->x_axis_style != x_axis_style(ss)) pcp_ss(fd, S_x_axis_style, x_axis_style_name(cp->x_axis_style), chan);
1106       if (fneq(cp->beats_per_minute, beats_per_minute(ss))) pcp_sf(fd, S_beats_per_minute, cp->beats_per_minute, chan);
1107       if (cp->beats_per_measure != beats_per_measure(ss)) pcp_sd(fd, S_beats_per_measure, cp->beats_per_measure, chan);
1108       if (cp->show_axes != show_axes(ss)) pcp_ss(fd, S_show_axes, show_axes2string(cp->show_axes), chan);
1109       if (cp->graphs_horizontal != graphs_horizontal(ss)) pcp_ss(fd, S_graphs_horizontal, b2s(cp->graphs_horizontal), chan);
1110       if ((Xen_is_vector(cp->properties)) &&
1111 	  (Xen_is_list(Xen_vector_ref(cp->properties, 0))) &&
1112 	  (!(Xen_is_null(Xen_vector_ref(cp->properties, 0)))))
1113 	{
1114 	  save_property_list(fd, Xen_vector_ref(cp->properties, 0), chan, -1); /* channel-properties */
1115 	}
1116 
1117       /* ap->default_xlabel if not null, user explicitly set it */
1118       /* ylabel can only be a user choice -- never set by Snd */
1119       if (cp->axis)
1120 	{
1121 	  if (cp->axis->default_xlabel) pcp_sss(fd, S_x_axis_label, cp->axis->default_xlabel, chan, "time-graph");
1122 	  if (cp->axis->ylabel)         pcp_sss(fd, S_y_axis_label, cp->axis->ylabel,         chan, "time-graph");
1123 	}
1124       if ((cp->fft) &&
1125 	  (cp->fft->axis))
1126 	{
1127 	  if (cp->fft->axis->default_xlabel) pcp_sss(fd, S_x_axis_label, cp->fft->axis->default_xlabel, chan, "transform-graph");
1128 	  if (cp->fft->axis->ylabel)         pcp_sss(fd, S_y_axis_label, cp->fft->axis->ylabel,         chan, "transform-graph");
1129 	}
1130       /* lisp_info is hidden in snd-chn.c */
1131 
1132       edit_history_to_file(fd, cp, true);
1133       {
1134 	int i;
1135 	for (i = 0; i <= cp->edit_ctr; i++)
1136 	  {
1137 	    ed_list *ed;
1138 	    ed = cp->edits[i];
1139 	    if ((Xen_is_vector(ed->properties)) &&
1140 		(Xen_is_list(Xen_vector_ref(ed->properties, 0))) &&
1141 		(!(Xen_is_null(Xen_vector_ref(ed->properties, 0)))))
1142 	      {
1143 		save_property_list(fd, Xen_vector_ref(ed->properties, 0), chan, i); /* edit-properties */
1144 	      }
1145 	  }
1146       }
1147 
1148 #if HAVE_SCHEME
1149       mix_info_to_file(fd, cp);
1150 #endif
1151       if (cursor_sample(cp) != 0) pcp_sod(fd, S_cursor, cursor_sample(cp), chan);
1152       check_selection(fd, cp);
1153       if ((!sp->remembering) &&
1154 	  (selected_channel() == cp))
1155 	{
1156 #if HAVE_SCHEME
1157 	  fprintf(fd, "%s(set! _saved_snd_selected_sound_ sfile)\n", white_space);
1158 	  fprintf(fd, "%s(set! _saved_snd_selected_channel_ %d)\n", white_space, cp->chan);
1159 #endif
1160 #if HAVE_RUBY
1161 	  fprintf(fd, "%ssaved_snd_selected_sound = sfile\n", white_space);
1162 	  fprintf(fd, "%ssaved_snd_selected_channel = %d\n", white_space, cp->chan);
1163 #endif
1164 #if HAVE_FORTH
1165 	  fprintf(fd, "%ssfile to saved_snd_selected_sound\n", white_space);
1166 	  fprintf(fd, "%s%d to saved_snd_selected_channel\n", white_space, cp->chan);
1167 #endif
1168 	}
1169     }
1170   close_save_sound_block(fd, !b_ok);
1171 }
1172 
1173 
1174 static Xen after_save_state_hook;
1175 static Xen before_save_state_hook;
1176 
save_state(const char * save_state_name)1177 void save_state(const char *save_state_name)
1178 {
1179   FILE *save_fd;
1180   char *fullname;
1181   bool append_new_state = false;
1182   if (!save_state_name)
1183     {
1184       snd_error("no save state file name?");
1185       return;
1186     }
1187   fullname = mus_expand_filename(save_state_name);
1188   if (Xen_hook_has_list(before_save_state_hook))
1189     {
1190       Xen res;
1191       res = run_or_hook(before_save_state_hook,
1192 			Xen_list_1(C_string_to_Xen_string(fullname)),
1193 			S_before_save_state_hook);
1194       append_new_state = Xen_boolean_to_C_bool(res);
1195     }
1196   if (append_new_state)
1197     save_fd = FOPEN(fullname, "a");
1198   else save_fd = FOPEN(fullname, "w");
1199   if (fullname) {free(fullname); fullname = NULL;}
1200   if (!save_fd)
1201     {
1202       snd_error("can't write %s: %s", save_state_name, snd_io_strerror());
1203       return;
1204     }
1205 
1206   save_options(save_fd);                            /* options = user-settable global state variables */
1207   /* the global settings need to precede possible local settings */
1208 
1209   if (ss->active_sounds > 0)
1210     {
1211       if (ss->selected_sound != NO_SELECTION)
1212 	{
1213 #if HAVE_SCHEME
1214 	  fprintf(save_fd, "\n(define _saved_snd_selected_sound_ #f)\n");
1215 	  fprintf(save_fd, "(define _saved_snd_selected_channel_ #f)\n");
1216 #endif
1217 #if HAVE_RUBY
1218 	  fprintf(save_fd, "\nsaved_snd_selected_sound = -1\n");
1219 	  fprintf(save_fd, "saved_snd_selected_channel = -1\n");
1220 #endif
1221 #if HAVE_FORTH
1222 	  fprintf(save_fd, "\n#f value saved_snd_selected_sound\n");
1223 	  fprintf(save_fd, "#f value saved_snd_selected_channel\n");
1224 	  fprintf(save_fd, "#f value sfile\n");
1225 #endif
1226 	}
1227       for_each_sound_with_void(save_sound_state, (void *)save_fd);      /* current sound state -- will traverse chans */
1228       if (ss->selected_sound != NO_SELECTION)
1229 	{
1230 #if HAVE_SCHEME
1231 	  fprintf(save_fd, "(if _saved_snd_selected_sound_\n");
1232 	  fprintf(save_fd, "  (begin\n");
1233 	  fprintf(save_fd, "    (%s _saved_snd_selected_sound_)\n", S_select_sound);
1234 	  fprintf(save_fd, "    (%s _saved_snd_selected_channel_)))\n", S_select_channel);
1235 #endif
1236 #if HAVE_RUBY
1237 	  fprintf(save_fd, "if saved_snd_selected_sound != -1\n");
1238 	  fprintf(save_fd, "  select_sound(saved_snd_selected_sound)\n");
1239 	  fprintf(save_fd, "  select_channel(saved_snd_selected_channel)\n");
1240 	  fprintf(save_fd, "end\n");
1241 #endif
1242 #if HAVE_FORTH
1243 	  fprintf(save_fd, "saved_snd_selected_sound false? not [if]\n");
1244 	  fprintf(save_fd, "  saved_snd_selected_sound   %s drop\n", S_select_sound);
1245 	  fprintf(save_fd, "  saved_snd_selected_channel %s drop\n", S_select_channel);
1246 	  fprintf(save_fd, "[then]\n\n");
1247 #endif
1248 	}
1249     }
1250   fprintf(save_fd, "\n");
1251   save_envelope_editor_state(save_fd);                    /* current envelope editor window state */
1252   save_regions(save_fd);                                  /* regions */
1253 
1254   if (transform_dialog_is_active()) fprintf(save_fd, BPAREN "%s" EPAREN "\n", to_proc_name(S_transform_dialog));
1255   if (enved_dialog_is_active()) fprintf(save_fd, BPAREN "%s" EPAREN "\n", to_proc_name(S_enved_dialog));
1256   if (color_orientation_dialog_is_active()) fprintf(save_fd, BPAREN "%s" EPAREN "\n", to_proc_name(S_color_orientation_dialog));
1257   if (region_dialog_is_active()) fprintf(save_fd, BPAREN "%s" EPAREN "\n", to_proc_name(S_view_regions_dialog));
1258   save_post_it_dialog_state(save_fd);
1259   save_find_dialog_state(save_fd);
1260   save_edit_header_dialog_state(save_fd);
1261 #if USE_MOTIF
1262   save_print_dialog_state(save_fd);
1263   save_view_files_dialogs(save_fd);
1264 #endif
1265   save_file_dialog_state(save_fd);
1266 
1267   /* saving mix/track state is problematic.  For example, if we make a selection, mix it,
1268    *   then make another selection and mix it, we get an edit list:
1269    *
1270    *   (change-samples-with-origin 266 451 "set! -mix-0 (mix-selection 266)" "/home/bil/zap/snd/snd_3309_9.snd" sfile 0 #f (list 1145009982 1848))
1271    *   (change-samples-with-origin 1655 480 "set! -mix-1 (mix-selection 1655)" "/home/bil/zap/snd/snd_3309_10.snd" sfile 0 #f (list 1145009982 1964))
1272    *   (set! (selection-member? sfile 0) #t)
1273    *   (set! (selection-position sfile 0) 816)
1274    *   (set! (selection-framples sfile 0) 480)
1275    *
1276    *  which won't even work for the current selection case!  If we mix some piece of a sound
1277    *    being edited in another window, we'd need to keep all edits in sync during the restore!
1278    *  But each mix has a temp file of its data, so perhaps an internal function to fake a mix
1279    *    using it?
1280    *
1281    *  :(edit-list->function)
1282    *    #<procedure #f ((snd chn)
1283    *       (let ((-mix-0 0) (-mix-1 1))
1284    *         (set! -mix-0 (mix-selection 266))
1285    *         ;; selection can change here!
1286    *         (set! -mix-1 (mix-selection 1655))))>
1287    *
1288    *  which is also wrong!  This has to use the shadowing temp files.
1289    *    so edit-list->function fails if selections involved (mix-selection) [or is this what is expected?]
1290    *
1291    *  To keep the mix/track dialogs in sync with the newly restored mixes would require keeping the
1292    *     old mix/track numbers and mapping to the new ones.
1293    */
1294 
1295   /* the problem here (with saving hooks) is that it is not straightforward to save the function source
1296    *   (with the current print-set! source option, or with an earlier procedure->string function using
1297    *   funclet etc); many types print in this case in ways that are not readable.
1298    *   The functions may depend on globals that are not in loaded files, or that were changed since
1299    *   loading, and trying to map over the current module's obarray, saving each such variable in
1300    *   its current form, is a major undertaking (although this can be done for simple vars); additionally,
1301    *   what if the user has changed these before restoring -- should the old forms be restored?
1302    * (this comment dates back to Guile days -- I think hook functions could be saved now)
1303    */
1304 
1305   snd_fclose(save_fd, save_state_name);
1306   if (Xen_hook_has_list(after_save_state_hook))
1307     run_hook(after_save_state_hook,
1308 	     Xen_list_1(C_string_to_Xen_string(save_state_name)),
1309 	     S_after_save_state_hook);
1310 }
1311 
1312 
save_options_in_prefs(void)1313 const char *save_options_in_prefs(void)
1314 {
1315 #if HAVE_EXTENSION_LANGUAGE
1316   FILE *fd;
1317   char *fullname;
1318 
1319 #if HAVE_RUBY
1320   #define SND_PREFS "~/.snd_prefs_ruby"
1321 #endif
1322 #if HAVE_FORTH
1323   #define SND_PREFS "~/.snd_prefs_forth"
1324 #endif
1325 #if HAVE_SCHEME
1326   #define SND_PREFS "~/.snd_prefs_s7"
1327 #endif
1328 
1329   fullname = mus_expand_filename(SND_PREFS);
1330   fd = FOPEN(fullname, "w");
1331   if (!fd)
1332     {
1333       snd_error("can't write %s: %s", SND_PREFS, snd_io_strerror());
1334       return(NULL);
1335     }
1336   save_options(fd);
1337   snd_fclose(fd, SND_PREFS);
1338   free(fullname);
1339   return(SND_PREFS);
1340 #else
1341   return(NULL);
1342 #endif
1343 }
1344 
1345 
1346 #if 0
1347 static char *file_extension(char *arg)
1348 {
1349   char *dot = NULL, *sp;
1350   if (arg)
1351     for (sp = arg; (*sp) != '\0'; sp++)
1352       if ((*sp) == '.')
1353 	dot = (++sp);
1354   return(dot);
1355 }
1356 #endif
1357 
1358 
1359 static char *startup_filename = NULL;
1360 static int script_arg = 0, script_argn = 0;
1361 static char **script_args;
1362 
g_script_arg(void)1363 static Xen g_script_arg(void)
1364 {
1365   #define H_script_arg "(" S_script_arg "): where we are in the startup arg list"
1366   return(C_int_to_Xen_integer(script_arg));
1367 }
1368 
1369 
g_set_script_arg(Xen arg)1370 static Xen g_set_script_arg(Xen arg)
1371 {
1372   script_arg = Xen_integer_to_C_int(arg);
1373   return(arg);
1374 }
1375 
1376 
g_script_args(void)1377 static Xen g_script_args(void)
1378 {
1379   #define H_script_args "(" S_script_args "): the args passed to Snd at startup as a list of strings"
1380   Xen lst = Xen_empty_list;
1381   int i;
1382   for (i = script_argn - 1; i >= 0; i--)
1383     lst = Xen_cons(C_string_to_Xen_string(script_args[i]), lst);
1384   return(lst);
1385 }
1386 
1387 
printout_to_stdout(const char * msg,void * ignore)1388 static void printout_to_stdout(const char *msg, void *ignore)
1389 {
1390   puts(msg);
1391 }
1392 
1393 
handle_next_startup_arg(int auto_open_ctr,char ** auto_open_file_names,bool with_title,int args)1394 int handle_next_startup_arg(int auto_open_ctr, char **auto_open_file_names, bool with_title, int args)
1395 {
1396   char *argname;
1397   argname = auto_open_file_names[auto_open_ctr];
1398   if (argname)
1399     { /* wanted to use "-d" and "-i" but they're in use */
1400       if ((mus_strcmp("-h", argname)) ||
1401 	  (mus_strcmp("-horizontal", argname)) ||
1402 	  (mus_strcmp("--horizontal", argname)) ||
1403 	  (mus_strcmp("-v", argname)) ||
1404 	  (mus_strcmp("-vertical", argname)) ||
1405 	  (mus_strcmp("--vertical", argname)) ||
1406 	  (mus_strcmp("-notebook", argname)) ||
1407 	  (mus_strcmp("--notebook", argname)) ||
1408 	  (mus_strcmp("-separate", argname)) ||
1409 	  (mus_strcmp("--separate", argname)) ||
1410 	  (mus_strcmp("-nostdin", argname)) ||
1411 	  (mus_strcmp("-noglob", argname)) ||
1412 	  (mus_strcmp("-noinit", argname)) ||
1413 	  (mus_strcmp("--noinit", argname)))
1414 	return(auto_open_ctr + 1);
1415       else
1416 	{
1417 	  if (mus_strcmp("-init", argname))
1418 	    return(auto_open_ctr + 2);
1419 	  else
1420 	    {
1421 #if (!USE_NO_GUI)
1422 	      if ((mus_strcmp("-p", argname)) ||
1423 		  (mus_strcmp("-preload", argname)) ||
1424 		  (mus_strcmp("--preload", argname)))
1425 		{
1426 		  /* preload sound files in dir (can be ., should be unquoted) */
1427 		  auto_open_ctr++;
1428 		  if ((auto_open_ctr >= args) ||
1429 		      (!auto_open_file_names[auto_open_ctr]))
1430 		    snd_error("%s but no directory to add?", argname);
1431 		  else view_files_add_directory(NULL_WIDGET, auto_open_file_names[auto_open_ctr]);
1432 		}
1433 	      else
1434 #endif
1435 		{
1436 		  if ((mus_strcmp("-l", argname)) ||
1437 		      (mus_strcmp("-load", argname)) ||
1438 		      (mus_strcmp("--load", argname)) ||
1439 		      (mus_strcmp("-b", argname)) ||
1440 		      (mus_strcmp("-batch", argname)) ||
1441 		      (mus_strcmp("--batch", argname)) ||
1442 		      (is_source_file(argname)))
1443 		    {
1444 		      if ((mus_strcmp("-l", argname)) ||
1445 			  (mus_strcmp("-load", argname)) ||
1446 			  (mus_strcmp("--load", argname)) ||
1447 			  (mus_strcmp("-b", argname)) ||
1448 			  (mus_strcmp("-batch", argname)) ||
1449 			  (mus_strcmp("--batch", argname)))
1450 			auto_open_ctr++;
1451 		      if ((auto_open_ctr >= args) ||
1452 			  (!auto_open_file_names[auto_open_ctr]))
1453 			snd_error("%s but no file to load?", argname);
1454 		      else
1455 			{
1456 			  script_arg = auto_open_ctr;
1457 			  script_argn = args;
1458 			  script_args = auto_open_file_names;
1459 			  redirect_everything_to(printout_to_stdout, NULL);
1460 			  snd_load_file(auto_open_file_names[auto_open_ctr]);
1461 			  redirect_everything_to(NULL, NULL);
1462 			  if (script_arg > auto_open_ctr)
1463 			    auto_open_ctr = script_arg;
1464 			}
1465 		    }
1466 		  else
1467 		    {
1468 		      if ((mus_strcmp("-e", argname)) ||
1469 			  (mus_strcmp("-eval", argname)) ||
1470 			  (mus_strcmp("--eval", argname)))
1471 			{
1472 			  /* evaluate expression */
1473 			  auto_open_ctr++;
1474 			  if ((auto_open_ctr >= args) ||
1475 			      (!auto_open_file_names[auto_open_ctr]))
1476 			    snd_error("%s but no form to evaluate?", argname);
1477 			  else
1478 			    {
1479 			      char *buf;
1480 			      buf = auto_open_file_names[auto_open_ctr];
1481 			      redirect_everything_to(printout_to_stdout, NULL);
1482 			      snd_report_result(snd_catch_any(eval_str_wrapper, (void *)buf, buf), buf);
1483 			      redirect_everything_to(NULL, NULL);
1484 			    }
1485 			}
1486 		      else
1487 			{
1488 			  if ((with_title) &&
1489 			      (mus_strcmp("-title", argname)))
1490 			    {
1491 			      auto_open_ctr++;
1492 			      if ((auto_open_ctr >= args) ||
1493 				  (!auto_open_file_names[auto_open_ctr]))
1494 				snd_error_without_format("-title but no title?"); /* Xt handles the Motif case */
1495 			      else ss->startup_title = mus_strdup(auto_open_file_names[auto_open_ctr]);
1496 			    }
1497 			  else
1498 			    {
1499 			      if (mus_strcmp("-I", argname))
1500 				{
1501 				  /* added 24-Oct-02: add to load path in either extension language */
1502 				  auto_open_ctr++;
1503 				  if ((auto_open_ctr >= args) ||
1504 				      (!auto_open_file_names[auto_open_ctr]))
1505 				    snd_error_without_format("-I but no path?");
1506 				  else
1507 				    {
1508 				      Xen_add_to_load_path(auto_open_file_names[auto_open_ctr]);
1509 				    }
1510 				}
1511 			      else
1512 				{
1513 				  if (!startup_filename)
1514 				    startup_filename = mus_strdup(argname);
1515 				  ss->open_requestor = FROM_STARTUP;
1516 				  if (!snd_open_file(argname, FILE_READ_WRITE))
1517 				    {
1518 				      /* non-existent file at startup */
1519 				      if (argname[0] == '-')
1520 					{
1521 					  /* probably a bad option */
1522 					  fprintf(stdout, "bad option: %s\n", argname);
1523 					}
1524 				      else
1525 					{
1526 					  fprintf(stdout, "can't open %s\n", argname);
1527 					  if (ss->startup_errors)
1528 					    ss->startup_errors = mus_format("%s\n%s ;%s\"%s\"\n", ss->startup_errors, listener_prompt(ss), "can't open ", argname);
1529 					  else ss->startup_errors = mus_format(";%s\"%s\"\n", "can't open ", argname);
1530 					}
1531 				    }
1532 				}
1533 			    }
1534 			}
1535 		    }
1536 		}
1537 	    }
1538 	}
1539     }
1540   return(auto_open_ctr + 1);
1541 }
1542 
1543 
save_state_error_handler(const char * msg,void * data)1544 static void save_state_error_handler(const char *msg, void *data)
1545 {
1546   char *filename = (char *)data;
1547   Xen fname;
1548   if (filename)
1549     {
1550       fname = C_string_to_Xen_string(filename);
1551       free(filename); /* this is "name" below */
1552     }
1553   else fname = C_string_to_Xen_string(save_state_file(ss));
1554   redirect_snd_error_to(NULL, NULL);
1555   Xen_error(Xen_make_error_type("cannot-save"),
1556 	    Xen_list_2(C_string_to_Xen_string(S_save_state ": can't save ~S"),
1557 		       fname));
1558 }
1559 
1560 
g_save_state(Xen filename)1561 static Xen g_save_state(Xen filename)
1562 {
1563   char *name = NULL;
1564   Xen res;
1565   #define H_save_state "(" S_save_state " :optional filename): save the current Snd state in filename; (load filename) restores it.  The \
1566 default " S_save_state " filename is " DEFAULT_SAVE_STATE_FILE ". It can be changed via " S_save_state_file "."
1567 
1568   Xen_check_type(Xen_is_string_or_unbound(filename), filename, 1, S_save_state, "a string");
1569 
1570   if (Xen_is_bound(filename))
1571     name = mus_strdup(Xen_string_to_C_string(filename));
1572   else name = mus_strdup(save_state_file(ss));
1573 
1574   redirect_snd_error_to(save_state_error_handler, (void *)name);
1575   save_state(name);
1576   redirect_snd_error_to(NULL, NULL);
1577 
1578   res = C_string_to_Xen_string(name);
1579   free(name);
1580   return(res);
1581 }
1582 
1583 
g_exit(Xen val)1584 static Xen g_exit(Xen val)
1585 {
1586   #define H_exit "(" S_exit " :optional val): exit Snd"
1587   if (snd_exit_cleanly(EXIT_NOT_FORCED))
1588     snd_exit((Xen_is_integer(val)) ? Xen_integer_to_C_int(val) : 1);
1589   return(Xen_false);
1590 }
1591 
1592 
snd_access(const char * dir,const char * caller)1593 static int snd_access(const char *dir, const char *caller)
1594 {
1595   int err;
1596   char *temp;
1597   temp = shorter_tempnam(dir, "snd_");
1598   err = mus_file_create(temp);
1599   if (err == -1)
1600     {
1601       Xen res;
1602       free(temp);
1603       temp = mus_format("%s: directory %s is not writable: %s", caller, dir, snd_open_strerror());
1604       res = C_string_to_Xen_string(temp);
1605       free(temp);
1606       Xen_error(NO_SUCH_FILE, Xen_list_1(res));
1607       return(0);
1608     }
1609   else snd_close(err, temp);
1610   snd_remove(temp, IGNORE_CACHE);
1611   free(temp);
1612   return(1);
1613 }
1614 
1615 
g_temp_dir(void)1616 static Xen g_temp_dir(void) {return(C_string_to_Xen_string(temp_dir(ss)));}
1617 
g_set_temp_dir(Xen val)1618 static Xen g_set_temp_dir(Xen val)
1619 {
1620   #define H_temp_dir "(" S_temp_dir "): name of directory for temp files (or " PROC_FALSE "=null)"
1621   const char *dir = MUS_DEFAULT_TEMP_DIR;
1622   Xen_check_type(Xen_is_string(val) || Xen_is_false(val), val, 1, S_set S_temp_dir, "a string or " PROC_FALSE "=default (null)");
1623   if (Xen_is_string(val)) dir = Xen_string_to_C_string(val);
1624   if (snd_access(dir, S_temp_dir))
1625     {
1626       if (temp_dir(ss)) free(temp_dir(ss));
1627       set_temp_dir(mus_strdup(dir));
1628     }
1629   return(C_string_to_Xen_string(temp_dir(ss)));
1630 }
1631 
1632 
g_peak_env_dir(void)1633 static Xen g_peak_env_dir(void) {return(C_string_to_Xen_string(peak_env_dir(ss)));}
1634 
g_set_peak_env_dir(Xen val)1635 static Xen g_set_peak_env_dir(Xen val)
1636 {
1637   #define H_peak_env_dir "(" S_peak_env_dir "): name of directory for peak env files (or " PROC_FALSE "=null)"
1638   Xen_check_type(Xen_is_string(val) || Xen_is_false(val), val, 1, S_set S_peak_env_dir, "a string or " PROC_FALSE "=default (null)");
1639   if (Xen_is_string(val))
1640     {
1641       const char *dir = NULL;
1642       dir = Xen_string_to_C_string(val);
1643       if (snd_access(dir, S_peak_env_dir))
1644 	{
1645 	  if (peak_env_dir(ss)) free(peak_env_dir(ss));
1646 	  set_peak_env_dir(mus_strdup(dir));
1647 	}
1648     }
1649   else
1650     {
1651       if (peak_env_dir(ss)) free(peak_env_dir(ss));
1652       set_peak_env_dir(NULL);
1653     }
1654   return(C_string_to_Xen_string(peak_env_dir(ss)));
1655 }
1656 
1657 
g_ladspa_dir(void)1658 static Xen g_ladspa_dir(void) {return(C_string_to_Xen_string(ladspa_dir(ss)));}
1659 
g_set_ladspa_dir(Xen val)1660 static Xen g_set_ladspa_dir(Xen val)
1661 {
1662   #define H_ladspa_dir "(" S_ladspa_dir "): name of directory for ladspa plugin libraries"
1663   Xen_check_type(Xen_is_string(val) || Xen_is_false(val), val, 1, S_set S_ladspa_dir, "a string or " PROC_FALSE "=default (null)");
1664   if (ladspa_dir(ss)) free(ladspa_dir(ss));
1665   if (Xen_is_false(val))
1666     set_ladspa_dir(mus_strdup(DEFAULT_LADSPA_DIR));
1667   else set_ladspa_dir(mus_strdup(Xen_string_to_C_string(val)));
1668   return(C_string_to_Xen_string(ladspa_dir(ss)));
1669 }
1670 
1671 
g_save_state_file(void)1672 static Xen g_save_state_file(void) {return(C_string_to_Xen_string(save_state_file(ss)));}
1673 
g_set_save_state_file(Xen val)1674 static Xen g_set_save_state_file(Xen val)
1675 {
1676   const char *filename;
1677   #define H_save_state_file "(" S_save_state_file "): the name of the saved state file (\"saved-snd." Xen_file_extension "\")"
1678   Xen_check_type(Xen_is_string(val), val, 1, S_set S_save_state_file, "a string");
1679   filename = Xen_string_to_C_string(val);
1680   if (save_state_file(ss)) free(save_state_file(ss));
1681   in_set_save_state_file(mus_strdup(filename));
1682   return(C_string_to_Xen_string(save_state_file(ss)));
1683 }
1684 
1685 
g_save_dir(void)1686 static Xen g_save_dir(void) {return(C_string_to_Xen_string(save_dir(ss)));}
1687 
g_set_save_dir(Xen val)1688 static Xen g_set_save_dir(Xen val)
1689 {
1690   #define H_save_dir "(" S_save_dir "): name of directory for saved state data (or " PROC_FALSE "=null)"
1691   const char *dir = MUS_DEFAULT_SAVE_DIR;
1692   Xen_check_type(Xen_is_string(val) || Xen_is_false(val), val, 1, S_set S_save_dir, "a string or " PROC_FALSE "=default (null)");
1693   if (Xen_is_string(val)) dir = Xen_string_to_C_string(val);
1694   if (snd_access(dir, S_save_dir))
1695     {
1696       if (save_dir(ss)) free(save_dir(ss));
1697       set_save_dir(mus_strdup(dir));
1698     }
1699   return(C_string_to_Xen_string(save_dir(ss)));
1700 }
1701 
1702 
g_open_file_dialog_directory(void)1703 static Xen g_open_file_dialog_directory(void) {return(C_string_to_Xen_string(open_file_dialog_directory(ss)));}
1704 
g_set_open_file_dialog_directory(Xen val)1705 static Xen g_set_open_file_dialog_directory(Xen val)
1706 {
1707   #define H_open_file_dialog_directory "(" S_open_file_dialog_directory "): name of directory for initial open file dialog search"
1708   const char *dir;
1709   Xen_check_type(Xen_is_string(val), val, 1, S_set S_open_file_dialog_directory, "a string");
1710   dir = Xen_string_to_C_string(val);
1711   if (snd_access(dir, S_open_file_dialog_directory))
1712     {
1713       if (open_file_dialog_directory(ss)) free(open_file_dialog_directory(ss));
1714       set_open_file_dialog_directory(mus_strdup(dir));
1715     }
1716   return(C_string_to_Xen_string(open_file_dialog_directory(ss)));
1717 }
1718 
1719 
snd_screen_height(void)1720 static int snd_screen_height(void)
1721 {
1722 #if USE_MOTIF
1723   return(HeightOfScreen(ScreenOfDisplay(main_display(ss), 0)));
1724 #else
1725   return(4000);
1726 #endif
1727 }
1728 
1729 
snd_screen_width(void)1730 static int snd_screen_width(void)
1731 {
1732 #if USE_MOTIF
1733   return(WidthOfScreen(ScreenOfDisplay(main_display(ss), 0)));
1734 #else
1735   return(4000);
1736 #endif
1737 }
1738 
1739 
g_window_height(void)1740 static Xen g_window_height(void)
1741 {
1742   #define H_window_height "(" S_window_height "): current Snd window height in pixels"
1743   return(C_int_to_Xen_integer(widget_height(main_shell(ss))));
1744 }
1745 
1746 
g_set_window_height(Xen height)1747 static Xen g_set_window_height(Xen height)
1748 {
1749   int val;
1750   Xen_check_type(Xen_is_integer(height), height, 1, S_set S_window_height, "an integer");
1751   val = Xen_integer_to_C_int(height);
1752   if ((val > 0) && (val < snd_screen_height()))
1753     {
1754 #if (!USE_NO_GUI)
1755       set_widget_height(main_shell(ss), val);
1756 #endif
1757       ss->init_window_height = val;
1758     }
1759   return(height);
1760 }
1761 
1762 
g_window_width(void)1763 static Xen g_window_width(void)
1764 {
1765   #define H_window_width "(" S_window_width "): current Snd window width in pixels"
1766   return(C_int_to_Xen_integer(widget_width(main_shell(ss))));
1767 }
1768 
1769 
g_set_window_width(Xen width)1770 static Xen g_set_window_width(Xen width)
1771 {
1772   int val;
1773   Xen_check_type(Xen_is_integer(width), width, 1, S_set S_window_width, "an integer");
1774   val = Xen_integer_to_C_int(width);
1775   if ((val > 0) && (val < snd_screen_width()))
1776     {
1777 #if (!USE_NO_GUI)
1778       set_widget_width(main_shell(ss), val);
1779 #endif
1780       ss->init_window_width = val;
1781     }
1782   return(width);
1783 }
1784 
1785 
g_window_x(void)1786 static Xen g_window_x(void)
1787 {
1788   #define H_window_x "(" S_window_x "): current Snd window x position in pixels"
1789   return(C_int_to_Xen_integer(widget_x(main_shell(ss))));
1790 }
1791 
1792 
g_set_window_x(Xen val)1793 static Xen g_set_window_x(Xen val)
1794 {
1795   int x;
1796   Xen_check_type(Xen_is_integer(val), val, 1, S_set S_window_x, "an integer");
1797   x = Xen_integer_to_C_int(val);
1798   if ((x >= 0) && (x < snd_screen_width()))
1799     {
1800       set_widget_x(main_shell(ss), x);
1801       ss->init_window_x = x;
1802     }
1803   return(val);
1804 }
1805 
1806 
g_window_y(void)1807 static Xen g_window_y(void)
1808 {
1809   #define H_window_y "(" S_window_y "): current Snd window y position in pixels"
1810   return(C_int_to_Xen_integer(widget_y(main_shell(ss))));
1811 }
1812 
1813 
g_set_window_y(Xen val)1814 static Xen g_set_window_y(Xen val)
1815 {
1816   int y;
1817   Xen_check_type(Xen_is_integer(val), val, 1, S_set S_window_y, "an integer");
1818   y = Xen_integer_to_C_int(val);
1819   if ((y >= 0) && (y < snd_screen_height()))
1820     {
1821       set_widget_y(main_shell(ss), y);
1822       ss->init_window_y = y;
1823     }
1824   return(val);
1825 }
1826 
1827 
g_just_sounds(void)1828 static Xen g_just_sounds(void)
1829 {
1830   #define H_just_sounds "(" S_just_sounds "): the 'just sounds' choice in the file chooser dialog"
1831   return(C_bool_to_Xen_boolean(just_sounds(ss)));
1832 }
1833 
1834 
g_set_just_sounds(Xen on)1835 static Xen g_set_just_sounds(Xen on)
1836 {
1837   Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_just_sounds, "a boolean");
1838   set_just_sounds(Xen_boolean_to_C_bool(on));
1839   reflect_just_sounds();
1840   return(C_bool_to_Xen_boolean(just_sounds(ss)));
1841 }
1842 
1843 
g_play_arrow_size(void)1844 static Xen g_play_arrow_size(void)
1845 {
1846   #define H_play_arrow_size "(" S_play_arrow_size "): the size of the play triangles"
1847   return(C_int_to_Xen_integer(play_arrow_size(ss)));
1848 }
1849 
1850 
g_set_play_arrow_size(Xen size)1851 static Xen g_set_play_arrow_size(Xen size)
1852 {
1853   int arrow_size;
1854   Xen_check_type(Xen_is_integer(size), size, 1, S_set S_play_arrow_size, "an integer");
1855 
1856   arrow_size = Xen_integer_to_C_int(size);
1857   if (arrow_size >= 0)
1858     set_play_arrow_size(arrow_size);
1859   else Xen_out_of_range_error(S_set S_play_arrow_size, 1, size, "must be >= 0");
1860 
1861   for_each_chan(update_graph);
1862   return(size);
1863 }
1864 
1865 
g_with_inset_graph(void)1866 static Xen g_with_inset_graph(void)
1867 {
1868   #define H_with_inset_graph "(" S_with_inset_graph "): if " PROC_TRUE " (default is " PROC_FALSE "), display the inset graph in the time domain section."
1869   return(C_bool_to_Xen_boolean(with_inset_graph(ss)));
1870 }
1871 
1872 
g_set_with_inset_graph(Xen on)1873 static Xen g_set_with_inset_graph(Xen on)
1874 {
1875   Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_with_inset_graph, "a boolean");
1876   set_with_inset_graph(Xen_boolean_to_C_bool(on));
1877   for_each_chan(update_graph);
1878   return(C_bool_to_Xen_boolean(with_inset_graph(ss)));
1879 }
1880 
1881 
g_with_interrupts(void)1882 static Xen g_with_interrupts(void)
1883 {
1884   #define H_with_interrupts "(" S_with_interrupts "): if " PROC_TRUE ", check for GUI events during computations."
1885   return(C_bool_to_Xen_boolean(with_interrupts(ss)));
1886 }
1887 
1888 
g_set_with_interrupts(Xen on)1889 static Xen g_set_with_interrupts(Xen on)
1890 {
1891   Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_with_interrupts, "a boolean");
1892   set_with_interrupts(Xen_boolean_to_C_bool(on));
1893   return(C_bool_to_Xen_boolean(with_interrupts(ss)));
1894 }
1895 
1896 
g_with_smpte_label(void)1897 static Xen g_with_smpte_label(void)
1898 {
1899   #define H_with_smpte_label "(" S_with_smpte_label "): if " PROC_TRUE " (default is " PROC_FALSE "), display the SMPTE data in the time domain section."
1900   return(C_bool_to_Xen_boolean(with_smpte_label(ss)));
1901 }
1902 
1903 
g_set_with_smpte_label(Xen on)1904 static Xen g_set_with_smpte_label(Xen on)
1905 {
1906   Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_with_smpte_label, "a boolean");
1907   set_with_smpte_label(Xen_boolean_to_C_bool(on));
1908   for_each_chan(update_graph);
1909   return(C_bool_to_Xen_boolean(with_smpte_label(ss)));
1910 }
1911 
1912 
g_with_pointer_focus(void)1913 static Xen g_with_pointer_focus(void)
1914 {
1915   #define H_with_pointer_focus "(" S_with_pointer_focus "): if " PROC_TRUE " (default is " PROC_FALSE "), activate the text or graph widget beneath the mouse."
1916   return(C_bool_to_Xen_boolean(with_pointer_focus(ss)));
1917 }
1918 
1919 
g_set_with_pointer_focus(Xen on)1920 static Xen g_set_with_pointer_focus(Xen on)
1921 {
1922   Xen_check_type(Xen_is_boolean(on), on, 1, S_set S_with_pointer_focus, "a boolean");
1923   set_with_pointer_focus(Xen_boolean_to_C_bool(on));
1924   return(C_bool_to_Xen_boolean(with_pointer_focus(ss)));
1925 }
1926 
1927 
g_tiny_font(void)1928 static Xen g_tiny_font(void) {return(C_string_to_Xen_string(tiny_font(ss)));}
1929 
g_set_tiny_font(Xen val)1930 static Xen g_set_tiny_font(Xen val)
1931 {
1932   #define H_tiny_font "(" S_tiny_font "): font use for some info in the graphs"
1933   Xen_check_type(Xen_is_string(val), val, 1, S_set S_tiny_font, "a string");
1934   set_tiny_font(Xen_string_to_C_string(val));
1935   return(C_string_to_Xen_string(tiny_font(ss)));
1936 }
1937 
1938 
g_axis_label_font(void)1939 static Xen g_axis_label_font(void) {return(C_string_to_Xen_string(axis_label_font(ss)));}
1940 
g_set_axis_label_font(Xen val)1941 static Xen g_set_axis_label_font(Xen val)
1942 {
1943   #define H_axis_label_font "(" S_axis_label_font "): font used for axis labels"
1944   Xen_check_type(Xen_is_string(val), val, 1, S_set S_axis_label_font, "a string");
1945   set_axis_label_font(Xen_string_to_C_string(val));
1946   return(C_string_to_Xen_string(axis_label_font(ss)));
1947 }
1948 
1949 
g_axis_numbers_font(void)1950 static Xen g_axis_numbers_font(void) {return(C_string_to_Xen_string(axis_numbers_font(ss)));}
1951 
g_set_axis_numbers_font(Xen val)1952 static Xen g_set_axis_numbers_font(Xen val)
1953 {
1954   #define H_axis_numbers_font "(" S_axis_numbers_font "): font used for axis numbers"
1955   Xen_check_type(Xen_is_string(val), val, 1, S_set S_axis_numbers_font, "a string");
1956   set_axis_numbers_font(Xen_string_to_C_string(val));
1957   return(C_string_to_Xen_string(axis_numbers_font(ss)));
1958 }
1959 
1960 
g_listener_font(void)1961 static Xen g_listener_font(void) {return(C_string_to_Xen_string(listener_font(ss)));}
1962 
g_set_listener_font(Xen val)1963 static Xen g_set_listener_font(Xen val)
1964 {
1965   #define H_listener_font "(" S_listener_font "): font used by the lisp listener"
1966   Xen_check_type(Xen_is_string(val), val, 1, S_set S_listener_font, "a string");
1967   set_listener_font(Xen_string_to_C_string(val));
1968   return(C_string_to_Xen_string(listener_font(ss)));
1969 }
1970 
1971 
g_bold_peaks_font(void)1972 static Xen g_bold_peaks_font(void) {return(C_string_to_Xen_string(bold_peaks_font(ss)));}
1973 
g_set_bold_peaks_font(Xen val)1974 static Xen g_set_bold_peaks_font(Xen val)
1975 {
1976   #define H_bold_peaks_font "(" S_bold_peaks_font "): bold font used by fft peak display"
1977   Xen_check_type(Xen_is_string(val), val, 1, S_set S_bold_peaks_font, "a string");
1978   set_bold_peaks_font(Xen_string_to_C_string(val));
1979   return(C_string_to_Xen_string(bold_peaks_font(ss)));
1980 }
1981 
1982 
g_peaks_font(void)1983 static Xen g_peaks_font(void) {return(C_string_to_Xen_string(peaks_font(ss)));}
1984 
g_set_peaks_font(Xen val)1985 static Xen g_set_peaks_font(Xen val)
1986 {
1987   #define H_peaks_font "(" S_peaks_font "): normal font used by fft peak display"
1988   Xen_check_type(Xen_is_string(val), val, 1, S_set S_peaks_font, "a string");
1989   set_peaks_font(Xen_string_to_C_string(val));
1990   return(C_string_to_Xen_string(peaks_font(ss)));
1991 }
1992 
1993 
g_auto_resize(void)1994 static Xen g_auto_resize(void) {return(C_bool_to_Xen_boolean(auto_resize(ss)));}
1995 
g_set_auto_resize(Xen val)1996 static Xen g_set_auto_resize(Xen val)
1997 {
1998   #define H_auto_resize "(" S_auto_resize "): " PROC_TRUE " if Snd can change its main window size as it pleases (default: " PROC_TRUE ")"
1999   Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_auto_resize, "a boolean");
2000   set_auto_resize(Xen_boolean_to_C_bool(val));
2001 #if USE_MOTIF
2002   XtVaSetValues(main_shell(ss), XmNallowShellResize, auto_resize(ss), NULL);
2003 #endif
2004   return(C_bool_to_Xen_boolean(auto_resize(ss)));
2005 }
2006 
2007 
g_color_cutoff(void)2008 static Xen g_color_cutoff(void) {return(C_double_to_Xen_real(color_cutoff(ss)));}
2009 
g_set_color_cutoff(Xen val)2010 static Xen g_set_color_cutoff(Xen val)
2011 {
2012   #define H_color_cutoff "(" S_color_cutoff "): color map cutoff point (default .003).  Any values \
2013 below the cutoff are displayed in the background color"
2014   Xen_check_type(Xen_is_number(val), val, 1, S_set S_color_cutoff, "a number");
2015   set_color_cutoff(mus_fclamp(0.0,
2016 			      Xen_real_to_C_double(val),
2017 #if USE_MOTIF
2018 			      0.25
2019 #else
2020 			      1.0
2021 #endif
2022 			      ));
2023   return(C_double_to_Xen_real(color_cutoff(ss)));
2024 }
2025 
2026 
g_color_inverted(void)2027 static Xen g_color_inverted(void) {return(C_bool_to_Xen_boolean(color_inverted(ss)));}
2028 
g_set_color_inverted(Xen val)2029 static Xen g_set_color_inverted(Xen val)
2030 {
2031   #define H_color_inverted "(" S_color_inverted "): whether the colormap in operation should be inverted"
2032   Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_color_inverted, "a boolean");
2033   set_color_inverted(Xen_boolean_to_C_bool(val));
2034   return(C_bool_to_Xen_boolean(color_inverted(ss)));
2035 }
2036 
2037 
g_color_scale(void)2038 static Xen g_color_scale(void) {return(C_double_to_Xen_real(color_scale(ss)));}
2039 
g_set_color_scale(Xen val)2040 static Xen g_set_color_scale(Xen val)
2041 {
2042   #define H_color_scale "(" S_color_scale "): darkness setting for colormaps (0.5)"
2043   Xen_check_type(Xen_is_number(val), val, 1, S_set S_color_scale, "a number");
2044   set_color_scale(mus_fclamp(0.0,
2045 			     Xen_real_to_C_double(val),
2046 			     1000.0));
2047   return(C_double_to_Xen_real(color_scale(ss)));
2048 }
2049 
2050 
g_selection_creates_region(void)2051 static Xen g_selection_creates_region(void) {return(C_bool_to_Xen_boolean(selection_creates_region(ss)));}
2052 
g_set_selection_creates_region(Xen val)2053 static Xen g_set_selection_creates_region(Xen val)
2054 {
2055   #define H_selection_creates_region "(" S_selection_creates_region "): " PROC_TRUE " if a region should be created each time a selection is made. \
2056 The default is currently " PROC_TRUE ", but that may change.  If you're dealing with large selections, and have no need of \
2057 regions (saved selections), you can speed up many operations by setting this flag to " PROC_FALSE
2058   Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_selection_creates_region, "a boolean");
2059   set_selection_creates_region(Xen_boolean_to_C_bool(val));
2060   return(C_bool_to_Xen_boolean(selection_creates_region(ss)));
2061 }
2062 
2063 
set_print_lengths(int len)2064 static void set_print_lengths(int len)
2065 {
2066   set_print_length(len);
2067   mus_vct_set_print_length(len);
2068 #if HAVE_SCHEME
2069   s7_let_field_set(s7, s7_make_symbol(s7, "print-length"), s7_make_integer(s7, len));
2070 #endif
2071 }
2072 
g_print_length(void)2073 static Xen g_print_length(void) {return(C_int_to_Xen_integer(print_length(ss)));}
2074 
g_set_print_length(Xen val)2075 static Xen g_set_print_length(Xen val)
2076 {
2077   int len;
2078   #define H_print_length "(" S_print_length "): number of vector elements to print in the listener (default: 12)"
2079   Xen_check_type(Xen_is_integer(val), val, 1, S_set S_print_length, "an integer");
2080   len = Xen_integer_to_C_int(val);
2081   if (len < 0)
2082     Xen_out_of_range_error(S_set S_print_length, 1, val, "must be >= 0");
2083   set_print_lengths(len);
2084   return(C_int_to_Xen_integer(print_length(ss)));
2085 }
2086 
2087 
g_show_indices(void)2088 static Xen g_show_indices(void) {return(C_bool_to_Xen_boolean(show_indices(ss)));}
2089 
g_set_show_indices(Xen val)2090 static Xen g_set_show_indices(Xen val)
2091 {
2092   #define H_show_indices "(" S_show_indices "): " PROC_TRUE " if sound name should be preceded by its index in the sound display."
2093   Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_show_indices, "a boolean");
2094   set_show_indices(Xen_boolean_to_C_bool(val));
2095   for_each_sound(update_sound_label);
2096   return(C_bool_to_Xen_boolean(show_indices(ss)));
2097 }
2098 
g_with_relative_panes(void)2099 static Xen g_with_relative_panes(void) {return(C_bool_to_Xen_boolean(with_relative_panes(ss)));}
2100 
g_set_with_relative_panes(Xen val)2101 static Xen g_set_with_relative_panes(Xen val)
2102 {
2103   #define H_with_relative_panes "(" S_with_relative_panes "): " PROC_TRUE " if multichannel sounds should try to maintain relative pane sizes"
2104   Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_with_relative_panes, "a boolean");
2105   set_with_relative_panes(Xen_boolean_to_C_bool(val));
2106   return(C_bool_to_Xen_boolean(with_relative_panes(ss)));
2107 }
2108 
2109 
g_with_background_processes(void)2110 static Xen g_with_background_processes(void) {return(C_bool_to_Xen_boolean(with_background_processes(ss)));}
2111 
g_set_with_background_processes(Xen val)2112 static Xen g_set_with_background_processes(Xen val)
2113 {
2114   #define H_with_background_processes "(" S_with_background_processes "): " PROC_TRUE " if Snd should use background (idle time) processing"
2115   Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_with_background_processes, "a boolean");
2116   set_with_background_processes(Xen_boolean_to_C_bool(val));
2117   return(C_bool_to_Xen_boolean(with_background_processes(ss)));
2118 }
2119 
2120 
g_with_file_monitor(void)2121 static Xen g_with_file_monitor(void) {return(C_bool_to_Xen_boolean(with_file_monitor(ss)));}
2122 
g_set_with_file_monitor(Xen val)2123 static Xen g_set_with_file_monitor(Xen val)
2124 {
2125   #define H_with_file_monitor "(" S_with_file_monitor "): " PROC_TRUE " if the file alteration monitor is active"
2126   Xen_check_type(Xen_is_boolean(val), val, 1, S_set S_with_file_monitor, "a boolean");
2127   set_with_file_monitor(Xen_boolean_to_C_bool(val));
2128   return(C_bool_to_Xen_boolean(with_file_monitor(ss)));
2129 }
2130 
2131 
g_snd_version(void)2132 static Xen g_snd_version(void)
2133 {
2134   #define H_snd_version "(" S_snd_version "): current Snd version (a string)"
2135   return(C_string_to_Xen_string("Snd " SND_VERSION ", " SND_DATE)); /* make it look like s7-version's output */
2136 }
2137 
2138 
g_color_orientation_dialog(Xen managed)2139 static Xen g_color_orientation_dialog(Xen managed)
2140 {
2141   #define H_color_orientation_dialog "(" S_color_orientation_dialog " :optional managed): start the Color/Orientation dialog"
2142   Xen_check_type(Xen_is_boolean_or_unbound(managed), managed, 1, S_color_orientation_dialog, "a boolean");
2143   return(Xen_wrap_widget(make_color_orientation_dialog(Xen_boolean_to_C_bool(managed))));
2144 }
2145 
2146 
g_transform_dialog(Xen managed)2147 static Xen g_transform_dialog(Xen managed)
2148 {
2149   #define H_transform_dialog "(" S_transform_dialog " :optional (managed " PROC_TRUE ")): start the Transforms dialog"
2150   Xen_check_type(Xen_is_boolean_or_unbound(managed), managed, 1, S_transform_dialog, "a boolean");
2151   return(Xen_wrap_widget(make_transform_dialog(Xen_boolean_to_C_bool(managed))));
2152 }
2153 
2154 
g_print_dialog(Xen managed,Xen direct_to_printer)2155 static Xen g_print_dialog(Xen managed, Xen direct_to_printer)
2156 {
2157   #define H_print_dialog "(" S_print_dialog " :optional managed direct): start the File Print dialog"
2158   Xen_check_type(Xen_is_boolean_or_unbound(managed), managed, 1, S_print_dialog, "a boolean");
2159   Xen_check_type(Xen_is_boolean_or_unbound(direct_to_printer), direct_to_printer, 2, S_print_dialog, "a boolean");
2160   return(Xen_wrap_widget(make_file_print_dialog(!(Xen_is_false(managed)), Xen_is_true(direct_to_printer))));
2161 }
2162 
2163 
g_preferences_dialog(void)2164 static Xen g_preferences_dialog(void)
2165 {
2166   #define H_preferences_dialog "(" S_preferences_dialog "): start the Options:Preferences dialog"
2167   return(Xen_wrap_widget(make_preferences_dialog()));
2168 }
2169 
2170 
g_abortt(void)2171 static Xen g_abortt(void) /* glib now exports g_abort (8-Sep-16) -- perhaps use some other prefix? (g=guile originally) */
2172 {
2173   #define H_abort "(" S_abort "): exit Snd via \"abort\", presumably to land in the debugger"
2174   abort();
2175   return(Xen_false);
2176 }
2177 
2178 
2179 #if (!HAVE_SCHEME)
g_abortq(void)2180 static Xen g_abortq(void)
2181 {
2182   #define H_abortQ "(" S_c_g "): allow pending user interface events to occur, returning " PROC_TRUE " if C-g was typed"
2183   check_for_event();
2184   if ((ss->C_g_typed) ||
2185       (ss->stopped_explicitly))
2186     {
2187       ss->stopped_explicitly = false;
2188       ss->C_g_typed = false;
2189       return(Xen_true);
2190     }
2191   return(Xen_false);
2192 }
2193 #endif
2194 
2195 
Xen_wrap_no_args(g_save_state_file_w,g_save_state_file)2196 Xen_wrap_no_args(g_save_state_file_w, g_save_state_file)
2197 Xen_wrap_1_arg(g_set_save_state_file_w, g_set_save_state_file)
2198 Xen_wrap_no_args(g_save_dir_w, g_save_dir)
2199 Xen_wrap_1_arg(g_set_save_dir_w, g_set_save_dir)
2200 Xen_wrap_no_args(g_open_file_dialog_directory_w, g_open_file_dialog_directory)
2201 Xen_wrap_1_arg(g_set_open_file_dialog_directory_w, g_set_open_file_dialog_directory)
2202 Xen_wrap_no_args(g_peak_env_dir_w, g_peak_env_dir)
2203 Xen_wrap_1_arg(g_set_peak_env_dir_w, g_set_peak_env_dir)
2204 Xen_wrap_no_args(g_temp_dir_w, g_temp_dir)
2205 Xen_wrap_1_arg(g_set_temp_dir_w, g_set_temp_dir)
2206 Xen_wrap_no_args(g_ladspa_dir_w, g_ladspa_dir)
2207 Xen_wrap_1_arg(g_set_ladspa_dir_w, g_set_ladspa_dir)
2208 Xen_wrap_1_optional_arg(g_save_state_w, g_save_state)
2209 Xen_wrap_1_optional_arg(g_exit_w, g_exit)
2210 Xen_wrap_no_args(g_script_arg_w, g_script_arg)
2211 Xen_wrap_1_arg(g_set_script_arg_w, g_set_script_arg)
2212 Xen_wrap_no_args(g_script_args_w, g_script_args)
2213 Xen_wrap_no_args(g_window_x_w, g_window_x)
2214 Xen_wrap_1_arg(g_set_window_x_w, g_set_window_x)
2215 Xen_wrap_no_args(g_window_y_w, g_window_y)
2216 Xen_wrap_1_arg(g_set_window_y_w, g_set_window_y)
2217 Xen_wrap_no_args(g_window_width_w, g_window_width)
2218 Xen_wrap_1_arg(g_set_window_width_w, g_set_window_width)
2219 Xen_wrap_no_args(g_window_height_w, g_window_height)
2220 Xen_wrap_1_arg(g_set_window_height_w, g_set_window_height)
2221 Xen_wrap_no_args(g_just_sounds_w, g_just_sounds)
2222 Xen_wrap_1_arg(g_set_just_sounds_w, g_set_just_sounds)
2223 Xen_wrap_no_args(g_play_arrow_size_w, g_play_arrow_size)
2224 Xen_wrap_1_arg(g_set_play_arrow_size_w, g_set_play_arrow_size)
2225 Xen_wrap_no_args(g_with_inset_graph_w, g_with_inset_graph)
2226 Xen_wrap_1_arg(g_set_with_inset_graph_w, g_set_with_inset_graph)
2227 Xen_wrap_no_args(g_with_interrupts_w, g_with_interrupts)
2228 Xen_wrap_1_arg(g_set_with_interrupts_w, g_set_with_interrupts)
2229 Xen_wrap_no_args(g_with_smpte_label_w, g_with_smpte_label)
2230 Xen_wrap_1_arg(g_set_with_smpte_label_w, g_set_with_smpte_label)
2231 Xen_wrap_no_args(g_with_pointer_focus_w, g_with_pointer_focus)
2232 Xen_wrap_1_arg(g_set_with_pointer_focus_w, g_set_with_pointer_focus)
2233 Xen_wrap_no_args(g_auto_resize_w, g_auto_resize)
2234 Xen_wrap_1_arg(g_set_auto_resize_w, g_set_auto_resize)
2235 Xen_wrap_no_args(g_color_cutoff_w, g_color_cutoff)
2236 Xen_wrap_1_arg(g_set_color_cutoff_w, g_set_color_cutoff)
2237 Xen_wrap_no_args(g_color_inverted_w, g_color_inverted)
2238 Xen_wrap_1_arg(g_set_color_inverted_w, g_set_color_inverted)
2239 Xen_wrap_no_args(g_color_scale_w, g_color_scale)
2240 Xen_wrap_1_arg(g_set_color_scale_w, g_set_color_scale)
2241 Xen_wrap_no_args(g_selection_creates_region_w, g_selection_creates_region)
2242 Xen_wrap_1_arg(g_set_selection_creates_region_w, g_set_selection_creates_region)
2243 Xen_wrap_no_args(g_print_length_w, g_print_length)
2244 Xen_wrap_1_arg(g_set_print_length_w, g_set_print_length)
2245 Xen_wrap_no_args(g_show_indices_w, g_show_indices)
2246 Xen_wrap_1_arg(g_set_show_indices_w, g_set_show_indices)
2247 Xen_wrap_no_args(g_with_relative_panes_w, g_with_relative_panes)
2248 Xen_wrap_1_arg(g_set_with_relative_panes_w, g_set_with_relative_panes)
2249 Xen_wrap_no_args(g_with_background_processes_w, g_with_background_processes)
2250 Xen_wrap_1_arg(g_set_with_background_processes_w, g_set_with_background_processes)
2251 Xen_wrap_no_args(g_with_file_monitor_w, g_with_file_monitor)
2252 Xen_wrap_1_arg(g_set_with_file_monitor_w, g_set_with_file_monitor)
2253 Xen_wrap_no_args(g_tiny_font_w, g_tiny_font)
2254 Xen_wrap_1_arg(g_set_tiny_font_w, g_set_tiny_font)
2255 Xen_wrap_no_args(g_peaks_font_w, g_peaks_font)
2256 Xen_wrap_1_arg(g_set_peaks_font_w, g_set_peaks_font)
2257 Xen_wrap_no_args(g_bold_peaks_font_w, g_bold_peaks_font)
2258 Xen_wrap_1_arg(g_set_bold_peaks_font_w, g_set_bold_peaks_font)
2259 Xen_wrap_no_args(g_axis_label_font_w, g_axis_label_font)
2260 Xen_wrap_1_arg(g_set_axis_label_font_w, g_set_axis_label_font)
2261 Xen_wrap_no_args(g_axis_numbers_font_w, g_axis_numbers_font)
2262 Xen_wrap_1_arg(g_set_axis_numbers_font_w, g_set_axis_numbers_font)
2263 Xen_wrap_no_args(g_listener_font_w, g_listener_font)
2264 Xen_wrap_1_arg(g_set_listener_font_w, g_set_listener_font)
2265 Xen_wrap_no_args(g_snd_version_w, g_snd_version)
2266 Xen_wrap_1_optional_arg(g_color_orientation_dialog_w, g_color_orientation_dialog)
2267 Xen_wrap_1_optional_arg(g_transform_dialog_w, g_transform_dialog)
2268 Xen_wrap_2_optional_args(g_print_dialog_w, g_print_dialog)
2269 Xen_wrap_no_args(g_preferences_dialog_w, g_preferences_dialog)
2270 Xen_wrap_no_args(g_abort_w, g_abortt)
2271 #if (!HAVE_SCHEME)
2272 Xen_wrap_no_args(g_abortq_w, g_abortq)
2273 #endif
2274 
2275 #if HAVE_SCHEME
2276 static s7_pointer acc_temp_dir(s7_scheme *sc, s7_pointer args) {return(g_set_temp_dir(s7_cadr(args)));}
acc_save_dir(s7_scheme * sc,s7_pointer args)2277 static s7_pointer acc_save_dir(s7_scheme *sc, s7_pointer args) {return(g_set_save_dir(s7_cadr(args)));}
acc_ladspa_dir(s7_scheme * sc,s7_pointer args)2278 static s7_pointer acc_ladspa_dir(s7_scheme *sc, s7_pointer args) {return(g_set_ladspa_dir(s7_cadr(args)));}
acc_peak_env_dir(s7_scheme * sc,s7_pointer args)2279 static s7_pointer acc_peak_env_dir(s7_scheme *sc, s7_pointer args) {return(g_set_peak_env_dir(s7_cadr(args)));}
acc_listener_font(s7_scheme * sc,s7_pointer args)2280 static s7_pointer acc_listener_font(s7_scheme *sc, s7_pointer args) {return(g_set_listener_font(s7_cadr(args)));}
acc_axis_label_font(s7_scheme * sc,s7_pointer args)2281 static s7_pointer acc_axis_label_font(s7_scheme *sc, s7_pointer args) {return(g_set_axis_label_font(s7_cadr(args)));}
acc_axis_numbers_font(s7_scheme * sc,s7_pointer args)2282 static s7_pointer acc_axis_numbers_font(s7_scheme *sc, s7_pointer args) {return(g_set_axis_numbers_font(s7_cadr(args)));}
acc_tiny_font(s7_scheme * sc,s7_pointer args)2283 static s7_pointer acc_tiny_font(s7_scheme *sc, s7_pointer args) {return(g_set_tiny_font(s7_cadr(args)));}
acc_peaks_font(s7_scheme * sc,s7_pointer args)2284 static s7_pointer acc_peaks_font(s7_scheme *sc, s7_pointer args) {return(g_set_peaks_font(s7_cadr(args)));}
acc_bold_peaks_font(s7_scheme * sc,s7_pointer args)2285 static s7_pointer acc_bold_peaks_font(s7_scheme *sc, s7_pointer args) {return(g_set_bold_peaks_font(s7_cadr(args)));}
acc_with_inset_graph(s7_scheme * sc,s7_pointer args)2286 static s7_pointer acc_with_inset_graph(s7_scheme *sc, s7_pointer args) {return(g_set_with_inset_graph(s7_cadr(args)));}
acc_with_pointer_focus(s7_scheme * sc,s7_pointer args)2287 static s7_pointer acc_with_pointer_focus(s7_scheme *sc, s7_pointer args) {return(g_set_with_pointer_focus(s7_cadr(args)));}
acc_with_smpte_label(s7_scheme * sc,s7_pointer args)2288 static s7_pointer acc_with_smpte_label(s7_scheme *sc, s7_pointer args) {return(g_set_with_smpte_label(s7_cadr(args)));}
acc_with_interrupts(s7_scheme * sc,s7_pointer args)2289 static s7_pointer acc_with_interrupts(s7_scheme *sc, s7_pointer args) {return(g_set_with_interrupts(s7_cadr(args)));}
acc_color_scale(s7_scheme * sc,s7_pointer args)2290 static s7_pointer acc_color_scale(s7_scheme *sc, s7_pointer args) {return(g_set_color_scale(s7_cadr(args)));}
acc_color_cutoff(s7_scheme * sc,s7_pointer args)2291 static s7_pointer acc_color_cutoff(s7_scheme *sc, s7_pointer args) {return(g_set_color_cutoff(s7_cadr(args)));}
acc_color_inverted(s7_scheme * sc,s7_pointer args)2292 static s7_pointer acc_color_inverted(s7_scheme *sc, s7_pointer args) {return(g_set_color_inverted(s7_cadr(args)));}
acc_auto_resize(s7_scheme * sc,s7_pointer args)2293 static s7_pointer acc_auto_resize(s7_scheme *sc, s7_pointer args) {return(g_set_auto_resize(s7_cadr(args)));}
acc_print_length(s7_scheme * sc,s7_pointer args)2294 static s7_pointer acc_print_length(s7_scheme *sc, s7_pointer args) {return(g_set_print_length(s7_cadr(args)));}
acc_selection_creates_region(s7_scheme * sc,s7_pointer args)2295 static s7_pointer acc_selection_creates_region(s7_scheme *sc, s7_pointer args) {return(g_set_selection_creates_region(s7_cadr(args)));}
acc_save_state_file(s7_scheme * sc,s7_pointer args)2296 static s7_pointer acc_save_state_file(s7_scheme *sc, s7_pointer args) {return(g_set_save_state_file(s7_cadr(args)));}
acc_with_background_processes(s7_scheme * sc,s7_pointer args)2297 static s7_pointer acc_with_background_processes(s7_scheme *sc, s7_pointer args) {return(g_set_with_background_processes(s7_cadr(args)));}
acc_with_file_monitor(s7_scheme * sc,s7_pointer args)2298 static s7_pointer acc_with_file_monitor(s7_scheme *sc, s7_pointer args) {return(g_set_with_file_monitor(s7_cadr(args)));}
acc_show_indices(s7_scheme * sc,s7_pointer args)2299 static s7_pointer acc_show_indices(s7_scheme *sc, s7_pointer args) {return(g_set_show_indices(s7_cadr(args)));}
acc_just_sounds(s7_scheme * sc,s7_pointer args)2300 static s7_pointer acc_just_sounds(s7_scheme *sc, s7_pointer args) {return(g_set_just_sounds(s7_cadr(args)));}
acc_play_arrow_size(s7_scheme * sc,s7_pointer args)2301 static s7_pointer acc_play_arrow_size(s7_scheme *sc, s7_pointer args) {return(g_set_play_arrow_size(s7_cadr(args)));}
acc_with_relative_panes(s7_scheme * sc,s7_pointer args)2302 static s7_pointer acc_with_relative_panes(s7_scheme *sc, s7_pointer args) {return(g_set_with_relative_panes(s7_cadr(args)));}
acc_open_file_dialog_directory(s7_scheme * sc,s7_pointer args)2303 static s7_pointer acc_open_file_dialog_directory(s7_scheme *sc, s7_pointer args) {return(g_set_open_file_dialog_directory(s7_cadr(args)));}
2304 #endif
2305 
2306 
g_init_main(void)2307 void g_init_main(void)
2308 {
2309 #if HAVE_SCHEME
2310   s7_pointer pl_b, pl_bb, pl_i, pl_ii, pl_bi, pl_s, pl_ss, pl_d, pl_dr, pl_p, pl_z, pl_zb, pl_zbb;
2311   {
2312     s7_pointer i, b, d, r, s, p, z;
2313     i = s7_make_symbol(s7, "integer?");
2314     b = s7_make_symbol(s7, "boolean?");
2315     d = s7_make_symbol(s7, "float?");
2316     r = s7_make_symbol(s7, "real?");
2317     s = s7_make_symbol(s7, "string?");
2318     p = s7_make_symbol(s7, "pair?");
2319 
2320     z = s7_make_signature(s7, 2, p, b);
2321     pl_b = s7_make_signature(s7, 1, b);
2322     pl_bb = s7_make_signature(s7, 2, b, b);
2323     pl_i = s7_make_signature(s7, 1, i);
2324     pl_ii = s7_make_signature(s7, 2, i, i);
2325     pl_bi = s7_make_signature(s7, 2, b, i);
2326     pl_s = s7_make_signature(s7, 1, s);
2327     pl_ss = s7_make_signature(s7, 2, s, s);
2328     pl_d = s7_make_signature(s7, 1, d);
2329     pl_dr = s7_make_signature(s7, 2, d, r);
2330     pl_p = s7_make_signature(s7, 1, p);
2331     pl_z = s7_make_signature(s7, 1, z);
2332     pl_zb = s7_make_signature(s7, 2, z, b);
2333     pl_zbb = s7_make_signature(s7, 3, z, b, b);
2334   }
2335 #endif
2336   Xen_define_typed_procedure(S_save_state,   g_save_state_w,   0, 1, 0, H_save_state, pl_ss);
2337 #if HAVE_FORTH			/* exit is an existing word */
2338   Xen_define_typed_procedure("snd-" S_exit,  g_exit_w,         0, 1, 0, H_exit, pl_bi);
2339 #else
2340   Xen_define_typed_procedure(S_exit,         g_exit_w,         0, 1, 0, H_exit, pl_bi);
2341 #endif
2342 
2343   Xen_define_typed_dilambda(S_save_state_file, g_save_state_file_w, H_save_state_file,
2344 			    S_set S_save_state_file, g_set_save_state_file_w, 0, 0, 1, 0, pl_s, pl_ss);
2345   Xen_define_typed_dilambda(S_save_dir, g_save_dir_w, H_save_dir,
2346 			    S_set S_save_dir, g_set_save_dir_w,  0, 0, 1, 0, pl_s, pl_ss);
2347 
2348   Xen_define_typed_dilambda(S_open_file_dialog_directory, g_open_file_dialog_directory_w, H_open_file_dialog_directory,
2349 			    S_set S_open_file_dialog_directory, g_set_open_file_dialog_directory_w,  0, 0, 1, 0, pl_s, pl_ss);
2350 
2351   Xen_define_typed_dilambda(S_peak_env_dir, g_peak_env_dir_w, H_peak_env_dir,
2352 			    S_set S_peak_env_dir, g_set_peak_env_dir_w,  0, 0, 1, 0, pl_s, pl_ss);
2353   Xen_define_typed_dilambda(S_temp_dir, g_temp_dir_w, H_temp_dir,
2354 			    S_set S_temp_dir, g_set_temp_dir_w,  0, 0, 1, 0, pl_s, pl_ss);
2355   Xen_define_typed_dilambda(S_ladspa_dir, g_ladspa_dir_w, H_ladspa_dir,
2356 			    S_set S_ladspa_dir, g_set_ladspa_dir_w,  0, 0, 1, 0, pl_s, pl_ss);
2357 
2358   #define H_before_exit_hook S_before_exit_hook " (): called upon exit. If it returns " PROC_TRUE ", Snd does not exit."
2359 
2360   before_exit_hook = Xen_define_hook(S_before_exit_hook, "(make-hook)", 0, H_before_exit_hook);
2361 
2362   #define H_exit_hook S_exit_hook " (): called upon exit.  This can be used to perform cleanup activities."
2363 
2364   exit_hook = Xen_define_hook(S_exit_hook, "(make-hook)", 0, H_exit_hook);
2365 
2366   #define H_after_save_state_hook S_after_save_state_hook " (name): called after Snd state has been saved; filename is the save state file."
2367   after_save_state_hook = Xen_define_hook(S_after_save_state_hook, "(make-hook 'name)", 1, H_after_save_state_hook);
2368 
2369   #define H_before_save_state_hook S_before_save_state_hook " (name): called before Snd state is saved. If \
2370 the hook functions return " PROC_TRUE ", the save state process opens the file 'name' for appending, rather than truncating."
2371   before_save_state_hook = Xen_define_hook(S_before_save_state_hook, "(make-hook 'name)", 1, H_before_save_state_hook);
2372 
2373   Xen_define_typed_dilambda(S_script_arg, g_script_arg_w, H_script_arg,
2374 			    S_set S_script_arg, g_set_script_arg_w,  0, 0, 1, 0, pl_i, pl_ii);
2375   Xen_define_typed_procedure(S_script_args, g_script_args_w, 0, 0, 0, H_script_args, pl_p);
2376 
2377   Xen_define_typed_dilambda(S_window_x, g_window_x_w, H_window_x,
2378 			    S_set S_window_x, g_set_window_x_w,  0, 0, 1, 0, pl_i, pl_ii);
2379   Xen_define_typed_dilambda(S_window_y, g_window_y_w, H_window_y,
2380 			    S_set S_window_y, g_set_window_y_w,  0, 0, 1, 0, pl_i, pl_ii);
2381   Xen_define_typed_dilambda(S_window_width, g_window_width_w, H_window_width,
2382 			    S_set S_window_width, g_set_window_width_w,  0, 0, 1, 0, pl_i, pl_ii);
2383   Xen_define_typed_dilambda(S_window_height, g_window_height_w, H_window_height,
2384 			    S_set S_window_height, g_set_window_height_w,  0, 0, 1, 0, pl_i, pl_ii);
2385 
2386   Xen_define_typed_dilambda(S_auto_resize, g_auto_resize_w, H_auto_resize,
2387 			    S_set S_auto_resize, g_set_auto_resize_w,  0, 0, 1, 0, pl_b, pl_bb);
2388   Xen_define_typed_dilambda(S_color_cutoff, g_color_cutoff_w, H_color_cutoff,
2389 			    S_set S_color_cutoff, g_set_color_cutoff_w,  0, 0, 1, 0, pl_d, pl_dr);
2390   Xen_define_typed_dilambda(S_color_inverted, g_color_inverted_w, H_color_inverted,
2391 			    S_set S_color_inverted, g_set_color_inverted_w,  0, 0, 1, 0, pl_b, pl_bb);
2392   Xen_define_typed_dilambda(S_color_scale, g_color_scale_w, H_color_scale,
2393 			    S_set S_color_scale, g_set_color_scale_w,  0, 0, 1, 0, pl_d, pl_dr);
2394 
2395   Xen_define_typed_dilambda(S_selection_creates_region, g_selection_creates_region_w, H_selection_creates_region,
2396 			    S_set S_selection_creates_region, g_set_selection_creates_region_w,  0, 0, 1, 0, pl_b, pl_bb);
2397 
2398   Xen_define_typed_dilambda(S_print_length, g_print_length_w, H_print_length,
2399 			    S_set S_print_length, g_set_print_length_w,  0, 0, 1, 0, pl_i, pl_ii);
2400   Xen_define_typed_dilambda(S_show_indices, g_show_indices_w, H_show_indices,
2401 			    S_set S_show_indices, g_set_show_indices_w,  0, 0, 1, 0, pl_b, pl_bb);
2402 
2403   Xen_define_typed_dilambda(S_with_relative_panes, g_with_relative_panes_w, H_with_relative_panes,
2404 			    S_set S_with_relative_panes, g_set_with_relative_panes_w,  0, 0, 1, 0, pl_b, pl_bb);
2405 
2406   Xen_define_typed_dilambda(S_with_background_processes, g_with_background_processes_w, H_with_background_processes,
2407 			    S_set S_with_background_processes, g_set_with_background_processes_w,  0, 0, 1, 0, pl_b, pl_bb);
2408 
2409   Xen_define_typed_dilambda(S_with_file_monitor, g_with_file_monitor_w, H_with_file_monitor,
2410 			    S_set S_with_file_monitor, g_set_with_file_monitor_w,  0, 0, 1, 0, pl_b, pl_bb);
2411   Xen_define_typed_dilambda(S_tiny_font, g_tiny_font_w, H_tiny_font,
2412 			    S_set S_tiny_font, g_set_tiny_font_w,  0, 0, 1, 0, pl_s, pl_ss);
2413   Xen_define_typed_dilambda(S_peaks_font, g_peaks_font_w, H_peaks_font,
2414 			    S_set S_peaks_font, g_set_peaks_font_w,  0, 0, 1, 0, pl_s, pl_ss);
2415   Xen_define_typed_dilambda(S_bold_peaks_font, g_bold_peaks_font_w, H_bold_peaks_font,
2416 			    S_set S_bold_peaks_font, g_set_bold_peaks_font_w,  0, 0, 1, 0, pl_s, pl_ss);
2417   Xen_define_typed_dilambda(S_axis_label_font, g_axis_label_font_w, H_axis_label_font,
2418 			    S_set S_axis_label_font, g_set_axis_label_font_w,  0, 0, 1, 0, pl_s, pl_ss);
2419   Xen_define_typed_dilambda(S_axis_numbers_font, g_axis_numbers_font_w, H_axis_numbers_font,
2420 			    S_set S_axis_numbers_font, g_set_axis_numbers_font_w,  0, 0, 1, 0, pl_s, pl_ss);
2421   Xen_define_typed_dilambda(S_listener_font, g_listener_font_w, H_listener_font,
2422 			    S_set S_listener_font, g_set_listener_font_w,  0, 0, 1, 0, pl_s, pl_ss);
2423   Xen_define_typed_dilambda(S_just_sounds, g_just_sounds_w, H_just_sounds,
2424 			    S_set S_just_sounds, g_set_just_sounds_w,  0, 0, 1, 0, pl_b, pl_bb);
2425   Xen_define_typed_dilambda(S_play_arrow_size, g_play_arrow_size_w, H_play_arrow_size,
2426 			    S_set S_play_arrow_size, g_set_play_arrow_size_w,  0, 0, 1, 0, pl_i, pl_ii);
2427   Xen_define_typed_dilambda(S_with_inset_graph, g_with_inset_graph_w, H_with_inset_graph,
2428 			    S_set S_with_inset_graph, g_set_with_inset_graph_w,  0, 0, 1, 0, pl_b, pl_bb);
2429   Xen_define_typed_dilambda(S_with_interrupts, g_with_interrupts_w, H_with_interrupts,
2430 			    S_set S_with_interrupts, g_set_with_interrupts_w,  0, 0, 1, 0, pl_b, pl_bb);
2431   Xen_define_typed_dilambda(S_with_smpte_label, g_with_smpte_label_w, H_with_smpte_label,
2432 			    S_set S_with_smpte_label, g_set_with_smpte_label_w,  0, 0, 1, 0, pl_b, pl_bb);
2433   Xen_define_typed_dilambda(S_with_pointer_focus, g_with_pointer_focus_w, H_with_pointer_focus,
2434 			    S_set S_with_pointer_focus, g_set_with_pointer_focus_w,  0, 0, 1, 0, pl_b, pl_bb);
2435 
2436   Xen_define_typed_procedure(S_snd_version,		g_snd_version_w,              0, 0, 0, H_snd_version,		   pl_s);
2437   Xen_define_typed_procedure(S_color_orientation_dialog,g_color_orientation_dialog_w, 0, 1, 0, H_color_orientation_dialog, pl_zb);
2438   Xen_define_typed_procedure(S_transform_dialog,        g_transform_dialog_w,         0, 1, 0, H_transform_dialog,	   pl_zb);
2439   Xen_define_typed_procedure(S_print_dialog,            g_print_dialog_w,             0, 2, 0, H_print_dialog,		   pl_zbb);
2440   Xen_define_typed_procedure(S_preferences_dialog,      g_preferences_dialog_w,       0, 0, 0, H_preferences_dialog,	   pl_z);
2441   Xen_define_typed_procedure(S_abort,			g_abort_w,                    0, 0, 0, H_abort,                    pl_b);
2442 #if (!HAVE_SCHEME)
2443   Xen_define_typed_procedure(S_c_g,			g_abortq_w,                   0, 0, 0, H_abortQ,                   pl_b);
2444 #endif
2445 
2446 #if HAVE_SCHEME
2447   s7_set_documentation(s7, ss->temp_dir_symbol, "*temp-dir*: name of directory for temp files (or #f=null)");
2448   s7_set_documentation(s7, ss->save_dir_symbol, "*save-dir*: name of directory for saved state data (or #f=null)");
2449   s7_set_documentation(s7, ss->ladspa_dir_symbol, "*ladspa-dir*: name of directory for ladspa plugin libraries");
2450   s7_set_documentation(s7, ss->peak_env_dir_symbol, "*peak-env-dir*: name of directory for peak env files (or #f=null)");
2451   s7_set_documentation(s7, ss->listener_font_symbol, "*listener-font*: font used by the lisp listener");
2452   s7_set_documentation(s7, ss->axis_label_font_symbol, "*axis-label-font*: font used for axis labels");
2453   s7_set_documentation(s7, ss->axis_numbers_font_symbol, "*axis-numbers-font*: font used for axis numbers");
2454   s7_set_documentation(s7, ss->tiny_font_symbol, "*tiny-font*: font use for some info in the graphs");
2455   s7_set_documentation(s7, ss->peaks_font_symbol, "*peaks-font*: normal font used by fft peak display");
2456   s7_set_documentation(s7, ss->bold_peaks_font_symbol, "*bold-peaks-font*: bold font used by fft peak display");
2457   s7_set_documentation(s7, ss->with_inset_graph_symbol, "*with-inset-graph*: if #t, display the inset graph in the time domain section.");
2458   s7_set_documentation(s7, ss->with_pointer_focus_symbol, "*with-pointer-focus*: if #t, activate the text or graph widget beneath the mouse.");
2459   s7_set_documentation(s7, ss->with_smpte_label_symbol, "*with-smpte-label*: if #t, display the SMPTE data in the time domain section.");
2460   s7_set_documentation(s7, ss->with_interrupts_symbol, "*with-interrupts*: if #t, check for GUI events during computations.");
2461   s7_set_documentation(s7, ss->color_scale_symbol, "*color-scale*: darkness setting for colormaps (0.5)");
2462   s7_set_documentation(s7, ss->color_cutoff_symbol, "*color-cutoff*: color map cutoff point (default .003).");
2463   s7_set_documentation(s7, ss->color_inverted_symbol, "*color-inverted*: whether the colormap in operation should be inverted");
2464   s7_set_documentation(s7, ss->auto_resize_symbol, "*auto-resize*: #t if Snd can change its main window size as it pleases");
2465   s7_set_documentation(s7, ss->print_length_symbol, "*print-length*: number of vector elements to print in the listener (12)");
2466   s7_set_documentation(s7, ss->selection_creates_region_symbol, "*selection-creates-region*: #t if a region should be created each time a selection is made.");
2467   s7_set_documentation(s7, ss->save_state_file_symbol, "*save-state-file*: the name of the saved state file (\"saved-snd.scm\")");
2468   s7_set_documentation(s7, ss->with_background_processes_symbol, "*with-background-processes*: #t if Snd should use background (idle time) processing");
2469   s7_set_documentation(s7, ss->with_file_monitor_symbol, "*with-file-monitor*: #t if the file alteration monitor is active");
2470   s7_set_documentation(s7, ss->show_indices_symbol, "*show-indices*: #t if sound name should be preceded by its index in the sound display.");
2471   s7_set_documentation(s7, ss->just_sounds_symbol, "*just-sounds*: the 'just sounds' choice in the file chooser dialog");
2472   s7_set_documentation(s7, ss->play_arrow_size_symbol, "*play-arrow-size*: the size of the play triangles");
2473   s7_set_documentation(s7, ss->with_relative_panes_symbol, "*with-relative-panes*: #t if multichannel sounds should try to maintain relative pane sizes");
2474   s7_set_documentation(s7, ss->open_file_dialog_directory_symbol, "*open-file-dialog-directory*: name of directory for initial open file dialog search");
2475 
2476   s7_set_setter(s7, ss->temp_dir_symbol, s7_make_function(s7, "[acc-" S_temp_dir "]", acc_temp_dir, 2, 0, false, "accessor"));
2477   s7_set_setter(s7, ss->save_dir_symbol, s7_make_function(s7, "[acc-" S_save_dir "]", acc_save_dir, 2, 0, false, "accessor"));
2478   s7_set_setter(s7, ss->ladspa_dir_symbol, s7_make_function(s7, "[acc-" S_ladspa_dir "]", acc_ladspa_dir, 2, 0, false, "accessor"));
2479   s7_set_setter(s7, ss->peak_env_dir_symbol, s7_make_function(s7, "[acc-" S_peak_env_dir "]", acc_peak_env_dir, 2, 0, false, "accessor"));
2480   s7_set_setter(s7, ss->listener_font_symbol, s7_make_function(s7, "[acc-" S_listener_font "]", acc_listener_font, 2, 0, false, "accessor"));
2481   s7_set_setter(s7, ss->axis_label_font_symbol, s7_make_function(s7, "[acc-" S_axis_label_font "]", acc_axis_label_font, 2, 0, false, "accessor"));
2482   s7_set_setter(s7, ss->axis_numbers_font_symbol, s7_make_function(s7, "[acc-" S_axis_numbers_font "]", acc_axis_numbers_font, 2, 0, false, "accessor"));
2483   s7_set_setter(s7, ss->tiny_font_symbol, s7_make_function(s7, "[acc-" S_tiny_font "]", acc_tiny_font, 2, 0, false, "accessor"));
2484   s7_set_setter(s7, ss->peaks_font_symbol, s7_make_function(s7, "[acc-" S_peaks_font "]", acc_peaks_font, 2, 0, false, "accessor"));
2485   s7_set_setter(s7, ss->bold_peaks_font_symbol, s7_make_function(s7, "[acc-" S_bold_peaks_font "]", acc_bold_peaks_font, 2, 0, false, "accessor"));
2486   s7_set_setter(s7, ss->with_inset_graph_symbol, s7_make_function(s7, "[acc-" S_with_inset_graph "]", acc_with_inset_graph, 2, 0, false, "accessor"));
2487   s7_set_setter(s7, ss->with_pointer_focus_symbol, s7_make_function(s7, "[acc-" S_with_pointer_focus "]", acc_with_pointer_focus, 2, 0, false, "accessor"));
2488   s7_set_setter(s7, ss->with_smpte_label_symbol, s7_make_function(s7, "[acc-" S_with_smpte_label "]", acc_with_smpte_label, 2, 0, false, "accessor"));
2489   s7_set_setter(s7, ss->with_interrupts_symbol, s7_make_function(s7, "[acc-" S_with_interrupts "]", acc_with_interrupts, 2, 0, false, "accessor"));
2490   s7_set_setter(s7, ss->color_scale_symbol, s7_make_function(s7, "[acc-" S_color_scale "]", acc_color_scale, 2, 0, false, "accessor"));
2491   s7_set_setter(s7, ss->color_cutoff_symbol, s7_make_function(s7, "[acc-" S_color_cutoff "]", acc_color_cutoff, 2, 0, false, "accessor"));
2492   s7_set_setter(s7, ss->color_inverted_symbol, s7_make_function(s7, "[acc-" S_color_inverted "]", acc_color_inverted, 2, 0, false, "accessor"));
2493   s7_set_setter(s7, ss->auto_resize_symbol, s7_make_function(s7, "[acc-" S_auto_resize "]", acc_auto_resize, 2, 0, false, "accessor"));
2494   s7_set_setter(s7, ss->print_length_symbol, s7_make_function(s7, "[acc-" S_print_length "]", acc_print_length, 2, 0, false, "accessor"));
2495   s7_set_setter(s7, ss->selection_creates_region_symbol, s7_make_function(s7, "[acc-" S_selection_creates_region "]", acc_selection_creates_region, 2, 0, false, "accessor"));
2496   s7_set_setter(s7, ss->save_state_file_symbol, s7_make_function(s7, "[acc-" S_save_state_file "]", acc_save_state_file, 2, 0, false, "accessor"));
2497   s7_set_setter(s7, ss->with_background_processes_symbol, s7_make_function(s7, "[acc-" S_with_background_processes "]", acc_with_background_processes, 2, 0, false, "accessor"));
2498   s7_set_setter(s7, ss->with_file_monitor_symbol, s7_make_function(s7, "[acc-" S_with_file_monitor "]", acc_with_file_monitor, 2, 0, false, "accessor"));
2499   s7_set_setter(s7, ss->show_indices_symbol, s7_make_function(s7, "[acc-" S_show_indices "]", acc_show_indices, 2, 0, false, "accessor"));
2500   s7_set_setter(s7, ss->just_sounds_symbol, s7_make_function(s7, "[acc-" S_just_sounds "]", acc_just_sounds, 2, 0, false, "accessor"));
2501   s7_set_setter(s7, ss->play_arrow_size_symbol, s7_make_function(s7, "[acc-" S_play_arrow_size "]", acc_play_arrow_size, 2, 0, false, "accessor"));
2502   s7_set_setter(s7, ss->with_relative_panes_symbol, s7_make_function(s7, "[acc-" S_with_relative_panes "]", acc_with_relative_panes, 2, 0, false, "accessor"));
2503   s7_set_setter(s7, ss->open_file_dialog_directory_symbol, s7_make_function(s7, "[acc-" S_open_file_dialog_directory "]", acc_open_file_dialog_directory, 2, 0, false, "accessor"));
2504 #endif
2505 }
2506