示例#1
0
文件: amr.c 项目: GGGO/baresip
static int encode_update(struct auenc_state **aesp,
			 const struct aucodec *ac,
			 struct auenc_param *prm, const char *fmtp)
{
	struct auenc_state *st;
	int err = 0;
	(void)prm;
	(void)fmtp;

	if (!aesp || !ac)
		return EINVAL;

	if (*aesp)
		return 0;

	st = mem_zalloc(sizeof(*st), encode_destructor);
	if (!st)
		return ENOMEM;

	st->ac = ac;

	switch (ac->srate) {

#ifdef AMR_NB
	case 8000:
		st->enc = Encoder_Interface_init(0);
		break;
#endif

#ifdef AMR_WB
	case 16000:
		st->enc = E_IF_init();
		break;
#endif
	}

	if (!st->enc)
		err = ENOMEM;

	if (err)
		mem_deref(st);
	else
		*aesp = st;

	return err;
}
示例#2
0
static GstStateChangeReturn
gst_voamrwbenc_state_change (GstElement * element, GstStateChange transition)
{
  GstVoAmrWbEnc *amrwbenc;
  GstStateChangeReturn ret;

  amrwbenc = GST_VOAMRWBENC (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      if (!(amrwbenc->handle = E_IF_init ()))
        return GST_STATE_CHANGE_FAILURE;
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      amrwbenc->rate = 0;
      amrwbenc->channels = 0;
      amrwbenc->ts = 0;
      amrwbenc->discont = FALSE;
      gst_adapter_clear (amrwbenc->adapter);
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_NULL:
      E_IF_exit (amrwbenc->handle);
      break;
    default:
      break;
  }

  return ret;
}
示例#3
0
/*
 * Open codec.
 */
