#include "snd.h"

#define CLM_BUFFER_SIZE 16384
static char *clm_buffer = NULL;
static int clm_buffer_size = 0;

int *clm_snd_data(snd_state *ss, int *length)
{
  int *arr;
  int i,j,beg,ints,blen,len;
  if (!clm_buffer) 
    {
      clm_buffer = (char *)snd_calloc(ss,CLM_BUFFER_SIZE,sizeof(char));
      clm_buffer_size = CLM_BUFFER_SIZE;
    }
  write(ss->to_clm,"nil",4);
  read(ss->from_clm,clm_buffer,4);
  len = big_endian_int(*((int *)clm_buffer));
  (*length) = len;
  blen = (clm_buffer_size/4);
  arr = (int *)snd_calloc(ss,len,sizeof(int));
  for (beg=0;beg<len;beg+=blen)
    {
      read(ss->from_clm,clm_buffer,clm_buffer_size);
      ints = len-beg;
      if (ints > blen) ints=blen;
      for (i=0,j=0;i<ints;i++,j+=4) arr[i+beg] = big_endian_int(*((int *)(clm_buffer+j)));
    }
  return(arr);
}

void snd_clm_data (snd_state *ss, int len, int *data)
{
  int beg,ints,blen,val;
  val = big_endian_int(len);
  write(ss->to_clm,(char *)(&val),4);
  blen = (clm_buffer_size/4);
#ifdef CLM_LITTLE_ENDIAN
  for (beg=0;beg<len;beg++)
    data[beg] = big_endian_int(data[beg]);
#endif
  for (beg=0;beg<len;beg+=blen)
    {
      ints = len-beg;
      if (ints > blen) ints=blen;
      write(ss->to_clm,(char *)(data+beg),ints*4);
    }
}

int get_clm_string(snd_state *ss, int fd, int from_clm)
{
  /* communication is via lisp expressions except for the find exprs -- these are in the C subset used by find */
  int bytes,i,j,k,m,n,start,commenting,len,parens,quoting,loop_start;
  char *tmp;
  if (!clm_buffer)
    {
      clm_buffer = (char *)snd_calloc(ss,CLM_BUFFER_SIZE,sizeof(char));
      clm_buffer_size = CLM_BUFFER_SIZE;
    }
  bytes=read(fd,clm_buffer,clm_buffer_size);
  if (bytes == 0) return(0);
  clm_buffer[bytes] = '\0';
  commenting = 0;
  parens = 0;
  quoting = FALSE;
  start = 0;
  loop_start = 0;
READ_CLM:
  for (i=loop_start;i<bytes;i++)
    {
      if (!quoting)
	{
	  if ((commenting == 0) && (clm_buffer[i] == ';')) commenting = 1;
	  else if ((commenting == 1) && (clm_buffer[i] == '\n')) commenting = 0;
	  else if ((commenting == 0) && (clm_buffer[i] == '#') && (clm_buffer[i+1] == '|')) commenting = 2;
	  else if ((commenting == 2) && (clm_buffer[i] == '|') && (clm_buffer[i+1] == '#')) commenting = 0;
	}
      if (clm_buffer[i] == '\"') quoting = (!quoting);
      if (commenting == 0)
	{
	  if (clm_buffer[i] == '(') {if (parens == 0) start = i; parens++;}
	  else if (clm_buffer[i] == ')') 
	    {
	      parens--; 
	      if (parens == 0) 
		{
		  tmp = (char *)calloc(i-start+2,sizeof(char));
		  for (m=0,n=start;n<=i;m++,n++) tmp[m] = clm_buffer[n];
		  tmp[m]='\0';
		  clm_doit(ss,tmp,from_clm);
		  free(tmp);
		}
	    }
	}
    }
  if (parens)
    {
      if (start != 0)
	for (i=start,j=0;i<bytes;i++,j++) clm_buffer[j] = clm_buffer[i];
      len = bytes - start;
      if (len == clm_buffer_size)
	{
	  clm_buffer_size *= 2;
	  clm_buffer = (char *)snd_realloc(ss,clm_buffer,clm_buffer_size*sizeof(char));
	}
      clm_buffer[len] = '\0';
      loop_start = len;
      k = read(fd,(char *)(clm_buffer+len),clm_buffer_size - len);
      if (k <= 0) 
	{
	  fprintf(stderr,snd_string_error_reading_file_extra_open_paren);
	  fprintf(stderr,"\ncurrent expression started at byte %d\n",start);
	  return(0); /* this ends the read loops below */
	}
      bytes = len + k;
      goto READ_CLM;
    }
  return(bytes);
}

void clm_snd_replace_samples(snd_state *ss, char *tempf, snd_info *sp)
{
  int err,i,num=1;
  char *ofile = NULL;
  /* sequester tempf so repeated clm with-sounds don't walk on previous edits */
  ofile = snd_tempnam(temp_dir(ss),"snd_"); 
  if ((err = (rename(tempf,ofile))))
    {
      if (errno == EXDEV) 
	{
	  err = copy_file(tempf,ofile,sp); 
	  if (!err) err = remove(tempf);
	}
      else 
	{
	  free(ofile); 
	  num=0;
	  ofile = tempf;
	}
    }
  for (i=0;i<sp->nchans;i++)
    {
      /* samples as -1 means use current tempfile read_header result in this case */
      file_override_samples(-1,ofile,sp->chans[i],i,(i == 0) ? DELETE_ME : DONT_DELETE_ME,LOCK_MIXES,"(clm-snd-replace-samples)");
    }
  if (num) free(ofile);
}

#if (!HAVE_GUILE)

static char clm_white_space[4]={' ','\t','\n',')'};
/* static char clm_open_paren[1] = {'('}; */
static char clm_null_string[1] = {'\0'};

#define RES_SIZE 512
static char res_buf[RES_SIZE];

static void display_results(snd_state *ss, char *msg)
{
  if (ss->respond_to_clm)
    write(ss->to_clm,msg,strlen(msg)+1);
  else
    {
      if (ss->mx_sp) 
	report_in_minibuffer(ss->mx_sp,msg);
      if (ss->listening)
	{
	  ss->result_printout = 1;
	  snd_append_command(ss,msg);
	}
    }
}

static void fsym(snd_state *ss, float val)
{
  sprintf(res_buf,"%f",val);
  display_results(ss,res_buf);
}

static void isym(snd_state *ss, int val)
{
  sprintf(res_buf,"%d",val);
  display_results(ss,res_buf);
}

static void ssym(snd_state *ss, char *val)
{
  sprintf(res_buf,"\"%s\"",val);
  display_results(ss,res_buf);
}

static float fstr(char *str)
{
  float val = 0.0;
  if ((str) && (*str)) sscanf(str,"%f",&val);
  return(val);
}

static int istr(char *str)
{
  int val = 0;
  if ((str) && (*str)) sscanf(str,"%d",&val);
  return(val);
}

static char *sstr(char *val)
{
  /* strip off double quotes, if any */
  int len;
  if ((val) && (*val))
    {
      if (val[0] == '\"') val++;
      len = strlen(val);
      if (val[len-1] == '\"') val[len-1] = 0;
    }
  return(val);
}

static void lsym(snd_state *ss, env *e)
{
  char *news;
  if (e)
    {
      news = env_to_string(e);
      if (news)
	{
	  if (ss->mx_sp)
	    report_in_minibuffer(ss->mx_sp,news);
	  else write(ss->to_clm,news,strlen(news)+1);
	  free(news);
	}
    }
}

typedef struct {
  char *name;
  env *val;
} lv;

static int env_table_size = 0;
static int env_table_top = 0;
static lv **env_table = NULL;

static void add_symbol(char *name, env *val)
{
  lv *v;
  if (env_table_top == env_table_size)
    {
      env_table_size += 16;
      if (env_table_top == 0) 
	env_table = (lv **)calloc(env_table_size,sizeof(lv));
      else env_table = (lv **)realloc(env_table,env_table_size * sizeof(lv));
    }
  v = (lv *)calloc(1,sizeof(lv));
  v->name = copy_string(name);
  v->val = copy_env(val);
  env_table[env_table_top] = v;
  env_table_top++;
}

static lv *find_symbol(char *name) 
{
  int i;
  for (i=0;i<env_table_top;i++) 
    if (strcmp(name,env_table[i]->name) == 0) return(env_table[i]);
  return(NULL);
}

static snd_info *get_sp(snd_state *state, char *str)
{
  int snd_n;
  if ((str) && (*str))
    sscanf(str,"%d",&snd_n);
  else 
    if ((state->selected_sound != NO_SELECTION) && (snd_ok(state->sounds[state->selected_sound])))
      snd_n = state->selected_sound;
    else snd_n = 0;
  if ((snd_n < state->max_sounds) && (snd_ok(state->sounds[snd_n])))
    return(state->sounds[snd_n]);
  else return(any_selected_sound(state));
}

static chan_info *get_cp(snd_state *state, char *sstr, char *cstr)
{
  snd_info *sp;
  int chn_n;
  sp = get_sp(state,sstr);
  if (sp) 
    {
      if ((cstr) && (*cstr))
	sscanf(cstr,"%d",&chn_n);
      else
	if (sp->selected_channel != NO_SELECTION) 
	  chn_n = sp->selected_channel;
	else chn_n = 0;
      if (chn_n < sp->nchans) return(sp->chans[chn_n]);
    }
  return(NULL);
}

static mark *get_m(snd_state *state, char *sstr, char *cstr, char *mstr)
{
  chan_info *cp;
  int mn;
  mark **mps;
  cp = get_cp(state,sstr,cstr);
  if ((cp) && (cp->marks))
    {
      mps = cp->marks[cp->edit_ctr];
      if (mps)
	{
	  if (mstr) 
	    sscanf(mstr,"%d",&mn);
	  else mn = 0;
	  return(mps[mn]);
	}
    }
  return(NULL);
}

static void g_save_envelopes(snd_state *state, char *name)
{
  FILE *fd;
  if (name == NULL) name = "envs.save";
  fd = fopen(name,"w");
  if (fd)
    {
      save_envelope_editor_state(state,fd);
      fclose(fd);
    }
}


void g_snd_callback(snd_state *ss, int callb) {}

env *name_to_env(char *str) 
{
  lv *e;
  e = find_symbol(str);
  if (e) return(copy_env(e->val));
  return(NULL);
}

static void pass_name_to_envelope_editor(snd_state *ss, char *fullstr) 
{
  /* fullstr is the incoming "defvar ...)" */
  char *name,*val,*defv;
  env *e;
  defv = strtok(fullstr,clm_white_space);
  name = strtok(NULL,clm_white_space);
  val = strtok(NULL,clm_null_string);
  e = scan_envelope(val);
  if (e)
    {
      alert_envelope_editor(ss,copy_string(name),e);
      add_symbol(name,e);
    }
}

