static int g722tolin_framein(struct cw_translator_pvt *pvt, struct cw_frame *f) { struct g722_decoder_pvt *tmp = (struct g722_decoder_pvt *) pvt; if (f->datalen == 0) { /* Perform PLC with nominal framesize of 20ms/320 samples */ if ((tmp->tail + 320) > BUFFER_SIZE) { cw_log(LOG_WARNING, "Out of buffer space\n"); return -1; } if (useplc) { plc_fillin(&tmp->plc, tmp->outbuf + tmp->tail, 320); tmp->tail += 320; } } else { if ((tmp->tail + f->datalen*2) > BUFFER_SIZE) { cw_log(LOG_WARNING, "Out of buffer space\n"); return -1; } tmp->tail += g722_decode(&(tmp->g722_state), tmp->outbuf + tmp->tail, (const uint8_t *) f->data, f->datalen); if (useplc) plc_rx(&tmp->plc, tmp->outbuf + tmp->tail - f->datalen*2, f->datalen*2); } return 0; }
/* PLC is only valid for Decoding (RX) */ static int dec(struct aufilt_st *st, struct mbuf *mb) { int nsamp = (int)mbuf_get_left(mb) / 2; if (nsamp) { nsamp = plc_rx(&st->plc, (int16_t *)mbuf_buf(mb), nsamp); if (nsamp >= 0) mb->end = mb->pos + (2*nsamp); } else { nsamp = (int)st->psize / 2; re_printf("plc: concealing %u bytes\n", st->psize); if (mbuf_get_space(mb) < st->psize) { int err = mbuf_resize(mb, st->psize); if (err) return err; } nsamp = plc_fillin(&st->plc, (int16_t *)mbuf_buf(mb), nsamp); mb->end = mb->pos + 2 * nsamp; } return 0; }
/* * PLC is only valid for Decoding (RX) * * NOTE: sampc == 0 , means Packet loss */ static int decode(struct aufilt_dec_st *st, int16_t *sampv, size_t *sampc) { struct plc_st *plc = (struct plc_st *)st; if (*sampc) plc_rx(&plc->plc, sampv, (int)*sampc); else *sampc = plc_fillin(&plc->plc, sampv, (int)plc->sampc); return 0; }
static int lpc10tolin_framein(struct cw_translator_pvt *tmp, struct cw_frame *f) { /* Assuming there's space left, decode into the current buffer at the tail location */ int len = 0; int16_t *sd; if (f->datalen == 0) { /* Perform PLC with nominal framesize of LPC10_SAMPLES_PER_FRAME */ if ((tmp->tail + LPC10_SAMPLES_PER_FRAME) > sizeof(tmp->buf)/sizeof(int16_t)) { cw_log(LOG_WARNING, "Out of buffer space\n"); return -1; } if (useplc) { plc_fillin(&tmp->plc, tmp->buf+tmp->tail, LPC10_SAMPLES_PER_FRAME); tmp->tail += LPC10_SAMPLES_PER_FRAME; } return 0; } while (len + LPC10_BYTES_IN_COMPRESSED_FRAME <= f->datalen) { if (tmp->tail + LPC10_SAMPLES_PER_FRAME >= sizeof(tmp->buf)/sizeof(int16_t)) { cw_log(LOG_WARNING, "Out of buffer space\n"); return -1; } sd = tmp->buf + tmp->tail; if (lpc10_decode(tmp->lpc10.dec, sd, f->data + len, 7) < LPC10_SAMPLES_PER_FRAME) { cw_log(LOG_WARNING, "Invalid lpc10 data\n"); return -1; } if (useplc) plc_rx(&tmp->plc, tmp->buf + tmp->tail, LPC10_SAMPLES_PER_FRAME); tmp->tail += LPC10_SAMPLES_PER_FRAME; len += LPC10_BYTES_IN_COMPRESSED_FRAME; } if (len != f->datalen) cw_log(LOG_WARNING, "Decoded %d, expected %d\n", len, f->datalen); return 0; }
static void gst_span_plc_send_fillin (GstSpanPlc * plc, GstClockTime duration) { guint buf_size; GstBuffer *buffer = NULL; buf_size = ((float) duration / GST_SECOND) * plc->sample_rate; buf_size *= sizeof (guint16); buffer = gst_buffer_new_and_alloc (buf_size); GST_DEBUG_OBJECT (plc, "Missing packet of %" GST_TIME_FORMAT " == %d bytes", GST_TIME_ARGS (duration), buf_size); plc_fillin (plc->plc_state, (int16_t *) GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer) / 2); GST_BUFFER_TIMESTAMP (buffer) = plc->last_stop; GST_BUFFER_DURATION (buffer) = duration; gst_buffer_set_caps (buffer, GST_PAD_CAPS (plc->srcpad)); gst_pad_push (plc->srcpad, buffer); }
unsigned int AmRtpAudio::default_plc(unsigned char* out_buf, unsigned int size, unsigned int channels, unsigned int sample_rate) { short* buf_offset = (short*)out_buf; #ifdef USE_SPANDSP_PLC plc_fillin(plc_state, buf_offset, PCM16_B2S(size)); #else for(unsigned int i=0; i<(PCM16_B2S(size)/FRAMESZ); i++){ fec->dofe(buf_offset); buf_offset += FRAMESZ; } #endif // USE_SPANDSP_PLC return PCM16_S2B(buf_offset - (short*)out_buf); }
static void gst_span_plc_send_fillin (GstSpanPlc * plc, GstClockTime timestamp, GstClockTime duration) { guint buf_size; GstBuffer *buffer = NULL; GstMapInfo map; buf_size = ((float) duration / GST_SECOND) * plc->sample_rate; buf_size *= sizeof (guint16); buffer = gst_buffer_new_and_alloc (buf_size); GST_DEBUG_OBJECT (plc, "Missing packet of %" GST_TIME_FORMAT " == %d bytes", GST_TIME_ARGS (duration), buf_size); gst_buffer_map (buffer, &map, GST_MAP_READWRITE); plc_fillin (plc->plc_state, (int16_t *) map.data, map.size / 2); gst_buffer_unmap (buffer, &map); GST_BUFFER_PTS (buffer) = timestamp; GST_BUFFER_DURATION (buffer) = duration; gst_pad_push (plc->srcpad, buffer); }
SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) { switch_io_event_hook_read_frame_t *ptr; switch_status_t status = SWITCH_STATUS_FALSE; int need_codec, perfect, do_bugs = 0, do_resample = 0, is_cng = 0; switch_codec_implementation_t codec_impl; unsigned int flag = 0; switch_assert(session != NULL); if (switch_mutex_trylock(session->codec_read_mutex) == SWITCH_STATUS_SUCCESS) { switch_mutex_unlock(session->codec_read_mutex); } else { switch_cond_next(); *frame = &runtime.dummy_cng_frame; return SWITCH_STATUS_SUCCESS; } if (!(session->read_codec && session->read_codec->implementation && switch_core_codec_ready(session->read_codec))) { if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || switch_channel_get_state(session->channel) == CS_HIBERNATE) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s reading on a session with no media!\n", switch_channel_get_name(session->channel)); switch_cond_next(); *frame = &runtime.dummy_cng_frame; return SWITCH_STATUS_SUCCESS; } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel)); switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); return SWITCH_STATUS_FALSE; } switch_mutex_lock(session->codec_read_mutex); if (!switch_core_codec_ready(session->read_codec)) { switch_mutex_unlock(session->codec_read_mutex); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel)); switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); *frame = &runtime.dummy_cng_frame; return SWITCH_STATUS_FALSE; } switch_mutex_lock(session->read_codec->mutex); top: if (session->dmachine && !switch_channel_test_flag(session->channel, CF_BROADCAST)) { switch_ivr_dmachine_ping(session->dmachine, NULL); } if (switch_channel_down(session->channel) || !switch_core_codec_ready(session->read_codec)) { *frame = NULL; status = SWITCH_STATUS_FALSE; goto even_more_done; } status = SWITCH_STATUS_FALSE; need_codec = perfect = 0; *frame = NULL; if (session->read_codec && !session->track_id && session->track_duration) { if (session->read_frame_count == 0) { switch_event_t *event; session->read_frame_count = (session->read_impl.actual_samples_per_second / session->read_impl.samples_per_packet) * session->track_duration; switch_event_create(&event, SWITCH_EVENT_SESSION_HEARTBEAT); switch_channel_event_set_data(session->channel, event); switch_event_fire(&event); } else { session->read_frame_count--; } } if (switch_channel_test_flag(session->channel, CF_HOLD)) { switch_yield(session->read_impl.microseconds_per_packet); status = SWITCH_STATUS_BREAK; goto even_more_done; } if (session->endpoint_interface->io_routines->read_frame) { switch_mutex_unlock(session->read_codec->mutex); switch_mutex_unlock(session->codec_read_mutex); if ((status = session->endpoint_interface->io_routines->read_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) { for (ptr = session->event_hooks.read_frame; ptr; ptr = ptr->next) { if ((status = ptr->read_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) { break; } } } if (!SWITCH_READ_ACCEPTABLE(status) || !session->read_codec || !switch_core_codec_ready(session->read_codec)) { *frame = NULL; return SWITCH_STATUS_FALSE; } switch_mutex_lock(session->codec_read_mutex); if (!switch_core_codec_ready(session->read_codec)) { switch_mutex_unlock(session->codec_read_mutex); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel)); switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); *frame = &runtime.dummy_cng_frame; return SWITCH_STATUS_FALSE; } switch_mutex_lock(session->read_codec->mutex); if (!switch_core_codec_ready(session->read_codec)) { *frame = NULL; status = SWITCH_STATUS_FALSE; goto even_more_done; } } if (status != SWITCH_STATUS_SUCCESS) { goto done; } if (!(*frame)) { goto done; } switch_assert(*frame != NULL); if (switch_test_flag(*frame, SFF_PROXY_PACKET)) { /* Fast PASS! */ status = SWITCH_STATUS_SUCCESS; goto done; } if (switch_test_flag(*frame, SFF_CNG)) { status = SWITCH_STATUS_SUCCESS; if (!session->bugs && !session->plc) { goto done; } is_cng = 1; } switch_assert((*frame)->codec != NULL); if (!(session->read_codec && (*frame)->codec && (*frame)->codec->implementation) && switch_core_codec_ready((*frame)->codec)) { status = SWITCH_STATUS_FALSE; goto done; } codec_impl = *(*frame)->codec->implementation; if (session->read_codec->implementation->impl_id != codec_impl.impl_id) { need_codec = TRUE; } if (codec_impl.actual_samples_per_second != session->read_impl.actual_samples_per_second) { do_resample = 1; } if (session->bugs && !need_codec) { do_bugs = 1; need_codec = 1; } if (switch_test_flag(session, SSF_READ_TRANSCODE) && !need_codec && switch_core_codec_ready(session->read_codec)) { switch_core_session_t *other_session; const char *uuid = switch_channel_get_variable(switch_core_session_get_channel(session), SWITCH_SIGNAL_BOND_VARIABLE); switch_clear_flag(session, SSF_READ_TRANSCODE); if (uuid && (other_session = switch_core_session_locate(uuid))) { switch_set_flag(other_session, SSF_READ_CODEC_RESET); switch_set_flag(other_session, SSF_READ_CODEC_RESET); switch_set_flag(other_session, SSF_WRITE_CODEC_RESET); switch_core_session_rwunlock(other_session); } } if (switch_test_flag(session, SSF_READ_CODEC_RESET)) { switch_core_codec_reset(session->read_codec); switch_clear_flag(session, SSF_READ_CODEC_RESET); } if (status == SWITCH_STATUS_SUCCESS && need_codec) { switch_frame_t *enc_frame, *read_frame = *frame; switch_set_flag(session, SSF_READ_TRANSCODE); if (!switch_test_flag(session, SSF_WARN_TRANSCODE)) { switch_core_session_message_t msg = { 0 }; msg.message_id = SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY; switch_core_session_receive_message(session, &msg); switch_set_flag(session, SSF_WARN_TRANSCODE); } if (read_frame->codec || is_cng) { session->raw_read_frame.datalen = session->raw_read_frame.buflen; if (is_cng) { if (session->plc) { plc_fillin(session->plc, session->raw_read_frame.data, read_frame->codec->implementation->decoded_bytes_per_packet / 2); is_cng = 0; flag &= !SFF_CNG; } else { memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->decoded_bytes_per_packet); } session->raw_read_frame.timestamp = 0; session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet; session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t); read_frame = &session->raw_read_frame; status = SWITCH_STATUS_SUCCESS; } else { switch_codec_t *use_codec = read_frame->codec; if (do_bugs) { switch_thread_rwlock_wrlock(session->bug_rwlock); if (!session->bugs) { do_bugs = 0; switch_thread_rwlock_unlock(session->bug_rwlock); goto done; } if (!switch_core_codec_ready(&session->bug_codec)) { switch_core_codec_copy(read_frame->codec, &session->bug_codec, NULL); } use_codec = &session->bug_codec; switch_thread_rwlock_unlock(session->bug_rwlock); switch_thread_rwlock_wrlock(session->bug_rwlock); if (!session->bugs) { do_bugs = 0; } switch_thread_rwlock_unlock(session->bug_rwlock); if (!do_bugs) goto done; } if (switch_test_flag(read_frame, SFF_PLC)) { session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet; session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t); memset(session->raw_read_frame.data, 255, session->raw_read_frame.datalen); status = SWITCH_STATUS_SUCCESS; } else { status = switch_core_codec_decode(use_codec, session->read_codec, read_frame->data, read_frame->datalen, session->read_impl.actual_samples_per_second, session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate, &read_frame->flags); } if (status == SWITCH_STATUS_SUCCESS) { if ((switch_channel_test_flag(session->channel, CF_JITTERBUFFER) || switch_channel_test_flag(session->channel, CF_CNG_PLC)) && !session->plc) { session->plc = plc_init(NULL); } if (session->plc) { if (switch_test_flag(read_frame, SFF_PLC)) { plc_fillin(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2); switch_clear_flag(read_frame, SFF_PLC); } else { plc_rx(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2); } } } } if (do_resample && ((status == SWITCH_STATUS_SUCCESS) || is_cng)) { status = SWITCH_STATUS_RESAMPLE; } switch (status) { case SWITCH_STATUS_RESAMPLE: if (!session->read_resampler) { switch_mutex_lock(session->resample_mutex); status = switch_resample_create(&session->read_resampler, read_frame->codec->implementation->actual_samples_per_second, session->read_impl.actual_samples_per_second, session->read_impl.decoded_bytes_per_packet, SWITCH_RESAMPLE_QUALITY, 1); switch_mutex_unlock(session->resample_mutex); if (status != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unable to allocate resampler\n"); status = SWITCH_STATUS_FALSE; goto done; } } case SWITCH_STATUS_SUCCESS: session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t); session->raw_read_frame.rate = read_frame->rate; if (read_frame->codec->implementation->samples_per_packet != session->read_impl.samples_per_packet) { session->raw_read_frame.timestamp = 0; } else { session->raw_read_frame.timestamp = read_frame->timestamp; } session->raw_read_frame.ssrc = read_frame->ssrc; session->raw_read_frame.seq = read_frame->seq; session->raw_read_frame.m = read_frame->m; session->raw_read_frame.payload = read_frame->payload; session->raw_read_frame.flags = 0; if (switch_test_flag(read_frame, SFF_PLC)) { session->raw_read_frame.flags |= SFF_PLC; } read_frame = &session->raw_read_frame; break; case SWITCH_STATUS_NOOP: if (session->read_resampler) { switch_mutex_lock(session->resample_mutex); switch_resample_destroy(&session->read_resampler); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating read resampler\n"); switch_mutex_unlock(session->resample_mutex); } status = SWITCH_STATUS_SUCCESS; break; case SWITCH_STATUS_BREAK: memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->decoded_bytes_per_packet); session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet; session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t); session->raw_read_frame.timestamp = read_frame->timestamp; session->raw_read_frame.rate = read_frame->rate; session->raw_read_frame.ssrc = read_frame->ssrc; session->raw_read_frame.seq = read_frame->seq; session->raw_read_frame.m = read_frame->m; session->raw_read_frame.payload = read_frame->payload; session->raw_read_frame.flags = 0; if (switch_test_flag(read_frame, SFF_PLC)) { session->raw_read_frame.flags |= SFF_PLC; } read_frame = &session->raw_read_frame; status = SWITCH_STATUS_SUCCESS; break; case SWITCH_STATUS_NOT_INITALIZED: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n"); goto done; default: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s decoder error!\n", session->read_codec->codec_interface->interface_name); goto done; } } if (session->bugs) { switch_media_bug_t *bp; switch_bool_t ok = SWITCH_TRUE; int prune = 0; switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { continue; } if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) { continue; } if (switch_test_flag(bp, SMBF_PRUNE)) { prune++; continue; } if (bp->ready && switch_test_flag(bp, SMBF_READ_STREAM)) { switch_mutex_lock(bp->read_mutex); switch_buffer_write(bp->raw_read_buffer, read_frame->data, read_frame->datalen); if (bp->callback) { ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ); } switch_mutex_unlock(bp->read_mutex); } if (ok && switch_test_flag(bp, SMBF_READ_REPLACE)) { do_bugs = 0; if (bp->callback) { bp->read_replace_frame_in = read_frame; bp->read_replace_frame_out = read_frame; if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_REPLACE)) == SWITCH_TRUE) { read_frame = bp->read_replace_frame_out; } } } if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) || ok == SWITCH_FALSE) { switch_set_flag(bp, SMBF_PRUNE); prune++; } } switch_thread_rwlock_unlock(session->bug_rwlock); if (prune) { switch_core_media_bug_prune(session); } } if (do_bugs) { goto done; } if (session->read_codec) { if (session->read_resampler) { short *data = read_frame->data; switch_mutex_lock(session->resample_mutex); switch_resample_process(session->read_resampler, data, (int) read_frame->datalen / 2); memcpy(data, session->read_resampler->to, session->read_resampler->to_len * 2); read_frame->samples = session->read_resampler->to_len; read_frame->datalen = session->read_resampler->to_len * 2; read_frame->rate = session->read_resampler->to_rate; switch_mutex_unlock(session->resample_mutex); } if (read_frame->datalen == session->read_impl.decoded_bytes_per_packet) { perfect = TRUE; } else { if (!session->raw_read_buffer) { switch_size_t bytes = session->read_impl.decoded_bytes_per_packet; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Engaging Read Buffer at %u bytes vs %u\n", (uint32_t) bytes, (uint32_t) (*frame)->datalen); switch_buffer_create_dynamic(&session->raw_read_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES, bytes * SWITCH_BUFFER_START_FRAMES, 0); } if (!switch_buffer_write(session->raw_read_buffer, read_frame->data, read_frame->datalen)) { status = SWITCH_STATUS_MEMERR; goto done; } } if (perfect || switch_buffer_inuse(session->raw_read_buffer) >= session->read_impl.decoded_bytes_per_packet) { if (perfect) { enc_frame = read_frame; session->raw_read_frame.rate = read_frame->rate; } else { session->raw_read_frame.datalen = (uint32_t) switch_buffer_read(session->raw_read_buffer, session->raw_read_frame.data, session->read_impl.decoded_bytes_per_packet); session->raw_read_frame.rate = session->read_impl.actual_samples_per_second; enc_frame = &session->raw_read_frame; } session->enc_read_frame.datalen = session->enc_read_frame.buflen; switch_assert(session->read_codec != NULL); switch_assert(enc_frame != NULL); switch_assert(enc_frame->data != NULL); status = switch_core_codec_encode(session->read_codec, enc_frame->codec, enc_frame->data, enc_frame->datalen, session->read_impl.actual_samples_per_second, session->enc_read_frame.data, &session->enc_read_frame.datalen, &session->enc_read_frame.rate, &flag); switch (status) { case SWITCH_STATUS_RESAMPLE: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Fixme 1\n"); case SWITCH_STATUS_SUCCESS: session->enc_read_frame.samples = session->read_impl.decoded_bytes_per_packet / sizeof(int16_t); if (perfect) { if (enc_frame->codec->implementation->samples_per_packet != session->read_impl.samples_per_packet) { session->enc_read_frame.timestamp = 0; } else { session->enc_read_frame.timestamp = read_frame->timestamp; } session->enc_read_frame.rate = read_frame->rate; session->enc_read_frame.ssrc = read_frame->ssrc; session->enc_read_frame.seq = read_frame->seq; session->enc_read_frame.m = read_frame->m; session->enc_read_frame.payload = session->read_impl.ianacode; } *frame = &session->enc_read_frame; break; case SWITCH_STATUS_NOOP: session->raw_read_frame.samples = enc_frame->codec->implementation->samples_per_packet; session->raw_read_frame.timestamp = read_frame->timestamp; session->raw_read_frame.payload = enc_frame->codec->implementation->ianacode; session->raw_read_frame.m = read_frame->m; session->raw_read_frame.ssrc = read_frame->ssrc; session->raw_read_frame.seq = read_frame->seq; *frame = enc_frame; status = SWITCH_STATUS_SUCCESS; break; case SWITCH_STATUS_NOT_INITALIZED: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n"); *frame = NULL; status = SWITCH_STATUS_GENERR; break; default: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s encoder error!\n", session->read_codec->codec_interface->interface_name); *frame = NULL; status = SWITCH_STATUS_GENERR; break; } } else { goto top; } } } done: if (!(*frame)) { status = SWITCH_STATUS_FALSE; } else { if (flag & SFF_CNG) { switch_set_flag((*frame), SFF_CNG); } if (session->bugs) { switch_media_bug_t *bp; switch_bool_t ok = SWITCH_TRUE; int prune = 0; switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { continue; } if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) { continue; } if (switch_test_flag(bp, SMBF_PRUNE)) { prune++; continue; } if (bp->ready && switch_test_flag(bp, SMBF_READ_PING)) { switch_mutex_lock(bp->read_mutex); if (bp->callback) { if (bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_PING) == SWITCH_FALSE || (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL))) { ok = SWITCH_FALSE; } } switch_mutex_unlock(bp->read_mutex); } if (ok == SWITCH_FALSE) { switch_set_flag(bp, SMBF_PRUNE); prune++; } } switch_thread_rwlock_unlock(session->bug_rwlock); if (prune) { switch_core_media_bug_prune(session); } } } even_more_done: if (!*frame || !(*frame)->codec || !(*frame)->codec->implementation || !switch_core_codec_ready((*frame)->codec)) { *frame = &runtime.dummy_cng_frame; } switch_mutex_unlock(session->read_codec->mutex); switch_mutex_unlock(session->codec_read_mutex); return status; }
int main(int argc, char *argv[]) { AFfilehandle inhandle; AFfilehandle outhandle; AFfilesetup filesetup; plc_state_t plc; int inframes; int outframes; int16_t amp[1024]; int block_no; int lost_blocks; int block_len; int loss_rate; int dropit; int block_real; int block_synthetic; int tone; int i; uint32_t phase_acc; int32_t phase_rate; loss_rate = 25; block_len = 160; block_real = FALSE; block_synthetic = FALSE; tone = -1; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-l") == 0) { loss_rate = atoi(argv[++i]); continue; } if (strcmp(argv[i], "-b") == 0) { block_len = atoi(argv[++i]); continue; } if (strcmp(argv[i], "-t") == 0) { tone = atoi(argv[++i]); continue; } if (strcmp(argv[i], "-r") == 0) block_real = TRUE; if (strcmp(argv[i], "-s") == 0) block_synthetic = TRUE; } if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP) { fprintf(stderr, " Failed to create file setup\n"); exit(2); } afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16); afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE); afInitFileFormat(filesetup, AF_FILE_WAVE); afInitChannels(filesetup, AF_DEFAULT_TRACK, 1); phase_rate = 0; inhandle = NULL; if (tone < 0) { if ((inhandle = afOpenFile(INPUT_FILE_NAME, "r", NULL)) == AF_NULL_FILEHANDLE) { fprintf(stderr, " Failed to open wave file '%s'\n", INPUT_FILE_NAME); exit(2); } } else { phase_rate = dds_phase_ratef((float) tone); } if ((outhandle = afOpenFile(OUTPUT_FILE_NAME, "w", filesetup)) == AF_NULL_FILEHANDLE) { fprintf(stderr, " Failed to open wave file '%s'\n", OUTPUT_FILE_NAME); exit(2); } plc_init(&plc); lost_blocks = 0; for (block_no = 0; ; block_no++) { if (tone < 0) { inframes = afReadFrames(inhandle, AF_DEFAULT_TRACK, amp, block_len); if (inframes != block_len) break; } else { if (block_no > 10000) break; for (i = 0; i < block_len; i++) amp[i] = (int16_t) dds_modf(&phase_acc, phase_rate, 10000.0, 0); inframes = block_len; } dropit = rand()/(RAND_MAX/100); if (dropit > loss_rate) { plc_rx(&plc, amp, inframes); if (block_real) memset(amp, 0, sizeof(int16_t)*inframes); } else { lost_blocks++; plc_fillin(&plc, amp, inframes); if (block_synthetic) memset(amp, 0, sizeof(int16_t)*inframes); } outframes = afWriteFrames(outhandle, AF_DEFAULT_TRACK, amp, inframes); if (outframes != inframes) { fprintf(stderr, " Error writing out sound\n"); exit(2); } } printf("Dropped %d of %d blocks\n", lost_blocks, block_no); if (tone < 0) { if (afCloseFile(inhandle) != 0) { fprintf(stderr, " Cannot close wave file '%s'\n", INPUT_FILE_NAME); exit(2); } } if (afCloseFile(outhandle) != 0) { fprintf(stderr, " Cannot close wave file '%s'\n", OUTPUT_FILE_NAME); exit(2); } afFreeFileSetup(filesetup); return 0; }
static int gsmtolin_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; unsigned char data[66]; int msgsm=0; if(f->datalen == 0) { /* perform PLC with nominal framesize of 20ms/160 samples */ if((tmp->tail + 160) > sizeof(tmp->buf) / 2) { ast_log(LOG_WARNING, "Out of buffer space\n"); return -1; } if(useplc) { plc_fillin(&tmp->plc, tmp->buf+tmp->tail, 160); tmp->tail += 160; } return 0; } if ((f->datalen % 33) && (f->datalen % 65)) { ast_log(LOG_WARNING, "Huh? A GSM frame that isn't a multiple of 33 or 65 bytes long from %s (%d)?\n", f->src, f->datalen); return -1; } if (f->datalen % 65 == 0) msgsm = 1; for (x=0; x<f->datalen; x+=(msgsm ? 65 : 33)) { if (msgsm) { /* Translate MSGSM format to Real GSM format before feeding in */ conv65(f->data + x, data); if (tmp->tail + 320 < sizeof(tmp->buf)/2) { if (gsm_decode(tmp->gsm, data, tmp->buf + tmp->tail)) { ast_log(LOG_WARNING, "Invalid GSM data (1)\n"); return -1; } tmp->tail+=160; if (gsm_decode(tmp->gsm, data + 33, tmp->buf + tmp->tail)) { ast_log(LOG_WARNING, "Invalid GSM data (2)\n"); return -1; } tmp->tail+=160; } else { ast_log(LOG_WARNING, "Out of (MS) buffer space\n"); return -1; } } else { if (tmp->tail + 160 < sizeof(tmp->buf)/2) { if (gsm_decode(tmp->gsm, f->data + x, tmp->buf + tmp->tail)) { ast_log(LOG_WARNING, "Invalid GSM data\n"); return -1; } tmp->tail+=160; } else { ast_log(LOG_WARNING, "Out of buffer space\n"); return -1; } } } /* just add the last 20ms frame; there must have been at least one */ if(useplc) plc_rx(&tmp->plc, tmp->buf+tmp->tail-160, 160); return 0; }