Пример #1
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;
}
Пример #2
0
int encoder_write(unsigned long id, void* rbuffer, unsigned long bsize)
{	
	short         lspeech[160];
	unsigned int  i = 0, j, z, byte_counter, k;

	if(pestreams[id].firstwrite)
	{
		if(pestreams[id].firstwrite == -1) return 0;

		if(pestreams[id].cfrequency != 8000 || pestreams[id].cchannels != 1)
		{
			MessageBox(0, uni("Sorry, input file needs to be in following format:\n8000Hz, Mono.\n\nPlease use \"Sound File Encoder\" to convert between formats (example: convert your file(s) into Wave format (with above settings), then convert those (.wav) file(s) into AMR)."), uni("AMR Conversion"), MB_ICONEXCLAMATION);
			pestreams[id].firstwrite = -1;
			return 0;
		}

		pestreams[id].fhandle = sys_file_createforcestream(pestreams[id].filepath, v_sys_file_forwrite);
		
		if(pestreams[id].fhandle == v_error_sys_file_create)return 0;


		memset(pestreams[id].serial_data, 0, sizeof(pestreams[id].serial_data));

		pestreams[id].req_mode = MR122;
		pestreams[id].dtx      = 0;
		pestreams[id].c        = 0;

		pestreams[id].enstate = Encoder_Interface_init(pestreams[id].dtx);

		sys_file_write(pestreams[id].fhandle, AMR_MAGIC_NUMBER, strlen(AMR_MAGIC_NUMBER));
		
		pestreams[id].firstwrite = 0;
	}

	j = pestreams[id].c;

	for(;;)
	{
		z = min(bsize - i, sizeof(pestreams[id].speech));
		memcpy(((char*)pestreams[id].speech) + j, ((char*)rbuffer) + i, z - j);

		pestreams[id].c = z - j;

		if(pestreams[id].c == sizeof(pestreams[id].speech))
		{
			for(k=0; k<160; k++)
				lspeech[k] = (short)(pestreams[id].speech[k] * 32767.0);

			byte_counter = Encoder_Interface_Encode(pestreams[id].enstate, pestreams[id].req_mode, lspeech, pestreams[id].serial_data, 0);

			sys_file_write(pestreams[id].fhandle, pestreams[id].serial_data, byte_counter);
		}

		i += z - j;
		j = 0;

		if(i >= bsize)break;
	}
	

	return 1;
}
Пример #3
0
static void enc_preprocess(MSFilter *f) {
    EncState *s = (EncState*) f->data;
    s->enc = Encoder_Interface_init(s->dtx);
}
Пример #4
0
static void enc_preprocess(AmrEncState *s) {
	s->amr_enc = Encoder_Interface_init(s->dtx);
}
Пример #5
0
/*
 * main
 *
 *
 * Function:
 *    Speech encoder main program
 *
 *    Usage: encoder speech_file bitstream_file mode dtx mode_file
 *
 *    Format for speech_file:
 *       Speech is read from a binary file of 16 bits data.
 *
 *    Format for ETSI bitstream file:
 *       1 word (2-byte) for the TX frame type
 *       244 words (2-byte) containing 244 bits.
 *          Bit 0 = 0x0000 and Bit 1 = 0x0001
 *       1 word (2-byte) for the mode indication
 *       4 words for future use, currently written as zero
 *
 *    Format for 3GPP bitstream file:
 *       Holds mode information and bits packed to octets.
 *       Size is from 1 byte to 31 bytes.
 *
 *    ETSI bitstream file format is defined using ETSI as preprocessor
 *    definition
 *
 *    mode        : MR475, MR515, MR59, MR67, MR74, MR795, MR102, MR122
 *    mode_file   : reads mode information from a file
 * Returns:
 *    0
 */
