static void process_delete(session_t *sp, rtp_event *e) { if (log_fp != 0) { struct timeval tv, *dead; int d_sec = -1, d_usec = -1; gettimeofday(&tv, 0); dead = (struct timeval *) e->data; if (dead != 0) { d_sec = (int) dead->tv_sec; d_usec = (int) dead->tv_usec; } fprintf(log_fp, "%d.%06d %d delete %x %d.%06d\n", (int) tv.tv_sec, (int) tv.tv_usec, rtp_get_ssrc_count(sp->rtp_session[0]), e->ssrc, d_sec, d_usec); fflush(log_fp); } if (e->ssrc != rtp_my_ssrc(sp->rtp_session[0]) && sp->mbus_engine != NULL) { struct s_source *s; pdb_entry_t *pdbe; if ((s = source_get_by_ssrc(sp->active_sources, e->ssrc)) != NULL) { source_remove(sp->active_sources, s); } if (pdb_item_get(sp->pdb, e->ssrc, &pdbe)) { pdb_item_destroy(sp->pdb, e->ssrc); /* Will not be in ui if not in pdb */ ui_send_rtp_remove(sp, sp->mbus_ui_addr, e->ssrc); } } }
rtcp_app* rtcp_app_site_callback(struct rtp *session, uint32_t rtp_ts, int max_size) { struct s_session *sp; int len; int datalen; int slen; sp = get_session(session); if (sp == NULL) { /* Shouldn't happen */ return NULL; } if (sp->rtp_session_app_site == NULL) { /* Site identifier not set */ return NULL; } if (sp->rtcp_app_packet_ts == rtp_ts) { /* Already sent an APP for this timestamp */ return NULL; } slen = strlen(sp->rtp_session_app_site); datalen = slen; if (slen % 4 > 0) { datalen += 4 - (slen % 4); } len = datalen + sizeof(rtcp_app) - 1; if (len > max_size) { /* Can't fit the site id in the current RTCP compound packet */ return NULL; } if (sp->rtcp_app_packet != NULL) { xfree(sp->rtcp_app_packet); } sp->rtcp_app_packet = xmalloc(len); sp->rtcp_app_packet->version = RTP_VERSION; sp->rtcp_app_packet->p = 0; sp->rtcp_app_packet->subtype = 0; sp->rtcp_app_packet->pt = 204; /* Host -> Network order is handled by common lib */ sp->rtcp_app_packet->length = 2 + datalen/4; sp->rtcp_app_packet->ssrc = rtp_my_ssrc(session); strncpy(sp->rtcp_app_packet->name, "site", 4); memset(sp->rtcp_app_packet->data, 0, datalen); strncpy(sp->rtcp_app_packet->data, sp->rtp_session_app_site, slen); sp->rtcp_app_packet_ts = rtp_ts; return sp->rtcp_app_packet; }
void settings_load_late(session_t *sp) { /* FIXME: This needs to be updated for the transcoder */ uint32_t my_ssrc; struct utsname u; char hostfmt[] = "RAT v" RAT_VERSION " %s %s (%s)"; char *field, username[32] = ""; load_init(); /* Initial settings come from the common prefs file... */ /* * We check to see it SDES items are set first. If they are * then presumeably it has come from the command line and * so it should override saved settings. */ my_ssrc = rtp_my_ssrc(sp->rtp_session[0]); if (settings_username(username, sizeof(username) - 1) == FALSE) { sprintf(username, "Unknown"); } field = setting_load_str("rtpName", username); if (rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_NAME) == NULL) { debug_msg("username %s %s\n", field, username); rtp_set_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_NAME, field, strlen(field)); } field = setting_load_str("rtpEmail", ""); if (rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_EMAIL) == NULL) { rtp_set_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_EMAIL, field, strlen(field)); } field = setting_load_str("rtpPhone", ""); if (rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_PHONE) == NULL) { rtp_set_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_PHONE, field, strlen(field)); } field = setting_load_str("rtpLoc", ""); if (rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_LOC) == NULL) { rtp_set_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_LOC, field, strlen(field)); } field = setting_load_str("rtpNote", ""); if (rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_NOTE) == NULL) { rtp_set_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_NOTE, field, strlen(field)); } field = (char*)xmalloc(3 * 256 + sizeof(hostfmt)); uname(&u); sprintf(field, hostfmt, u.sysname, u.release, u.machine); rtp_set_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_TOOL, field, strlen(field)); xfree(field); /* This is evil [csp] */ field = xstrdup(" rattest"); field[0] = 3; rtp_set_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_PRIV, field, strlen(field)); xfree(field); init_part_two(); /* Switch to pulling settings from the RAT specific prefs file... */ load_done(); }
static void process_rr(session_t *sp, rtp_event *rtp_e) { pdb_entry_t *e; uint32_t fract_lost, my_ssrc; uint32_t ssrc = rtp_e->ssrc; rtcp_rr *r = (rtcp_rr *) rtp_e->data; /* Calculate rtt estimate */ my_ssrc = rtp_my_ssrc(sp->rtp_session[0]); if (pdb_item_get(sp->pdb, r->ssrc, &e) == FALSE) { /* Maybe deleted or not heard from yet */ debug_msg("Receiver report on unknown participant (0x%lx)\n", r->ssrc); return; } if (pdb_item_get(sp->pdb, ssrc, &e) && r->ssrc == my_ssrc && r->ssrc != ssrc && /* filter self reports */ r->lsr != 0) { uint32_t ntp_sec, ntp_frac, ntp32; double rtt; ntp64_time(&ntp_sec, &ntp_frac); ntp32 = ntp64_to_ntp32(ntp_sec, ntp_frac); rtt = rtp_rtt_calc(ntp32, r->lsr, r->dlsr); /* * Filter out blatantly wrong rtt values. Some tools might not * implement dlsr and lsr (broken) or forget to do byte-swapping */ if (rtt < 100.0) { e->last_rtt = rtt; debug_msg("rtt %f\n", rtt); } else { debug_msg("Junk rtt (%f secs) ntp32 0x%08x lsr 0x%08x dlsr 0x%08x ?\n", rtt, ntp32, r->lsr, r->dlsr); } if (e->avg_rtt == 0.0) { e->avg_rtt = e->last_rtt; } else { e->avg_rtt += (e->last_rtt - e->avg_rtt) / 2.0; } if (sp->mbus_engine != NULL) { ui_send_rtp_rtt(sp, sp->mbus_ui_addr, ssrc, e->avg_rtt); } } fract_lost = (r->fract_lost * 100) >> 8; /* Update loss stats */ if (sp->mbus_engine != NULL) { ui_send_rtp_packet_loss(sp, sp->mbus_ui_addr, ssrc, r->ssrc, fract_lost); } /* Do we have to log anything? */ if ((r->ssrc == my_ssrc) && (sp->logger != NULL)) { rtpdump_header(sp->logger, "rtt ", rtp_e); fprintf(sp->logger, "%f\n", e->avg_rtt); } }
void ui_send_stats(session_t *sp, char *addr, uint32_t ssrc) { /* Send RAT specific statistics to the user interface... */ const rtcp_rr *rr; uint32_t fract_lost, my_ssrc, total_lost; double skew_rate; char *args, *mbes; struct s_source *src; uint32_t buffered, delay; pdb_entry_t *pdbe; session_validate(sp); if (!sp->ui_on) return; if (pdb_item_get(sp->pdb, ssrc, &pdbe) == FALSE) { debug_msg("pdb entry does not exist (0x%08x)\n", ssrc); return; } pdbe->last_ui_update = sp->cur_ts; if (pdbe->enc_fmt) { mbes = mbus_encode_str(pdbe->enc_fmt); args = (char *) xmalloc(strlen(mbes) + 12); sprintf(args, "\"%08x\" %s", pdbe->ssrc, mbes); xfree(mbes); } else { args = (char *) xmalloc(19); sprintf(args, "\"%08x\" unknown", pdbe->ssrc); } mbus_qmsg(sp->mbus_engine, addr, "rtp.source.codec", args, FALSE); xfree(args); src = source_get_by_ssrc(sp->active_sources, pdbe->ssrc); if (src) { buffered = timestamp_to_ms(source_get_audio_buffered(src)); delay = timestamp_to_ms(source_get_playout_delay(src)); skew_rate = source_get_skew_rate(src); } else { buffered = 0; delay = 0; skew_rate = 1.0; } mbus_qmsgf(sp->mbus_engine, addr, FALSE, "tool.rat.audio.buffered", "\"%08lx\" %ld", (unsigned long)pdbe->ssrc, buffered); mbus_qmsgf(sp->mbus_engine, addr, FALSE, "tool.rat.audio.delay", "\"%08lx\" %ld", (unsigned long)pdbe->ssrc, delay); mbus_qmsgf(sp->mbus_engine, addr, FALSE, "tool.rat.audio.skew", "\"%08lx\" %.5f", (unsigned long)pdbe->ssrc, skew_rate); mbus_qmsgf(sp->mbus_engine, addr, FALSE, "tool.rat.spike.events", "\"%08lx\" %ld", (unsigned long)pdbe->ssrc, pdbe->spike_events); mbus_qmsgf(sp->mbus_engine, addr, FALSE, "tool.rat.spike.toged", "\"%08lx\" %ld", (unsigned long)pdbe->ssrc, pdbe->spike_toged); my_ssrc = rtp_my_ssrc(sp->rtp_session[0]); rr = rtp_get_rr(sp->rtp_session[0], my_ssrc, pdbe->ssrc); if (rr != NULL) { fract_lost = (rr->fract_lost * 100) >> 8; total_lost = rr->total_lost; } else {
static void process_rr(struct rtp *session, rtp_event * e) { float fract_lost, tmp; uint32_t ntp_sec, ntp_frac, now; rtcp_rr *r = (rtcp_rr *) e->data; if (e->ssrc == rtp_my_ssrc(session)) { /* Filter out loopback reports */ return; } if (r->ssrc == rtp_my_ssrc(session)) { /* Received a reception quality report for data we are sending. */ /* */ /* Check for excessive congestion: exit if it occurs, to protect */ /* other users of the network. */ fract_lost = (r->fract_lost * 100.0) / 256.0; /* percentage lost packets */ if (fract_lost > 20) { printf("Receiver 0x%08x reports excessive congestion\n", e->ssrc); } /* Compute network round-trip time: */ if (r->lsr != 0) { ntp64_time(&ntp_sec, &ntp_frac); now = ntp64_to_ntp32(ntp_sec, ntp_frac); if ((now < r->lsr) || (now - r->lsr < r->dlsr)) { /* Packet arrived before it was sent, ignore. This represents */ /* a bug in the remote: either our timestamp was incorrectly */ /* echoed back to us, or the remote miscalculated in time for */ /* which it held the packet. */ debug_msg("Bogus RTT from 0x%08x ignored\n", e->ssrc); } else { tmp = ((float)(now - r->lsr - r->dlsr)) / 65536.0; /* RTT in seconds */ RTT = tmp * 1000000; /* RTT in usec */ } debug_msg(" RTT=%d usec\n", RTT); } } }
static void process_rtp_data(session_t *sp, uint32_t ssrc, rtp_packet *p) { struct s_source *s; pdb_entry_t *e; if (sp->filter_loopback && ssrc == rtp_my_ssrc(sp->rtp_session[0])) { /* This packet is from us and we are filtering our own */ /* packets. */ xfree(p); return; } if (pdb_item_get(sp->pdb, ssrc, &e) == FALSE) { debug_msg("Packet discarded: unknown source (0x%08x).\n", ssrc); xfree(p); return; } e->received++; s = source_get_by_ssrc(sp->active_sources, ssrc); if (s == NULL) { s = source_create(sp->active_sources, ssrc, sp->pdb); ui_send_rtp_active(sp, sp->mbus_ui_addr, ssrc); debug_msg("Source created\n"); } /* Calculate the relative playout delay, for this source. Needed for lip-sync. */ /* Discard packet if output is muted... no point wasting time decoding it... */ if ((sp->playing_audio == FALSE) || (e->mute)) { xfree(p); return; } /* Discard packets that contain no data */ if (p->meta.data_len == 0) { printf("Zero length packet\n"); xfree(p); return; } /* Remove any padding */ if (p->fields.p) { p->meta.data_len -= p->meta.data[p->meta.data_len - 1]; p->fields.p = 0; } source_add_packet(s, p); }
rtp_session_t * init_rtp_session(uint32_t port, char *addr){ rtp_session_t *rtp; char *mcast_if = NULL; double rtcp_bw = DEFAULT_RTCP_BW; int ttl = DEFAULT_TTL; struct module tmod; struct tx *tx_session; rtp = (rtp_session_t *) malloc(sizeof(rtp_session_t)); if (rtp == NULL){ error_msg("rtp_session: malloc error"); return NULL; } rtp->port = port; rtp->addr = addr; module_init_default(&tmod); struct rtp *rtp_conn = rtp_init_if(addr, mcast_if, 0, port, ttl, rtcp_bw, 0, dummy_callback, (void *)NULL, 0); if (rtp_conn == NULL){ error_msg("rtp_session: rtp_init error"); return NULL; } rtp_set_option(rtp_conn, RTP_OPT_WEAK_VALIDATION, 1); rtp_set_sdes(rtp_conn, rtp_my_ssrc(rtp_conn), RTCP_SDES_TOOL, PACKAGE_STRING, strlen(PACKAGE_STRING)); rtp_set_send_buf(rtp_conn, DEFAULT_SEND_BUFFER_SIZE); tx_session = tx_init_h264(&tmod, MTU, TX_MEDIA_VIDEO, NULL, NULL); if (tx_session == NULL){ error_msg("rtp_session: tx_init error"); return NULL; } rtp->rtp = rtp_conn; rtp->tx_session = tx_session; return rtp; }
/* * recv_callback - callback for when bytestream is active - basically, * put things on the queue */ int CRtpByteStreamBase::recv_callback (struct rtp *session, rtp_event *e) { switch (e->type) { case RX_RTP: rtp_packet *rpak; rpak = (rtp_packet *)e->data; if (rpak->rtp_data_len == 0) { xfree(rpak); } else { // need to add lock/unlock of mutex here if (m_have_recv_last_ts) { int32_t diff = rpak->rtp_pak_ts - m_recv_last_ts; int32_t ts, nts; ts = m_timescale * 2; nts = 0 - ts; if (diff > ts || diff < nts) { rtp_message(LOG_INFO, "%s - rtp timestamp diff %d last %u now %u", m_name, diff, m_recv_last_ts, rpak->rtp_pak_ts); flush_rtp_packets(); reset(); } } m_have_recv_last_ts = true; m_recv_last_ts = rpak->rtp_pak_ts; if (m_buffering == 0) { rpak->pd.rtp_pd_timestamp = get_time_of_day(); rpak->pd.rtp_pd_have_timestamp = 1; } if (SDL_mutexP(m_rtp_packet_mutex) == -1) { rtp_message(LOG_CRIT, "SDL Lock mutex failure in rtp bytestream recv"); break; } add_rtp_packet_to_queue(rpak, &m_head, &m_tail, m_name); if (SDL_mutexV(m_rtp_packet_mutex) == -1) { rtp_message(LOG_CRIT, "SDL Lock mutex failure in rtp bytestream recv"); break; } m_recvd_pak = true; check_buffering(); } break; case RX_SR: rtcp_sr *srpak; srpak = (rtcp_sr *)e->data; if (rtp_my_ssrc(session) != e->ssrc) { //rtp_message(LOG_DEBUG, "%s received rtcp", m_name); calculate_wallclock_offset_from_rtcp(srpak->ntp_frac, srpak->ntp_sec, srpak->rtp_ts); } break; case RX_APP: free(e->data); break; default: #if 0 rtp_message(LOG_DEBUG, "Thread %u - Callback from rtp with %d %p", SDL_ThreadID(),e->type, e->rtp_data); #endif break; } return m_buffering; }
int os_sound_start (call_t * ca, int port) { int p, cond; int bits = 16; int stereo = 0; /* 0 is mono */ int rate = 8000; int blocksize = 512; if (ca->local_sendrecv == _SENDRECV || ca->local_sendrecv == _RECVONLY) { ca->fd = open (AUDIO_DEVICE, O_RDWR | O_NONBLOCK); if (ca->fd < 0) return -EWOULDBLOCK; fcntl (ca->fd, F_SETFL, fcntl (ca->fd, F_GETFL) & ~O_NONBLOCK); ioctl (ca->fd, SNDCTL_DSP_RESET, 0); p = bits; /* 16 bits */ ioctl (ca->fd, SNDCTL_DSP_SAMPLESIZE, &p); p = stereo; /* number of channels */ ioctl (ca->fd, SNDCTL_DSP_CHANNELS, &p); #ifdef USE_PCM p = AFMT_S16_NE; /* choose LE or BE (endian) */ ioctl (ca->fd, SNDCTL_DSP_SETFMT, &p); #else if (ca->payload == 0) p = AFMT_MU_LAW; else if (ca->payload == 8) p = AFMT_A_LAW; else if (ca->payload == 110 || ca->payload == 111) p = AFMT_S16_NE; /* choose LE or BE (endian) */ ioctl (ca->fd, SNDCTL_DSP_SETFMT, &p); #endif p = rate; /* rate in khz */ ioctl (ca->fd, SNDCTL_DSP_SPEED, &p); ioctl (ca->fd, SNDCTL_DSP_GETBLKSIZE, &min_size); if (min_size > blocksize) { cond = 1; p = min_size / blocksize; while (cond) { int i = ioctl (ca->fd, SNDCTL_DSP_SUBDIVIDE, &p); /* fprintf(stderr, "SUB_DIVIDE said error=%i,errno=%i\n",i,errno); */ if ((i == 0) || (p == 1)) cond = 0; else p = p / 2; } } ioctl (ca->fd, SNDCTL_DSP_GETBLKSIZE, &min_size); if (min_size > blocksize) { fprintf (stderr, "dsp block size set to %i.", min_size); exit (0); } else { /* no need to access the card with less latency than needed */ min_size = blocksize; } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "blocksize = %i\n", min_size)); } else { /* send a wav file! */ ca->fd = open (ca->wav_file, O_RDONLY); if (ca->fd < 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "Could not open wav file: %s\n", ca->wav_file)); return -1; } } #ifdef SPEEX_SUPPORT { float vbr_qual; int value; int quality; ca->speex_enc = speex_encoder_init (&speex_nb_mode); /* 8kHz */ /* 16kHz speex_enc = speex_encoder_init(&speex_wb_mode); */ /* 32kHz speex_enc = speex_encoder_init(&speex_uwb_mode); */ ca->speex_dec = speex_decoder_init (&speex_nb_mode); value = 1; speex_decoder_ctl (ca->speex_dec, SPEEX_SET_ENH, &value); quality = 8; /* 15kb */ speex_encoder_ctl (ca->speex_enc, SPEEX_SET_QUALITY, &quality); /* ou bien le bit rate: value = 15000; // 15kb speex_encoder_ctl(ca->speex_enc, SPEEX_SET_BITRATE, &value); */ /* silence suppression (VAD) value = 1; // 15kb speex_encoder_ctl(ca->speex_enc, SPEEX_SET_VAD, &value); Discontinuous transmission (DTX) value = 1; // 15kb speex_encoder_ctl(ca->speex_enc, SPEEX_SET_DTX, &value); Variable Bit Rate (VBR) value = 1; // 15kb speex_encoder_ctl(ca->speex_enc, SPEEX_SET_VBR, &value); vbr_qual = 5,0; // between 0 and 10 speex_encoder_ctl(ca->speex_enc, SPEEX_SET_VBR_QUALITY, &vbr_qual); Average bit rate: (ABR) value = 15000; // 15kb speex_encoder_ctl(ca->speex_enc, SPEEX_SET_ABR, &value); */ speex_encoder_ctl (ca->speex_enc, SPEEX_GET_FRAME_SIZE, &ca->speex_fsize); ca->speex_nb_packet = 1; speex_bits_init (&(ca->speex_bits)); speex_bits_init (&(ca->dec_speex_bits)); } #endif if (ca->local_sendrecv == _SENDRECV) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "starting sendrecv session\n")); } else if (ca->local_sendrecv == _SENDONLY) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "starting sendonly session\n")); } else { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "starting recvonly session\n")); } ca->rtp_session = rtp_init (ca->remote_sdp_audio_ip, port, ca->remote_sdp_audio_port, 16, 64000, rtp_event_handler, (void *) ca); if (ca->rtp_session) { const char *username = "******"; /* should be taken from the SDP */ const char *telephone = "0033-MY-NUMBER"; const char *app_name = "josua"; uint32_t my_ssrc = rtp_my_ssrc (ca->rtp_session); /* set local participant info */ rtp_set_sdes (ca->rtp_session, my_ssrc, RTCP_SDES_NAME, username, strlen (username)); rtp_set_sdes (ca->rtp_session, my_ssrc, RTCP_SDES_PHONE, telephone, strlen (telephone)); rtp_set_sdes (ca->rtp_session, my_ssrc, RTCP_SDES_TOOL, app_name, strlen (app_name)); /* Filter out local packets if requested */ /* rtp_set_option(ca->rtp_session, RTP_OPT_FILTER_MY_PACKETS, filter_me); */ rtp_set_option (ca->rtp_session, RTP_OPT_WEAK_VALIDATION, TRUE); ca->enable_audio = 1; ca->audio_thread = osip_thread_create (20000, os_sound_start_thread, ca); } else { fprintf (stderr, "Could not initialize session for %s port %d\n", ca->remote_sdp_audio_ip, ca->remote_sdp_audio_port); } return 0; }
void * os_sound_start_thread (void *_ca) { int i; call_t *ca = (call_t *) _ca; struct timeval timeout; uint32_t rtp_ts, round; uint8_t mulaw_buffer[MULAW_BYTES * 16]; int mulaw_buffer_pos; #ifdef USE_PCM char data_out[MULAW_BYTES * 2 * 16]; #endif fprintf (stderr, "Sending and listening to "); fprintf (stderr, "%s port %d (local SSRC = 0x%08x)\n", rtp_get_addr (ca->rtp_session), rtp_get_rx_port (ca->rtp_session), rtp_my_ssrc (ca->rtp_session)); round = 0; mulaw_buffer_pos = 0; while (ca->enable_audio != -1) { struct timeval t_beg; struct timeval t_end; struct timeval interval; gettimeofday (&t_beg, NULL); round++; /* original line rtp_ts = round * MULAW_MS; */ rtp_ts = round * MULAW_BYTES; if (ca->local_sendrecv != _RECVONLY) { if (mulaw_buffer_pos < MULAW_BYTES * 4) { /* Send control packets */ rtp_send_ctrl (ca->rtp_session, rtp_ts, NULL); /* Send data packets */ #ifdef USE_PCM i = read (ca->fd, data_out, MULAW_BYTES * 4); if (ca->local_sendrecv == _SENDRECV || ca->local_sendrecv == _RECVONLY) { } else { if (i < MULAW_BYTES * 4) { memset (data_out, 0, MULAW_BYTES * 4); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "restarting: %i\n", i)); close (ca->fd); /* send a wav file! */ ca->fd = open (ca->wav_file, O_RDONLY); if (ca->fd < 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "Could not open wav file: %s\n", ca->wav_file)); ca->fd = -1; break; } i = read (ca->fd, data_out, MULAW_BYTES * 4); } } if (ca->payload == 8) /* A-Law */ alaw_enc (data_out, mulaw_buffer + mulaw_buffer_pos, i); if (ca->payload == 0) /* Mu-Law */ mulaw_enc (data_out, mulaw_buffer + mulaw_buffer_pos, i); i = i / 2; mulaw_buffer_pos = mulaw_buffer_pos + i; #else memset (mulaw_buffer + mulaw_buffer_pos, 0, MULAW_BYTES * 2); i = read (ca->fd, mulaw_buffer + mulaw_buffer_pos, MULAW_BYTES * 2); /* ?? */ mulaw_buffer_pos = mulaw_buffer_pos + i; #endif } i = 0; if (mulaw_buffer_pos >= MULAW_BYTES) { i = rtp_send_data (ca->rtp_session, rtp_ts, ca->payload, 0, 0, 0, (char *) mulaw_buffer, MULAW_BYTES, 0, 0, 0); memmove (mulaw_buffer, mulaw_buffer + MULAW_BYTES, MULAW_BYTES * 15); mulaw_buffer_pos = mulaw_buffer_pos - MULAW_BYTES; } } else { /* Send control packets */ rtp_send_ctrl (ca->rtp_session, rtp_ts, NULL); } /* Receive control and data packets */ timeout.tv_sec = 0; timeout.tv_usec = 0; i = rtp_recv (ca->rtp_session, &timeout, rtp_ts); /* State maintenance */ rtp_update (ca->rtp_session); gettimeofday (&t_end, NULL); /* make a diff between t_beg and t_end */ interval.tv_sec = t_end.tv_sec - t_beg.tv_sec; interval.tv_usec = t_end.tv_usec - t_beg.tv_usec; if (interval.tv_usec < 0) { interval.tv_usec += 1000000L; --interval.tv_sec; } interval.tv_usec = (MULAW_MS * 1000 - interval.tv_usec); if (interval.tv_usec < 0) { interval.tv_usec += 1000000L; --interval.tv_sec; } if (interval.tv_sec < 0) { interval.tv_sec = 0; interval.tv_usec = 0; } select (0, NULL, NULL, NULL, &interval); } return NULL; }
void settings_save(session_t *sp) { /* FIXME: This needs to be updated for the transcoder */ const codec_format_t *pri_cf; const audio_port_details_t *iapd = NULL; const audio_port_details_t *oapd = NULL; const audio_format *af = NULL; const repair_details_t *repair = NULL; const converter_details_t *converter = NULL; const audio_device_details_t *add = NULL; const cc_details_t *ccd = NULL; codec_id_t pri_id; int cc_len; char *cc_param; int i; uint16_t j,n; uint32_t my_ssrc; pri_id = codec_get_by_payload(sp->encodings[0]); pri_cf = codec_get_format(pri_id); cc_len = 3 * (CODEC_LONG_NAME_LEN + 4) + 1; cc_param = (char*) xmalloc(cc_len); channel_encoder_get_parameters(sp->channel_coder, cc_param, cc_len); ccd = channel_get_coder_identity(sp->channel_coder); n = (uint16_t)converter_get_count(); for (j = 0; j < n; j++) { converter = converter_get_details(j); if (sp->converter == converter->id) { break; } } n = repair_get_count(); for (j = 0; j < n; j++) { repair = repair_get_details(j); if (sp->repair == repair->id) { break; } } n = (int)audio_get_device_count(); for (i = 0; i < n; i++) { add = audio_get_device_details(i); if (sp->audio_device == add->descriptor) { break; } } af = audio_get_ifmt(sp->audio_device); for(i = 0; i < audio_get_iport_count(sp->audio_device); i++) { iapd = audio_get_iport_details(sp->audio_device, i); if (iapd->port == audio_get_iport(sp->audio_device)) { break; } } for(i = 0; i < audio_get_oport_count(sp->audio_device); i++) { oapd = audio_get_oport_details(sp->audio_device, i); if (oapd->port == audio_get_oport(sp->audio_device)) { break; } } save_init_rtp(); my_ssrc = rtp_my_ssrc(sp->rtp_session[0]); setting_save_str("rtpName", rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_NAME)); setting_save_str("rtpEmail", rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_EMAIL)); setting_save_str("rtpPhone", rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_PHONE)); setting_save_str("rtpLoc", rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_LOC)); setting_save_str("rtpNote", rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_NOTE)); save_done_rtp(); save_init_rat(); setting_save_str("audioTool", rtp_get_sdes(sp->rtp_session[0], my_ssrc, RTCP_SDES_TOOL)); setting_save_str("audioDevice", add->name); setting_save_int("audioFrequency", af->sample_rate); setting_save_int("audioChannelsIn", af->channels); /* If we save a dynamically mapped codec we crash when we reload on startup */ if (pri_cf->default_pt != CODEC_PAYLOAD_DYNAMIC) { setting_save_str("audioPrimary", pri_cf->short_name); } setting_save_int("audioUnits", channel_encoder_get_units_per_packet(sp->channel_coder)); /* Don't save the layered channel coder - you need to start it */ /* from the command line anyway */ if (strcmp(ccd->name, "Layering") == 0) { setting_save_str("audioChannelCoding", "Vanilla"); } else { setting_save_str("audioChannelCoding", ccd->name); } setting_save_str("audioChannelParameters", cc_param); setting_save_str("audioRepair", repair->name); setting_save_str("audioAutoConvert", converter->name); setting_save_int("audioLimitPlayout", sp->limit_playout); setting_save_int("audioMinPlayout", sp->min_playout); setting_save_int("audioMaxPlayout", sp->max_playout); setting_save_int("audioLecture", sp->lecture); setting_save_int("audio3dRendering", sp->render_3d); setting_save_int("audioAGC", sp->agc_on); setting_save_int("audioLoopback", sp->loopback_gain); setting_save_int("audioEchoSuppress", sp->echo_suppress); setting_save_int("audioOutputGain", audio_get_ogain(sp->audio_device)); setting_save_int("audioInputGain", audio_get_igain(sp->audio_device)); setting_save_str("audioOutputPort", oapd->name); setting_save_str("audioInputPort", iapd->name); setting_save_int("audioPowermeters", sp->meter); setting_save_str("audioSilence", sd_name(sp->silence_detection)); setting_save_int("audioSilenceManualThresh", sp->manual_sd_thresh); /* We do not save audioOutputMute and audioInputMute by default, but should */ /* recognize them when reloading. */ save_done_rat(); xfree(cc_param); }