Ejemplo n.º 1
0
/** 
 * <JA>
 * メイン関数
 * 
 * @param argc [in] 引数列の長さ
 * @param argv [in] 引数列
 * 
 * @return 
 * </JA>エラー時 1,通常終了時 0 を返す.
 * <EN>
 * Main function.
 * 
 * @param argc [in] number of argument.
 * @param argv [in] array of arguments.
 * 
 * @return 1 on error, 0 on success.
 * </EN>
 */
int
main(int argc, char *argv[])
{
  Recog *recog;
  Jconf *jconf;
  int ret;
  int i;
  boolean is_continues;

  /* create instance */
  recog = j_recog_new();
  jconf = j_jconf_new();
  recog->jconf = jconf;

  /********************/
  /* setup parameters */
  /********************/
  /* register additional options */
  j_add_option("-in", 1, 1, "input from", opt_in);
  j_add_option("-out", 1, 1, "output to", opt_out);
  j_add_option("-server", 1, 1, "hostname (-out adinnet)", opt_server);
  j_add_option("-NA", 1, 1, "NetAudio server host:unit (-in netaudio)", opt_NA);
  j_add_option("-port", 1, 1, "port number (-out adinnet)", opt_port);
  j_add_option("-inport", 1, 1, "port number (-in adinnet)", opt_inport);
  j_add_option("-filename", 1, 1, "(base) filename to record (-out file)", opt_filename);
  j_add_option("-startid", 1, 1, "recording start id (-out file)", opt_startid);
  j_add_option("-freq", 1, 1, "sampling frequency in Hz", opt_freq);
  j_add_option("-nosegment", 0, 0, "not segment input speech, record all", opt_nosegment);
  j_add_option("-segment", 0, 0, "force segment input speech", opt_segment);
  j_add_option("-oneshot", 0, 0, "exit after the first input", opt_oneshot);
  j_add_option("-raw", 0, 0, "save in raw (BE) format", opt_raw);
  j_add_option("-autopause", 0, 0, "automatically pause at each input end", opt_autopause);
  j_add_option("-loosesync", 0, 0, "loose sync of resume among servers", opt_loosesync);
  j_add_option("-rewind", 1, 1, "rewind to the msec", opt_rewind);
  j_add_option("-h", 0, 0, "display this help", opt_help);
  j_add_option("-help", 0, 0, "display this help", opt_help);
  j_add_option("--help", 0, 0, "display this help", opt_help);

  /* when no argument, output help and exit */
  if (argc <= 1) {
    opt_help(jconf, NULL, 0);
    return 0;
  }

  /* read arguments and set parameters */
  if (j_config_load_args(jconf, argc, argv) == -1) {
    fprintf(stderr, "Error reading arguments\n");
    return -1;
  }

  /* check needed arguments */
  if (speech_output == SPOUT_FILE && filename == NULL) {
    fprintf(stderr, "Error: output filename not specified\n");
    return(-1);
  }
  if (speech_output == SPOUT_ADINNET && adinnet_servnum < 1) {
    fprintf(stderr, "Error: adinnet server name for output not specified\n");
    return(-1);
  }
  if (jconf->input.speech_input == SP_ADINNET &&
      speech_output != SPOUT_ADINNET &&
      adinnet_servnum >= 1) {
    fprintf(stderr, "Warning: you specified port num by -port, but it's for output\n");
    fprintf(stderr, "Warning: you may specify input port by -inport instead.\n");
    fprintf(stderr, "Warning: now the default value (%d) will be used\n", ADINNET_PORT);
  }
#ifdef USE_NETAUDIO
  if (jconf->input.speech_input == SP_NETAUDIO && jconf->input.netaudio_devname == NULL) {
    fprintf(stderr, "Error: NetAudio server name not specified\n");
    return(-1);
  }
#endif
  if (adinnet_portnum != adinnet_servnum) {
    /* if only one server, use default */
    if (adinnet_servnum == 1) {
      adinnet_port[0] = ADINNET_PORT;
      adinnet_portnum = 1;
    } else {
      fprintf(stderr, "Error: you should specify both server names and different port for each!\n");
      fprintf(stderr, "\tserver:");
      for(i=0;i<adinnet_servnum;i++) fprintf(stderr, " %s", adinnet_serv[i]);
      fprintf(stderr, "\n\tport  :");
      for(i=0;i<adinnet_portnum;i++) fprintf(stderr, " %d", adinnet_port[i]);
      fprintf(stderr, "\n");
      return(-1);
    }
  }

  /* set Julius default parameters for unspecified acoustic parameters */
  apply_para(&(jconf->am_root->analysis.para), &(jconf->am_root->analysis.para_default));

  /* set some values */
  jconf->input.sfreq = jconf->am_root->analysis.para.smp_freq;
  jconf->input.period = jconf->am_root->analysis.para.smp_period;
  jconf->input.frameshift = jconf->am_root->analysis.para.frameshift;
  jconf->input.framesize = jconf->am_root->analysis.para.framesize;

  /* disable successive segmentation when no segmentation available */
  if (!jconf->detect.silence_cut) continuous_segment = FALSE;
  /* store sampling rate locally */
  sfreq = jconf->am_root->analysis.para.smp_freq;

  /********************/
  /* setup for output */
  /********************/
  if (speech_output == SPOUT_FILE) {
    /* allocate work area for output file name */
    if (continuous_segment) {
      outpath = (char *)mymalloc(strlen(filename) + 10);
    } else {
      if (use_raw) {
	outpath = filename;
      } else {
	outpath = new_output_filename(filename, ".wav");
      }
    }
  } else if (speech_output == SPOUT_ADINNET) {
    /* connect to adinnet server(s) */
    for(i=0;i<adinnet_servnum;i++) {
      fprintf(stderr, "connecting to #%d (%s:%d)...", i+1, adinnet_serv[i], adinnet_port[i]);
      sd[i] = make_connection(adinnet_serv[i], adinnet_port[i]);
      if (sd[i] < 0) return 1;	/* on error */
      fprintf(stderr, "connected\n");
    }
  } else if (speech_output == SPOUT_STDOUT) {
    /* output to stdout */
    fd = 1;
    fprintf(stderr,"[STDOUT]");
  }

  /**********************/
  /* interrupt handling */
  /**********************/
  if (signal(SIGINT, interrupt_record) == SIG_ERR) {
    fprintf(stderr, "Warning: signal interruption may collapse output\n");
  }
  if (signal(SIGTERM, interrupt_record) == SIG_ERR) {
    fprintf(stderr, "Warning: signal interruption may collapse output\n");
  }
#ifdef SIGPIPE
  if (signal(SIGPIPE, interrupt_record) == SIG_ERR) {
    fprintf(stderr, "Warning: signal interruption may collapse output\n");
  }
#endif
#ifdef SIGQUIT
  if (signal(SIGQUIT, interrupt_record) == SIG_ERR) {
    fprintf(stderr, "Warning: signal interruption may collapse output\n");
  }
#endif

  /***************************/
  /* initialize input device */
  /***************************/
  if (jconf->input.speech_input == SP_ADINNET) {
    jconf->input.adinnet_port = adinnet_port_in;
  }
  if (j_adin_init(recog) == FALSE) {
    fprintf(stderr, "Error in initializing adin device\n");
    return -1;
  }
  if (rewind_msec > 0) {
    /* allow adin module to keep triggered speech while pausing */
#ifdef HAVE_PTHREAD
    if (recog->adin->enable_thread) {
      recog->adin->ignore_speech_while_recog = FALSE;
    }
#endif
  }

  /*********************/
  /* add some callback */
  /*********************/
  callback_add(recog, CALLBACK_EVENT_SPEECH_START, record_trigger_time, NULL);


  /**************************************/
  /* display input/output configuration */
  /**************************************/
  put_status(recog);

  /*******************/
  /* begin recording */
  /*******************/
  if (continuous_segment) {	/* reset parameter for successive output */
    total_speechlen = 0;
    sid = startid;
  }
  fprintf(stderr,"[start recording]\n");
  if (jconf->input.speech_input == SP_RAWFILE) file_counter = 0;

  /*********************/
  /* input stream loop */
  /*********************/
  while(1) {

    /* begin A/D input of a stream */
    ret = j_open_stream(recog, NULL);
    switch(ret) {
    case 0:			/* succeeded */
      break;
    case -1:      		/* error */
      /* go on to next input */
      continue;
    case -2:			/* end of recognition process */
      switch(jconf->input.speech_input) {
      case SP_RAWFILE:
	fprintf(stderr, "%d files processed\n", file_counter);
	break;
      case SP_STDIN:
	fprintf(stderr, "reached end of input on stdin\n");
	break;
      default:
	fprintf(stderr, "failed to begin input stream\n");
      }
      /* exit recording */
      goto record_end;
    }

    /*********************************/
    /* do VAD and recording */
    /*********************************/
    do {
      /* process one segment with segmentation */
      /* for incoming speech input, speech detection and segmentation are
	 performed and, adin_callback_* is called for speech output for each segment block.
      */
      /* adin_go() return when input segmented by long silence, or input stream reached to the end */
      speechlen = 0;
      stop_at_next = FALSE;
      if (jconf->input.speech_input == SP_MIC) {
	fprintf(stderr, "<<< please speak >>>");
      }
      if (speech_output == SPOUT_ADINNET) {
	ret = adin_go(adin_callback_adinnet, adinnet_check_command, recog);
      } else {
	ret = adin_go(adin_callback_file, NULL, recog);
      }
      /* return value of adin_go:
	 -2: input terminated by pause command from adinnet server
	 -1: input device read error or callback process error
	 0:  paused by input stream (end of file, etc..)
	 >0: detected end of speech segment:
             by adin-cut, or by callback process
	 (or return value of ad_check (<0) (== not used in this program))
      */
      /* if PAUSE or TERMINATE command has been received while input,
	 stop_at_next is TRUE here  */
      switch(ret) {
      case -2:	     /* terminated by terminate command from server */
	fprintf(stderr, "[terminated by server]\n");
	break;
      case -1:		     /* device read error or callback error */
	fprintf(stderr, "[error]\n");
	break;
      case 0:			/* reached to end of input */
	fprintf(stderr, "[eof]\n");
	break;
      default:	  /* input segmented by silence or callback process */
	fprintf(stderr, "[segmented]\n");
	break;
      }
      
      if (ret == -1) {
	/* error in input device or callback function, so terminate program here */
	return 1;
      }

      /*************************/
      /* one segment processed */
      /*************************/
      if (speech_output == SPOUT_FILE) {
	/* close output files */
	if (close_files() == FALSE) return 1;
      } else if (speech_output == SPOUT_ADINNET) {
	if (speechlen > 0) {
	  if (ret >= 0 || stop_at_next) { /* segmented by adin-cut or end of stream or server-side command */
	    /* send end-of-segment ack to client */
	    adin_send_end_of_segment();
	  }
	  /* output info */
	  printf("sent: %d samples (%.2f sec.) [%6d (%5.2fs) - %6d (%5.2fs)]\n", 
		 speechlen, (float)speechlen / (float)sfreq,
		 trigger_sample, (float)trigger_sample / (float)sfreq, 
		 trigger_sample + speechlen, (float)(trigger_sample + speechlen) / (float)sfreq);
	}
      }

      /*************************************/
      /* increment ID and total sample len */
      /*************************************/
      if (continuous_segment) {
	total_speechlen += speechlen;
	sid++;
      }

      /***************************************************/
      /* with adinnet server, if terminated by           */
      /* server-side PAUSE command, wait for RESUME here */
      /***************************************************/
      if (pause_each) {
	/* pause at each end */
	//if (speech_output == SPOUT_ADINNET && speechlen > 0) {
	if (speech_output == SPOUT_ADINNET) {
	  if (adinnet_wait_command() < 0) {
	    /* command error: terminate program here */
	    return 1;
	  }
	}
      } else {
	if (speech_output == SPOUT_ADINNET && stop_at_next) {
	  if (adinnet_wait_command() < 0) {
	    /* command error: terminate program here */
	    return 1;
	  }
	}
      }

      /* loop condition check */
      is_continues = FALSE;
      if (continuous_segment && (ret > 0 || ret == -2)) {
	is_continues = TRUE;
      }
      
    } while (is_continues); /* to the next segment in this input stream */

    /***********************/
    /* end of input stream */
    /***********************/
    adin_end(recog->adin);

  } /* to the next input stream (i.e. next input file in SP_RAWFILE) */

 record_end:

  if (speech_output == SPOUT_FILE) {
    if (continuous_segment) {
      printf("recorded total %d samples (%.2f sec.) segmented to %s.%04d - %s.%04d files\n", total_speechlen, (float)total_speechlen / (float)sfreq, filename, 0, filename, sid-1);
    }
  }

  return 0;
}
Ejemplo n.º 2
0
/** 
 * <JA>
 * メイン関数
 * 
 * @param argc [in] 引数列の長さ
 * @param argv [in] 引数列
 * 
 * @return 
 * </JA>エラー時 1,通常終了時 0 を返す.
 * <EN>
 * Main function.
 * 
 * @param argc [in] number of argument.
 * @param argv [in] array of arguments.
 * 
 * @return 1 on error, 0 on success.
 * </EN>
 */