int main (int argc, char * argv[]){

   /* file strucrures */
   FILE * file_speech = NULL;
   FILE * file_encoded = NULL;
   FILE * file_mode = NULL;

   /* input speech vector */
   short speech[160];

   /* counters */
   int byte_counter, frames = 0, bytes = 0;

   /* pointer to encoder state structure */
   int *enstate;

   /* requested mode */
   enum Mode req_mode = MR122;
   int dtx = 0;

   /* temporary variables */
   char mode_string[9];
   long mode_tmp;

   /* bitstream filetype */
#ifndef ETSI
   unsigned char serial_data[32];
#else
   short serial_data[250] = {0};
#endif

   /* Process command line options */

   if ((argc == 5) || (argc == 4)){
      file_encoded = fopen(argv[argc - 1], "wb");
      if (file_encoded == NULL){
         Usage(argv);
         return 1;
      }
      file_speech = fopen(argv[argc - 2], "rb");
      if (file_speech == NULL){
         fclose(file_encoded);
         Usage(argv);
         return 1;
      }
      if (strncmp(argv[argc - 3], "-modefile=", 10) == 0){
         file_mode = fopen(&argv[argc - 3][10], "rt");
         if (file_mode == NULL){
            Usage(argv);
            fclose(file_speech);
            fclose(file_encoded);
            return 1;
         }
      }
      else {
         mode_tmp = strtol(&argv[argc - 3][2], NULL, 0);
         for (req_mode = 0; req_mode < 8; req_mode++){
            if (mode_tmp == modeConv[req_mode])
               break;
         }
         if (req_mode == 8){
            Usage(argv);
            fclose(file_speech);
            fclose(file_encoded);
            if (file_mode != NULL)
               fclose(file_mode);
            return 1;
         }
      }
      if (argc == 5){
         if ((strcmp(argv[1], "-dtx") != 0)){
            Usage(argv);
            fclose(file_speech);
            fclose(file_encoded);
            if (file_mode != NULL){
               fclose(file_mode);
            }
            return 1;
         }
         else {
            dtx = 1;
         }
      }
   }
   else {
      Usage(argv);
      return 1;
   }


   enstate = Encoder_Interface_init(dtx);

   Copyright();
#ifndef VAD2
   fprintf( stderr, "%s\n", "Code compiled with VAD option: VAD1");
#else
   fprintf( stderr, "%s\n", "Code compiled with VAD option: VAD2");
#endif

#ifndef ETSI
#ifndef IF2
   /* write magic number to indicate single channel AMR file storage format */
   	bytes = fwrite(AMR_MAGIC_NUMBER, sizeof(char), strlen(AMR_MAGIC_NUMBER), file_encoded);
#endif
#endif

   /* read file */
   while (fread( speech, sizeof (Word16), 160, file_speech ) > 0)
   {
      /* read mode */
      if (file_mode != NULL){
         req_mode = 8;
         if (fscanf(file_mode, "%9s\n", mode_string) != EOF) {
            mode_tmp = strtol(&mode_string[2], NULL, 0);
            for (req_mode = 0; req_mode < 8; req_mode++){
               if (mode_tmp == modeConv[req_mode]){
                  break;
               }
            }
         }
         if (req_mode == 8){
            break;
         }
      }

      frames ++;

      /* call encoder */
      byte_counter = Encoder_Interface_Encode(enstate, req_mode, speech, serial_data, 0);

      bytes += byte_counter;
      fwrite(serial_data, sizeof (UWord8), byte_counter, file_encoded );
      fflush(file_encoded);
   }
   Encoder_Interface_exit(enstate);

#ifndef ETSI
#ifdef IF2
   fprintf ( stderr, "\n%s%i%s%i%s\n", "Frame structure AMR IF2: ", frames, " frames, ", bytes, " bytes.");
#else
   fprintf ( stderr, "\n%s%i%s%i%s\n", "Frame structure AMR MIME file storage format: ", frames, " frames, ", bytes, " bytes.");
#endif
#else
   fprintf ( stderr, "\n%s%i%s\n", "Frame structure AMR ETSI: ", frames, " frames. ");
#endif

   fclose(file_speech);
   fclose(file_encoded);
   if (file_mode != NULL)
      fclose(file_mode);

   return 0;
}
Пример #6
0
int encode_amr(const char* infile, const char* outfile) {
    enum Mode mode = MR122;
    FILE *out;
    void *wav, *amr;
    int format, sampleRate, channels, bitsPerSample;
    int inputSize;
    uint8_t* inputBuf;

    wav = wav_read_open(infile);
    if (!wav) {
        fprintf(stderr, "Unable to open wav file %s\n", infile);
        return 1;
    }
    if (!wav_get_header(wav, &format, &channels, &sampleRate, &bitsPerSample, NULL)) {
        fprintf(stderr, "Bad wav file %s\n", infile);
        return 1;
    }
    if (format != 1) {
        fprintf(stderr, "Unsupported WAV format %d\n", format);
        return 1;
    }
    if (bitsPerSample != 16) {
        fprintf(stderr, "Unsupported WAV sample depth %d\n", bitsPerSample);
        return 1;
    }
    if (channels != 1)
        fprintf(stderr, "Warning, only compressing one audio channel\n");
    if (sampleRate != 8000)
        fprintf(stderr, "Warning, AMR-NB uses 8000 Hz sample rate (WAV file has %d Hz)\n", sampleRate);
    
    inputSize = channels*2*160;
    inputBuf = (uint8_t*) malloc(inputSize);
    
    amr = Encoder_Interface_init(0);
    out = fopen(outfile, "wb");
    if (!out) {
        perror(outfile);
        return 1;
    }
    
    fwrite("#!AMR\n", 1, 6, out);
    while (1) {
        short buf[160];
        uint8_t outbuf[500];
        int read, i, n;
        read = wav_read_data(wav, inputBuf, inputSize);
        read /= channels;
        read /= 2;
        if (read < 160)
            break;
        for (i = 0; i < 160; i++) {
            const uint8_t* in = &inputBuf[2*channels*i];
            buf[i] = in[0] | (in[1] << 8);
        }
        n = Encoder_Interface_Encode(amr, mode, buf, outbuf, 0);
        fwrite(outbuf, 1, n, out);
    }
    free(inputBuf);
    fclose(out);
    Encoder_Interface_exit(amr);
    wav_read_close(wav);
    
    return 0;
}
Пример #7
0
static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
{
#ifdef AMR_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 amr_context *context = NULL;
	switch_codec_fmtp_t codec_fmtp;
	amr_codec_settings_t amr_codec_settings;
	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 amr_context))))) {
		return SWITCH_STATUS_FALSE;
	} else {

		memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp));
		codec_fmtp.private_info = &amr_codec_settings;
		switch_amr_fmtp_parse(codec->fmtp_in, &codec_fmtp);

		if (context->enc_modes) {
			for (i = 7; 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, AMR_OPT_OCTET_ALIGN) ? 1 : 0,
						context->enc_mode);
		codec->fmtp_out = switch_core_strdup(codec->memory_pool, fmtptmp);

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

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

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

		codec->private_info = context;

		return SWITCH_STATUS_SUCCESS;
	}
