static int codec_decoder(const struct PluginCodec_Definition * codec, void * context, const void * from, unsigned * fromLen, void * to, unsigned * toLen, unsigned int * flag) { int i; #ifndef OPAL_SYSTEM_ILBC float block[BLOCKL_MAX]; short * sampleBuffer = (short *)to; #endif struct iLBC_Dec_Inst_t_ * decoder = (struct iLBC_Dec_Inst_t_ *)context; // If packet not have integral number of frames for this mode if ((*fromLen % decoder->no_of_bytes) != 0) { // Then switch to the other mode initDecode(context, decoder->mode == 20 ? 30 : 20, 0); if ((*fromLen % decoder->no_of_bytes) != 0) return 0; // Still wrong, what are they sending us? } /* do actual decoding of block */ #ifdef OPAL_SYSTEM_ILBC iLBC_decode((short *)to, (WebRtc_UWord16 *)from, decoder, 1); #else iLBC_decode(block, (unsigned char *)from, decoder, 1); /* convert to short */ for (i = 0; i < decoder->blockl; i++) { float tmp = block[i]; if (tmp < -32767) tmp = -32767; else if (tmp > 32767) tmp = 32767; sampleBuffer[i] = (short)tmp; } #endif if (*toLen < decoder->blockl*2U) return 0; // set output lengths *toLen = decoder->blockl*2; *fromLen = decoder->no_of_bytes; return 1; }
static int do_dec(struct audec_state *st, int16_t *sampv, size_t *sampc, const uint8_t *buf, size_t len) { float float_buf[st->nsamp]; const int mode = len ? 1 : 0; uint32_t i; /* Make sure there is enough space in the buffer */ if (*sampc < st->nsamp) return ENOMEM; iLBC_decode(float_buf, /* (o) decoded signal block */ (uint8_t *)buf, /* (i) encoded signal bits */ &st->dec, /* (i/o) the decoder state structure */ mode); /* (i) 0: bad packet, PLC, 1: normal */ /* Convert from float to 16-bit samples */ for (i=0; i<st->nsamp; i++) { sampv[i] = (int16_t)float_buf[i]; } *sampc = st->nsamp; return 0; }
/*! \brief decode a frame and store in outbuf */ static int ilbctolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f) { struct ilbc_coder_pvt *tmp = pvt->pvt; int plc_mode = 1; /* 1 = normal data, 0 = plc */ /* Assuming there's space left, decode into the current buffer at the tail location. Read in as many frames as there are */ int x,i; int16_t *dst = (int16_t *)pvt->outbuf; float tmpf[ILBC_SAMPLES]; if (f->datalen == 0) { /* native PLC, set fake f->datalen and clear plc_mode */ f->datalen = ILBC_FRAME_LEN; f->samples = ILBC_SAMPLES; plc_mode = 0; /* do native plc */ pvt->samples += ILBC_SAMPLES; } if (f->datalen % ILBC_FRAME_LEN) { ast_log(LOG_WARNING, "Huh? An ilbc frame that isn't a multiple of 50 bytes long from %s (%d)?\n", f->src, f->datalen); return -1; } for (x=0; x < f->datalen ; x += ILBC_FRAME_LEN) { if (pvt->samples + ILBC_SAMPLES > BUFFER_SAMPLES) { ast_log(LOG_WARNING, "Out of buffer space\n"); return -1; } iLBC_decode(tmpf, plc_mode ? f->data + x : NULL, &tmp->dec, plc_mode); for ( i=0; i < ILBC_SAMPLES; i++) dst[pvt->samples + i] = tmpf[i]; pvt->samples += ILBC_SAMPLES; pvt->datalen += 2*ILBC_SAMPLES; } return 0; }
short decode( /* (o) Number of decoded samples */ iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) Decoder instance */ short *decoded_data, /* (o) Decoded signal block*/ short *encoded_data, /* (i) Encoded bytes */ short mode /* (i) 0=PL, 1=Normal */ ){ int k; float decblock[BLOCKL_MAX], dtmp; /* check if mode is valid */ if (mode<0 || mode>1) { printf("\nERROR - Wrong mode - 0, 1 allowed\n"); exit(3);} /* do actual decoding of block */ iLBC_decode(decblock, (unsigned char *)encoded_data, iLBCdec_inst, mode); /* convert to short */ for (k=0; k<iLBCdec_inst->blockl; k++){ dtmp=decblock[k]; if (dtmp<MIN_SAMPLE) dtmp=MIN_SAMPLE; else if (dtmp>MAX_SAMPLE) dtmp=MAX_SAMPLE; decoded_data[k] = (short) dtmp; } return (iLBCdec_inst->blockl); }
static int ilbctolin_framein(struct ast_translator_pvt *tmp, struct ast_frame *f) { /* Assuming there's space left, decode into the current buffer at the tail location. Read in as many frames as there are */ int x,i; float tmpf[240]; if (f->datalen % 50) { ast_log(LOG_WARNING, "Huh? An ilbc frame that isn't a multiple of 50 bytes long from %s (%d)?\n", f->src, f->datalen); return -1; } for (x=0;x<f->datalen;x+=50) { if (tmp->tail + 240 < sizeof(tmp->buf)/2) { iLBC_decode(tmpf, f->data + x, &tmp->dec, 1); for (i=0;i<240;i++) tmp->buf[tmp->tail + i] = tmpf[i]; tmp->tail+=240; } else { ast_log(LOG_WARNING, "Out of buffer space\n"); return -1; } } return 0; }
/*解码一次 */ static int decode(unsigned char *data, short *samples, int mode) { int i; float block[BLOCKL_MAX]; // Validate Mode if (mode != 0 && mode != 1) { LOGE("Bad mode"); return -1; } iLBC_decode(block, data, &g_dec_inst, mode); // Validate PCM16 for (i = 0; i < g_dec_inst.blockl; i++) { float point; point = block[i]; if (point < MIN_SAMPLE) { point = MIN_SAMPLE; } else if (point > MAX_SAMPLE) { point = MAX_SAMPLE; } samples[i] = point; } return g_dec_inst.blockl * 2; }
static void dec_process(MSFilter *f){ DecState *s=(DecState*)f->data; mblk_t *im,*om; int nbytes; float samples[BLOCKL_MAX],tmp; int i; while ((im=ms_queue_get(f->inputs[0]))!=NULL){ nbytes=msgdsize(im); if (nbytes<=0) return; if (nbytes%38!=0 && nbytes%50!=0) return; if (nbytes%38==0 && s->nbytes!=NO_OF_BYTES_20MS) { /* not yet configured, or misconfigured */ s->ms_per_frame=20; s->nbytes=NO_OF_BYTES_20MS; s->nsamples=BLOCKL_20MS; initDecode(&s->ilbc_dec,s->ms_per_frame,0); } else if (nbytes%50==0 && s->nbytes!=NO_OF_BYTES_30MS) { /* not yet configured, or misconfigured */ s->ms_per_frame=30; s->nbytes=NO_OF_BYTES_30MS; s->nsamples=BLOCKL_30MS; initDecode(&s->ilbc_dec,s->ms_per_frame,0); } if (s->nbytes>0 && nbytes>=s->nbytes){ int frame_per_packet = nbytes/s->nbytes; int k; for (k=0;k<frame_per_packet;k++) { om=allocb(s->nsamples*2,0); iLBC_decode(samples,(uint8_t*)im->b_rptr+(k*s->nbytes),&s->ilbc_dec,1); for (i=0;i<s->nsamples;i++,om->b_wptr+=2){ tmp=samples[i]; //ÐÞÕý±¬ÆÆÒô if (tmp<MIN_SAMPLE) tmp=MIN_SAMPLE; else if (tmp>MAX_SAMPLE) tmp=MAX_SAMPLE; *((int16_t*)om->b_wptr)= tmp; } ms_queue_put(f->outputs[0],om); } }else{ ms_warning("bad iLBC frame !"); } freemsg(im); } }
static int iLBC_2_Pcm16_Ext( unsigned char* out_buf, unsigned char* in_buf, unsigned int size, unsigned int channels, unsigned int rate, long h_codec, int mode ) { short* out_b = (short*)out_buf; int i,k,noframes; float decblock[BLOCKL_MAX]; float dtmp; iLBC_Codec_Inst_t* codec_inst; short out_buf_offset=0; if (!h_codec){ ERROR("iLBC codec not initialized.\n"); return 0; } if ((channels!=1)||(rate!=8000)) { ERROR("Unsupported input format for iLBC encoder.\n"); return 0; } codec_inst = (iLBC_Codec_Inst_t*)h_codec; noframes = size / codec_inst->iLBC_Dec_Inst.no_of_bytes; if (noframes*codec_inst->iLBC_Dec_Inst.no_of_bytes != size) { WARN("Dropping extra %d bytes from iLBC packet.\n", size - noframes*codec_inst->iLBC_Dec_Inst.no_of_bytes); } for (i=0;i<noframes;i++) { /* do actual decoding of block */ iLBC_decode(decblock,in_buf+i*codec_inst->iLBC_Dec_Inst.no_of_bytes, &codec_inst->iLBC_Dec_Inst, mode/* mode 0=PL, 1=Normal */); for (k=0; k<codec_inst->iLBC_Dec_Inst.blockl; k++){ dtmp=decblock[k]; if (dtmp<MIN_SAMPLE) dtmp=MIN_SAMPLE; else if (dtmp>MAX_SAMPLE) dtmp=MAX_SAMPLE; out_b[out_buf_offset] = (short) dtmp; out_buf_offset++; } } return out_buf_offset*2; // sample size: 2 bytes (short) }
static int codec_decoder(const struct PluginCodec_Definition * codec, void * context, const void * from, unsigned * fromLen, void * to, unsigned * toLen, unsigned int * flag) { int i; float block[BLOCKL_MAX]; struct iLBC_Dec_Inst_t_ * decoder = (struct iLBC_Dec_Inst_t_ *)context; short * sampleBuffer = (short *)to; if (*fromLen < (unsigned)decoder->no_of_bytes) return 0; /* do actual decoding of block */ iLBC_decode(block, (unsigned char *)from, decoder, 1); if (*toLen < (unsigned)decoder->blockl*2) return 0; /* convert to short */ for (i = 0; i < decoder->blockl; i++) { float tmp = block[i]; if (tmp < MIN_SAMPLE) tmp = MIN_SAMPLE; else if (tmp > MAX_SAMPLE) tmp = MAX_SAMPLE; sampleBuffer[i] = (short)tmp; } *toLen = decoder->blockl*2; return 1; }
static void dec_process(MSFilter *f){ DecState *s=(DecState*)f->data; mblk_t *im,*om; int nbytes; float samples[BLOCKL_MAX]={0}; int i; while ((im=ms_queue_get(f->inputs[0]))!=NULL){ nbytes=msgdsize(im); if (nbytes==0 || (nbytes%38!=0 && nbytes%50!=0)){ freemsg(im); continue; } if (nbytes%38==0 && s->nbytes!=NO_OF_BYTES_20MS) { /* not yet configured, or misconfigured */ s->ms_per_frame=20; s->nbytes=NO_OF_BYTES_20MS; s->nsamples=BLOCKL_20MS; s->ready=TRUE; initDecode(&s->ilbc_dec,s->ms_per_frame,s->postfilter); } else if (nbytes%50==0 && s->nbytes!=NO_OF_BYTES_30MS) { /* not yet configured, or misconfigured */ s->ms_per_frame=30; s->nbytes=NO_OF_BYTES_30MS; s->nsamples=BLOCKL_30MS; s->ready=TRUE; initDecode(&s->ilbc_dec,s->ms_per_frame,s->postfilter); } if (s->nbytes>0 && nbytes>=s->nbytes){ int frame_per_packet = nbytes/s->nbytes; int k; int plctime; for (k=0;k<frame_per_packet;k++) { om=allocb(s->nsamples*2,0); iLBC_decode(samples,(uint8_t*)im->b_rptr+(k*s->nbytes),&s->ilbc_dec,1); for (i=0;i<s->nsamples;i++,om->b_wptr+=2){ *((int16_t*)om->b_wptr)=samples[i]; } mblk_meta_copy(im,om); ms_queue_put(f->outputs[0],om); } if (s->plcctx){ plctime=ms_concealer_inc_sample_time(s->plcctx,f->ticker->time,frame_per_packet*s->ms_per_frame,1); if (plctime>0){ ms_warning("ilbc: did plc during %i ms",plctime); } } }else{ ms_warning("bad iLBC frame !"); } freemsg(im); } if (s->plcctx && s->ready && ms_concealer_context_is_concealement_required(s->plcctx,f->ticker->time)){ om=allocb(s->nsamples*2,0); iLBC_decode(samples,(uint8_t*)NULL,&s->ilbc_dec,0 /*PLC*/); for (i=0;i<s->nsamples;i++,om->b_wptr+=2){ *((int16_t*)om->b_wptr)=samples[i]; } mblk_set_plc_flag(om,TRUE); ms_queue_put(f->outputs[0],om); ms_concealer_inc_sample_time(s->plcctx,f->ticker->time,s->ms_per_frame,0); } }
void IlbcToPcmFilter::AudioChunkIn(AudioChunkRef& inputAudioChunk) { int r_samples = 0, fs = 0, i = 0, pos = 0, o_samples = 0, j = 0; float ilbcf[240]; m_outputAudioChunk.reset(); if(inputAudioChunk.get() == NULL) { return; } if(inputAudioChunk->GetNumSamples() == 0) { return; } AudioChunkDetails outputDetails = *inputAudioChunk->GetDetails(); if(SupportsInputRtpPayloadType(outputDetails.m_rtpPayloadType) == false) { return; } r_samples = inputAudioChunk->GetNumSamples(); if((r_samples % 50) && (r_samples % 38)) { /* Strange iLBC frame that is not a multiple of 50 bytes * (30ms frame) and neither is it a multiple of 38 bytes * (20ms frame). We should probably log something? */ LOG4CXX_ERROR(this->s_ilbclog, "Error, received iLBC frame is not a multiple of 50 or 38!"); return; } if(!(r_samples % 50)) { i = r_samples / 50; o_samples = i * 240; fs = 50; #if 0 LOG4CXX_INFO(this->s_ilbclog, "Frame size is 50 bytes"); #endif } else { i = r_samples / 38; o_samples = i * 160; fs = 38; #if 0 LOG4CXX_INFO(this->s_ilbclog, "Frame size is 38 bytes"); #endif } m_outputAudioChunk.reset(new AudioChunk()); outputDetails.m_rtpPayloadType = -1; outputDetails.m_encoding = PcmAudio; outputDetails.m_numBytes = (o_samples * 2); short* outputBuffer = (short*)m_outputAudioChunk->CreateBuffer(outputDetails); unsigned char* inputBuffer = (unsigned char*)inputAudioChunk->m_pBuffer; for(i = 0; i < r_samples; i += fs) { if((pos+((fs == 50) ? 240 : 160)) <= o_samples) { if(fs == 50) { iLBC_decode(ilbcf, inputBuffer+i, &dec30, 1); for(j = 0; j < 240; j++) { outputBuffer[pos + j] = (short)ilbcf[j]; } pos += 240; } else { iLBC_decode(ilbcf, inputBuffer+i, &dec20, 1); for(j = 0; j < 160; j++) { outputBuffer[pos + j] = (short)ilbcf[j]; } pos += 160; } } else { /* This should ordinarily never happen. * Log something? */ CStdString logMsg; logMsg.Format("Strange, I ran out of space: pos=%d, o_samples=%d, r_samples=%d, i=%d, " "(pos+((fs == 50) ? 240 : 160))=%d", pos, o_samples, r_samples, i, (pos+((fs == 50) ? 240 : 160))); LOG4CXX_ERROR(this->s_ilbclog, logMsg); return; } } }
static tsk_size_t tdav_codec_ilbc_decode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size, const tsk_object_t* proto_hdr) { int blocks, i, k, block_size; float dtmp; tsk_size_t out_size; tdav_codec_ilbc_t* ilbc = (tdav_codec_ilbc_t*)self; if(!self || !in_data || !in_size || !out_data){ TSK_DEBUG_ERROR("Invalid parameter"); return 0; } if((in_size % NO_OF_BYTES_20MS) == 0){ /* Using 20ms mode */ blocks = (in_size/NO_OF_BYTES_20MS); out_size = (BLOCKL_20MS * blocks) * sizeof(short); block_size = out_size/blocks; if(ilbc->decoder.mode != 20){ initDecode(&ilbc->decoder, 20, tsk_true/* Enhancer */); } } else if((in_size % NO_OF_BYTES_30MS) == 0){ /* Using 30ms mode */ blocks = (in_size/NO_OF_BYTES_30MS); out_size = (BLOCKL_30MS * blocks) * sizeof(short); block_size = out_size/blocks; if(ilbc->decoder.mode != 30){ initDecode(&ilbc->decoder, 30, tsk_true/* Enhancer */); } } else{ TSK_DEBUG_ERROR("Invalid iLBC mode"); return 0; } /* allocate new buffer if needed */ if(*out_max_size<out_size){ if(!(*out_data = tsk_realloc(*out_data, out_size))){ TSK_DEBUG_ERROR("Failed to allocate new buffer"); *out_max_size = 0; return 0; } *out_max_size = out_size; } for(i = 0; i<blocks; i++){ iLBC_decode(ilbc->decblock, &((uint8_t*)in_data)[i*block_size], &ilbc->decoder, 1/* Normal */); /* convert to short */ for(k=0; k<ilbc->decoder.blockl; k++){ dtmp=ilbc->decblock[k]; if(dtmp<MIN_SAMPLE){ dtmp = MIN_SAMPLE; } else if(dtmp>MAX_SAMPLE){ dtmp = MAX_SAMPLE; } ((short*)*out_data)[(i*block_size) + k] = ((short) dtmp); } } return out_size; }