static void enc_process(MSFilter *f){ static const int nsamples=160; EncState *s=(EncState*)f->data; mblk_t *im,*om; int16_t samples[nsamples]; while((im=ms_queue_get(f->inputs[0]))!=NULL){ ms_bufferizer_put (s->mb,im); } while((ms_bufferizer_read(s->mb,(uint8_t*)samples,nsamples*2))>=nsamples*2){ int ret; om=allocb(33,0); *om->b_wptr=0xf0; om->b_wptr++; ret=Encoder_Interface_Encode(s->enc,MR122,samples,om->b_wptr,0); if (ret<=0){ ms_warning("Encoder returned %i",ret); freemsg(om); continue; } om->b_wptr+=ret; mblk_set_timestamp_info(om,s->ts); s->ts+=nsamples; ms_queue_put(f->outputs[0],om); } }
static int amr_codec_encoder(const struct PluginCodec_Definition * codec, void * context, const void * fromPtr, unsigned * fromLen, void * toPtr, unsigned * toLen, unsigned int * flag) { AmrEncoderContext * amr = (AmrEncoderContext *)context; int byteCount; unsigned char buffer[100]; // Need this as encoder is very rude and can output more bytes than to pointer might be pointing to if (*fromLen < L_FRAME*sizeof(short)) return FALSE; byteCount = Encoder_Interface_Encode(amr->encoder_state, (enum Mode)amr->mode, (const short *)fromPtr, buffer+1, 0); if (byteCount <= 1 || *toLen <= byteCount) { *toLen = 0; return byteCount == 1; // Is a DTX frame } buffer[0] = 0xf0; // CMR is always this for us memcpy(toPtr, buffer, *toLen); *toLen = byteCount+1; return TRUE; }
int main(void) { FILE *fp; FILE *decoder_fp; int read_num = 0; int write_num = 0; char buffer[1024] = {0}; char decoder_buffer[1024] = {0}; int* fAudioCodec, *fAudioDecodec; unsigned char fTo[1024] = {0}; fAudioCodec = (int*)Encoder_Interface_init(0); fAudioDecodec = (int*)Decoder_Interface_init(); fp = fopen(AUDIO_FILE, "rb"); decoder_fp = fopen("temp.txt", "wb+"); if (fp < 0 || decoder_fp < 0) { } while((read_num = fread(buffer, 1, 320, fp))) { Encoder_Interface_Encode(fAudioCodec, MR475, (const short int*)buffer, fTo, 0); Decoder_Interface_Decode(fAudioDecodec, (const unsigned char *)fTo, (short int *)decoder_buffer, 0); fseek(decoder_fp, write_num, SEEK_SET); write_num += read_num; fwrite(decoder_buffer, 1, 320, decoder_fp); if(read_num < 320) break; } fclose(fp); fclose(decoder_fp); }
static int amr_codec_encoder(const struct PluginCodec_Definition * codec, void * context, const void * from, unsigned * fromLen, void * to, unsigned * toLen, unsigned int * flag) { AmrEncoderContext *ctx = (AmrEncoderContext *)context; unsigned int mode = ctx->mode; if( *fromLen != 160*sizeof(short)) { fprintf(stderr,"AMR codec: audio frame of size %u doesn't match expected %u\n", *fromLen,160*sizeof(short)); return 0; } if(*toLen < bytes_per_frame[mode]) { fprintf(stderr,"AMR codec: output buffer of size %u too short for mode %u\n", *toLen, mode ); return 0; } /* fprintf(stderr,"AMR codec: encoding to mode %u size %u\n", mode, *toLen); */ *toLen = Encoder_Interface_Encode(ctx->encoder_state,mode,(void *)from,to,0); return 1; }
static GstFlowReturn gst_amrnbenc_handle_frame (GstAudioEncoder * enc, GstBuffer * buffer) { GstAmrnbEnc *amrnbenc; GstFlowReturn ret; GstBuffer *out; GstMapInfo in_map, out_map; gsize out_size; amrnbenc = GST_AMRNBENC (enc); g_return_val_if_fail (amrnbenc->handle, GST_FLOW_FLUSHING); /* we don't deal with squeezing remnants, so simply discard those */ if (G_UNLIKELY (buffer == NULL)) { GST_DEBUG_OBJECT (amrnbenc, "no data"); return GST_FLOW_OK; } gst_buffer_map (buffer, &in_map, GST_MAP_READ); if (G_UNLIKELY (in_map.size < 320)) { gst_buffer_unmap (buffer, &in_map); GST_DEBUG_OBJECT (amrnbenc, "discarding trailing data of %" G_GSIZE_FORMAT " bytes", in_map.size); return gst_audio_encoder_finish_frame (enc, NULL, -1); } /* get output, max size is 32 */ out = gst_buffer_new_and_alloc (32); /* AMR encoder actually writes into the source data buffers it gets */ /* should be able to handle that with what we are given */ gst_buffer_map (out, &out_map, GST_MAP_WRITE); /* encode */ out_size = Encoder_Interface_Encode (amrnbenc->handle, amrnbenc->bandmode, (short *) in_map.data, out_map.data, 0); gst_buffer_unmap (out, &out_map); gst_buffer_resize (out, 0, out_size); gst_buffer_unmap (buffer, &in_map); GST_LOG_OBJECT (amrnbenc, "output data size %" G_GSIZE_FORMAT, out_size); if (out_size) { ret = gst_audio_encoder_finish_frame (enc, out, 160); } else { /* should not happen (without dtx or so at least) */ GST_WARNING_OBJECT (amrnbenc, "no encoded data; discarding input"); gst_buffer_unref (out); ret = gst_audio_encoder_finish_frame (enc, NULL, -1); } return ret; }
int i51KitAmrPcmStream2AmrStream ( void* pcm_stream , iU32 stream_length , void* amr_buffer , iU32 buff_length ) { // author : jelo // since : 2012.3.21 // (C) 2011 , PKIG Tech. Co., Ltd. if ( 0 == pcm_stream || 0 == stream_length || 0 == amr_buffer || 0 == buff_length ) { iLog ( "AMR-Enc : Buffer is Empty" ) ; return 0 ; } Encoder_Interface_init () ; enstate = Encoder_Interface_init(dtx); 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); }
static void enc_process(AmrEncState *s) { s->curwavstream = s->wavstream; s->curamrstream = s->amrstream; memcpy(s->curamrstream, AMR_MAGIC_NUMBER, strlen(AMR_MAGIC_NUMBER)); s->curamrstream += strlen(AMR_MAGIC_NUMBER); int curwavdatasize = s->wavdatasize; int curamrdatasize = s->amrdatasize; while(curwavdatasize>=160*2 && curamrdatasize>=(block_size[s->req_mode]+1)) { int byte_conter = Encoder_Interface_Encode(s->amr_enc, req_mode, s->curwavstream, s->curamrstream, 0); s->curwavstream += 160*2; s->curwavdatasize -= 160*2; s->curamrstream += byte_conter; s->curamrdatasize -= byte_conter; } }
void EncoderAudioSource::doGetNextFrame() { // Copy an encoded audio frame into buffer `fTo' // Read a new frame into fBuffer, YUV420 format is assumed unsigned char frame[100]; int size = fFrameLength; int audioType; Debug(ckite_log_message, "EncoderAudioSource::doGetNextFrame.\n"); computeAudioPresentationTime(); if (strcmp(mediaType, "store") == 0) { // getFileAudioFrame( fp, 0, (unsigned char*)fBuffer, &size, &audioType); } else { audioGetFrameInfo(fp, mediaType,(char *)fBuffer, &size, &audioType); } if (size <= 0) return ; // Encode the frame int ret = 0; if(audioType == AUDIO_AMRNB || audioType == AUDIO_AMRWB) { fFrameSize = size; } else if(audioType == AUDIO_RAW) { if (fAudioCodec != NULL) { #ifndef __WIN32__ ret = Encoder_Interface_Encode(fAudioCodec, MR122, (const short int*)fBuffer, frame, 0); #endif } if (ret > 0) { fLastFrameHeader = frame[0]; fFrameSize = ret-1; memcpy(fTo, frame+1, ret-1); } } afterGetting(this); }
static int encode_nb(struct auenc_state *st, uint8_t *buf, size_t *len, const int16_t *sampv, size_t sampc) { int r; if (!st || !buf || !len || !sampv || sampc != FRAMESIZE_NB) return EINVAL; if (*len < NB_SERIAL_MAX) return ENOMEM; /* CMR value 15 indicates that no mode request is present */ buf[0] = 15 << 4; r = Encoder_Interface_Encode(st->enc, MR122, sampv, &buf[1], 0); if (r <= 0) return EPROTO; *len = (1 + r); return 0; }
void EncoderAudioSource::doGetNextFrame() { // Copy an encoded audio frame into buffer `fTo' // Read a new frame into fBuffer, YUV420 format is assumed unsigned char frame[100]; int size = fFrameLength; int audioType; Debug(ckite_log_message, "EncoderAudioSource::doGetNextFrame.\n"); computeAudioPresentationTime(); if (strcmp(mediaType, "store") == 0) { getStoreAudioFrame( fp, 0, (unsigned char*)fBuffer, &size, &audioType); } else { getRealAudioFrame(fp, mediaType,(char *)fBuffer, &size, &audioType); } if (size <= 0) size = 0; // Encode the frame #ifdef ENC_SOURCE int ret = 0; if (fAudioCodec != NULL) { ret = Encoder_Interface_Encode(fAudioCodec, MR122, (const short int*)fBuffer, frame, 0); } if (ret > 0) { fLastFrameHeader = frame[0]; fFrameSize = ret-1; memcpy(fTo, frame+1, ret-1); } #else if (size != 0) memcpy(fTo, fBuffer, size); fFrameSize = size; #endif afterGetting(this); }
void AMRAudioEncoder::doGetNextFrame() { // If we have enough samples in order to encode a frame, do this now: if (fInputSampleBufferBytesFull >= fInputSampleBufferBytesDesired) { if (fMaxSize < AMR_MAX_CODED_FRAME_SIZE) { // Our sink hasn't given us enough space for a frame. We can't encode. fFrameSize = 0; fNumTruncatedBytes = AMR_MAX_CODED_FRAME_SIZE; } else { enum Mode ourAMRMode = MR122; // the only mode that we support fFrameSize = Encoder_Interface_Encode(fEncoderState, ourAMRMode, (short*)fInputSampleBuffer, fTo, 0/*disable DTX*/); // Note the 1-byte AMR frame header (which wasn't included in the encoded data): fLastFrameHeader = toc_byte[ourAMRMode]; fNumTruncatedBytes = 0; // Shift any remaining samples down the the start of the buffer: fInputSampleBufferBytesFull -= fInputSampleBufferBytesDesired; memmove(fInputSampleBuffer, &fInputSampleBuffer[fInputSampleBufferBytesDesired], fInputSampleBufferBytesFull); } // Complete delivery to the client: fPresentationTime = fLastInputDataPresentationTime; //fDurationInMicroseconds = AMR_MICROSECONDS_PER_FRAME; fDurationInMicroseconds = 0; // because audio capture is bursty, check for it ASAP afterGetting(this); } else { // Read more samples from our source, then try again: unsigned maxBytesToRead = fInputSampleBufferSize - fInputSampleBufferBytesFull; fInputPCMSource ->getNextFrame(&fInputSampleBuffer[fInputSampleBufferBytesFull], maxBytesToRead, afterGettingFrame, this, FramedSource::handleClosure, this); } }
static switch_status_t switch_amr_encode(switch_codec_t *codec, switch_codec_t *other_codec, void *decoded_data, uint32_t decoded_data_len, uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, unsigned int *flag) { #ifdef AMR_PASSTHROUGH switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This codec is only usable in passthrough mode!\n"); return SWITCH_STATUS_FALSE; #else struct amr_context *context = codec->private_info; if (!context) { return SWITCH_STATUS_FALSE; } *encoded_data_len = Encoder_Interface_Encode(context->encoder_state, context->enc_mode, (int16_t *) decoded_data, (switch_byte_t *) encoded_data, 0); return SWITCH_STATUS_SUCCESS; #endif }
static void enc_process(MSFilter *f) { EncState *s = (EncState*) f->data; unsigned int unitary_buff_size = sizeof (int16_t)*160; unsigned int buff_size = unitary_buff_size * s->ptime / 20; mblk_t *im; uint8_t tmp[OUT_MAX_SIZE]; int16_t samples[buff_size]; while ((im = ms_queue_get(f->inputs[0])) != NULL) { ms_bufferizer_put(s->mb, im); } while (ms_bufferizer_get_avail(s->mb) >= buff_size) { mblk_t *om = allocb(OUT_MAX_SIZE * buff_size / unitary_buff_size + 1, 0); ms_bufferizer_read(s->mb, (uint8_t*) samples, buff_size); *om->b_wptr = 0xf0; uint8_t *tocs = om->b_wptr++; om->b_wptr += buff_size / unitary_buff_size; int offset; for (offset = 0; offset < buff_size; offset += unitary_buff_size) { int ret = Encoder_Interface_Encode(s->enc, s->mode, &samples[offset / sizeof (int16_t)], tmp, s->dtx); if (ret <= 0 || ret > 32) { ms_warning("Encoder returned %i", ret); freemsg(om); continue; } memcpy(om->b_wptr, &tmp[1], ret - 1); om->b_wptr += ret - 1; *(++tocs) = tmp[0] | 0x80; // Not last payload } *tocs &= 0x7F; // last payload mblk_set_timestamp_info(om, s->ts); ms_queue_put(f->outputs[0], om); s->ts += buff_size / sizeof (int16_t)/*sizeof(buf)/2*/; } }
/* * Encode frame. */ static pj_status_t amr_codec_encode( pjmedia_codec *codec, const struct pjmedia_frame *input, unsigned output_buf_len, struct pjmedia_frame *output) { struct amr_data *amr_data = (struct amr_data*) codec->codec_data; unsigned char *bitstream; pj_int16_t *speech; unsigned nsamples, samples_per_frame; enum {MAX_FRAMES_PER_PACKET = 16}; pjmedia_frame frames[MAX_FRAMES_PER_PACKET]; pj_uint8_t *p; unsigned i, out_size = 0, nframes = 0; pj_size_t payload_len; unsigned dtx_cnt, sid_cnt; pj_status_t status; pj_assert(amr_data != NULL); PJ_ASSERT_RETURN(input && output, PJ_EINVAL); nsamples = input->size >> 1; samples_per_frame = amr_data->clock_rate * FRAME_LENGTH_MS / 1000; PJ_ASSERT_RETURN(nsamples % samples_per_frame == 0, PJMEDIA_CODEC_EPCMFRMINLEN); nframes = nsamples / samples_per_frame; PJ_ASSERT_RETURN(nframes <= MAX_FRAMES_PER_PACKET, PJMEDIA_CODEC_EFRMTOOSHORT); /* Encode the frames */ speech = (pj_int16_t*)input->buf; bitstream = (unsigned char*)output->buf; while (nsamples >= samples_per_frame) { int size; if (amr_data->enc_setting.amr_nb) { #ifdef USE_AMRNB size = Encoder_Interface_Encode (amr_data->encoder, amr_data->enc_mode, speech, bitstream, 0); #else size = 0; #endif } else { #ifdef USE_AMRWB size = E_IF_encode (amr_data->encoder, amr_data->enc_mode, speech, bitstream, 0); #else size = 0; #endif } if (size == 0) { output->size = 0; output->buf = NULL; output->type = PJMEDIA_FRAME_TYPE_NONE; TRACE_((THIS_FILE, "AMR encode() failed")); return PJMEDIA_CODEC_EFAILED; } nsamples -= samples_per_frame; speech += samples_per_frame; bitstream += size; out_size += size; TRACE_((THIS_FILE, "AMR encode(): mode=%d, size=%d", amr_data->enc_mode, out_size)); } /* Pack payload */ p = (pj_uint8_t*)output->buf + output_buf_len - out_size; pj_memmove(p, output->buf, out_size); dtx_cnt = sid_cnt = 0; for (i = 0; i < nframes; ++i) { pjmedia_codec_amr_bit_info *info = (pjmedia_codec_amr_bit_info*) &frames[i].bit_info; info->frame_type = (pj_uint8_t)((*p >> 3) & 0x0F); info->good_quality = (pj_uint8_t)((*p >> 2) & 0x01); info->mode = (pj_int8_t)amr_data->enc_mode; info->start_bit = 0; frames[i].buf = p + 1; if (amr_data->enc_setting.amr_nb) { frames[i].size = (info->frame_type <= 8)? pjmedia_codec_amrnb_framelen[info->frame_type] : 0; } else { frames[i].size = (info->frame_type <= 9)? pjmedia_codec_amrwb_framelen[info->frame_type] : 0; } p += frames[i].size + 1; /* Count the number of SID and DTX frames */ if (info->frame_type == 15) /* DTX*/ ++dtx_cnt; else if (info->frame_type == 8) /* SID */ ++sid_cnt; } /* VA generates DTX frames as DTX+SID frames switching quickly and it * seems that the SID frames occur too often (assuming the purpose is * only for keeping NAT alive?). So let's modify the behavior a bit. * Only an SID frame will be sent every PJMEDIA_CODEC_MAX_SILENCE_PERIOD * milliseconds. */ if (sid_cnt + dtx_cnt == nframes) { pj_int32_t dtx_duration; dtx_duration = pj_timestamp_diff32(&amr_data->last_tx, &input->timestamp); if (PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 || dtx_duration < PJMEDIA_CODEC_MAX_SILENCE_PERIOD* amr_data->clock_rate/1000) { output->size = 0; output->type = PJMEDIA_FRAME_TYPE_NONE; output->timestamp = input->timestamp; return PJ_SUCCESS; } } payload_len = output_buf_len; status = pjmedia_codec_amr_pack(frames, nframes, &amr_data->enc_setting, output->buf, &payload_len); if (status != PJ_SUCCESS) { output->size = 0; output->buf = NULL; output->type = PJMEDIA_FRAME_TYPE_NONE; TRACE_((THIS_FILE, "Failed to pack AMR payload, status=%d", status)); return status; } output->size = payload_len; output->type = PJMEDIA_FRAME_TYPE_AUDIO; output->timestamp = input->timestamp; amr_data->last_tx = input->timestamp; return PJ_SUCCESS; }
static GstFlowReturn gst_amrnbenc_chain (GstPad * pad, GstBuffer * buffer) { GstAmrnbEnc *amrnbenc; GstFlowReturn ret; amrnbenc = GST_AMRNBENC (GST_PAD_PARENT (pad)); g_return_val_if_fail (amrnbenc->handle, GST_FLOW_WRONG_STATE); if (amrnbenc->rate == 0 || amrnbenc->channels == 0) goto not_negotiated; /* discontinuity clears adapter, FIXME, maybe we can set some * encoder flag to mask the discont. */ if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) { gst_adapter_clear (amrnbenc->adapter); amrnbenc->ts = 0; } /* take latest timestamp, FIXME timestamp is the one of the * first buffer in the adapter. */ if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) amrnbenc->ts = GST_BUFFER_TIMESTAMP (buffer); ret = GST_FLOW_OK; gst_adapter_push (amrnbenc->adapter, buffer); /* Collect samples until we have enough for an output frame */ while (gst_adapter_available (amrnbenc->adapter) >= 320) { GstBuffer *out; guint8 *data; gint outsize; /* get output, max size is 32 */ out = gst_buffer_new_and_alloc (32); GST_BUFFER_DURATION (out) = amrnbenc->duration; GST_BUFFER_TIMESTAMP (out) = amrnbenc->ts; if (amrnbenc->ts != -1) amrnbenc->ts += amrnbenc->duration; gst_buffer_set_caps (out, GST_PAD_CAPS (amrnbenc->srcpad)); /* The AMR encoder actually writes into the source data buffers it gets */ data = gst_adapter_take (amrnbenc->adapter, 320); /* encode */ outsize = Encoder_Interface_Encode (amrnbenc->handle, amrnbenc->bandmode, (short *) data, (guint8 *) GST_BUFFER_DATA (out), 0); g_free (data); GST_BUFFER_SIZE (out) = outsize; /* play */ if ((ret = gst_pad_push (amrnbenc->srcpad, out)) != GST_FLOW_OK) break; } return ret; /* ERRORS */ not_negotiated: { GST_ELEMENT_ERROR (amrnbenc, STREAM, TYPE_NOT_FOUND, (NULL), ("unknown type")); return GST_FLOW_NOT_NEGOTIATED; } }
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; }
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; }
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; }
/* * 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; }