#endif
}
Пример #8
0
int main(int argc, char *argv[]) {
	enum Mode mode = MR122;
	int ch, dtx = 0;
	const char *infile, *outfile;
	FILE *out;
	void *wav, *amr;
	int format, sampleRate, channels, bitsPerSample;
	int inputSize;
	uint8_t* inputBuf;
	while ((ch = getopt(argc, argv, "r:d")) != -1) {
		switch (ch) {
		case 'r':
			mode = findMode(optarg);
			break;
		case 'd':
			dtx = 1;
			break;
		case '?':
		default:
			usage(argv[0]);
			return 1;
		}
	}
	if (argc - optind < 2) {
		usage(argv[0]);
		return 1;
	}
	infile = argv[optind];
	outfile = argv[optind + 1];

	wav = wav_read_open(infile);
	if (!wav) {
		fprintf(stderr, "Unable to open wav file %s\n", infile);
		return 1;
	}
	if (!wav_get_header(wav, &format, &channels, &sampleRate, &bitsPerSample, NULL)) {
		fprintf(stderr, "Bad wav file %s\n", infile);
		return 1;
	}
	if (format != 1) {
		fprintf(stderr, "Unsupported WAV format %d\n", format);
		return 1;
	}
	if (bitsPerSample != 16) {
		fprintf(stderr, "Unsupported WAV sample depth %d\n", bitsPerSample);
		return 1;
	}
	if (channels != 1)
		fprintf(stderr, "Warning, only compressing one audio channel\n");
	if (sampleRate != 8000)
		fprintf(stderr, "Warning, AMR-NB uses 8000 Hz sample rate (WAV file has %d Hz)\n", sampleRate);
	inputSize = channels*2*160;
	inputBuf = (uint8_t*) malloc(inputSize);

	amr = Encoder_Interface_init(dtx);
	out = fopen(outfile, "wb");
	if (!out) {
		perror(outfile);
		return 1;
	}

	fwrite("#!AMR\n", 1, 6, out);
	while (1) {
		short buf[160];
		uint8_t outbuf[500];
		int read, i, n;
		read = wav_read_data(wav, inputBuf, inputSize);
		read /= channels;
		read /= 2;
		if (read < 160)
			break;
		for (i = 0; i < 160; i++) {
			const uint8_t* in = &inputBuf[2*channels*i];
			buf[i] = in[0] | (in[1] << 8);
		}
		n = Encoder_Interface_Encode(amr, mode, buf, outbuf, 0);
		fwrite(outbuf, 1, n, out);
	}
	free(inputBuf);
	fclose(out);
	Encoder_Interface_exit(amr);
	wav_read_close(wav);

	return 0;
}