int
main(int argc, char *argv[])
{
  int silence_cut = 1;	/* 0=disabled, 1=enabled, 2=undef */

  /* parse option */
  opt_parse(argc, argv);

  /* select microphone input */
  if (adin_select(SP_MIC) == FALSE) {
    j_printerr("Error: microphone input is not supported\n");
    return(1);
  }
  
  /* ready the microphone (arg is dummy) */
  if (use_48to16) {
    if (sfreq != 16000) {
      j_printerr("Error: in 48kHz mode, required rate should be 16kHz!\n");
      return(1);
    }
    /* setup for down sampling */
    adin_setup_48to16();
    /* set device sampling rate to 48kHz */
    if (adin_standby(48000, NULL) == FALSE) { /* fail */
      j_printerr("Error: failed to ready input device to 48kHz\n");
      return(1);
    }
  } else {
    if (adin_standby(sfreq, NULL) == FALSE) {
      j_printerr("Error: failed to standby input\n");
      return(1);
    }
  }
  /* set device-independent param */
  adin_setup_param(silence_cut, strip_zero_sample, level_thres, zero_cross_num, margin, margin, sfreq, TRUE, use_zmean);/* use same margin for head and tail */

  /* file check */
  if (!stout) {
    if (access(filename, F_OK) == 0) {
      if (access(filename, W_OK) == 0) {
	fprintf(stderr, "Warning: overwriting file \"%s\"\n", filename);
      } else {
	perror("adinrec");
	return(1);
      }
    }
  } /* output file will be opened when triggered (not here) */

  /* set interrupt signal handler to properly close output file */
  if (signal(SIGINT, interrupt_record) == SIG_ERR) {
    fprintf(stderr, "Warning: signal intterupt may collapse output\n");
  }
  
  /* do recoding */
  speechlen = 0;
  
  adin_begin();
  j_printerr("<<< please speak >>>"); /* moved from adin-cut.c */
  adin_go(adin_callback_file, NULL);
  adin_end();

  /* close file and output status */
  close_file();

  return 1;
}
Ejemplo n.º 3
0
int
main(int argc, char *argv[])
{
  Recog *recog;
  Jconf *jconf;
  float *ss;
  MFCCWork *wrk;

  /* create instance */
  recog = j_recog_new();
  jconf = j_jconf_new();
  recog->jconf = jconf;

  /* set application-specific additional options */
  j_add_option("-freq", 1, 1, "sampling freq in Hz", opt_freq);
  j_add_option("-len", 1, 1, "record length in msec", opt_len);
  j_add_option("-h", 0, 0, "display this help", opt_help);
  j_add_option("-help", 0, 0, "display this help", opt_help);
  j_add_option("--help", 0, 0, "display this help", opt_help);

  /* when no argument, output help and exit */
  if (argc <= 1) {
    opt_help(jconf, NULL, 0);
    return 0;
  }

  /* regard last arg as filename */
  if (strmatch(argv[argc-1], "-")) {
    stout = TRUE;
  } else {
    filename = argv[argc-1];
  }

  /* set default as same as "-input mic" */
  jconf->input.type = INPUT_WAVEFORM;
  jconf->input.speech_input = SP_MIC;
  jconf->input.device = SP_INPUT_DEFAULT;
  /* process config and load them */
  if (j_config_load_args(jconf, argc-1, argv) == -1) {
    fprintf(stderr, "Error reading arguments\n");
    return -1;
  }
  /* force some default values */
  jconf->detect.silence_cut  = 0; /* disable silence cut */
  jconf->preprocess.strip_zero_sample = TRUE; /* strip zero samples */
  jconf->detect.level_thres = 0;	/* no VAD, record all */
  /* set Julius default parameters for unspecified acoustic parameters */
  apply_para(&(jconf->am_root->analysis.para), &(jconf->am_root->analysis.para_default));
  /* set some values */
  jconf->input.sfreq = jconf->am_root->analysis.para.smp_freq;
  jconf->input.period = jconf->am_root->analysis.para.smp_period;
  jconf->input.frameshift = jconf->am_root->analysis.para.frameshift;
  jconf->input.framesize = jconf->am_root->analysis.para.framesize;

  sfreq = jconf->am_root->analysis.para.smp_freq;

  /* output file check */
  if (!stout) {
    if (access(filename, F_OK) == 0) {
      if (access(filename, W_OK) == 0) {
	fprintf(stderr, "Warning: overwriting file \"%s\"\n", filename);
      } else {
	perror("mkss");
	return(1);
      }
    }
  }

  /* allocate speech store buffer */
  samples = sfreq * slen / 1000;
  speech = (SP16 *)mymalloc(sizeof(SP16) * samples);

  /* allocate work area to compute spectrum */
  wrk = WMP_work_new(&(jconf->am_root->analysis.para));
  if (wrk == NULL) {
    jlog("ERROR: m_fusion: failed to initialize MFCC computation for SS\n");
    return -1;
  }

  /* initialize input device */
  if (j_adin_init(recog) == FALSE) {
    fprintf(stderr, "Error in initializing adin device\n");
    return -1;
  }

  /* open device */
  if (j_open_stream(recog, NULL) < 0) {
    fprintf(stderr, "Error in opening adin device\n");
  }

  /* record mic input */
  fprintf(stderr, "%dHz recording for %.2f seconds of noise\n", sfreq, (float)slen /(float)1000);
  speechnum = 0;
  adin_go(adin_callback, NULL, recog);

  /* close device */
  adin_end(recog->adin);
  fprintf(stderr, "\n%d samples (%d bytes, %.1f sec) recorded\n", samples, samples * sizeof(SP16), (float)samples / (float)sfreq);

  /* compute SS */
  fprintf(stderr, "compute SS:\n");
  fprintf(stderr, "  fsize : %4d samples (%.1f msec)\n", jconf->input.framesize, (float)jconf->input.framesize * 1000.0/ (float)sfreq);
  fprintf(stderr, "  fshift: %4d samples (%.1f msec)\n", jconf->input.frameshift, (float)jconf->input.frameshift * 1000.0/ (float)sfreq);

  ss = new_SS_calculate(speech, samples, &sslen, wrk, &(jconf->am_root->analysis.para));

  fprintf(stderr, "  points: %4d\n", sslen);
  fprintf(stderr, "noise spectrum was measured\n");
  
  /* open file for recording */
  fprintf(stderr, "writing average noise spectrum to [%s]...", filename);
  if (stout) {
    fd = 1;
  } else {
    if ((fd = open(filename, O_CREAT | O_RDWR
#ifdef O_BINARY
		   | O_BINARY
#endif
		   , 0644)) == -1) {
      perror("mkss");
      return(1);
    }
  }
  x = sslen;
#ifndef WORDS_BIGENDIAN
  swap_bytes((char *)&x, sizeof(int), 1);
#endif
  if (write(fd, &x, sizeof(int)) < sizeof(int)) {
    perror("mkss");
    return(1);
  }
#ifndef WORDS_BIGENDIAN
  swap_bytes((char *)ss, sizeof(float), sslen);
#endif
  if (write(fd, ss, sslen * sizeof(float)) < sslen * sizeof(float)) {
    perror("mkss");
    return(1);
  }
  if (!stout) {
    if (close(fd) < 0) {
      perror("mkss");
      return(1);
    }
  }
  fprintf(stderr, "done\n");

  WMP_free(wrk);

  return 0;
}
Ejemplo n.º 4
0
/** 
 * <JA>
 * メイン関数
 * 
 * @param argc [in] 引数列の長さ
 * @param argv [in] 引数列
 * 
 * @return 
 * </JA>エラー時 1,通常終了時 0 を返す.
 * <EN>
 * Main function.
 * 
 * @param argc [in] number of argument.
 * @param argv [in] array of arguments.
 * 
 * @return 1 on error, 0 on success.
 * </EN>
 */
