Ejemplo n.º 1
0
void
ptt (int mode)
{
  if (mode == 1)
    {
      /* mic is muted so unmute and mute speaker */
      iaxc_input_level_set (level_in);
      if (!check_special_frq (selected_frequency))
	{
	  iaxc_output_level_set (0.0);
	  std::cout << "[SPEAK] unmute mic, mute speaker" << std::endl;
	}
      else
	{
	  std::cout << "[SPEAK] unmute mic" << std::endl;
	}
    }
  else
    {
      /* mic is unmuted so mute and unmute speaker */
      iaxc_input_level_set (0.0);
      if (!check_special_frq (selected_frequency))
	{
	  iaxc_output_level_set (level_out);
	  std::cout << "[LISTEN] mute mic, unmute speaker" << std::endl;
	}
      else
	{
	  std::cout << "[LISTEN] mute mic" << std::endl;
	}
    }
}
Ejemplo n.º 2
0
int iaxc_input_postprocess(void *audio, int len, int rate)
{
    double volume;
    static double lowest_volume = 1;
    int silent=0;

    if(!st || (speex_state_size != len) || (speex_state_rate != rate)) {
	if(st) speex_preprocess_state_destroy(st);
	st = speex_preprocess_state_init(len,rate);
	speex_state_size = len;
	speex_state_rate = rate;
	iaxc_set_speex_filters();
    }

    calculate_level(audio, len, &input_level);

    /* only preprocess if we're interested in VAD, AGC, or DENOISE */
    if((iaxc_filters & (IAXC_FILTER_DENOISE | IAXC_FILTER_AGC)) || iaxc_silence_threshold > 0)
	silent = !speex_preprocess(st, audio, NULL);

    /* Analog AGC: Bring speex AGC gain out to mixer, with lots of hysteresis */
    /* use a higher continuation threshold for AAGC than for VAD itself */
    if(!silent && 
	(iaxc_silence_threshold != 0) &&
	(iaxc_filters & IAXC_FILTER_AGC) && 
	(iaxc_filters & IAXC_FILTER_AAGC) && 
	(st->speech_prob > .20)
	) {
      static int i;
      double level;


      i++;

      if((i&0x3f) == 0) {
	  float loudness = st->loudness2;
	  if((loudness > 8000) || (loudness < 4000)) {
	    level =  iaxc_input_level_get();
	    /* fprintf(stderr, "loudness = %f, level = %f\n", loudness, level); */
	    /* lower quickly if we're really too hot */
	     if((loudness > 16000) && (level > 0.5)) {
		   /* fprintf(stderr, "lowering quickly level\n"); */
		   iaxc_input_level_set(level - 0.2);
	     } 
	     /* lower less quickly if we're a bit too hot */
	     else if((loudness > 8000) && (level >= 0.15)) {
		   /* fprintf(stderr, "lowering slowly level\n"); */
		   iaxc_input_level_set(level - 0.1);
	     }
	     /* raise slowly if we're cold */
	     else if((loudness < 4000) && (level <= 0.9)) {
		   /* fprintf(stderr, "raising level\n"); */
		   iaxc_input_level_set(level + 0.1);
	     }
	  }
      }
    }


    /* this is ugly.  Basically just don't get volume level if speex thought
     * we were silent.  just set it to 0 in that case */
    if(iaxc_silence_threshold > 0 && silent)
	input_level = 0;

    do_level_callback();

    volume = vol_to_db(input_level);

    if(volume < lowest_volume) lowest_volume = volume;

    if(iaxc_silence_threshold > 0)
	return silent;
    else
	return volume < iaxc_silence_threshold;
}
Ejemplo n.º 3
0
static int input_postprocess(void *audio, int len, int rate)
{
	static float lowest_volume = 1.0f;
	float volume;
	int silent = 0;

	if ( !st || speex_state_size != len || speex_state_rate != rate )
	{
		if (st)
			speex_preprocess_state_destroy(st);
		st = speex_preprocess_state_init(len,rate);
		speex_state_size = len;
		speex_state_rate = rate;
		set_speex_filters();
	}

	calculate_level((short *)audio, len, &input_level);

	/* only preprocess if we're interested in VAD, AGC, or DENOISE */
	if ( (iaxci_filters & (IAXC_FILTER_DENOISE | IAXC_FILTER_AGC)) ||
			iaxci_silence_threshold > 0.0f )
		silent = !speex_preprocess(st, (spx_int16_t *)audio, NULL);

	/* Analog AGC: Bring speex AGC gain out to mixer, with lots of hysteresis */
	/* use a higher continuation threshold for AAGC than for VAD itself */
	if ( !silent &&
	     iaxci_silence_threshold != 0.0f &&
	     (iaxci_filters & IAXC_FILTER_AGC) &&
	     (iaxci_filters & IAXC_FILTER_AAGC)
	   )
	{
		static int i = 0;

		i++;

		if ( (i & 0x3f) == 0 )
		{
			float loudness;
#ifdef SPEEX_PREPROCESS_GET_AGC_LOUDNESS
			speex_preprocess_ctl(st, SPEEX_PREPROCESS_GET_AGC_LOUDNESS, &loudness);
#else
			loudness = st->loudness2;
#endif
			if ( loudness > 8000.0f || loudness < 4000.0f )
			{
				const float level = iaxc_input_level_get();

				if ( loudness > 16000.0f && level > 0.5f )
				{
					/* lower quickly if we're really too hot */
					iaxc_input_level_set(level - 0.2f);
				}
				else if ( loudness > 8000.0f && level >= 0.15f )
				{
					/* lower less quickly if we're a bit too hot */
					iaxc_input_level_set(level - 0.1f);
				}
				else if ( loudness < 4000.0f && level <= 0.9f )
				{
					/* raise slowly if we're cold */
					iaxc_input_level_set(level + 0.1f);
				}
			}
		}
	}

	/* This is ugly. Basically just don't get volume level if speex thought
	 * we were silent. Just set it to 0 in that case */
	if ( iaxci_silence_threshold > 0.0f && silent )
		input_level = 0.0f;

	do_level_callback();

	volume = vol_to_db(input_level);

	if ( volume < lowest_volume )
		lowest_volume = volume;

	if ( iaxci_silence_threshold > 0.0f )
		return silent;
	else
		return volume < iaxci_silence_threshold;
}
Ejemplo n.º 4
0
int
main (int argc, char *argv[])
{
  int numbytes;
  static char buf[MAXBUFLEN];
  //int c;
  //int ret = 0;

	prog = strdup( base_name(argv[0]) );
  
	/* program header */
	std::cout << prog << " - a communication radio based on VoIP with IAX/Asterisk" << std::endl;
	std::cout << "Original (c) 2007-2011 by H. Wirtz <*****@*****.**>" << std::endl;
    std::cout << "OSX and Windows ports 2012 by Yves Sablonier and Geoff R. McLane, respectively." << std::endl;
	std::cout << "Version " << FGCOM_VERSION << " build " << SVN_REV << " date " << __DATE__ << ", at " << __TIME__ << std::endl;
	std::cout << "Using iaxclient library Version " << iaxc_version (tmp) << std::endl;
	std::cout << std::endl;

  /* init values */
  voipserver = DEFAULT_VOIP_SERVER;
  fgserver = DEFAULT_FG_SERVER;
  port = DEFAULT_FG_PORT;
  username = DEFAULT_USER;
  password = DEFAULT_PASSWORD;
  codec_option = DEFAULT_CODEC;
  mode = 0;			/* 0 = ATC mode, 1 = FG mode */
  positions_file = (char *) DEFAULT_POSITIONS_FILE;
  frequency_file = (char *) SPECIAL_FREQUENCIES_FILE;

#ifndef _WIN32
  /* catch signals */
  signal (SIGINT, quit);
  signal (SIGQUIT, quit);
  signal (SIGTERM, quit);
#endif

  /* setup iax */
#ifdef HAVE_IAX12
  if (iaxc_initialize (DEFAULT_MAX_CALLS))
#else
  if (iaxc_initialize (DEFAULT_IAX_AUDIO, DEFAULT_MAX_CALLS))
#endif
    fatal_error ("cannot initialize iaxclient!\nHINT: Have you checked the mic and speakers?");

  initialized = 1;

  // option parser
  fgcomInitOptions (fgcomOptionArray, argc, argv);

  // codec
  if (codec_option)
    {
      switch (codec_option)
	{
	case 'u':
	  codec = IAXC_FORMAT_ULAW;
	  break;
	case 'a':
	  codec = IAXC_FORMAT_ALAW;
	  break;
	case 'g':
	  codec = IAXC_FORMAT_GSM;
	  break;
	case '7':
	  codec = IAXC_FORMAT_G726;
	  break;
	case 's':
	  codec = IAXC_FORMAT_SPEEX;
	  break;
	}
    }

  // airport
  if (airport_option)
    {
      strtoupper (airport_option, airport, sizeof (airport));
    }

  // input level
  if (level_in > 1.0)
    {
      level_in = 1.0;
    }
  if (level_in < 0.0)
    {
      level_in = 0.0;
    }

  // output level
  if (level_out > 1.0)
    {
      level_out = 1.0;
    }
  if (level_out < 0.0)
    {
      level_out = 0.0;
    }

  // microphone boost
  if (mic_boost)
    {
      iaxc_mic_boost_set (1);
    }

  if (list_audio)
    {
      std::cout << "Input audio devices:" << std::endl;
      std::cout << report_devices (IAXC_AD_INPUT) << std::endl;

      std::cout << "Output audio devices:" << std::endl;
      std::cout << report_devices (IAXC_AD_OUTPUT) << std::endl;

      iaxc_shutdown ();
      exit (1);
    }


  if (audio_in)
    {
      set_device (audio_in, 0);
    }

  if (audio_out)
    {
      set_device (audio_out, 1);
    }

//#ifdef DEBUG
  /* Print any remaining command line arguments (not options). */
  //if (optind < argc) {
  //      printf ("non-option ARGV-elements: ");
  //      while (optind < argc)
  //              printf ("%s ", argv[optind++]);
  //      putchar ('\n');
  //}
//#endif

  /* checking consistency of arguments */
  if (frequency > 0.0 && frequency < 1000.0)
    {
      if (strlen (airport) == 0 || strlen (airport) > 4)
	{
	  strcpy (airport, "ZZZZ");
	}
      /* airport and frequency are given => ATC mode */
      mode = 0;
    }
  else
    {
      /* no airport => FG mode */
      mode = 1;
    }

	/* Read special frequencies file (if exists).
	 * If no file $(INSTALL_DIR)/special_frequencies.txt exists, then default frequencies
	 * are used and are hard coded.
	 */

    if (fix_input_files()) { /* adjust default input per OS */
        fatal_error ("cannot adjust default input files per OS!\nHINT: Maybe recompile with larger buffer.");
    }

	if((special_frequencies = read_special_frequencies(frequency_file)) == 0) {
        std::cout << "Failed to load file [" << frequency_file << "]!\nUsing internal defaults." << std::endl;
        special_frequencies = special_frq;
    } else {
        std::cout << "Loaded file [" << frequency_file << "]." << std::endl;
    }

	/* read airport frequencies and positions */
	airportlist = read_airports (positions_file);   /* never returns if fail! */

  /* preconfigure iax */
  std::cout << "Initializing IAX client as " << username << ":" <<
    "xxxxxxxxxxx@" << voipserver << std::endl;

  iaxc_set_callerid (const_cast < char *>(username),
		     const_cast < char *>("0125252525122750"));
  iaxc_set_formats (codec,
		    IAXC_FORMAT_ULAW | IAXC_FORMAT_GSM | IAXC_FORMAT_SPEEX);
  iaxc_set_event_callback (iaxc_callback);

  iaxc_start_processing_thread ();

  if (username && password && voipserver)
    {
      reg_id =
	iaxc_register (const_cast < char *>(username),
		       const_cast < char *>(password),
		       const_cast < char *>(voipserver));
#ifdef DEBUG
      std::cout << "DEBUG: Registered as '" << username << "' at '" << voipserver <<
	"'." << std::endl;
#endif
    }
  else
    {
      std::cout << "Failed iaxc_register!\nHINT: Check user name, pwd and ip of server." << std::endl;
      exitcode = 130;
      quit (0);
    }

  iaxc_millisleep (DEFAULT_MILLISLEEP);

  /* main loop */
#ifdef DEBUG
  std::cout << "Entering main loop in mode " << mode_map[mode] << "." <<
    std::endl;
#endif

  if (mode == 1)
    {
      /* only in FG mode */
      netInit ();
      netSocket fgsocket;
      fgsocket.open (false);
      fgsocket.bind (fgserver, port);

      /* mute mic, speaker on */
      iaxc_input_level_set (0);
      iaxc_output_level_set (level_out);

      ulClock clock;
      clock.update ();
      double next_update = clock.getAbsTime () + DEFAULT_ALARM_TIMER;
      /* get data from flightgear */
      while (1)
	{
	  clock.update ();
	  double wait = next_update - clock.getAbsTime ();
	  if (wait > 0.001)
	    {
	      netSocket *readsockets[2] = { &fgsocket, 0 };
	      if (fgsocket.select (readsockets, readsockets + 1,
				   (int) (wait * 1000)) == 1)
		{
		  netAddress their_addr;
		  if ((numbytes =
		       fgsocket.recvfrom (buf, MAXBUFLEN - 1, 0,
					  &their_addr)) == -1)
		    {
		      perror ("recvfrom");
		      exit (1);
		    }
		  buf[numbytes] = '\0';
#ifdef DEBUG
		  std::
		    cout << "DEBUG: got packet from " << their_addr.getHost () << ":"
		    << their_addr.getPort () << std::endl;
		  std::cout << "packet is " << numbytes << " bytes long" <<
		    std::endl;
		  std::
		    cout << "packet contains \"" << buf << "\"" << std::endl;
#endif
		  process_packet (buf);
		}
	    }
	  else
	    {
	      alarm_handler (0);
	      clock.update ();
	      next_update = clock.getAbsTime () + DEFAULT_ALARM_TIMER;
	    }
	}
    }
  else
    {
      /* only in ATC mode */
      struct pos p;

      /* mic on, speaker on */
      iaxc_input_level_set (level_in);
      iaxc_output_level_set (level_out);

      /* get geo positions of the airport */
      p = posbyicao (airportlist, airport);

      icao2number (airport, frequency, tmp);
#ifdef DEBUG
      printf ("DEBUG: dialing %s %3.3f MHz: %s\n", airport, frequency, tmp);
#endif
      do_iaxc_call (username, password, voipserver, tmp);
      /* iaxc_select_call (0); */

      while (1)
	{
	  /* sleep endless */
	  ulSleep (3600);
	}
    }

  /* should never be reached */
  exitcode = 999;
  quit (0);
}