void add_or_edit_symbol(char *name, env *val)
{
  lv *v;
  v = find_symbol(name);
  if (v)
    v->val = copy_env(val);
  else add_symbol(name,val);
}

static int prefix_fix(char *str)
{
  int val = 1;
  if ((str) && (*str)) sscanf(str,"%d",&val);
  return(val);
}

static int symit(snd_state *ss,char **str);

int clm_just_doit(snd_state *ss, char *buf) 
{
  int val;
  /* this is called from the lisp listener when the user has typed in a form (so don't echo it) */
  ss->result_printout = 1;
  val = clm_doit(ss,buf,FALSE);
  ss->result_printout = 0;
  return(val);
}

int clm_doit(snd_state *ss, char *buf, int from_clm)
{
  int i,err = 0;
  char *tmp;
  char *tok[10];
  snd_info *sp;
  chan_info *cp;
  if (buf == NULL) return(0);
  if ((!(from_clm)) && (!(ss->result_printout))) snd_append_command(ss,buf);
  cp = NULL;
  sp = any_selected_sound(ss);
  if (sp) cp = any_selected_channel(sp);
  for (i=0;i<10;i++) tok[i] = NULL;
  /* tmp = strtok(buf,clm_open_paren); */ /* someday I'll understand why this doesn't work... */
  tmp = buf;
  if (tmp[0] == '(') tmp++;
  ss->respond_to_clm = from_clm;
  /* now a kludge to handle the special defvar case */
  if ((snd_strlen(tmp) > 7) && (tmp[0]=='d') && (tmp[1]=='e') && (tmp[2]=='f') && (tmp[3]=='v') && (tmp[4]=='a') && (tmp[5]=='r'))
    {
      pass_name_to_envelope_editor(ss,tmp);
      isym(ss,0);
    }
  else
    {
      tok[0] = strtok(tmp,clm_white_space);
      for (i=1;i<10;i++) 
	{
	  tok[i] = strtok(NULL,clm_white_space);
	  if (tok[i] == NULL) break;
	}
      if (tok[0] == NULL) {fprintf(stderr,"can't parse %s\n",buf); return(-1);}
      err = symit(ss,tok);
      if ((err == -1) && (cp)) err = execute_macro(cp,buf,1);
    }
  ss->respond_to_clm = 0;
  return(err);
}