int
main(int argc, char *argv[])
{
  Recog *recog;
  Jconf *jconf;

  /* create instance */
  jconf = j_jconf_new();

  /* register application options */
  j_add_option("-freq", 1, 1, "sampling frequency in Hz", opt_freq);
  j_add_option("-raw", 0, 0, "save in raw (BE) format", opt_raw);
  j_add_option("-h", 0, 0, "display this help", opt_help);
  j_add_option("-help", 0, 0, "display this help", opt_help);
  j_add_option("--help", 0, 0, "display this help", opt_help);

  /* when no argument, output help and exit */
  if (argc <= 1) {
    opt_help(jconf, NULL, 0);
    return 0;
  }

  /* regard last arg as filename */
  if (strmatch(argv[argc-1], "-")) {
    stout = TRUE;
    use_raw = TRUE;
  } else {
    filename = argv[argc-1];
  }

  /* set default as same as "-input mic" */
  jconf->input.type = INPUT_WAVEFORM;
  jconf->input.speech_input = SP_MIC;
  jconf->input.device = SP_INPUT_DEFAULT;

  /* read arguments and set parameters */
  if (j_config_load_args(jconf, argc-1, argv) == -1) {
    fprintf(stderr, "Error reading arguments\n");
    return -1;
  }

  /* exit if no file name specified */
  if (filename == NULL && stout == FALSE) {
    opt_help(jconf, NULL, 0);
    return -1;
  }

  /* finalize config */
  //if (j_jconf_finalize(jconf) == FALSE) return -1;

  /* set Julius default parameters for unspecified acoustic parameters */
  apply_para(&(jconf->am_root->analysis.para), &(jconf->am_root->analysis.para_default));
  
  /* set some values */
  jconf->input.sfreq = jconf->am_root->analysis.para.smp_freq;
  jconf->input.period = jconf->am_root->analysis.para.smp_period;
  jconf->input.frameshift = jconf->am_root->analysis.para.frameshift;
  jconf->input.framesize = jconf->am_root->analysis.para.framesize;

  /* preliminary check of output file */
  /* (output file will be opened later when input is triggered) */
  if (!stout) {
    if (access(filename, F_OK) == 0) {
      if (access(filename, W_OK) == 0) {
	fprintf(stderr, "Warning: overwriting file \"%s\"\n", filename);
      } else {
	perror("adinrec");
	return(1);
      }
    }
  }
  /* set signal handlers to properly close output file */
  if (signal(SIGINT, interrupt_record) == SIG_ERR) {
    fprintf(stderr, "Warning: signal intterupt may collapse output\n");
  }
  if (signal(SIGTERM, interrupt_record) == SIG_ERR) {
    fprintf(stderr, "Warning: signal intterupt may collapse output\n");
  }
#ifdef SIGPIPE
  if (signal(SIGPIPE, interrupt_record) == SIG_ERR) {
    fprintf(stderr, "Warning: signal intterupt may collapse output\n");
  }
#endif
#ifdef SIGQUIT
  if (signal(SIGQUIT, interrupt_record) == SIG_ERR) {
    fprintf(stderr, "Warning: signal intterupt may collapse output\n");
  }
#endif

  recog = j_recog_new();
  recog->jconf = jconf;

  /* initialize input device */
  if (j_adin_init(recog) == FALSE) {
    fprintf(stderr, "Error in initializing adin device\n");
    return -1;
  }
  /* open device */
  if (j_open_stream(recog, NULL) < 0) {
    fprintf(stderr, "Error in opening adin device\n");
  }
  /* do recoding */
  speechlen = 0;
  sfreq = recog->jconf->input.sfreq;
  fprintf(stderr, "<<< please speak >>>"); /* moved from adin-cut.c */
  adin_go(adin_callback_file, NULL, recog);
  /* close device */
  adin_end(recog->adin);
  /* close output file */
  close_file();

  return 0;
}