static void dec_process(MSFilter *f){ DecState *s=(DecState*)f->data; mblk_t *inputMessage, *outputMessage; struct BV16_Bit_Stream bs; while((inputMessage=ms_queue_get(f->inputs[0]))!=NULL){ while(inputMessage->b_rptr<inputMessage->b_wptr) { outputMessage = allocb(SIGNAL_FRAME_SIZE,0); mblk_meta_copy(inputMessage, outputMessage); BV16_BitUnPack((UWord8*)inputMessage->b_rptr, &bs); BV16_Decode(&bs, &s->state, (short*)(outputMessage->b_wptr)); outputMessage->b_wptr+=SIGNAL_FRAME_SIZE; inputMessage->b_rptr+=BITSTREAM_FRAME_SIZE; ms_queue_put(f->outputs[0],outputMessage); if (s->plc) ms_concealer_inc_sample_time(s->concealer,f->ticker->time, 5, 1); } freemsg(inputMessage); } // called every 10 ms if (s->plc && ms_concealer_context_is_concealement_required(s->concealer, f->ticker->time)) { int ms_concealed; // need to conceal 10 ms for (ms_concealed=0; ms_concealed<s->packet_ms_size; ms_concealed+=5){ outputMessage = allocb(SIGNAL_FRAME_SIZE,0); BV16_PLC(&s->state,(short*)outputMessage->b_wptr); outputMessage->b_wptr+=SIGNAL_FRAME_SIZE; mblk_set_plc_flag(outputMessage, 1); ms_queue_put(f->outputs[0],outputMessage); } ms_concealer_inc_sample_time(s->concealer,f->ticker->time,10, 0); } }
static void filter_process(MSFilter *f){ isac_decoder_t* obj = (isac_decoder_t*)f->data; mblk_t* im; int count = 0; im = ms_queue_get( f->inputs[0] ); while( im != NULL ){ decode(f, im); freemsg(im); count++; im = ms_queue_get( f->inputs[0] ); } if( ms_concealer_context_is_concealement_required(obj->plc_ctx, f->ticker->time) ) { WebRtc_Word16 flen = (obj->ptime == 30) ? ISAC_30MS_SAMPLE_COUNT : ISAC_60MS_SAMPLE_COUNT; mblk_t* plc_blk = allocb(flen*2, 0 ); // ms_message("PLC for %d ms", obj->ptime); // interpolate 1 frame for 30ms ptime, 2 frames for 60ms WebRtc_Word16 ret = WebRtcIsacfix_DecodePlc(obj->isac, (WebRtc_Word16*)plc_blk->b_wptr, (obj->ptime == 30) ? 1 : 2); if( ret < 0 ) { ms_error("WebRtcIsacfix_DecodePlc error: %d", WebRtcIsacfix_GetErrorCode(obj->isac) ); freeb(plc_blk); } else { plc_blk->b_wptr += ret*2; obj->seq_nb++; // insert this interpolated block into the output, with correct args: mblk_set_cseq(plc_blk, obj->seq_nb ); mblk_set_plc_flag(plc_blk, 1); // this one's a PLC packet ms_queue_put(f->outputs[0], plc_blk); ms_concealer_inc_sample_time(obj->plc_ctx, f->ticker->time, obj->ptime, FALSE); } } }
static void decode(MSFilter *f, mblk_t *im) { isac_decoder_t* obj = (isac_decoder_t*)f->data; WebRtc_Word16 samples_nb, ret; WebRtc_Word16 speech_type; // needed but not used.. // im is one packet from the encoder, so it's either 30 or 60 ms of audio ret = WebRtcIsacfix_ReadFrameLen( (const WebRtc_Word16*)im->b_rptr, &samples_nb); // ms_message("WebRtcIsacfix_ReadFrameLen -> %d", samples_nb); if( ret == 0 ) { mblk_t *om = allocb(samples_nb*2, 0); mblk_meta_copy(im, om); obj->ptime = (samples_nb == ISAC_30MS_SAMPLE_COUNT) ? 30 : 60; // update ptime // ms_message("DECODED om datap @%p", om->b_datap); ret = WebRtcIsacfix_Decode(obj->isac, (const WebRtc_UWord16*)im->b_rptr, (im->b_wptr - im->b_rptr), (WebRtc_Word16*)om->b_wptr, &speech_type ); if( ret < 0 ) { ms_error( "WebRtcIsacfix_Decode error: %d", WebRtcIsacfix_GetErrorCode(obj->isac) ); freeb(om); } else { // ms_message("Decoded %d samples", ret); om->b_wptr+= ret*2; mblk_set_plc_flag(om, 0); ms_queue_put(f->outputs[0], om); } } else { ms_error( "WebRtcIsacfix_ReadFrameLen failed: %d", WebRtcIsacfix_GetErrorCode(obj->isac) ); } obj->seq_nb = mblk_get_cseq(im); ms_concealer_inc_sample_time(obj->plc_ctx, f->ticker->time, obj->ptime, TRUE); return; }
static void ms_opus_dec_process(MSFilter *f) { OpusDecData *d = (OpusDecData *)f->data; mblk_t *im; mblk_t *om; int frames; if (!d->state) ms_queue_flush(f->inputs[0]); /* decode available packets */ while ((im = ms_queue_get(f->inputs[0])) != NULL) { om = allocb(5760 * d->channels * SIGNAL_SAMPLE_SIZE, 0); /* 5760 is the maximum number of sample in a packet (120ms at 48KHz) */ frames = opus_decode(d->state, (const unsigned char *)im->b_rptr, im->b_wptr - im->b_rptr, (opus_int16 *)om->b_wptr, 5760, 0); if (frames < 0) { ms_warning("Opus decoder error: %s", opus_strerror(frames)); freemsg(om); } else { d->lastPacketLength = frames; // store the packet length for eventual PLC if next two packets are missing om->b_wptr += frames * d->channels * SIGNAL_SAMPLE_SIZE; mblk_meta_copy(im,om); ms_queue_put(f->outputs[0], om); /*ms_message("Opus: outputing a normal frame of %i bytes (%i samples,%i ms)",(int)(om->b_wptr-om->b_rptr),frames,frames*1000/d->samplerate);*/ d->sequence_number = mblk_get_cseq(im); // used to get eventual FEC information if next packet is missing ms_concealer_inc_sample_time(d->concealer,f->ticker->time, frames*1000/d->samplerate, 1); } freemsg(im); } /* Concealment if needed */ if (ms_concealer_context_is_concealement_required(d->concealer, f->ticker->time)) { int imLength = 0; uint8_t *payload = NULL; im = NULL; // try fec : info are stored in the next packet, do we have it? if (d->rtp_picker_context.picker) { /* FEC information is in the next packet, last valid packet was d->sequence_number, the missing one shall then be d->sequence_number+1, so check jitter buffer for d->sequence_number+2 */ /* but we may have the n+1 packet in the buffer and adaptative jitter control keeping it for later, in that case, just go for PLC */ if (d->rtp_picker_context.picker(&d->rtp_picker_context,d->sequence_number+1) == NULL) { /* missing packet is really missing */ im = d->rtp_picker_context.picker(&d->rtp_picker_context,d->sequence_number+2); /* try to get n+2 */ if (im) { imLength=rtp_get_payload(im,&payload); } } } om = allocb(5760 * d->channels * SIGNAL_SAMPLE_SIZE, 0); /* 5760 is the maximum number of sample in a packet (120ms at 48KHz) */ /* call to the decoder, we'll have either FEC or PLC, do it on the same length that last received packet */ if (payload) { // found frame to try FEC d->statsfec++; frames = opus_decode(d->state, payload, imLength, (opus_int16 *)om->b_wptr, d->lastPacketLength, 1); } else { // do PLC: PLC doesn't seem to be able to generate more than 960 samples (20 ms at 48000 Hz), get PLC until we have the correct number of sample //frames = opus_decode(d->state, NULL, 0, (opus_int16 *)om->b_wptr, d->lastPacketLength, 0); // this should have work if opus_decode returns the requested number of samples d->statsplc++; frames = 0; while (frames < d->lastPacketLength) { frames += opus_decode(d->state, NULL, 0, (opus_int16 *)(om->b_wptr + (frames*d->channels*SIGNAL_SAMPLE_SIZE)), d->lastPacketLength-frames, 0); } } if (frames < 0) { ms_warning("Opus decoder error in concealment: %s", opus_strerror(frames)); freemsg(om); } else { om->b_wptr += frames * d->channels * SIGNAL_SAMPLE_SIZE; /*ms_message("Opus: outputing a PLC frame of %i bytes (%i samples,%i ms)",(int)(om->b_wptr-om->b_rptr),frames,frames*1000/d->samplerate);*/ mblk_set_plc_flag(om,TRUE); ms_queue_put(f->outputs[0], om); d->sequence_number++; ms_concealer_inc_sample_time(d->concealer,f->ticker->time, frames*1000/d->samplerate, 0); } } }
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); } }
static void ms_opus_dec_process(MSFilter *f) { OpusDecData *d = (OpusDecData *)f->data; mblk_t *im; mblk_t *om; int frames; /* decode available packets */ while ((im = ms_queue_get(f->inputs[0])) != NULL) { om = allocb(5760 * d->channels * SIGNAL_SAMPLE_SIZE, 0); /* 5760 is the maximum number of sample in a packet (120ms at 48KHz) */ frames = opus_decode(d->state, (const unsigned char *)im->b_rptr, im->b_wptr - im->b_rptr, (opus_int16 *)om->b_wptr, 5760, 0); if (frames < 0) { ms_warning("Opus decoder error: %s", opus_strerror(frames)); freemsg(om); } else { d->lastPacketLength = frames; // store the packet length for eventual PLC if next two packets are missing om->b_wptr += frames * d->channels * SIGNAL_SAMPLE_SIZE; ms_queue_put(f->outputs[0], om); d->sequence_number = mblk_get_cseq(im); // used to get eventual FEC information if next packet is missing ms_concealer_inc_sample_time(d->concealer,f->ticker->time, frames*1000/d->samplerate, 1); } freemsg(im); } /* Concealment if needed */ if (ms_concealer_context_is_concealement_required(d->concealer, f->ticker->time)) { int imLength = 0; im = NULL; uint8_t *payload = NULL; // try fec : info are stored in the next packet, do we have it? if (d->rtp_picker_context.picker) { im = d->rtp_picker_context.picker(&d->rtp_picker_context,d->sequence_number+1); if (im) { imLength=rtp_get_payload(im,&payload); d->statsfec++; } else { d->statsplc++; } } om = allocb(5760 * d->channels * SIGNAL_SAMPLE_SIZE, 0); /* 5760 is the maximum number of sample in a packet (120ms at 48KHz) */ /* call to the decoder, we'll have either FEC or PLC, do it on the same length that last received packet */ if (payload) { // found frame to try FEC frames = opus_decode(d->state, payload, imLength, (opus_int16 *)om->b_wptr, d->lastPacketLength, 1); } else { // do PLC: PLC doesn't seem to be able to generate more than 960 samples (20 ms at 48000 Hz), get PLC until we have the correct number of sample //frames = opus_decode(d->state, NULL, 0, (opus_int16 *)om->b_wptr, d->lastPacketLength, 0); // this should have work if opus_decode returns the requested number of samples frames = 0; while (frames < d->lastPacketLength) { frames += opus_decode(d->state, NULL, 0, (opus_int16 *)(om->b_wptr + (frames*d->channels*SIGNAL_SAMPLE_SIZE)), d->lastPacketLength-frames, 0); } } if (frames < 0) { ms_warning("Opus decoder error in concealment: %s", opus_strerror(frames)); freemsg(om); } else { om->b_wptr += frames * d->channels * SIGNAL_SAMPLE_SIZE; ms_queue_put(f->outputs[0], om); d->sequence_number++; ms_concealer_inc_sample_time(d->concealer,f->ticker->time, frames*1000/d->samplerate, 0); } } }
static void generic_plc_process(MSFilter *f) { generic_plc_struct *mgps=(generic_plc_struct*)f->data; unsigned int buff_size = mgps->rate*sizeof(int16_t)*mgps->nchannels*f->ticker->interval/1000; mblk_t *m; while((m=ms_queue_get(f->inputs[0]))!=NULL){ int transitionBufferSize = mgps->rate*sizeof(int16_t)*TRANSITION_DELAY/1000; unsigned char buf[128]; unsigned int time = (1000*(m->b_wptr - m->b_rptr))/(mgps->rate*sizeof(int16_t)*mgps->nchannels); ms_concealer_inc_sample_time(mgps->concealer, f->ticker->time, time, TRUE); /* introduce 16 sample delay (2ms) */ memcpy(buf, m->b_wptr-transitionBufferSize, transitionBufferSize); memmove(m->b_rptr+transitionBufferSize, m->b_rptr, m->b_wptr - m->b_rptr - transitionBufferSize); memcpy(m->b_rptr, mgps->continuity_buffer, transitionBufferSize); memcpy(mgps->continuity_buffer, buf, transitionBufferSize); if (mgps->cng_running){ /*we were doing CNG, now resuming with normal audio*/ int16_t continuity_buffer[80]; #ifdef HAVE_G729B bcg729Decoder(mgps->decoderChannelContext, NULL, 0, 1, 1, 1, continuity_buffer); #else memset (continuity_buffer, 0, 80*sizeof(int16_t)); #endif memcpy(m->b_rptr, continuity_buffer, transitionBufferSize); generic_plc_transition_mix((int16_t *)(m->b_rptr+transitionBufferSize), &(continuity_buffer[mgps->rate*TRANSITION_DELAY/1000]), mgps->rate*TRANSITION_DELAY/1000); mgps->cng_running=FALSE; mgps->cng_set=FALSE; } ms_queue_put(f->outputs[0], m); } if (ms_concealer_context_is_concealement_required(mgps->concealer, f->ticker->time)) { #ifdef HAVE_G729B m = allocb(buff_size, 0); /* Transmitted CNG data is in mgps->cng_data : give it to bcg729 decoder -> output in m->b_wptr */ if (mgps->cng_set) { /* received some CNG data */ mgps->cng_set=FALSE; /* reset flag */ mgps->cng_running=TRUE; bcg729Decoder(mgps->decoderChannelContext, mgps->cng_data.data, mgps->cng_data.datasize, 0, 1, 1, (int16_t *)(m->b_wptr)); mblk_set_cng_flag(m, 1); generic_plc_transition_mix((int16_t *)m->b_wptr, (int16_t *)mgps->continuity_buffer, mgps->rate*TRANSITION_DELAY/1000); /* TODO: if ticker->interval is not 10 ms which is also G729 frame length, we must generate untransmitted frame CNG until we reach the requested data amount */ } else if (mgps->cng_running) { /* missing frame but CNG is ongoing: shall be an untransmitted frame */ bcg729Decoder(mgps->decoderChannelContext, NULL, 0, 1, 1, 1, (int16_t *)(m->b_wptr)); mblk_set_cng_flag(m, 1); } else { mblk_set_plc_flag(m, 1); memset(m->b_wptr, 0, buff_size); } #else m = allocb(buff_size, 0); if (!mgps->cng_running && mgps->cng_set){ mgps->cng_running=TRUE; mblk_set_cng_flag(m, 1); /*TODO do something with the buffer*/ }else{ mblk_set_plc_flag(m, 1); } memset(m->b_wptr, 0, buff_size); #endif m->b_wptr += buff_size; ms_queue_put(f->outputs[0], m); ms_concealer_inc_sample_time(mgps->concealer, f->ticker->time, f->ticker->interval, FALSE); } }
static void generic_plc_process(MSFilter *f) { generic_plc_struct *mgps=(generic_plc_struct*)f->data; plc_context_t *plc_context = mgps->plc_context; mblk_t *m; while((m=ms_queue_get(f->inputs[0]))!=NULL){ int transitionBufferSize = mgps->rate*sizeof(int16_t)*TRANSITION_DELAY/1000; size_t msg_size = msgdsize(m); unsigned int time = (unsigned int)((1000*msg_size)/(mgps->rate*sizeof(int16_t)*mgps->nchannels)); ms_concealer_inc_sample_time(mgps->concealer, f->ticker->time, time, TRUE); /* Store current msg in plc_buffer */ generic_plc_update_plc_buffer(plc_context, m->b_rptr, msg_size); /* introduce delay (TRANSITION_DELAY ms) */ generic_plc_update_continuity_buffer(plc_context, m->b_rptr, msg_size); if (mgps->cng_running){ /*we were doing CNG, now resuming with normal audio*/ int16_t continuity_buffer[80]; #ifdef HAVE_G729B bcg729Decoder(mgps->decoderChannelContext, NULL, 0, 1, 1, 1, continuity_buffer); #else memset (continuity_buffer, 0, 80*sizeof(int16_t)); #endif memcpy(m->b_rptr, continuity_buffer, transitionBufferSize); generic_plc_transition_mix((int16_t *)(m->b_rptr+transitionBufferSize), continuity_buffer, mgps->rate*TRANSITION_DELAY/1000); mgps->cng_running=FALSE; mgps->cng_set=FALSE; } if (plc_context->plc_samples_used!=0) { /*we were doing PLC, now resuming with normal audio, continuity buffer is twice the transition delay lengths, * the second half is untouched by the update function and contains transition data generated by PLC */ generic_plc_transition_mix((int16_t *)(m->b_rptr+transitionBufferSize), (int16_t *)(plc_context->continuity_buffer+transitionBufferSize), mgps->rate*TRANSITION_DELAY/1000); } plc_context->plc_index=0; plc_context->plc_samples_used=0; ms_queue_put(f->outputs[0], m); } if (ms_concealer_context_is_concealement_required(mgps->concealer, f->ticker->time)) { unsigned int buff_size = mgps->rate*sizeof(int16_t)*mgps->nchannels*f->ticker->interval/1000; #ifdef HAVE_G729B m = allocb(buff_size, 0); /* Transmitted CNG data is in mgps->cng_data : give it to bcg729 decoder -> output in m->b_wptr */ if (mgps->cng_set) { /* received some CNG data */ mgps->cng_set=FALSE; /* reset flag */ mgps->cng_running=TRUE; bcg729Decoder(mgps->decoderChannelContext, mgps->cng_data.data, mgps->cng_data.datasize, 0, 1, 1, (int16_t *)(m->b_wptr)); mblk_set_cng_flag(m, 1); generic_plc_transition_mix((int16_t *)m->b_wptr, (int16_t *)plc_context->continuity_buffer, mgps->rate*TRANSITION_DELAY/1000); /* TODO: if ticker->interval is not 10 ms which is also G729 frame length, we must generate untransmitted frame CNG until we reach the requested data amount */ } else if (mgps->cng_running) { /* missing frame but CNG is ongoing: shall be an untransmitted frame */ bcg729Decoder(mgps->decoderChannelContext, NULL, 0, 1, 1, 1, (int16_t *)(m->b_wptr)); mblk_set_cng_flag(m, 1); } else { /* plc */ mblk_set_plc_flag(m, 1); generic_plc_generate_samples(plc_context, (int16_t *)m->b_wptr, buff_size/sizeof(int16_t)); /* store the generated samples into plc_buffer */ generic_plc_update_plc_buffer(plc_context, m->b_wptr, buff_size); //memset(m->b_wptr, 0, buff_size); } #else m = allocb(buff_size, 0); if (mgps->cng_set){ mgps->cng_set=FALSE; /* reset flag */ mgps->cng_running=TRUE; mblk_set_cng_flag(m, 1); /*TODO do something with the buffer*/ memset(m->b_wptr, 0, buff_size); } else if (mgps->cng_running) { /* missing frame but CNG is ongoing: shall be an untransmitted frame */ memset(m->b_wptr, 0, buff_size); mblk_set_cng_flag(m, 1); }else{ /* plc */ mblk_set_plc_flag(m, 1); generic_plc_generate_samples(plc_context, (int16_t *)m->b_wptr, buff_size/sizeof(int16_t)); /* store the generated samples into plc_buffer */ generic_plc_update_plc_buffer(plc_context, m->b_wptr, buff_size); //memset(m->b_wptr, 0, buff_size); } #endif m->b_wptr += buff_size; ms_queue_put(f->outputs[0], m); ms_concealer_inc_sample_time(mgps->concealer, f->ticker->time, f->ticker->interval, FALSE); } }