FreeCalypso > hg > themwi-system-sw
view mgw/dtmf_timer.c @ 150:529906fddcfa
mgw DTMF timing fix in the corner case of no speech
arriving between the end of one DTMF and the start of next
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 11 Oct 2022 14:10:29 -0800 |
parents | f062c32a5116 |
children |
line wrap: on
line source
/* * In this module we implement the timer function of DTMF generation. */ #include <sys/types.h> #include <sys/socket.h> #include <sys/time.h> #include <netinet/in.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <syslog.h> #include "struct.h" #include "int_defs.h" #include "dtmf_defs.h" extern struct timeval cur_event_time; extern struct endpoint *dtmf_list_head; int dtmf_timer_running; struct timeval dtmf_next_time; void start_dtmf_timer() { if (dtmf_timer_running) return; dtmf_next_time = cur_event_time; dtmf_timer_running = 1; } dtmf_timer_one(ep) struct endpoint *ep; { struct rtp_packet pkt; socklen_t addrlen; unsigned frame_limit; pkt.v_p_x_cc = 0x80; pkt.m_pt = ep->pstn_payload_type; if (ep->dtmf_m_bit) { pkt.m_pt |= 0x80; ep->dtmf_m_bit = 0; } pkt.seq = htons(++ep->g2p_out_seq); ep->dtmf_last_ts += SAMPLES_PER_FRAME; pkt.tstamp = htonl(ep->dtmf_last_ts); pkt.ssrc = ep->g2p_ssrc; g711_encode_frame(ep->dtmf_sample_ptr, pkt.payload, ep->pstn_payload_type); ep->dtmf_sample_ptr += SAMPLES_PER_FRAME; addrlen = sizeof(struct sockaddr_in); sendto(ep->rtp_pstn.rtp_fd, &pkt, RTP_PACKET_SIZE_PSTN, 0, (struct sockaddr *) &ep->rtp_pstn.remote_addr, addrlen); ep->dtmf_frames_sent++; ep->dtmf_last_time = cur_event_time; frame_limit = ep->dtmf_stop_req ? DTMF_MIN_FRAMES : DTMF_MAX_FRAMES; if (ep->dtmf_frames_sent >= frame_limit) return 1; else return 0; } void dtmf_timer_process() { struct endpoint *ep; int fin; for (ep = dtmf_list_head; ep; ep = ep->dtmf_next) { fin = dtmf_timer_one(ep); if (!fin) continue; ep->dtmf_aftermath = 1; *ep->dtmf_pp = ep->dtmf_next; if (ep->dtmf_next) ep->dtmf_next->dtmf_pp = ep->dtmf_pp; ep->dtmf_pp = 0; ep->dtmf_next = 0; } if (dtmf_list_head) { dtmf_next_time.tv_usec += 20000; if (dtmf_next_time.tv_usec >= 1000000) { dtmf_next_time.tv_usec -= 1000000; dtmf_next_time.tv_sec++; } } else dtmf_timer_running = 0; }