static int symit(snd_state *ss,char **str)
{
  char *tok,*filename,*tempfile;
  int ival,i,num,len,beg;
  chan_info *cp;
  snd_info *sp;
  mark **mps;
  mark *m;
  float scls[1];
  int *clmvals;
  int ivals[2];
  tok = str[0];
  switch (*tok)
    {
    case 'a':
      if (strcmp(tok,"active-sounds") == 0) 
	{
	  num = 0;
	  for (i=0;i<ss->max_sounds;i++) if (snd_ok(ss->sounds[i])) num++;
	  isym(ss,num);
	  return(0);
	}
      if (strcmp(tok,"add-mark") == 0) {cp = get_cp(ss,str[2],str[3]); if (cp) add_mark(istr(str[1]),NULL,cp); isym(ss,0); return(0);}
      if (strcmp(tok,"add-to-main-menu") == 0) {isym(ss,0); /* noop */ return(0);}
      if (strcmp(tok,"add-to-menu") == 0) {isym(ss,0); /* noop */ return(0);}
      if (strcmp(tok,"aiff-sound-file") == 0) {isym(ss,AIFF_sound_file); return(0);}
      if (strcmp(tok,"amp") == 0) {sp = get_sp(ss,str[1]); if (sp) fsym(ss,sp->amp); else isym(ss,0); return(0);}
      if (strcmp(tok,"append-to-minibuffer") == 0) {sp = get_sp(ss,str[2]); if (sp) append_to_minibuffer(sp,sstr(str[1])); isym(ss,0); return(0);}
      if (strcmp(tok,"ask-before-overwrite") == 0) {isym(ss,ask_before_overwrite(ss)); return(0);}
      if (strcmp(tok,"audio-error") == 0) {isym(ss,audio_error()); return(0);}
      if (strcmp(tok,"audio-error-name") == 0) {ssym(ss,audio_error_name(istr(str[1]))); return(0);}
      if (strcmp(tok,"auto-resize") == 0) {isym(ss,auto_resize(ss)); return(0);}
      break;
    case 'b':
      if (strcmp(tok,"backward-graph") == 0) {goto_previous_graph(current_channel(ss),prefix_fix(str[1])); isym(ss,0); return(0);}
      if (strcmp(tok,"backward-mark") == 0) {goto_mark(current_channel(ss),-prefix_fix(str[1])); isym(ss,0); return(0);}
      if (strcmp(tok,"backward-mix") == 0) {goto_mix(current_channel(ss),-prefix_fix(str[1])); isym(ss,0); return(0);}
      if (strcmp(tok,"backward-sample") == 0) {cp = current_channel(ss); if (cp) handle_cursor(cp,cursor_move(cp,-prefix_fix(str[1]))); isym(ss,0); return(0);}
      if (strcmp(tok,"bytes-per-sample") == 0) {isym(ss,bytes_per_sample(istr(str[1]))); return(0);}
      break;
    case 'c':
#if HAVE_OSS
      if (strcmp(tok,"clear-audio-inputs") == 0) {clear_soundcard_inputs(); isym(ss,0); return(0);}
#endif
      if (strcmp(tok,"change-menu-label") == 0) {/* no-op */ isym(ss,0); return(0);}
      if (strcmp(tok,"channel-style") == 0) {isym(ss,channel_style(ss)); return(0);}
      if (strcmp(tok,"channels") == 0) {sp = get_sp(ss,str[1]); if (sp) isym(ss,sp->nchans); else isym(ss,0); return(0);}
      if (strcmp(tok,"chans") == 0) {sp = get_sp(ss,str[1]); if (sp) isym(ss,sp->nchans); else isym(ss,0); return(0);}
      if (strcmp(tok,"clm-dialog") == 0) {start_clm_dialog(ss,sstr(str[1]),NULL); isym(ss,0); return(0);}
      if (strcmp(tok,"clm-snd-replace-samples") == 0) 
	{
	  tempfile = sstr(str[1]);
	  if ((str[2]) && (*(str[2]))) 
	    sp = find_sound(ss,sstr(str[2]));
	  else sp = any_selected_sound(ss);
	  clm_snd_replace_samples(ss,tempfile,sp);
	  isym(ss,0); 
	  return(0);
	}
      if (strcmp(tok,"clm-snd-samples") == 0) 
	{
	  cp = current_channel(ss);
	  if (cp)
	    {
	      beg = istr(str[1]);
	      len = istr(str[2]);
	      clmvals = load_samples(beg,len,cp);
	      snd_clm_data(ss,len,clmvals);
	      free(clmvals);
	    }
	  isym(ss,0);
	  return(0);
	}
      if (strcmp(tok,"clm-snd-set-samples") == 0) 
	{
	  cp = current_channel(ss);
	  if (cp)
	    {
	      beg = istr(str[1]);
	      clmvals = clm_snd_data(ss,&len);
	      change_samples(beg,len,clmvals,cp,LOCK_MIXES,"(clm-snd-set-samples)");
	      check_for_first_edit(cp);
	      update_graph(cp,NULL);
	      free(clmvals);
	    }
	  isym(ss,0); 
	  return(0);
	}
      if (strcmp(tok,"clm-snd-update") == 0) 
	{
	  filename = sstr(str[1]);
	  sp = find_sound(ss,filename);
	  if (sp)
	    snd_update(ss,sp);
	  else snd_open_file(filename,ss);
	  isym(ss,0);
	  return(0);
	}
      if (strcmp(tok,"clm-snd-close") == 0) 
	{
	  filename = sstr(str[1]);
	  sp = find_sound(ss,filename);
	  if (sp) snd_close_file(sp,ss);
	  isym(ss,0);
	  return(0);
	}
      if (strcmp(tok,"close-sound") == 0) {sp = get_sp(ss,str[1]); if (sp) snd_close_file(sp,ss); isym(ss,0); return(0);}
      if (strcmp(tok,"color-cutoff") == 0) {fsym(ss,color_cutoff(ss)); return(0);}
      if (strcmp(tok,"color-dialog") == 0) {start_color_dialog(ss,0,0); isym(ss,0); return(0);}
      if (strcmp(tok,"color-inverted") == 0) {isym(ss,color_inverted(ss)); return(0);}
      if (strcmp(tok,"color-scale") == 0) {fsym(ss,color_scale(ss)); return(0);}
      if (strcmp(tok,"comment") == 0) {sp = get_sp(ss,str[1]); if (sp) ssym(ss,sound_comment(sp->fullname)); else isym(ss,0); return(0);}
      if (strcmp(tok,"contrast") == 0) {sp = get_sp(ss,str[1]); if (sp) fsym(ss,sp->contrast); else isym(ss,0); return(0);}
      if (strcmp(tok,"contrast-amp") == 0) {sp = get_sp(ss,str[1]); if (sp) fsym(ss,sp->contrast_amp); else isym(ss,0); return(0);}
      if (strcmp(tok,"contrasting?") == 0) {sp = get_sp(ss,str[1]); if (sp) isym(ss,sp->contrasting); else isym(ss,0); return(0);}
      if (strcmp(tok,"control-panel-restore") == 0) {sp = get_sp(ss,str[1]); if (sp) restore_control_state(sp); isym(ss,0); return(0);}
      if (strcmp(tok,"control-panel-save") == 0) {sp = get_sp(ss,str[1]); if (sp) save_control_state(sp); isym(ss,0); return(0);}
      if (strcmp(tok,"cursor") == 0) {cp = get_cp(ss,str[1],str[2]); if (cp) isym(ss,cp->cursor); else isym(ss,0); return(0);}
      if (strcmp(tok,"cursor-follows-play") == 0) {sp = get_sp(ss,str[1]); if (sp) isym(ss,sp->cursor_follows_play); else isym(ss,0); return(0);}
      if (strcmp(tok,"cut") == 0) 
	{
	  finish_keyboard_selection();
	  if (region_ok(0))
	    {
	      delete_selection("(cut)");
	    }
	  isym(ss,0);
	  return(0);
	}
      break;
    case 'd':
      if (strcmp(tok,"data-format") == 0) {sp = get_sp(ss,str[1]); if (sp) isym(ss,(sp->hdr)->format); else isym(ss,0); return(0);}
      if (strcmp(tok,"data-location") == 0) {sp = get_sp(ss,str[1]); if (sp) isym(ss,(sp->hdr)->data_location); else isym(ss,0); return(0);}
      if (strcmp(tok,"default-amp") == 0) {fsym(ss,default_amp(ss)); return(0);}
      if (strcmp(tok,"default-contrast") == 0) {fsym(ss,default_contrast(ss)); return(0);}
      if (strcmp(tok,"default-contrast-amp") == 0) {fsym(ss,default_contrast_amp(ss)); return(0);}
      if (strcmp(tok,"default-contrasting") == 0) {isym(ss,default_contrasting(ss)); return(0);}
      if (strcmp(tok,"default-expand") == 0) {fsym(ss,default_expand(ss)); return(0);}
      if (strcmp(tok,"default-expand-hop") == 0) {fsym(ss,default_expand_hop(ss)); return(0);}
      if (strcmp(tok,"default-expand-length") == 0) {fsym(ss,default_expand_length(ss)); return(0);}
      if (strcmp(tok,"default-expand-ramp") == 0) {fsym(ss,default_expand_ramp(ss)); return(0);}
      if (strcmp(tok,"default-expanding") == 0) {isym(ss,default_expanding(ss)); return(0);}
      if (strcmp(tok,"default-filter-order") == 0) {isym(ss,default_filter_order(ss)); return(0);}
      if (strcmp(tok,"default-filtering") == 0) {isym(ss,default_filtering(ss)); return(0);}
      if (strcmp(tok,"default-output-type") == 0) {isym(ss,default_output_type(ss)); return(0);}
      if (strcmp(tok,"default-reverb-feedback") == 0) {fsym(ss,default_reverb_feedback(ss)); return(0);}
      if (strcmp(tok,"default-reverb-length") == 0) {fsym(ss,default_reverb_length(ss)); return(0);}
      if (strcmp(tok,"default-reverb-lowpass") == 0) {fsym(ss,default_reverb_lowpass(ss)); return(0);}
      if (strcmp(tok,"default-reverb-scale") == 0) {fsym(ss,default_reverb_scale(ss)); return(0);}
      if (strcmp(tok,"default-reverbing") == 0) {isym(ss,default_reverbing(ss)); return(0);}
      if (strcmp(tok,"default-speed") == 0) {fsym(ss,default_speed(ss)); return(0);}
      if (strcmp(tok,"delete-mark") == 0) {cp = get_cp(ss,str[2],str[3]); m = get_m(ss,str[1],str[2],str[3]); if (m) delete_mark(m->samp,cp); isym(ss,0); return(0);}
      if (strcmp(tok,"delete-region") == 0) {delete_region_and_update_browser(ss,istr(str[1])); isym(ss,0); return(0);}
      if (strcmp(tok,"dot-size") == 0) {isym(ss,dot_size(ss)); return(0);}
      if (strcmp(tok,"delete-sample") == 0) 
	{
	  cp = get_cp(ss,str[2],str[3]); 
	  if (cp) 
	    {
	      delete_samples(istr(str[1]),1,cp,"(delete-sample)"); 
	      check_for_first_edit(cp); 
	      update_graph(cp,NULL);
	    } 
	  isym(ss,0);
	  return(0);
	}
      if (strcmp(tok,"delete-samples") == 0) 
	{
	  cp = get_cp(ss,str[3],str[4]);
	  if (cp) 
	    {
	      delete_samples(istr(str[1]),istr(str[2]),cp,"(delete-samples)"); 
	      check_for_first_edit(cp); 
	      update_graph(cp,NULL);
	    } 
	  isym(ss,0);
	  return(0);
	}
#ifdef _DEBUG_MALLOC_INC
      if (strcmp(tok,"dump-memory") == 0) 
	{
	  int fd;
	  unsigned long cur;
	  malloc_size(&cur);
	  fd = creat("snd.mem",0666);
	  malloc_list(fd,state->orig_size,cur);
	  close(fd);
	  isym(0);
	  return(0);
	}
#endif      
      break;
    case 'e':
      if (strcmp(tok,"edit-header-dialog") == 0) {edit_header(get_sp(ss,str[1])); isym(ss,0); return(0);}
      if (strcmp(tok,"edit-history-width") == 0) {isym(ss,edit_history_width(ss)); return(0);}
      if (strcmp(tok,"edits") == 0) {isym(ss,0); /* noop */ return(0);}
      if (strcmp(tok,"enved-base") == 0) {fsym(ss,enved_base(ss)); return(0);}
      if (strcmp(tok,"enved-clipping") == 0) {isym(ss,enved_clipping(ss)); return(0);}
      if (strcmp(tok,"enved-dialog") == 0) {create_envelope_editor(ss); isym(ss,0); return(0);}
      if (strcmp(tok,"enved-exping") == 0) {isym(ss,enved_exping(ss)); return(0);}
      if (strcmp(tok,"enved-target") == 0) {isym(ss,enved_target(ss)); return(0);}
      if (strcmp(tok,"enved-waving") == 0) {isym(ss,enved_waving(ss)); return(0);}
      if (strcmp(tok,"eps-file") == 0) {ssym(ss,eps_file(ss)); return(0);}
      if (strcmp(tok,"exit") == 0) {snd_exit_cleanly(ss); exit(1);}
      if (strcmp(tok,"expand") == 0) {sp = get_sp(ss,str[1]); if (sp) fsym(ss,sp->expand); else isym(ss,0); return(0);}
      if (strcmp(tok,"expand-hop") == 0) {sp = get_sp(ss,str[1]); if (sp) fsym(ss,sp->local_exphop); else isym(ss,0); return(0);}
      if (strcmp(tok,"expand-length") == 0) {sp = get_sp(ss,str[1]); if (sp) fsym(ss,sp->local_explen); else isym(ss,0); return(0);}
      if (strcmp(tok,"expand-ramp") == 0) {sp = get_sp(ss,str[1]); if (sp) fsym(ss,sp->local_exprmp); else isym(ss,0); return(0);}
      if (strcmp(tok,"expanding?") == 0) {sp = get_sp(ss,str[1]); if (sp) isym(ss,sp->expanding); else isym(ss,0); return(0);}
      if (strcmp(tok,"env-selection") == 0)
	{
	  cp = get_cp(ss,str[3],str[4]);
	  if ((cp) && (active_selection(cp))) apply_env(cp,scan_envelope(str[1]),0,0,1.0,TRUE,FALSE,"(env-selection)");
	  isym(ss,0);
	  return(0);
	}
      if (strcmp(tok,"env") == 0) 
	{
	  int dur,samp;
	  cp = get_cp(ss,str[5],str[6]);
	  if (cp)
	    {
	      if ((str[2]) && (*(str[2]))) samp = istr(str[2]);
	      if ((str[3]) && (*(str[3]))) dur = istr(str[3]); else dur = current_ed_samples(cp);
	      apply_env(cp,scan_envelope(str[1]),samp,dur,1.0,FALSE,FALSE,"(env)");
	    }
	  isym(ss,0);
	  return(0);
	}
      break;
    case 'f':
      if (strcmp(tok,"fft") == 0) {isym(ss,0); /* noop */ return(0);}
      if (strcmp(tok,"fft-beta") == 0) {fsym(ss,fft_beta(ss)); return(0);}
      if (strcmp(tok,"fft-log-frequency") == 0) {isym(ss,fft_log_frequency(ss)); return(0);}
      if (strcmp(tok,"fft-log-magnitude") == 0) {isym(ss,fft_log_magnitude(ss)); return(0);}
      if (strcmp(tok,"fft-size") == 0) {isym(ss,fft_size(ss)); return(0);}
      if (strcmp(tok,"fft-style") == 0) {isym(ss,fft_style(ss)); return(0);}
      if (strcmp(tok,"fft-window") == 0) {isym(ss,fft_window(ss)); return(0);}
      if (strcmp(tok,"ffting?") == 0) {cp = get_cp(ss,str[1],str[2]); if (cp) isym(ss,cp->ffting); else isym(ss,0); return(0);}
      if (strcmp(tok,"file-dialog") == 0) {start_file_dialog(ss,0,0); isym(ss,0); return(0);}
      if (strcmp(tok,"file-name") == 0) {sp = get_sp(ss,str[1]); if (sp) ssym(ss,sp->fullname); else isym(ss,0); return(0);}
      if (strcmp(tok,"filter") == 0) 
	{cp = get_cp(ss,str[3],str[4]); if (cp) apply_filter(cp,istr(str[2]),scan_envelope(str[1]),FALSE,"(filter)"); isym(ss,0); return(0);}
      if (strcmp(tok,"filter-env") == 0) {sp = get_sp(ss,str[1]); if (sp) ssym(ss,env_to_string(sp->filter_env)); else isym(ss,0); return(0);}
      if (strcmp(tok,"filter-env-order") == 0) {isym(ss,filter_env_order(ss)); return(0);}
      if (strcmp(tok,"filter-order") == 0) {sp = get_sp(ss,str[1]); if (sp) isym(ss,sp->filter_order); else isym(ss,0); return(0);}
      if (strcmp(tok,"filtering?") == 0) {sp = get_sp(ss,str[1]); if (sp) isym(ss,sp->filtering); else isym(ss,0); return(0);}
      if (strcmp(tok,"find-sound") == 0) 
	{
	  filename = sstr(str[1]);
	  for (i=0;i<ss->max_sounds;i++)
	    {
	      sp = ss->sounds[i];
	      if ((snd_ok(sp)) && ((strcmp(filename,sp->fullname) == 0) || (strcmp(filename,sp->shortname) == 0)))
		{
		  isym(ss,i);
		  return(0);
		}
	    }
	  isym(ss,-1); 
	  return(0);
	}
      if (strcmp(tok,"fit-data-on-open") == 0) {isym(ss,fit_data_on_open(ss)); return(0);}
      if (strcmp(tok,"forward-graph") == 0) {goto_next_graph(current_channel(ss),prefix_fix(str[1])); isym(ss,0); return(0);}
      if (strcmp(tok,"forward-mark") == 0) {goto_mark(current_channel(ss),prefix_fix(str[1])); isym(ss,0); return(0);}
      if (strcmp(tok,"forward-mix") == 0) {goto_mix(current_channel(ss),prefix_fix(str[1])); isym(ss,0); return(0);}
      if (strcmp(tok,"forward-sample") == 0) {cp = current_channel(ss); if (cp) handle_cursor(cp,cursor_move(cp,prefix_fix(str[1]))); isym(ss,0); return(0);}
      if (strcmp(tok,"find-mark") == 0) 
	{
	  if (str[1]) 
	    {
	      cp = get_cp(ss,str[2],str[3]); 
	      if ((cp) && (cp->marks)) 
		{
		  mps = cp->marks[cp->edit_ctr]; 
		  if (mps) 
		    {
		      if (isdigit(str[1][0]))
			{
			  num = istr(str[1]);
			  for (i=0;i<=cp->mark_ctr[cp->edit_ctr];i++) 
			    if (mps[i]->samp == num) {isym(ss,i); return(0);}
			}
		      else
			{
			  filename = sstr(str[1]);
			  for (i=0;i<=cp->mark_ctr[cp->edit_ctr];i++) 
			    if ((mps[i]->name) && (strcmp(filename,mps[i]->name) == 0)) {isym(ss,i); return(0);}
			}
		    }
		}
	    } 
	  isym(ss,-1);
	  return(-0);
	} 
      break;
    case 'g':
      if (strcmp(tok,"global-set-key") == 0) {set_keymap_entry(istr(str[1]),istr(str[2]),sstr(str[3])); isym(ss,0); return(0);}
      if (strcmp(tok,"global-unset-key") == 0) {set_keymap_entry(istr(str[1]),istr(str[2]),"5"); isym(ss,0); return(0);}
      if (strcmp(tok,"graph") == 0) {isym(ss,0); /* noop */ return(0);}
      if (strcmp(tok,"graph-style") == 0) {isym(ss,graph_style(ss)); return(0);}
      if (strcmp(tok,"graphing?") == 0) {cp = get_cp(ss,str[1],str[2]); if (cp) isym(ss,cp->lisp_graphing); else isym(ss,0); return(0);}
      if (strcmp(tok,"group-amp") == 0) {fsym(ss,mx_get_group_amp(istr(str[1]),istr(str[2]))); return(0);}
      if (strcmp(tok,"group-beg") == 0) {fsym(ss,mx_get_group_beg(istr(str[1]))); return(0);}
      if (strcmp(tok,"group-dialog") == 0) {fire_up_group_browser(ss); isym(ss,0); return(0);}
      if (strcmp(tok,"group-end") == 0) {fsym(ss,mx_get_group_end(istr(str[1]))); return(0);}
      if (strcmp(tok,"group-ok?") == 0) {isym(ss,group_ok(ss,istr(str[1]))); return(0);}
      if (strcmp(tok,"group-speed") == 0) {fsym(ss,mx_get_group_speed(istr(str[1]))); return(0);}
      if (strcmp(tok,"group-tempo") == 0) {fsym(ss,mx_get_group_tempo(istr(str[1]))); return(0);}
      if (strcmp(tok,"groups") == 0) {isym(ss,active_groups(ss)); return(0);}
      if (strcmp(tok,"guile") == 0) {isym(ss,0); return(0);}
      break;
    case 'h':
      if (strcmp(tok,"header-type") == 0) {sp = get_sp(ss,str[1]); if (sp) isym(ss,(sp->hdr)->type); else isym(ss,0); return(0);}
      if (strcmp(tok,"help-dialog") == 0) {snd_help(ss,sstr(str[1]),sstr(str[2])); isym(ss,0); return(0);}
      if (strcmp(tok,"hide-listener") == 0) {if (ss->listening == 1) handle_listener(ss); isym(ss,0); return(0);}
#if HAVE_XmHTML
      if (strcmp(tok,"html-dir") == 0) {ssym(ss,html_dir(ss)); return(0);}
#endif
      break;
    case 'i':
      if (strcmp(tok,"initial-x0") == 0) {fsym(ss,initial_x0(ss)); return(0);}
      if (strcmp(tok,"initial-x1") == 0) {fsym(ss,initial_x1(ss)); return(0);}
      if (strcmp(tok,"initial-y0") == 0) {fsym(ss,initial_y0(ss)); return(0);}
      if (strcmp(tok,"initial-y1") == 0) {fsym(ss,initial_y1(ss)); return(0);}
      if (strcmp(tok,"insert-samples") == 0) {isym(ss,0); /* noop */ return(0);}
      if (strcmp(tok,"insert-int-samples") == 0) {isym(ss,0); /* noop */ return(0);}
      if (strcmp(tok,"insert-sample") == 0) 
	{
	  cp = get_cp(ss,str[3],str[4]); 
	  if (cp) 
	    {
	      ivals[0] = clm_sndfix * fstr(str[2]); 
	      insert_samples(istr(str[1]),1,ivals,cp,"(insert-sample)"); 
	      check_for_first_edit(cp); 
	      update_graph(cp,NULL);
	    } 
	  isym(ss,0);
	  return(0);
	}
      if (strcmp(tok,"insert-region") == 0) 
	{
	  ival = istr(str[1]); 
	  cp = get_cp(ss,str[2],str[3]); 
	  if (cp) 
	    {
	      finish_keyboard_selection(); 
	      paste_region(ival,cp,"(insert-region)"); 
	      update_graph(cp,NULL);
	    } 
	  isym(ss,0);
	  return(0);
	}
      if (strcmp(tok,"insert-sound") == 0) 
	{
	  cp = get_cp(ss,str[3],str[4]);
	  if (cp)
	    {
	      filename = complete_filename(sstr(str[1]));
	      file_insert_samples(0,sound_samples(filename)/sound_chans(filename),filename,cp,istr(str[2]),DONT_DELETE_ME,"(insert-sound)");
	      check_for_first_edit(cp);
	      update_graph(cp,NULL);
	    }
	  isym(ss,0);
	  return(0);
	}
      break;
    case 'j':
      break;
    case 'k':
      if (strcmp(tok,"key") == 0) {keyboard_command(current_channel(ss),istr(str[1]),istr(str[2])); isym(ss,0); return(0);}
      break;
    case 'l':
      if (strcmp(tok,"left-sample") == 0) {cp = get_cp(ss,str[1],str[2]); if ((cp) && (cp->axis)) isym(ss,(cp->axis)->losamp); else isym(ss,0); return(0);}
      if (strcmp(tok,"line-size") == 0) {isym(ss,line_size(ss)); return(0);}
      if (strcmp(tok,"load") == 0) {isym(ss,snd_load_file(ss,sstr(str[1]))); return(0);}
      break;
    case 'm':
      if (strcmp(tok,"make-region") == 0) {cp = get_cp(ss,str[3],str[4]); if (cp) define_region(cp,istr(str[1]),istr(str[2])); isym(ss,0); return(0);}
      if (strcmp(tok,"mark-name") == 0) {m = get_m(ss,str[2],str[3],str[1]); if (m) ssym(ss,m->name); else isym(ss,0); return(0);}
      if (strcmp(tok,"mark-sample") == 0) {m = get_m(ss,str[2],str[3],str[1]); if (m) isym(ss,m->samp); else isym(ss,0); return(0);}
      if (strcmp(tok,"marks") == 0) {cp = get_cp(ss,str[1],str[2]); if ((cp) && (cp->marks)) isym(ss,1+cp->mark_ctr[cp->edit_ctr]); else isym(ss,0); return(0);}
      if (strcmp(tok,"max-sounds") == 0) {isym(ss,ss->max_sounds); return(0);}
      if (strcmp(tok,"mix") == 0) /* file samp chan snd chn */
	{
	  cp = get_cp(ss,str[4],str[5]);
	  if (cp)
	    {
	      filename = complete_filename(sstr(str[1]));
	      file_mix_samples(istr(str[2]),sound_samples(filename)/sound_chans(filename),filename,cp,istr(str[3]),DONT_DELETE_ME,FALSE,1,"(mix)");
	    }
	  isym(ss,0);
	  return(0);
	}
      if (strcmp(tok,"maxamp") == 0) {cp = get_cp(ss,str[1],str[2]); if (cp) fsym(ss,get_maxamp(ss,cp->sound,cp)); else isym(ss,0); return(0);}
      if (strcmp(tok,"mix-amp") == 0) {fsym(ss,in_mix_amp(ss,istr(str[1]),istr(str[2]))); return(0);}
      if (strcmp(tok,"mix-amp-scaler") == 0) {fsym(ss,get_mix_amp_scaler()); return(0);}
      if (strcmp(tok,"mix-anchor") == 0) {isym(ss,mix_anchor(ss,istr(str[1]))); return(0);}
      if (strcmp(tok,"mix-duration-brackets") == 0) {isym(ss,mix_duration_brackets(ss)); return(0);}
      if (strcmp(tok,"mix-groups") == 0) {isym(ss,mix_groups(ss,istr(str[1]))); return(0);}
      if (strcmp(tok,"mix-length") == 0) {isym(ss,mix_length(ss,istr(str[1]))); return(0);}
      if (strcmp(tok,"mix-position") == 0) {isym(ss,mix_position(ss,istr(str[1]))); return(0);}
      if (strcmp(tok,"mix-region") == 0) {cp = get_cp(ss,str[4],str[5]); if (cp) mix_region(istr(str[3]),cp,istr(str[1]),fstr(str[2])); isym(ss,0); return(0);}
      if (strcmp(tok,"mix-speed") == 0) {fsym(ss,in_mix_speed(ss,istr(str[1]))); return(0);}
      if (strcmp(tok,"mix-speed-scaler") == 0) {fsym(ss,get_mix_speed_scaler()); return(0);}
      if (strcmp(tok,"mix-state") == 0) {isym(ss,in_mix_state(ss,istr(str[1]))); return(0);}
      if (strcmp(tok,"mix-tempo-scaler") == 0) {fsym(ss,get_mix_tempo_scaler()); return(0);}
      if (strcmp(tok,"mixer-group-max-out-chans") == 0) {isym(ss,mixer_group_max_out_chans(ss)); return(0);}
      if (strcmp(tok,"mixer-groups") == 0) {isym(ss,mixer_groups(ss)); return(0);}
      if (strcmp(tok,"movies") == 0) {isym(ss,movies(ss)); return(0);}
      break;
    case 'n':
      if (strcmp(tok,"new-sound") == 0) {snd_new_file(ss,sstr(str[1])); isym(ss,0); return(0);}
      if (strcmp(tok,"next-sound_file") == 0) {isym(ss,NeXT_sound_file); return(0);}
      if (strcmp(tok,"normalize-fft") == 0) {isym(ss,normalize_fft(ss)); return(0);}
      if (strcmp(tok,"normalize-on-open") == 0) {isym(ss,normalize_on_open(ss)); return(0);}
      if (strcmp(tok,"normalize-view") == 0) {normalize_all_sounds(ss); isym(ss,0); return(0);}
      break;
    case 'o': 
      if (strcmp(tok,"ok?") == 0) {sp = get_sp(ss,str[1]); if (sp) isym(ss,snd_ok(sp)); else isym(ss,0); return(0);}
      if (strcmp(tok,"open-sound") == 0) {sp = snd_open_file(sstr(str[1]),ss); if (sp) isym(ss,sp->index); else isym(ss,0); return(0);}
      if (strcmp(tok,"open-alternate-sound") == 0) 
	{
	  sp = any_selected_sound(ss);
	  if (sp) snd_close_file(sp,ss);
	  sp = snd_open_file(sstr(str[1]),ss);
	  if (sp) isym(ss,sp->index); else isym(ss,0);
	  return(0);
	}
      if (strcmp(tok,"or") == 0) {lsym(ss,name_to_env(str[1])); return(0);}
      if (strcmp(tok,"orientation-dialog") == 0) {start_orientation_dialog(ss,0,0); isym(ss,0); return(0);}
      if (strcmp(tok,"override-data-location") == 0) {c_snd_header_override_data_location(istr(str[1])); isym(ss,0); return(0);}
      if (strcmp(tok,"override-data-format") == 0) {c_snd_header_override_sound_format(istr(str[1])); isym(ss,0); return(0);}
      if (strcmp(tok,"override-data-size") == 0) {c_snd_header_override_data_size(); isym(ss,0); return(0);}
      break;
    case 'p':
      if (strcmp(tok,"peaks") == 0) {cp = get_cp(ss,str[1],str[2]); if (cp) display_fft_peaks(cp); isym(ss,0); return(0);}
      if (strcmp(tok,"play-region") == 0) {play_region(ss,istr(str[1]),NULL); isym(ss,0); return(0);}
      if (strcmp(tok,"preload-directory") == 0) {add_directory_to_prevlist(ss,sstr(str[1])); isym(ss,0); return(0);}
      if (strcmp(tok,"preload-file") == 0) {remember_me(ss,filename_without_home_directory(sstr(str[1])),sstr(str[1])); isym(ss,0); return(0);}
      if (strcmp(tok,"print") == 0) {snd_print(ss,eps_file(ss),1); isym(ss,0); return(0);}
      if (strcmp(tok,"print-length") == 0) {isym(ss,print_length(ss)); return(0);}
      if (strcmp(tok,"protect-region") == 0) {if (str[2]) ival = istr(str[2]); else ival = 1; set_region_protect(istr(str[1]),ival); isym(ss,0); return(0);}
      if (strcmp(tok,"play") == 0) 
	{
	  if (str[3]) 
	    {
	      cp = get_cp(ss,str[2],str[3]);
	      if (cp) start_playing(cp,istr(str[1])); 
	    }
	  else 
	    {
	      sp = get_sp(ss,str[2]); 
	      if (sp) start_playing(sp,istr(str[1]));
	    }
	  isym(ss,0);
	  return(0);
	}
      break;
    case 'r':
      if (strcmp(tok,"raw-chans") == 0) {isym(ss,raw_chans(ss)); return(0);}
      if (strcmp(tok,"raw-format") == 0) {isym(ss,raw_format(ss)); return(0);}
      if (strcmp(tok,"raw-srate") == 0) {isym(ss,raw_srate(ss)); return(0);}
      if (strcmp(tok,"raw-type") == 0) {isym(ss,raw_type(ss)); return(0);}
      if (strcmp(tok,"read-only?") == 0) {sp = get_sp(ss,str[1]); if (sp) isym(ss,sp->read_only); else isym(ss,0); return(0);}
      if (strcmp(tok,"record-dialog") == 0) {snd_record_file(ss); isym(ss,0); return(0);}
      if (strcmp(tok,"recorder-autoload") == 0) {isym(ss,recorder_autoload(ss)); return(0);}
      if (strcmp(tok,"recorder-buffer-size") == 0) {isym(ss,recorder_buffer_size(ss)); return(0);}
      if (strcmp(tok,"recorder-file") == 0) {ssym(ss,recorder_file(ss)); return(0);}
      if (strcmp(tok,"recorder-gain") == 0) {fsym(ss,read_record_state(AUDIO_GAINS,istr(str[1]),0)); return(0);}
      if (strcmp(tok,"recorder-in-amp") == 0) {fsym(ss,read_record_state(REC_IN_AMPS,istr(str[1]),istr(str[2]))); return(0);}
      if (strcmp(tok,"recorder-in-format") == 0) {isym(ss,recorder_in_format(ss)); return(0);}
      if (strcmp(tok,"recorder-out-amp") == 0) {fsym(ss,read_record_state(REC_OUT_AMPS,istr(str[1]),0)); return(0);}
      if (strcmp(tok,"recorder-out-chans") == 0) {isym(ss,recorder_out_chans(ss)); return(0);}
      if (strcmp(tok,"recorder-out-format") == 0) {isym(ss,recorder_out_format(ss)); return(0);}
      if (strcmp(tok,"recorder-srate") == 0) {isym(ss,recorder_srate(ss)); return(0);}
      if (strcmp(tok,"region-chans") == 0) {isym(ss,region_chans(istr(str[1]))); return(0);}
      if (strcmp(tok,"region-dialog") == 0) {if (snd_regions() > 0) View_Region_Callback(main_PANE(ss),(XtPointer)ss,NULL); isym(ss,0); return(0);}
      if (strcmp(tok,"region-length") == 0) {isym(ss,region_len(istr(str[1]))); return(0);}
      if (strcmp(tok,"region-maxamp") == 0) {fsym(ss,region_maxamp(istr(str[1]))); return(0);}
      if (strcmp(tok,"region-sample") == 0) {finish_keyboard_selection(); fsym(ss,region_sample(istr(str[2]),istr(str[3]),istr(str[1]))); return(0);}
      if (strcmp(tok,"region-samples") == 0) {isym(ss,0); /* noop */ return(0);}
      if (strcmp(tok,"region-srate") == 0) {isym(ss,region_srate(istr(str[1]))); return(0);}
      if (strcmp(tok,"regions") == 0) {isym(ss,snd_regions()); return(0);}
      if (strcmp(tok,"report-in-minibuffer") == 0) {sp = get_sp(ss,str[2]); if (sp) report_in_minibuffer(sp,str[1]); isym(ss,0); return(0);}
      if (strcmp(tok,"reverb-decay") == 0) {fsym(ss,reverb_decay(ss)); return(0);}
      if (strcmp(tok,"reverb-feedback") == 0) {sp = get_sp(ss,str[1]); if (sp) fsym(ss,sp->local_revfb); else isym(ss,0); return(0);}
      if (strcmp(tok,"reverb-length") == 0) {sp = get_sp(ss,str[1]); if (sp) fsym(ss,sp->revlen); else isym(ss,0); return(0);}
      if (strcmp(tok,"reverb-lowpass") == 0) {sp = get_sp(ss,str[1]); if (sp) fsym(ss,sp->local_revlp); else isym(ss,0); return(0);}
      if (strcmp(tok,"reverb-scale") == 0) {sp = get_sp(ss,str[1]); if (sp) fsym(ss,sp->revscl); else isym(ss,0); return(0);}
      if (strcmp(tok,"reverbing?") == 0) {sp = get_sp(ss,str[1]); if (sp) isym(ss,sp->reverbing); else isym(ss,0); return(0);}
      if (strcmp(tok,"remove-from-menu") == 0) {isym(ss,0); /* noop */ return(0);}
      if (strcmp(tok,"riff-sound-file") == 0) {isym(ss,RIFF_sound_file); return(0);}
      if (strcmp(tok,"right-sample") == 0) {cp = get_cp(ss,str[1],str[2]); if ((cp) && (cp->axis)) isym(ss,(cp->axis)->hisamp); else isym(ss,0); return(0);}
      if (strcmp(tok,"redo") == 0) 
	{
	  ival = istr(str[1]); 
	  if (ival == 0) ival = 1; 
	  cp = get_cp(ss,str[2],str[3]); 
	  if (cp) 
	    {
	      redo_EDIT(cp,ival); 
	      update_graph(cp,NULL);
	    }
	  isym(ss,0);
	  return(0);
	}
      if (strcmp(tok,"revert-sound") == 0) 
	{
	  sp = get_sp(ss,str[1]);
	  if (sp)
	    {
	      for (i=0;i<sp->nchans;i++) 
		{
		  revert_edits(sp->chans[i],NULL); 
		  update_graph(sp->chans[i],NULL);
		}
	      reflect_file_revert_in_label(sp);
	      reflect_file_revert_in_menu(ss);
	    }
	  isym(ss,0);
	  return(0);
	}
      break;
    case 's':
      if ((tok[1] == 'e') && (tok[2] == 't') && (tok[3] == '-'))
	{
	  if (strcmp(tok,"set-ask-before-overwrite") == 0) {set_ask_before_overwrite(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-auto-resize") == 0) {set_auto_resize(ss,istr(str[1])); reflect_resize(ss); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-channel-style") == 0) {in_set_channel_style(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-channel-style") == 0) {set_channel_style(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-color-cutoff") == 0) {set_color_cutoff(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-color-inverted") == 0) {set_color_inverted(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-color-scale") == 0) {set_color_scale(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-cursor") == 0) 
	    {
	      cp = get_cp(ss,str[2],str[3]); 
	      if (cp) 
		{
		  cp->cursor_on = 1;
		  handle_cursor(cp,cursor_moveto(cp,istr(str[1]))); 
		}
	      isym(ss,0); 
	      return(0);
	    }
	  if (strcmp(tok,"set-cursor-follows-play") == 0) {sp = get_sp(ss,str[2]); if (sp) sp->cursor_follows_play = istr(str[1]); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-default-amp") == 0) {set_default_amp(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-default-contrast") == 0) {set_default_contrast(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-default-contrast-amp") == 0) {set_default_contrast_amp(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-default-contrasting") == 0) {set_default_contrasting(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-default-expand") == 0) {set_default_expand(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-default-expand-hop") == 0) {set_default_expand_hop(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-default-expand-length") == 0) {set_default_expand_length(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-default-expand-ramp") == 0) {set_default_expand_ramp(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-default-expanding") == 0) {set_default_expanding(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-default-filter-order") == 0) {set_default_filter_order(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-default-filtering") == 0) {set_default_filtering(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-default-output-type") == 0) {set_default_output_type(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-default-reverb-feedback") == 0) {set_default_reverb_feedback(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-default-reverb-length") == 0) {set_default_reverb_length(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-default-reverb-lowpass") == 0) {set_default_reverb_lowpass(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-default-reverb-scale") == 0) {set_default_reverb_scale(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-default-reverbing") == 0) {set_default_reverbing(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-default-speed") == 0) {set_default_speed(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-dot-size") == 0) {in_set_dot_size(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-dot-size") == 0) {set_dot_size(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-edit-history-width") == 0) {set_edit_history_width(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-env-base") == 0) {isym(ss,set_env_base(sstr(str[1]),fstr(str[2]))); return(0);}
	  if (strcmp(tok,"set-enved-base") == 0) {in_set_enved_base(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-enved-clipping") == 0) {in_set_enved_clipping(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-enved-exping") == 0) {in_set_enved_exping(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-enved-target") == 0) {in_set_enved_target(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-enved-waving") == 0) {in_set_enved_waving(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-eps-file") == 0) {set_eps_file(ss,sstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-expand") == 0) 
	    {sp = get_sp(ss,str[2]); if (sp) snd_expand_changed(sp,set_raw_value(snd_widget(sp,W_snd_expand),snd_expand_to_int(fstr(str[1])))); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-expand-hop") == 0) {sp = get_sp(ss,str[2]); if (sp) sp->local_exphop = fstr(str[1]); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-expand-length") == 0) {sp = get_sp(ss,str[2]); if (sp) sp->local_explen = fstr(str[1]); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-expand-ramp") == 0) {sp = get_sp(ss,str[2]); if (sp) sp->local_exprmp = fstr(str[1]); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-expanding") == 0) {sp = get_sp(ss,str[2]); if (sp) toggle_expand_button(sp,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-fft-beta") == 0) {set_fft_beta(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-fft-log-frequency") == 0) {set_fft_log_frequency(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-fft-log-magnitude") == 0) {set_fft_log_magnitude(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-fft-size") == 0) {set_fft_size(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-fft-style") == 0) {set_fft_style(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-fft-window") == 0) {set_fft_window(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-ffting") == 0) {cp = get_cp(ss,str[2],str[3]); if (cp) fftb(cp,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-filter-env-order") == 0) {set_filter_env_order(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-filter-order") == 0) {sp = get_sp(ss,str[2]); if (sp) filter_order_changed(sp,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-filter_env") == 0) 
	    {sp = get_sp(ss,str[2]); if (sp) {sp->filter_env = scan_envelope(str[1]); filter_env_changed(sp,sp->filter_env); isym(ss,0); return(0);}}
	  if (strcmp(tok,"set-filtering") == 0) {sp = get_sp(ss,str[2]); if (sp) toggle_filter_button(sp,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-fit-data-on-open") == 0) {set_fit_data_on_open(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-graph-style") == 0) {in_set_graph_style(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-graph-style") == 0) {set_graph_style(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-graphing") == 0) {cp = get_cp(ss,str[2],str[3]); if (cp) cp->lisp_graphing = istr(str[1]); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-group-amp") == 0) {mx_set_group_amp(ss,istr(str[1]),istr(str[2]),fstr(str[3])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-group-beg") == 0) {mx_set_group_beg(ss,istr(str[1]),fstr(str[2])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-group-end") == 0) {mx_set_group_end(ss,istr(str[1]),fstr(str[2])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-group-speed") == 0) {mx_set_group_speed(ss,istr(str[1]),fstr(str[2])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-group-tempo") == 0) {mx_set_group_tempo(ss,istr(str[1]),fstr(str[2])); isym(ss,0); return(0);}
#if HAVE_XmHTML
	  if (strcmp(tok,"set-html-dir") == 0) {set_html_dir(ss,sstr(str[1])); isym(ss,0); return(0);}
#endif
	  if (strcmp(tok,"set-initial-x0") == 0) {set_initial_x0(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-initial-x1") == 0) {set_initial_x1(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-initial-y0") == 0) {set_initial_y0(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-initial-y1") == 0) {set_initial_y1(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-just-sounds") == 0) {toggle_just_sounds(istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-left-sample") == 0) {clm_left_axis(get_cp(ss,str[2],str[3]),istr(str[1])); isym(ss,0);return(0);}
	  if (strcmp(tok,"set-line-size") == 0) {set_line_size(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-mark-name") == 0) {m = get_m(ss,str[3],str[4],str[1]); m->name = copy_string(sstr(str[2])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-menu-sensitive") == 0) {/* no-op */ isym(ss,0); return(0);}
	  if (strcmp(tok,"set-mix-amp") == 0) {in_set_mix_amp(ss,istr(str[1]),istr(str[2]),fstr(str[3])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-mix-amp-scaler") == 0) {set_mix_amp_scaler(fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-mix-anchor") == 0) {set_mix_anchor(ss,istr(str[1]),istr(str[2])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-mix-duration-brackets") == 0) {set_mix_duration_brackets(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-mix-groups") == 0) {set_mix_groups(ss,istr(str[1]),istr(str[2])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-mix-length") == 0) {set_mix_length(ss,istr(str[1]),istr(str[2])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-mix-position") == 0) {set_mix_position(ss,istr(str[1]),istr(str[2])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-mix-speed") == 0) {in_set_mix_speed(ss,istr(str[1]),fstr(str[2])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-mix-speed-scaler") == 0) {set_mix_speed_scaler(fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-mix-state") == 0) {in_set_mix_state(ss,istr(str[1]),istr(str[2])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-mix-tempo-scaler") == 0) {set_mix_tempo_scaler(fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-mixer-group-max-out-chans") == 0) {set_mixer_group_max_out_chans(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-mixer-groups") == 0) {set_mixer_groups(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-movies") == 0) {set_movies(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-normalize-fft") == 0) {set_normalize_fft(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-normalize-on-open") == 0) {set_normalize_on_open(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-oss-buffers") == 0)
	    {
#if HAVE_OSS
	      set_oss_buffers(istr(str[1]),istr(str[2]));
#endif
	      isym(ss,0);
	      return(0);
	    }
	  if (strcmp(tok,"set-print-length") == 0) {set_print_length(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-raw-chans") == 0) {set_raw_chans(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-raw-format") == 0) {set_raw_format(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-raw-srate") == 0) {set_raw_srate(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-raw-type") == 0) {set_raw_type(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-read-only") == 0) 
	    {sp = get_sp(ss,str[2]); if (sp) {ival = istr(str[1]); sp->read_only = ival; snd_file_lock_icon(sp,ival);} isym(ss,0); return(0);}
	  if (strcmp(tok,"set-recorder-autoload") == 0) {set_autoload(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-recorder-buffer-size") == 0) {in_set_recorder_buffer_size(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-recorder-file") == 0) {in_set_recorder_file(ss,sstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-recorder-gain") == 0) {write_record_state(AUDIO_GAINS,istr(str[1]),0,fstr(str[2])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-recorder-in-amp") == 0) {write_record_state(REC_IN_AMPS,istr(str[1]),istr(str[2]),fstr(str[3])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-recorder-in-format") == 0) {in_set_recorder_in_format(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-recorder-out-amp") == 0) {write_record_state(REC_OUT_AMPS,istr(str[1]),0,fstr(str[2])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-recorder-out-chans") == 0) {in_set_recorder_out_chans(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-recorder-out-format") == 0) {in_set_recorder_out_format(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-recorder-srate") == 0) {in_set_recorder_srate(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-reverb-decay") == 0) {set_reverb_decay(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-reverb-feedback") == 0) {sp = get_sp(ss,str[2]); if (sp) sp->local_revfb = fstr(str[1]); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-reverb-length") == 0) 
	    {sp = get_sp(ss,str[2]); if (sp) snd_revlen_changed(sp,set_raw_value(snd_widget(sp,W_snd_revlen),snd_revlen_to_int(fstr(str[1])))); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-reverb-lowpass") == 0) {sp = get_sp(ss,str[2]); if (sp) sp->local_revlp = fstr(str[1]); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-reverb-scale") == 0) 
	    {sp = get_sp(ss,str[2]); if (sp) snd_revscl_changed(sp,set_raw_value(snd_widget(sp,W_snd_revscl),snd_revscl_to_int(fstr(str[1])))); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-reverbing") == 0) {sp = get_sp(ss,str[2]); if (sp) toggle_reverb_button(sp,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-right-sample") == 0) {clm_right_axis(get_cp(ss,str[2],str[3]),istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-save-state-on-exit") == 0) {set_save_state_on_exit(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-session-file") == 0) {set_session_file(ss,sstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-show-edit-history") == 0) {edit_history(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-show-fft-peaks") == 0) {set_show_fft_peaks(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-show-marks") == 0) {set_show_marks(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-show-mix-consoles") == 0) {set_show_mix_consoles(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-show-y-zero") == 0) {set_show_y_zero(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-showing-controls") == 0) 
	    {sp = get_sp(ss,str[2]); if (sp) if (istr(str[1])) sound_show_ctrls(sp); else sound_hide_ctrls(sp); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-sinc-width") == 0) {set_sinc_width(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-sound-style") == 0) {set_sound_style(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-spectro-color") == 0) {set_spectro_color(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-spectro-cutoff") == 0) {set_spectro_cutoff_and_redisplay(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-spectro-hop") == 0) {set_spectro_hop(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-spectro-x-angle") == 0) {set_spectro_x_angle(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-spectro-x-scale") == 0) {set_spectro_x_scale(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-spectro-y-angle") == 0) {set_spectro_y_angle(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-spectro-y-scale") == 0) {set_spectro_y_scale(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-spectro-z-angle") == 0) {set_spectro_z_angle(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-spectro-z-scale") == 0) {set_spectro_z_scale(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-speed") == 0) 
	    {sp = get_sp(ss,str[2]); if (sp) snd_srate_changed(sp,set_raw_value(snd_widget(sp,W_snd_srate),snd_srate_to_int(fstr(str[1])))); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-speed-style") == 0) {activate_speed_in_menu(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-speed-tones") == 0) {set_speed_tones(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-subsampling") == 0) {set_subsampling(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-syncing") == 0) {sp = get_sp(ss,str[2]); if (sp) syncb(sp,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-temp-dir") == 0) {set_temp_dir(ss,sstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-transform-type") == 0) {set_transform_type(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-uniting") == 0) {sp = get_sp(ss,str[2]); if (sp) combineb(sp,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-use-raw-defaults") == 0) {set_use_raw_defaults(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-verbose-cursor") == 0) {set_verbose_cursor(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-vu-font") == 0) {set_vu_font(ss,copy_string(sstr(str[1]))); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-vu-font-size") == 0) {set_vu_font_size(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-vu-size") == 0) {set_vu_size(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-wavelet-type") == 0) {set_wavelet_type(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-waving") == 0) {cp = get_cp(ss,str[2],str[3]); if (cp) waveb(cp,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-wavo") == 0) {set_wavo(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-wavo-hop") == 0) {set_wavo_hop(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-wavo-trace") == 0) {set_wavo_trace(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-window-height") == 0) {set_snd_window_height(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-window-width") == 0) {set_snd_window_width(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-window-x") == 0) {in_set_window_x(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-window-y") == 0) {in_set_window_y(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-x-axis-style") == 0) {in_set_x_axis_style(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-x-bounds") == 0) {cp = get_cp(ss,str[3],str[4]); if (cp) clm_x_axis(cp,fstr(str[1]),fstr(str[2])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-xmax") == 0) {set_xmax(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-xmin") == 0) {set_xmin(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-y-bounds") == 0) {cp = get_cp(ss,str[3],str[4]); if (cp) clm_y_axis(cp,fstr(str[1]),fstr(str[2])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-ymax") == 0) {set_ymax(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-ymin") == 0) {set_ymin(ss,fstr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-zero-pad") == 0) {set_zero_pad(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-zoom-focus-style") == 0) {activate_focus_menu(ss,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-amp") == 0) 
	    {sp = get_sp(ss,str[2]); if (sp) snd_amp_changed(sp,set_raw_value(snd_widget(sp,W_snd_amp),snd_amp_to_int(fstr(str[1])))); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-contrast") == 0) 
	    {
	      sp = get_sp(ss,str[2]); 
	      if (sp) snd_contrast_changed(sp,set_raw_value(snd_widget(sp,W_snd_contrast),snd_contrast_to_int(fstr(str[1])))); 
	      isym(ss,0); 
	      return(0);
	    }
	  if (strcmp(tok,"set-contrast-amp") == 0) {sp = get_sp(ss,str[2]); if (sp) sp->contrast_amp = fstr(str[1]); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-contrasting") == 0) {sp = get_sp(ss,str[2]); if (sp) toggle_contrast_button(sp,istr(str[1])); isym(ss,0); return(0);}
	  if (strcmp(tok,"set-sample") == 0) 
	    {
	      cp = get_cp(ss,str[3],str[4]); 
	      if (cp) 
		{
		  ivals[0] = clm_sndfix * fstr(str[2]); 
		  change_samples(istr(str[1]),1,ivals,cp,LOCK_MIXES,"(set-sample)");
		  check_for_first_edit(cp); 
		  update_graph(cp,NULL); 
		} 
	      isym(ss,0);
	      return(0);
	    }
	  if (strcmp(tok,"set-samples") == 0) {isym(ss,0); /* noop */ return(0);}
	  if (strcmp(tok,"set-int-samples") == 0) {isym(ss,0); /* noop */ return(0);}
	  if (strcmp(tok,"set-mark-sample") == 0) 
	    {
	      cp = get_cp(ss,str[3],str[4]); 
	      m = get_m(ss,str[3],str[4],str[1]); 
	      if (m) 
		{
		  m->samp = istr(str[2]); 
		  finish_moving_mark(cp,m);
		}
	      isym(ss,0);
	      return(0);
	    }
	}
      if (strcmp(tok,"sample") == 0) {cp = get_cp(ss,str[2],str[3]); if (cp) fsym(ss,sample(istr(str[1]),cp)); return(0);}
      if (strcmp(tok,"samples") == 0) {isym(ss,0); /* noop */ return(0);} 
      if (strcmp(tok,"save-envelopes") == 0) {g_save_envelopes(ss,str[1]); isym(ss,0); return(0);}
      if (strcmp(tok,"save-macros") == 0) {save_macros(ss); isym(ss,0); return(0);}
      if (strcmp(tok,"save-marks") == 0) {sp = get_sp(ss,str[1]); if (sp) save_marks(sp); isym(ss,0); return(0);}
      if (strcmp(tok,"save-options") == 0) 
	{
	  FILE *fd;
	  fd = fopen(sstr(str[1]),"w");
	  if (fd)
	    {
	      save_snd_state_options(ss,fd); 
	      fclose(fd);
	    }
	  isym(ss,0); 
	  return(0);
	}
      if (strcmp(tok,"save-region") == 0) {save_region(ss,istr(str[1]),str[2]); isym(ss,0); return(0);}
      if (strcmp(tok,"save-state-on-exit") == 0) {isym(ss,save_state_on_exit(ss)); return(0);}
      if (strcmp(tok,"save-state") == 0) {save_state(ss,sstr(str[1])); isym(ss,0); return(0);}
      if (strcmp(tok,"scale-selection-to") == 0) 
	{
	  if (region_ok(0))
	    {
	      scls[0] = fstr(str[1]);
	      scale_to(ss,NULL,NULL,scls,1,TRUE);
	      fsym(ss,scls[0]);
	    }
	  else isym(ss,-1);
	  return(0);
	}
      if (strcmp(tok,"scale-selection-by") == 0) 
	{
	  if (region_ok(0))
	    {
	      scls[0] = fstr(str[1]);
	      scale_by(ss,NULL,NULL,scls,1,TRUE);
	      fsym(ss,scls[0]);
	    }
	  else isym(ss,-1);
	  return(0);
	}
      if (strcmp(tok,"scale-to") == 0) 
	{
	  cp = get_cp(ss,str[2],str[3]);
	  if (cp)
	    {
	      scls[0] = fstr(str[1]);
	      scale_to(ss,cp->sound,cp,scls,1,FALSE); 
	    }
	  fsym(ss,scls[0]);
	  return(0);
	}
      if (strcmp(tok,"scale-by") == 0) 
	{
	  cp = get_cp(ss,str[2],str[3]);
	  if (cp)
	    {
	      scls[0] = fstr(str[1]);
	      scale_by(ss,cp->sound,cp,scls,1,FALSE); 
	    }
	  fsym(ss,scls[0]);
	  return(0);
	}
      if (strcmp(tok,"select-channel") == 0) {select_channel(any_selected_sound(ss),istr(str[1])); isym(ss,0); return(0);}
      if (strcmp(tok,"select-region") == 0) {select_region_and_update_browser(ss,istr(str[1])); isym(ss,0); return(0);}
      if (strcmp(tok,"select-sound") == 0) {ival = istr(str[1]); if (snd_ok(ss->sounds[ival])) select_sound(ss,ss->sounds[ival]); isym(ss,0); return(0);}
      if (strcmp(tok,"selected-channel") == 0) {sp = get_sp(ss,str[1]); if (sp) isym(ss,sp->selected_channel); else isym(ss,0); return(0);}
      if (strcmp(tok,"session-file") == 0) {ssym(ss,session_file(ss)); return(0);}
      if (strcmp(tok,"short-file-name") == 0) {sp = get_sp(ss,str[1]); if (sp) ssym(ss,sp->shortname); else isym(ss,0); return(0);}
      if (strcmp(tok,"show-edit-history") == 0) {isym(ss,show_edit_history(ss)); return(0);}
      if (strcmp(tok,"show-fft-peaks") == 0) {isym(ss,show_fft_peaks(ss)); return(0);}
      if (strcmp(tok,"show-listener") == 0) {if (ss->listening != 1) handle_listener(ss); isym(ss,0); return(0);}
      if (strcmp(tok,"show-marks") == 0) {isym(ss,show_marks(ss)); return(0);}
      if (strcmp(tok,"show-mix-consoles") == 0) {isym(ss,show_mix_consoles(ss)); return(0);}
      if (strcmp(tok,"show-y-zero") == 0) {isym(ss,show_y_zero(ss)); return(0);}
      if (strcmp(tok,"showing-controls?") == 0) {sp = get_sp(ss,str[1]); if (sp) isym(ss,control_panel_open(sp)); else isym(ss,0); return(0);}
      if (strcmp(tok,"sinc-width") == 0) {isym(ss,sinc_width(ss)); return(0);}
      if (strcmp(tok,"snd-clm-samples") == 0)
	  {
	    file_info *hdr;
	    sp = NULL;
	    if ((str[1]) &&(*(str[1])))
	      {
		filename = sstr(str[1]);
		sp = find_sound(ss,filename);
	      }
	    if (!sp) sp = any_selected_sound(ss);
	    if (sp)
	      {
		filename = snd_tempnam(temp_dir(ss),"snd_");
		hdr = sp->hdr;
		save_edits_2(sp,filename,hdr->type,hdr->format,hdr->srate,NULL);
		ssym(ss,filename);
	      }
	    else isym(ss,0);
	    return(0);
	  }
      if (strcmp(tok,"snd-length") == 0) {cp = get_cp(ss,str[1],str[2]); if (cp) isym(ss,current_ed_samples(cp)); else isym(ss,0); return(0);}
      if (strcmp(tok,"snd-16-linear") == 0) {isym(ss,snd_16_linear); return(0);}
      if (strcmp(tok,"snd-16-linear-little-endian") == 0) {isym(ss,snd_16_linear_little_endian); return(0);}
      if (strcmp(tok,"snd-24-linear") == 0) {isym(ss,snd_24_linear); return(0);}
      if (strcmp(tok,"snd-32-float") == 0) {isym(ss,snd_32_float); return(0);}
      if (strcmp(tok,"snd-32-float-little-endian") == 0) {isym(ss,snd_32_float_little_endian); return(0);}
      if (strcmp(tok,"snd-32-linear") == 0) {isym(ss,snd_32_linear); return(0);}
      if (strcmp(tok,"snd-32-linear-little-endian") == 0) {isym(ss,snd_32_linear_little_endian); return(0);}
      if (strcmp(tok,"snd-64-double") == 0) {isym(ss,snd_64_double); return(0);}
      if (strcmp(tok,"snd-8-alaw") == 0) {isym(ss,snd_8_alaw); return(0);}
      if (strcmp(tok,"snd-8-linear") == 0) {isym(ss,snd_8_linear); return(0);}
      if (strcmp(tok,"snd-8-mulaw") == 0) {isym(ss,snd_8_mulaw); return(0);}
      if (strcmp(tok,"snd-8-unsigned") == 0) {isym(ss,snd_8_unsigned); return(0);}
      if (strcmp(tok,"sound-chans") == 0) {isym(ss,sound_chans(sstr(str[1]))); return(0);}
      if (strcmp(tok,"sound-comment") == 0) {ssym(ss,sound_comment(sstr(str[1]))); return(0);}
      if (strcmp(tok,"sound-data-format") == 0) {isym(ss,sound_data_format(sstr(str[1]))); return(0);}
      if (strcmp(tok,"sound-data-location") == 0) {isym(ss,sound_data_location(sstr(str[1]))); return(0);}
      if (strcmp(tok,"sound-datum-size") == 0) {isym(ss,sound_datum_size(sstr(str[1]))); return(0);}
      if (strcmp(tok,"sound-format-name") == 0) {ssym(ss,sound_format_name(istr(str[1]))); return(0);}
      if (strcmp(tok,"sound-header-type") == 0) {isym(ss,sound_header_type(sstr(str[1]))); return(0);}
      if (strcmp(tok,"sound-length") == 0) {isym(ss,sound_length(sstr(str[1]))); return(0);}
      if (strcmp(tok,"sound-samples") == 0) {isym(ss,sound_samples(sstr(str[1]))); return(0);}
      if (strcmp(tok,"sound-srate") == 0) {isym(ss,sound_srate(sstr(str[1]))); return(0);}
      if (strcmp(tok,"sound-style") == 0) {isym(ss,sound_style(ss)); return(0);}
      if (strcmp(tok,"sound-type-name") == 0) {ssym(ss,sound_type_name(istr(str[1]))); return(0);}
      if (strcmp(tok,"sound-type-specifier") == 0) {isym(ss,sound_type_specifier(sstr(str[1]))); return(0);}
      if (strcmp(tok,"spectro-color") == 0) {isym(ss,spectro_color(ss)); return(0);}
      if (strcmp(tok,"spectro-cutoff") == 0) {fsym(ss,spectro_cutoff(ss)); return(0);}
      if (strcmp(tok,"spectro-hop") == 0) {isym(ss,spectro_hop(ss));  return(0);}
      if (strcmp(tok,"spectro-x-angle") == 0) {fsym(ss,spectro_x_angle(ss)); return(0);}
      if (strcmp(tok,"spectro-x-scale") == 0) {fsym(ss,spectro_x_scale(ss)); return(0);}
      if (strcmp(tok,"spectro-y-angle") == 0) {fsym(ss,spectro_y_angle(ss)); return(0);}
      if (strcmp(tok,"spectro-y-scale") == 0) {fsym(ss,spectro_y_scale(ss)); return(0);}
      if (strcmp(tok,"spectro-z-angle") == 0) {fsym(ss,spectro_z_angle(ss)); return(0);}
      if (strcmp(tok,"spectro-z-scale") == 0) {fsym(ss,spectro_z_scale(ss)); return(0);}
      if (strcmp(tok,"speed") == 0) {sp = get_sp(ss,str[1]); if (sp) fsym(ss,sp->srate); else isym(ss,0); return(0);}
      if (strcmp(tok,"speed-style") == 0) {isym(ss,speed_style(ss)); return(0);}
      if (strcmp(tok,"speed-tones") == 0) {isym(ss,speed_tones(ss)); return(0);}
      if (strcmp(tok,"srate") == 0) {sp = get_sp(ss,str[1]); if (sp) isym(ss,(sp->hdr)->srate); else isym(ss,0); return(0);}
      if (strcmp(tok,"src") == 0) {src_env_or_num(ss,NULL,fstr(str[1]),TRUE,FALSE,"(src)"); isym(ss,0); return(0);} /* no env case */
      if (strcmp(tok,"stop") == 0) {sp = get_sp(ss,str[1]); if (sp) stop_playing(sp->playing); isym(ss,0); return(0);}
      if (strcmp(tok,"subsampling") == 0) {isym(ss,subsampling(ss)); return(0);}
      if (strcmp(tok,"syncing?") == 0) {sp = get_sp(ss,str[1]); if (sp) isym(ss,sp->syncing); return(0);}
      if (strcmp(tok,"selected-sound") == 0) {isym(ss,ss->selected_sound); return(0);}
      if (strcmp(tok,"save-sound") == 0) {sp = get_sp(ss,str[1]); if (sp) save_edits(sp,NULL); isym(ss,0); return(0);}
      if (strcmp(tok,"save-sound-as") == 0) 
	{
	  sp = get_sp(ss,str[2]);
	  save_edits_2(sp,sstr(str[1]),(sp->hdr)->type,(sp->hdr)->format,(sp->hdr)->srate,NULL);
	  isym(ss,0);
	  return(0);
	}
      break;
    case 't':
      if (strcmp(tok,"temp-dir") == 0) {ssym(ss,temp_dir(ss)); return(0);}
      if (strcmp(tok,"transform-dialog") == 0) {fire_up_transform_dialog(ss); isym(ss,0); return(0);}
      if (strcmp(tok,"transform-sample") == 0) {isym(ss,0); /* noop */ return(0);}
      if (strcmp(tok,"transform-samples") == 0) {isym(ss,0); /* noop */ return(0);}
      if (strcmp(tok,"transform-type") == 0) {isym(ss,transform_type(ss)); return(0);}
      break;
    case 'u':
      if (strcmp(tok,"uniting?") == 0) {sp = get_sp(ss,str[1]); if (sp) isym(ss,sp->combining); return(0);}
      if (strcmp(tok,"update-ffts") == 0) {map_over_chans(ss,calculate_fft,NULL); isym(ss,0); return(0);}
      if (strcmp(tok,"update-graphs") == 0) {map_over_chans(ss,update_graph,NULL); isym(ss,0); return(0);}
      if (strcmp(tok,"update-sound") == 0) {sp = get_sp(ss,str[1]); if (sp) snd_update(ss,sp); isym(ss,0); return(0);}
      if (strcmp(tok,"use-raw-defaults") == 0) {isym(ss,use_raw_defaults(ss)); return(0);}
      if (strcmp(tok,"undo") == 0) 
	{
	  ival = istr(str[1]); 
	  if (ival == 0) ival = 1; 
	  cp = get_cp(ss,str[2],str[3]); 
	  if (cp) 
	    {
	      undo_EDIT(cp,ival); 
	      update_graph(cp,NULL);
	    }
	  isym(ss,0);
	  return(0);
	}
      break;
    case 'v':
      if (strcmp(tok,"verbose-cursor") == 0) {isym(ss,verbose_cursor(ss)); return(0);}
      if (strcmp(tok,"version") == 0) {ssym(ss,SND_VERSION); return(0);}
      if (strcmp(tok,"vu-font") == 0) {ssym(ss,vu_font(ss)); return(0);}
      if (strcmp(tok,"vu-font-size") == 0) {fsym(ss,vu_font_size(ss)); return(0);}
      if (strcmp(tok,"vu-size") == 0) {fsym(ss,vu_size(ss)); return(0);}
      if (strcmp(tok,"view-sound") == 0) 
	{
	  ss->viewing = 1;
	  sp = snd_open_file(sstr(str[1]),ss);
	  ss->viewing = 0;
	  if (sp) isym(ss,sp->index); else isym(ss,0);
	  return(0);
	}
      break;
    case 'w':
      if (strcmp(tok,"wavelet-type") == 0) {isym(ss,wavelet_type(ss)); return(0);}
      if (strcmp(tok,"waving?") == 0) {cp = get_cp(ss,str[1],str[2]); if (cp) isym(ss,cp->waving); else isym(ss,0); return(0);}
      if (strcmp(tok,"wavo") == 0) {isym(ss,wavo(ss)); return(0);}
      if (strcmp(tok,"wavo-hop") == 0) {isym(ss,wavo_hop(ss)); return(0);}
      if (strcmp(tok,"wavo-trace") == 0) {isym(ss,wavo_trace(ss)); return(0);}
      if (strcmp(tok,"window-height") == 0) {isym(ss,snd_window_height(ss)); return(0);}
      if (strcmp(tok,"window-width") == 0) {isym(ss,snd_window_width(ss)); return(0);}
      if (strcmp(tok,"window-x") == 0) {isym(ss,window_x(ss)); return(0);}
      if (strcmp(tok,"window-y") == 0) {isym(ss,window_y(ss)); return(0);}
      break;
    case 'x':
      if (strcmp(tok,"x-axis-style") == 0) {isym(ss,x_axis_style(ss)); return(0);}
      if (strcmp(tok,"x-bounds") == 0) {cp = get_cp(ss,str[3],str[4]); if (cp) fsym(ss,(cp->axis)->x0); else isym(ss,0); return(0);}
      if (strcmp(tok,"xmax") == 0) {fsym(ss,xmax(ss)); return(0);}
      if (strcmp(tok,"xmin") == 0) {fsym(ss,xmin(ss)); return(0);}
      break;
    case 'y':
      if (strcmp(tok,"y-bounds") == 0) {cp = get_cp(ss,str[3],str[4]); if (cp) fsym(ss,(cp->axis)->y0); else isym(ss,0); return(0);}
      if (strcmp(tok,"ymax") == 0) {fsym(ss,ymax(ss)); return(0);}
      if (strcmp(tok,"ymin") == 0) {fsym(ss,ymin(ss)); return(0);}
      break;
    case 'z':
      if (strcmp(tok,"zero-pad") == 0) {isym(ss,zero_pad(ss)); return(0);}
      if (strcmp(tok,"zoom-focus-style") == 0) {isym(ss,zoom_focus_style(ss)); return(0);}
      break;
    default: break;
    }
  isym(ss,-1); /* don't hang clm on mistyped input! */
  return(-1);
}

static int clm_buffer_in_progress = 0;
static char init_file_buffer[128];

void snd_load_init_file(snd_state *ss)
{
  /* look for ".snd" on the home directory, and load it using the lisp-like CLM syntax given above */
  int fd;
  char *str;
  if (ss->init_file)
    {
      str = ss->init_file;
      if ((*str) == '~')
	{
	  strcpy(init_file_buffer,getenv("HOME"));
	  strcat(init_file_buffer,++str);
	  fd = open(init_file_buffer,O_RDONLY,0);
	}
      else fd = open(ss->init_file,O_RDONLY,0);
      if (fd == -1) return;
      if (!clm_buffer) 
	{
	  clm_buffer = (char *)snd_calloc(ss,CLM_BUFFER_SIZE,sizeof(char));
	  clm_buffer_size = CLM_BUFFER_SIZE;
	}
      clm_buffer_in_progress = 1;
      while (get_clm_string(ss,fd,FALSE));
      clm_buffer_in_progress = 0;
      close(fd);
    }
}

int snd_load_file(snd_state *ss,char *filename)
{
  int fd,old_progress;
  char *str,*saved_buf;
  str=filename;
  saved_buf = NULL;
  if ((*str) == '~')
    {
      strcpy(init_file_buffer,getenv("HOME"));
      strcat(init_file_buffer,++str);
      fd = open(init_file_buffer,O_RDONLY,0);
    }
  else fd = open(str,O_RDONLY,0);
  if (fd == -1) return(-1);
  if (!clm_buffer) 
    {
      clm_buffer = (char *)snd_calloc(ss,CLM_BUFFER_SIZE,sizeof(char));
      clm_buffer_size = CLM_BUFFER_SIZE;
    }
  old_progress = clm_buffer_in_progress;
  if (clm_buffer_in_progress)
    {
      saved_buf = (char *)snd_calloc(ss,clm_buffer_size,sizeof(char));
      strcpy(saved_buf,clm_buffer);
    }
  clm_buffer_in_progress = 1;
  while (get_clm_string(ss,fd,FALSE));
  close(fd);
  clm_buffer_in_progress = old_progress;
  if (saved_buf)
    {
      strcpy(clm_buffer,saved_buf);
      free(saved_buf);
    }
  return(0);
}

#endif /* HAVE_GUILE */
