Mercurial > hg > audiostuff
diff spandsp-0.0.6pre17/spandsp-sim/rfc2198_sim.c @ 4:26cd8f1ef0b1
import spandsp-0.0.6pre17
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 15:50:58 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/spandsp-0.0.6pre17/spandsp-sim/rfc2198_sim.c Fri Jun 25 15:50:58 2010 +0200 @@ -0,0 +1,179 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * rfc2198_sim.c - Simulate the behaviour of RFC2198 (or UDPTL) redundancy. + * + * Written by Steve Underwood <steveu@coppice.org> + * + * Copyright (C) 2007 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: rfc2198_sim.c,v 1.10 2009/06/01 16:27:12 steveu Exp $ + */ + +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <stdlib.h> +#include <unistd.h> +#include <inttypes.h> +#include <string.h> +#include <time.h> +#include <stdio.h> +#include <fcntl.h> +#if defined(HAVE_TGMATH_H) +#include <tgmath.h> +#endif +#if defined(HAVE_MATH_H) +#define GEN_CONST +#include <math.h> +#endif +#include "floating_fudge.h" + +#include "spandsp.h" +#include "spandsp/g1050.h" +#include "spandsp/rfc2198_sim.h" + +#define PACKET_LOSS_TIME -1 + +#define FALSE 0 +#define TRUE (!FALSE) + +SPAN_DECLARE(rfc2198_sim_state_t *) rfc2198_sim_init(int model, + int speed_pattern, + int packet_size, + int packet_rate, + int redundancy_depth) +{ + rfc2198_sim_state_t *s; + + if ((s = (rfc2198_sim_state_t *) malloc(sizeof(*s))) == NULL) + return NULL; + memset(s, 0, sizeof(*s)); + + s->g1050 = g1050_init(model, speed_pattern, packet_size, packet_rate); + s->redundancy_depth = redundancy_depth; + return s; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) rfc2198_sim_put(rfc2198_sim_state_t *s, + const uint8_t buf[], + int len, + int seq_no, + double departure_time) +{ + uint8_t buf2[8192]; + uint8_t *p; + uint16_t *q; + int slot; + int i; + + /* Save the packet in the history buffer */ + memcpy(s->tx_pkt[s->next_pkt], buf, len); + s->tx_pkt_len[s->next_pkt] = len; + s->tx_pkt_seq_no[s->next_pkt] = seq_no; + + /* Construct the redundant packet */ + p = buf2; + slot = s->next_pkt; + q = (uint16_t *) p; + *q = s->redundancy_depth; + p += sizeof(uint16_t); + for (i = 0; i < s->redundancy_depth; i++) + { + q = (uint16_t *) p; + *q = s->tx_pkt_len[slot]; + p += sizeof(uint16_t); + memcpy(p, s->tx_pkt[slot], s->tx_pkt_len[slot]); + p += s->tx_pkt_len[slot]; + slot = (slot - 1) & 0x1F; + } + s->next_pkt = (s->next_pkt + 1) & 0x1F; + return g1050_put(s->g1050, buf2, p - buf2, seq_no, departure_time); +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) rfc2198_sim_get(rfc2198_sim_state_t *s, + uint8_t buf[], + int max_len, + double current_time, + int *seq_no, + double *departure_time, + double *arrival_time) +{ + int len; + int lenx; + int seq_nox; + int i; +#if defined(_MSC_VER) + uint8_t *bufx = (uint8_t *) _alloca(s->redundancy_depth*1024); +#else + uint8_t bufx[s->redundancy_depth*1024]; +#endif + uint8_t *p; + uint16_t *q; + int redundancy_depth; + + if (s->rx_queued_pkts) + { + /* We have some stuff from the last g1050_get() still to deliver */ + s->rx_queued_pkts--; + memcpy(buf, s->rx_pkt[s->rx_queued_pkts], s->rx_pkt_len[s->rx_queued_pkts]); + *seq_no = s->rx_pkt_seq_no[s->rx_queued_pkts]; + return s->rx_pkt_len[s->rx_queued_pkts]; + } + len = g1050_get(s->g1050, bufx, s->redundancy_depth*1024, current_time, &seq_nox, departure_time, arrival_time); + if (len > 0) + { + p = bufx; + q = (uint16_t *) p; + redundancy_depth = *q; + p += sizeof(uint16_t); + i = 0; + if (seq_nox > s->next_seq_no) + { + /* Some stuff is missing. Try to fill it in. */ + s->rx_queued_pkts = seq_nox - s->next_seq_no; + if (s->rx_queued_pkts >= redundancy_depth) + s->rx_queued_pkts = redundancy_depth - 1; + for (i = 0; i < s->rx_queued_pkts; i++) + { + q = (uint16_t *) p; + s->rx_pkt_len[i] = *q; + p += sizeof(uint16_t); + memcpy(s->rx_pkt[i], p, s->rx_pkt_len[i]); + s->rx_pkt_seq_no[i] = seq_nox - i; + p += s->rx_pkt_len[i]; + } + } + *seq_no = seq_nox - i; + q = (uint16_t *) p; + lenx = *q; + p += sizeof(uint16_t); + memcpy(buf, p, lenx); + s->next_seq_no = seq_nox + 1; + } + else + { + lenx = len; + } + return lenx; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/