/* file = grab.c
   This program
     1. measures ambiant noise level 
     2. outputs a click to indicate it is ready
     3. reads from /dev/audio, checking for signal-or-silence in real time
     4. clicks to indicate recording terminated
     5. echos the recorded signal
     6. writes out detected signal, in raw audio form */
/* Nigel Ward, University of Tokyo, April 1994 */

#include "cheap.h"

#define INTERVAL 512   /* samples per chunk */

/*-----------------------------------------------------------------------------*/
static char raw_data[MAX_SAMPLES];
static int echop, monitorp;
static int out_fd;
static float threshold;
static char info_string[MAX_INFO_STRING_LEN];

main(argc,argv)      int argc;      char *argv[];
{
  int finished, signal_start, signal_end, data_length, bytes_written;

  process_grab_args(argc, argv);

  measure_noise_level(monitorp, DEFAULT_THRESHOLD);
  init_grab(MAX_SAMPLES, INTERVAL);

  finished = FALSE;
  beep();
  while(!finished) {
    finished = grab_some(raw_data, &signal_start, &signal_end, monitorp); }

  clean_up_grab();
  beep();

  data_length = signal_end - signal_start;
  write_audio_hdr(out_fd, info_string, data_length,
		  AUDIO_ENCODING_ULAW, SAMPLING_RATE, 1);  /* shouldn't be hardwired */
  bytes_written = write(out_fd, raw_data + signal_start, data_length); 
  fprintf(stderr, "%d bytes written \n", bytes_written); 
  if (echop) {echo_signal(raw_data, signal_start, data_length);}

  close(out_fd);
}

/*-----------------------------------------------------------------------------*/
process_grab_args(argc, argv)    int argc;      char *argv[];
{
  int i; char new_path[MAX_PATH_LEN];

  threshold = DEFAULT_THRESHOLD;
  echop = TRUE;
  strcpy(info_string, "recorded-by-grab");
  i = 1;
  while(i < argc && argv[i][0] == '-') {
    switch(argv[i][1]) {
    case NULL: 
      fprintf(stderr, "*** writing to stdout ***\n");
      out_fd = 1;
      break;
    case 's': echop = FALSE;  break;
    case 'm': monitorp = TRUE;  break;
    case 't': i++; sscanf(argv[i], "%f", &threshold);  break;
    case 'i': i++; strcpy(info_string, argv[i]);  break;
    case 'h':   grab_usage(); exit(NORMAL);    break;
    default: 
      fprintf(stderr, "   (%c is not a known option)\n", argv[i][0]);
      grab_usage(); exit(STRANGE); break; 
    }
    i++;
  }
  if (i < argc) {
    make_new_path(new_path, argv[i], ".au");
    out_fd =  open(new_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (i + 1 < argc)
      fprintf(stderr," Note: ignoring stuff after filename: %s\n",argv[i]);
  }
  else  if (out_fd == 0) {
    /* no file name given, nor stdout specified, so write it to /tmp/new.au */
    out_fd =  open("/tmp/new.au", O_WRONLY | O_CREAT | O_TRUNC, 0644); }
}

/*-----------------------------------------------------------------------------*/
grab_usage()  
{  
  fprintf(stderr, "usage: \n");
  fprintf(stderr, "   grab [options] [output_file.au]\n");
  fprintf(stderr, "Options \n");
  fprintf(stderr, "  -    write to standard output)\n");
  fprintf(stderr, "  -i <string> set info string (for .au file header)\n");
  fprintf(stderr, "  -s   silent (don't echo recorded input to speaker)\n");
  fprintf(stderr, "  -m   continually show monitor result (signal or noise)\n");
  fprintf(stderr, "  -t <ratio> set threshold for signal detection (default = %.2f) \n",
	  DEFAULT_THRESHOLD);
}

/*-----------------------------------------------------------------------------*/