static pj_status_t amr_codec_open( pjmedia_codec *codec, 
				   pjmedia_codec_param *attr )
{
    struct amr_data *amr_data = (struct amr_data*) codec->codec_data;
    pjmedia_codec_amr_pack_setting *setting;
    unsigned i;
    pj_uint8_t octet_align = 0;
    pj_int8_t enc_mode;
    const pj_str_t STR_FMTP_OCTET_ALIGN = {"octet-align", 11};
    unsigned idx;

    PJ_ASSERT_RETURN(codec && attr, PJ_EINVAL);
    PJ_ASSERT_RETURN(amr_data != NULL, PJ_EINVALIDOP);

    idx = (attr->info.clock_rate <= 8000? IDX_AMR_NB: IDX_AMR_WB);
    enc_mode = pjmedia_codec_amr_get_mode(attr->info.avg_bps);
    pj_assert(enc_mode >= 0 && enc_mode < amr_bitrates_size[idx]);

    /* Check octet-align */
    for (i = 0; i < attr->setting.dec_fmtp.cnt; ++i) {
	if (pj_stricmp(&attr->setting.dec_fmtp.param[i].name, 
		       &STR_FMTP_OCTET_ALIGN) == 0)
	{
	    octet_align = (pj_uint8_t)
			  (pj_strtoul(&attr->setting.dec_fmtp.param[i].val));
	    break;
	}
    }

    /* Check mode-set */
    for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) {
	const pj_str_t STR_FMTP_MODE_SET = {"mode-set", 8};
        
	if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, 
		       &STR_FMTP_MODE_SET) == 0)
	{
	    const char *p;
	    pj_size_t l;
	    pj_int8_t diff = 99;

	    /* Encoding mode is chosen based on local default mode setting:
	     * - if local default mode is included in the mode-set, use it
	     * - otherwise, find the closest mode to local default mode;
	     *   if there are two closest modes, prefer to use the higher
	     *   one, e.g: local default mode is 4, the mode-set param
	     *   contains '2,3,5,6', then 5 will be chosen.
	     */
	    p = pj_strbuf(&attr->setting.enc_fmtp.param[i].val);
	    l = pj_strlen(&attr->setting.enc_fmtp.param[i].val);
	    while (l--) {
		if (*p>='0' && *p<=('0'+amr_bitrates_size[idx]-1)) {
		    pj_int8_t tmp = *p - '0' - enc_mode;

		    if (PJ_ABS(diff) > PJ_ABS(tmp) || 
			(PJ_ABS(diff) == PJ_ABS(tmp) && tmp > diff))
		    {
			diff = tmp;
			if (diff == 0) break;
		    }
		}
		++p;
	    }
	    PJ_ASSERT_RETURN(diff != 99, PJMEDIA_CODEC_EFAILED);

	    enc_mode = enc_mode + diff;

	    break;
	}
    }

    amr_data->clock_rate = attr->info.clock_rate;
    amr_data->vad_enabled = (attr->setting.vad != 0);
    amr_data->plc_enabled = (attr->setting.plc != 0);
    amr_data->enc_mode = enc_mode;

    if (idx == IDX_AMR_NB) {
#ifdef USE_AMRNB
        amr_data->encoder = Encoder_Interface_init(amr_data->vad_enabled);
#endif
    } else {
#ifdef USE_AMRWB
        amr_data->encoder = E_IF_init();
#endif
    }
    if (amr_data->encoder == NULL) {
	TRACE_((THIS_FILE, "Encoder initialization failed"));
	amr_codec_close(codec);
	return PJMEDIA_CODEC_EFAILED;
    }
    setting = &amr_data->enc_setting;
    pj_bzero(setting, sizeof(pjmedia_codec_amr_pack_setting));
    setting->amr_nb = (idx == IDX_AMR_NB? 1: 0);
    setting->reorder = 0;
    setting->octet_aligned = octet_align;
    setting->cmr = 15;

    if (idx == IDX_AMR_NB) {
#ifdef USE_AMRNB
        amr_data->decoder = Decoder_Interface_init();
#endif
    } else {
#ifdef USE_AMRWB
        amr_data->decoder = D_IF_init();
#endif
    }
    if (amr_data->decoder == NULL) {
	TRACE_((THIS_FILE, "Decoder initialization failed"));
	amr_codec_close(codec);
	return PJMEDIA_CODEC_EFAILED;
    }
    setting = &amr_data->dec_setting;
    pj_bzero(setting, sizeof(pjmedia_codec_amr_pack_setting));
    setting->amr_nb = (idx == IDX_AMR_NB? 1: 0);
    setting->reorder = 0;
    setting->octet_aligned = octet_align;

    TRACE_((THIS_FILE, "AMR codec allocated: clockrate=%d vad=%d, plc=%d,"
                       " bitrate=%d", amr_data->clock_rate,
			amr_data->vad_enabled, amr_data->plc_enabled, 
			amr_bitrates[idx][amr_data->enc_mode]));
    return PJ_SUCCESS;
}
示例#4
0
int main(int argc, char *argv[])
{
   FILE *f_speech = NULL;                 /* File of speech data                   */
   FILE *f_serial = NULL;                 /* File of serial bits for transmission  */
   FILE *f_mode = NULL;                   /* File of modes for each frame          */

   Word32 serial_size, frame;
   Word16 signal[L_FRAME16k];             /* Buffer for speech @ 16kHz             */
   Word16 coding_mode = 0, allow_dtx, mode_file, mode = 0;
   UWord8 serial[NB_SERIAL_MAX];
   void *st;

   fprintf(stderr, "\n");
   fprintf(stderr, "===================================================================\n");
   fprintf(stderr, " 3GPP AMR-WB Floating-point Speech Coder, v6.0.0, Dec 14, 2004\n");
   fprintf(stderr, "===================================================================\n");
   fprintf(stderr, "\n");

   /*
    * Open speech file and result file (output serial bit stream)
    */

   if ((argc < 4) || (argc > 6))
   {
      fprintf(stderr, "Usage : encoder  (-dtx) mode speech_file  bitstream_file\n");
      fprintf(stderr, "\n");
      fprintf(stderr, "Format for speech_file:\n");
      fprintf(stderr, "  Speech is read form a binary file of 16 bits data.\n");
      fprintf(stderr, "\n");
      fprintf(stderr, "Format for bitstream_file:\n");
#ifdef IF2
      fprintf(stderr, "  Described in TS26.201.\n");
#else
      fprintf(stderr, "  Described in RFC 3267 (Sections 5.1 and 5.3).\n");
#endif
      fprintf(stderr, "\n");
      fprintf(stderr, "mode: 0 to 8 (9 bits rates) or\n");
      fprintf(stderr, "      -modefile filename\n");
      fprintf(stderr, " ===================================================================\n");
      fprintf(stderr, " mode   :  (0)  (1)   (2)   (3)   (4)   (5)   (6)   (7)   (8)     \n");
      fprintf(stderr, " bitrate: 6.60 8.85 12.65 14.25 15.85 18.25 19.85 23.05 23.85 kbit/s\n");
      fprintf(stderr, " ===================================================================\n");
      fprintf(stderr, "\n");
      fprintf(stderr, "-dtx if DTX is ON, default is OFF\n");
      fprintf(stderr, "\n");
      exit(0);
   }
   allow_dtx = 0;
   if (strcmp(argv[1], "-dtx") == 0)
   {
      allow_dtx = 1;
      argv++;
   }
   mode_file = 0;
   if (strcmp(argv[1], "-modefile") == 0)
   {
      mode_file = 1;
      argv++;
      if ((f_mode = fopen(argv[1], "r")) == NULL)
      {
         fprintf(stderr, "Error opening input file  %s !!\n", argv[1]);
         exit(0);
      }
      fprintf(stderr, "Mode file:  %s\n", argv[1]);
   }
   else
   {
      mode = (Word16) atoi(argv[1]);
      if ((mode < 0) || (mode > 8))
      {
         fprintf(stderr, " error in bit rate mode %d: use 0 to 8\n", mode);
         exit(0);
      }
   }

   if ((f_speech = fopen(argv[2], "rb")) == NULL)
   {
      fprintf(stderr, "Error opening input file  %s !!\n", argv[2]);
      exit(0);
   }
   fprintf(stderr, "Input speech file:  %s\n", argv[2]);

   if ((f_serial = fopen(argv[3], "wb")) == NULL)
   {
      fprintf(stderr, "Error opening output bitstream file %s !!\n", argv[3]);
      exit(0);
   }
   fprintf(stderr, "Output bitstream file:  %s\n", argv[3]);

   /*
    * Initialisation
    */

   st = E_IF_init();

#ifndef IF2

   /* If MMS output is selected, write the magic number at the beginning of the
    * bitstream file
	*/

	fwrite(AMRWB_MAGIC_NUMBER, sizeof(char), strlen(AMRWB_MAGIC_NUMBER), f_serial);

#endif

   /*
    * Loop for every analysis/transmission frame.
    *   -New L_FRAME data are read. (L_FRAME = number of speech data per frame)
    *   -Conversion of the speech data from 16 bit integer to real
    *   -Call coder to encode the speech.
    *   -The compressed serial output stream is written to a file.
    */

   fprintf(stderr, "\n --- Running ---\n");

   frame = 0;

   while (fread(signal, sizeof(Word16), L_FRAME16k, f_speech) == L_FRAME16k)
   {
      if (mode_file)
      {
         if (fscanf(f_mode, "%hd", &mode) == EOF)
         {
            mode = coding_mode;
            fprintf(stderr, "\n end of mode control file reached\n");
            fprintf(stderr, " From now on using mode: %hd.\n", mode);
            mode_file = 0;
         }

         if ((mode < 0) || (mode > 8))
         {
            fprintf(stderr, " error in bit rate mode %hd: use 0 to 8\n", mode);
            E_IF_exit(st);
            fclose(f_speech);
            fclose(f_serial);
            fclose(f_mode);
            exit(0);
         }
      }

      coding_mode = mode;

      frame++;
      fprintf(stderr, " Frames processed: %ld\r", frame);

      serial_size = E_IF_encode(st, coding_mode, signal, serial, allow_dtx);

      fwrite(serial, 1, serial_size, f_serial);

   }

   E_IF_exit(st);

   fclose(f_speech);
   fclose(f_serial);

   if (f_mode != NULL)
   {
      fclose(f_mode);
   }

   return 0;
}
示例#5
0
static switch_status_t switch_amrwb_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
{
#ifdef AMRWB_PASSTHROUGH
	codec->flags |= SWITCH_CODEC_FLAG_PASSTHROUGH;
	if (codec->fmtp_in) {
		codec->fmtp_out = switch_core_strdup(codec->memory_pool, codec->fmtp_in);
	}
	return SWITCH_STATUS_SUCCESS;
#else
	struct amrwb_context *context = NULL;
	int encoding, decoding;
	int x, i, argc;
	char *argv[10];
	char fmtptmp[128];

	encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
	decoding = (flags & SWITCH_CODEC_FLAG_DECODE);

	if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(struct amrwb_context))))) {
		return SWITCH_STATUS_FALSE;
	} else {

		if (codec->fmtp_in) {
			argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0])));
			for (x = 0; x < argc; x++) {
				char *data = argv[x];
				char *arg;
				while (*data && *data == ' ') {
					data++;
				}
				if ((arg = strchr(data, '='))) {
					*arg++ = '\0';
					if (!strcasecmp(data, "octet-align")) {
						if (atoi(arg)) {
							switch_set_flag(context, AMRWB_OPT_OCTET_ALIGN);
						}
					} else if (!strcasecmp(data, "mode-change-neighbor")) {
						if (atoi(arg)) {
							switch_set_flag(context, AMRWB_OPT_MODE_CHANGE_NEIGHBOR);
						}
					} else if (!strcasecmp(data, "crc")) {
						if (atoi(arg)) {
							switch_set_flag(context, AMRWB_OPT_CRC);
						}
					} else if (!strcasecmp(data, "robust-sorting")) {
						if (atoi(arg)) {
							switch_set_flag(context, AMRWB_OPT_ROBUST_SORTING);
						}
					} else if (!strcasecmp(data, "interveaving")) {
						if (atoi(arg)) {
							switch_set_flag(context, AMRWB_OPT_INTERLEAVING);
						}
					} else if (!strcasecmp(data, "mode-change-period")) {
						context->change_period = atoi(arg);
					} else if (!strcasecmp(data, "ptime")) {
						context->ptime = (switch_byte_t) atoi(arg);
					} else if (!strcasecmp(data, "channels")) {
						context->channels = (switch_byte_t) atoi(arg);
					} else if (!strcasecmp(data, "maxptime")) {
						context->max_ptime = (switch_byte_t) atoi(arg);
					} else if (!strcasecmp(data, "mode-set")) {
						int y, m_argc;
						char *m_argv[8];
						m_argc = switch_separate_string(arg, ',', m_argv, (sizeof(m_argv) / sizeof(m_argv[0])));
						for (y = 0; y < m_argc; y++) {
							context->enc_modes |= (1 << atoi(m_argv[y]));
						}
					}
				}
			}
		}

		if (context->enc_modes) {
			for (i = 8; i > -1; i++) {
				if (context->enc_modes & (1 << i)) {
					context->enc_mode = (switch_byte_t) i;
					break;
				}
			}
		}

		if (!context->enc_mode) {
			context->enc_mode = globals.default_bitrate;
		}

		switch_snprintf(fmtptmp, sizeof(fmtptmp), "octet-align=%d; mode-set=%d", switch_test_flag(context, AMRWB_OPT_OCTET_ALIGN) ? 1 : 0,
						context->enc_mode);
		codec->fmtp_out = switch_core_strdup(codec->memory_pool, fmtptmp);

		context->enc_mode = AMRWB_DEFAULT_BITRATE;
		context->encoder_state = NULL;
		context->decoder_state = NULL;

		if (encoding) {
			context->encoder_state = E_IF_init();
		}

		if (decoding) {
			context->decoder_state = D_IF_init();
		}

		codec->private_info = context;

		return SWITCH_STATUS_SUCCESS;
	}
#endif
}