* #36737: switch back to svn repo, remove assert in sip_transaction.c
diff --git a/jni/pjproject-android/.svn/pristine/f1/f1083269fc8b86c30e001360c18772aca40525cd.svn-base b/jni/pjproject-android/.svn/pristine/f1/f1083269fc8b86c30e001360c18772aca40525cd.svn-base
new file mode 100644
index 0000000..2ef6538
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f1/f1083269fc8b86c30e001360c18772aca40525cd.svn-base
@@ -0,0 +1,2098 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia/conference.h>
+#include <pjmedia/alaw_ulaw.h>
+#include <pjmedia/delaybuf.h>
+#include <pjmedia/errno.h>
+#include <pjmedia/port.h>
+#include <pjmedia/resample.h>
+#include <pjmedia/silencedet.h>
+#include <pjmedia/sound_port.h>
+#include <pjmedia/stereo.h>
+#include <pj/array.h>
+#include <pj/assert.h>
+#include <pj/log.h>
+#include <pj/pool.h>
+#include <pj/string.h>
+
+#if !defined(PJMEDIA_CONF_USE_SWITCH_BOARD) || PJMEDIA_CONF_USE_SWITCH_BOARD==0
+
+/* CONF_DEBUG enables detailed operation of the conference bridge.
+ * Beware that it prints large amounts of logs (several lines per frame).
+ */
+//#define CONF_DEBUG
+#ifdef CONF_DEBUG
+# include <stdio.h>
+# define TRACE_(x) PJ_LOG(5,x)
+#else
+# define TRACE_(x)
+#endif
+
+
+/* REC_FILE macro enables recording of the samples written to the sound
+ * device. The file contains RAW PCM data with no header, and has the
+ * same settings (clock rate etc) as the conference bridge.
+ * This should only be enabled when debugging audio quality *only*.
+ */
+//#define REC_FILE "confrec.pcm"
+#ifdef REC_FILE
+static FILE *fhnd_rec;
+#endif
+
+
+#define THIS_FILE "conference.c"
+
+#define RX_BUF_COUNT PJMEDIA_SOUND_BUFFER_COUNT
+
+#define BYTES_PER_SAMPLE 2
+
+#define SIGNATURE PJMEDIA_CONF_BRIDGE_SIGNATURE
+#define SIGNATURE_PORT PJMEDIA_SIG_PORT_CONF_PASV
+/* Normal level is hardcodec to 128 in all over places */
+#define NORMAL_LEVEL 128
+#define SLOT_TYPE unsigned
+#define INVALID_SLOT ((SLOT_TYPE)-1)
+
+
+/* These are settings to control the adaptivity of changes in the
+ * signal level of the ports, so that sudden change in signal level
+ * in the port does not cause misaligned signal (which causes noise).
+ */
+#define ATTACK_A (conf->clock_rate / conf->samples_per_frame)
+#define ATTACK_B 1
+#define DECAY_A 0
+#define DECAY_B 1
+
+#define SIMPLE_AGC(last, target) \
+ if (target >= last) \
+ target = (ATTACK_A*(last+1)+ATTACK_B*target)/(ATTACK_A+ATTACK_B); \
+ else \
+ target = (DECAY_A*last+DECAY_B*target)/(DECAY_A+DECAY_B)
+
+#define MAX_LEVEL (32767)
+#define MIN_LEVEL (-32768)
+
+#define IS_OVERFLOW(s) ((s > MAX_LEVEL) || (s < MIN_LEVEL))
+
+
+/*
+ * DON'T GET CONFUSED WITH TX/RX!!
+ *
+ * TX and RX directions are always viewed from the conference bridge's point
+ * of view, and NOT from the port's point of view. So TX means the bridge
+ * is transmitting to the port, RX means the bridge is receiving from the
+ * port.
+ */
+
+
+/**
+ * This is a port connected to conference bridge.
+ */
+struct conf_port
+{
+ pj_str_t name; /**< Port name. */
+ pjmedia_port *port; /**< get_frame() and put_frame() */
+ pjmedia_port_op rx_setting; /**< Can we receive from this port */
+ pjmedia_port_op tx_setting; /**< Can we transmit to this port */
+ unsigned listener_cnt; /**< Number of listeners. */
+ SLOT_TYPE *listener_slots;/**< Array of listeners. */
+ unsigned transmitter_cnt;/**<Number of transmitters. */
+
+ /* Shortcut for port info. */
+ unsigned clock_rate; /**< Port's clock rate. */
+ unsigned samples_per_frame; /**< Port's samples per frame. */
+ unsigned channel_count; /**< Port's channel count. */
+
+ /* Calculated signal levels: */
+ unsigned tx_level; /**< Last tx level to this port. */
+ unsigned rx_level; /**< Last rx level from this port. */
+
+ /* The normalized signal level adjustment.
+ * A value of 128 (NORMAL_LEVEL) means there's no adjustment.
+ */
+ unsigned tx_adj_level; /**< Adjustment for TX. */
+ unsigned rx_adj_level; /**< Adjustment for RX. */
+
+ /* Resample, for converting clock rate, if they're different. */
+ pjmedia_resample *rx_resample;
+ pjmedia_resample *tx_resample;
+
+ /* RX buffer is temporary buffer to be used when there is mismatch
+ * between port's sample rate or ptime with conference's sample rate
+ * or ptime. The buffer is used for sampling rate conversion AND/OR to
+ * buffer the samples until there are enough samples to fulfill a
+ * complete frame to be processed by the bridge.
+ *
+ * When both sample rate AND ptime of the port match the conference
+ * settings, this buffer will not be created.
+ *
+ * This buffer contains samples at port's clock rate.
+ * The size of this buffer is the sum between port's samples per frame
+ * and bridge's samples per frame.
+ */
+ pj_int16_t *rx_buf; /**< The RX buffer. */
+ unsigned rx_buf_cap; /**< Max size, in samples */
+ unsigned rx_buf_count; /**< # of samples in the buf. */
+
+ /* Mix buf is a temporary buffer used to mix all signal received
+ * by this port from all other ports. The mixed signal will be
+ * automatically adjusted to the appropriate level whenever
+ * there is possibility of clipping.
+ *
+ * This buffer contains samples at bridge's clock rate.
+ * The size of this buffer is equal to samples per frame of the bridge.
+ */
+
+ int mix_adj; /**< Adjustment level for mix_buf. */
+ int last_mix_adj; /**< Last adjustment level. */
+ pj_int32_t *mix_buf; /**< Total sum of signal. */
+
+ /* Tx buffer is a temporary buffer to be used when there's mismatch
+ * between port's clock rate or ptime with conference's sample rate
+ * or ptime. This buffer is used as the source of the sampling rate
+ * conversion AND/OR to buffer the samples until there are enough
+ * samples to fulfill a complete frame to be transmitted to the port.
+ *
+ * When both sample rate and ptime of the port match the bridge's
+ * settings, this buffer will not be created.
+ *
+ * This buffer contains samples at port's clock rate.
+ * The size of this buffer is the sum between port's samples per frame
+ * and bridge's samples per frame.
+ */
+ pj_int16_t *tx_buf; /**< Tx buffer. */
+ unsigned tx_buf_cap; /**< Max size, in samples. */
+ unsigned tx_buf_count; /**< # of samples in the buffer. */
+
+ /* When the port is not receiving signal from any other ports (e.g. when
+ * no other ports is transmitting to this port), the bridge periodically
+ * transmit NULL frame to the port to keep the port "alive" (for example,
+ * a stream port needs this heart-beat to periodically transmit silence
+ * frame to keep NAT binding alive).
+ *
+ * This NULL frame should be sent to the port at the port's ptime rate.
+ * So if the port's ptime is greater than the bridge's ptime, the bridge
+ * needs to delay the NULL frame until it's the right time to do so.
+ *
+ * This variable keeps track of how many pending NULL samples are being
+ * "held" for this port. Once this value reaches samples_per_frame
+ * value of the port, a NULL frame is sent. The samples value on this
+ * variable is clocked at the port's clock rate.
+ */
+ unsigned tx_heart_beat;
+
+ /* Delay buffer is a special buffer for sound device port (port 0, master
+ * port) and other passive ports (sound device port is also passive port).
+ *
+ * We need the delay buffer because we can not expect the mic and speaker
+ * thread to run equally after one another. In most systems, each thread
+ * will run multiple times before the other thread gains execution time.
+ * For example, in my system, mic thread is called three times, then
+ * speaker thread is called three times, and so on. This we call burst.
+ *
+ * There is also possibility of drift, unbalanced rate between put_frame
+ * and get_frame operation, in passive ports. If drift happens, snd_buf
+ * needs to be expanded or shrinked.
+ *
+ * Burst and drift are handled by delay buffer.
+ */
+ pjmedia_delay_buf *delay_buf;
+};
+
+
+/*
+ * Conference bridge.
+ */
+struct pjmedia_conf
+{
+ unsigned options; /**< Bitmask options. */
+ unsigned max_ports; /**< Maximum ports. */
+ unsigned port_cnt; /**< Current number of ports. */
+ unsigned connect_cnt; /**< Total number of connections */
+ pjmedia_snd_port *snd_dev_port; /**< Sound device port. */
+ pjmedia_port *master_port; /**< Port zero's port. */
+ char master_name_buf[80]; /**< Port0 name buffer. */
+ pj_mutex_t *mutex; /**< Conference mutex. */
+ struct conf_port **ports; /**< Array of ports. */
+ unsigned clock_rate; /**< Sampling rate. */
+ unsigned channel_count;/**< Number of channels (1=mono). */
+ unsigned samples_per_frame; /**< Samples per frame. */
+ unsigned bits_per_sample; /**< Bits per sample. */
+};
+
+
+/* Prototypes */
+static pj_status_t put_frame(pjmedia_port *this_port,
+ pjmedia_frame *frame);
+static pj_status_t get_frame(pjmedia_port *this_port,
+ pjmedia_frame *frame);
+static pj_status_t get_frame_pasv(pjmedia_port *this_port,
+ pjmedia_frame *frame);
+static pj_status_t destroy_port(pjmedia_port *this_port);
+static pj_status_t destroy_port_pasv(pjmedia_port *this_port);
+
+
+/*
+ * Create port.
+ */
+static pj_status_t create_conf_port( pj_pool_t *pool,
+ pjmedia_conf *conf,
+ pjmedia_port *port,
+ const pj_str_t *name,
+ struct conf_port **p_conf_port)
+{
+ struct conf_port *conf_port;
+ pj_status_t status;
+
+ /* Create port. */
+ conf_port = PJ_POOL_ZALLOC_T(pool, struct conf_port);
+ PJ_ASSERT_RETURN(conf_port, PJ_ENOMEM);
+
+ /* Set name */
+ pj_strdup_with_null(pool, &conf_port->name, name);
+
+ /* Default has tx and rx enabled. */
+ conf_port->rx_setting = PJMEDIA_PORT_ENABLE;
+ conf_port->tx_setting = PJMEDIA_PORT_ENABLE;
+
+ /* Default level adjustment is 128 (which means no adjustment) */
+ conf_port->tx_adj_level = NORMAL_LEVEL;
+ conf_port->rx_adj_level = NORMAL_LEVEL;
+
+ /* Create transmit flag array */
+ conf_port->listener_slots = (SLOT_TYPE*)
+ pj_pool_zalloc(pool,
+ conf->max_ports * sizeof(SLOT_TYPE));
+ PJ_ASSERT_RETURN(conf_port->listener_slots, PJ_ENOMEM);
+
+ /* Save some port's infos, for convenience. */
+ if (port) {
+ pjmedia_audio_format_detail *afd;
+
+ afd = pjmedia_format_get_audio_format_detail(&port->info.fmt, 1);
+ conf_port->port = port;
+ conf_port->clock_rate = afd->clock_rate;
+ conf_port->samples_per_frame = PJMEDIA_AFD_SPF(afd);
+ conf_port->channel_count = afd->channel_count;
+ } else {
+ conf_port->port = NULL;
+ conf_port->clock_rate = conf->clock_rate;
+ conf_port->samples_per_frame = conf->samples_per_frame;
+ conf_port->channel_count = conf->channel_count;
+ }
+
+ /* If port's clock rate is different than conference's clock rate,
+ * create a resample sessions.
+ */
+ if (conf_port->clock_rate != conf->clock_rate) {
+
+ pj_bool_t high_quality;
+ pj_bool_t large_filter;
+
+ high_quality = ((conf->options & PJMEDIA_CONF_USE_LINEAR)==0);
+ large_filter = ((conf->options & PJMEDIA_CONF_SMALL_FILTER)==0);
+
+ /* Create resample for rx buffer. */
+ status = pjmedia_resample_create( pool,
+ high_quality,
+ large_filter,
+ conf->channel_count,
+ conf_port->clock_rate,/* Rate in */
+ conf->clock_rate, /* Rate out */
+ conf->samples_per_frame *
+ conf_port->clock_rate /
+ conf->clock_rate,
+ &conf_port->rx_resample);
+ if (status != PJ_SUCCESS)
+ return status;
+
+
+ /* Create resample for tx buffer. */
+ status = pjmedia_resample_create(pool,
+ high_quality,
+ large_filter,
+ conf->channel_count,
+ conf->clock_rate, /* Rate in */
+ conf_port->clock_rate, /* Rate out */
+ conf->samples_per_frame,
+ &conf_port->tx_resample);
+ if (status != PJ_SUCCESS)
+ return status;
+ }
+
+ /*
+ * Initialize rx and tx buffer, only when port's samples per frame or
+ * port's clock rate or channel number is different then the conference
+ * bridge settings.
+ */
+ if (conf_port->clock_rate != conf->clock_rate ||
+ conf_port->channel_count != conf->channel_count ||
+ conf_port->samples_per_frame != conf->samples_per_frame)
+ {
+ unsigned port_ptime, conf_ptime, buff_ptime;
+
+ port_ptime = conf_port->samples_per_frame / conf_port->channel_count *
+ 1000 / conf_port->clock_rate;
+ conf_ptime = conf->samples_per_frame / conf->channel_count *
+ 1000 / conf->clock_rate;
+
+ /* Calculate the size (in ptime) for the port buffer according to
+ * this formula:
+ * - if either ptime is an exact multiple of the other, then use
+ * the larger ptime (e.g. 20ms and 40ms, use 40ms).
+ * - if not, then the ptime is sum of both ptimes (e.g. 20ms
+ * and 30ms, use 50ms)
+ */
+ if (port_ptime > conf_ptime) {
+ buff_ptime = port_ptime;
+ if (port_ptime % conf_ptime)
+ buff_ptime += conf_ptime;
+ } else {
+ buff_ptime = conf_ptime;
+ if (conf_ptime % port_ptime)
+ buff_ptime += port_ptime;
+ }
+
+ /* Create RX buffer. */
+ //conf_port->rx_buf_cap = (unsigned)(conf_port->samples_per_frame +
+ // conf->samples_per_frame *
+ // conf_port->clock_rate * 1.0 /
+ // conf->clock_rate + 0.5);
+ conf_port->rx_buf_cap = conf_port->clock_rate * buff_ptime / 1000;
+ if (conf_port->channel_count > conf->channel_count)
+ conf_port->rx_buf_cap *= conf_port->channel_count;
+ else
+ conf_port->rx_buf_cap *= conf->channel_count;
+
+ conf_port->rx_buf_count = 0;
+ conf_port->rx_buf = (pj_int16_t*)
+ pj_pool_alloc(pool, conf_port->rx_buf_cap *
+ sizeof(conf_port->rx_buf[0]));
+ PJ_ASSERT_RETURN(conf_port->rx_buf, PJ_ENOMEM);
+
+ /* Create TX buffer. */
+ conf_port->tx_buf_cap = conf_port->rx_buf_cap;
+ conf_port->tx_buf_count = 0;
+ conf_port->tx_buf = (pj_int16_t*)
+ pj_pool_alloc(pool, conf_port->tx_buf_cap *
+ sizeof(conf_port->tx_buf[0]));
+ PJ_ASSERT_RETURN(conf_port->tx_buf, PJ_ENOMEM);
+ }
+
+
+ /* Create mix buffer. */
+ conf_port->mix_buf = (pj_int32_t*)
+ pj_pool_zalloc(pool, conf->samples_per_frame *
+ sizeof(conf_port->mix_buf[0]));
+ PJ_ASSERT_RETURN(conf_port->mix_buf, PJ_ENOMEM);
+ conf_port->last_mix_adj = NORMAL_LEVEL;
+
+
+ /* Done */
+ *p_conf_port = conf_port;
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Add passive port.
+ */
+static pj_status_t create_pasv_port( pjmedia_conf *conf,
+ pj_pool_t *pool,
+ const pj_str_t *name,
+ pjmedia_port *port,
+ struct conf_port **p_conf_port)
+{
+ struct conf_port *conf_port;
+ pj_status_t status;
+ unsigned ptime;
+
+ /* Create port */
+ status = create_conf_port(pool, conf, port, name, &conf_port);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Passive port has delay buf. */
+ ptime = conf->samples_per_frame * 1000 / conf->clock_rate /
+ conf->channel_count;
+ status = pjmedia_delay_buf_create(pool, name->ptr,
+ conf->clock_rate,
+ conf->samples_per_frame,
+ conf->channel_count,
+ RX_BUF_COUNT * ptime, /* max delay */
+ 0, /* options */
+ &conf_port->delay_buf);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ *p_conf_port = conf_port;
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Create port zero for the sound device.
+ */
+static pj_status_t create_sound_port( pj_pool_t *pool,
+ pjmedia_conf *conf )
+{
+ struct conf_port *conf_port;
+ pj_str_t name = { "Master/sound", 12 };
+ pj_status_t status;
+
+
+ status = create_pasv_port(conf, pool, &name, NULL, &conf_port);
+ if (status != PJ_SUCCESS)
+ return status;
+
+
+ /* Create sound device port: */
+
+ if ((conf->options & PJMEDIA_CONF_NO_DEVICE) == 0) {
+ pjmedia_aud_stream *strm;
+ pjmedia_aud_param param;
+
+ /*
+ * If capture is disabled then create player only port.
+ * Otherwise create bidirectional sound device port.
+ */
+ if (conf->options & PJMEDIA_CONF_NO_MIC) {
+ status = pjmedia_snd_port_create_player(pool, -1, conf->clock_rate,
+ conf->channel_count,
+ conf->samples_per_frame,
+ conf->bits_per_sample,
+ 0, /* options */
+ &conf->snd_dev_port);
+
+ } else {
+ status = pjmedia_snd_port_create( pool, -1, -1, conf->clock_rate,
+ conf->channel_count,
+ conf->samples_per_frame,
+ conf->bits_per_sample,
+ 0, /* Options */
+ &conf->snd_dev_port);
+
+ }
+
+ if (status != PJ_SUCCESS)
+ return status;
+
+ strm = pjmedia_snd_port_get_snd_stream(conf->snd_dev_port);
+ status = pjmedia_aud_stream_get_param(strm, ¶m);
+ if (status == PJ_SUCCESS) {
+ pjmedia_aud_dev_info snd_dev_info;
+ if (conf->options & PJMEDIA_CONF_NO_MIC)
+ pjmedia_aud_dev_get_info(param.play_id, &snd_dev_info);
+ else
+ pjmedia_aud_dev_get_info(param.rec_id, &snd_dev_info);
+ pj_strdup2_with_null(pool, &conf_port->name, snd_dev_info.name);
+ }
+
+ PJ_LOG(5,(THIS_FILE, "Sound device successfully created for port 0"));
+ }
+
+
+ /* Add the port to the bridge */
+ conf->ports[0] = conf_port;
+ conf->port_cnt++;
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Create conference bridge.
+ */
+PJ_DEF(pj_status_t) pjmedia_conf_create( pj_pool_t *pool,
+ unsigned max_ports,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_conf **p_conf )
+{
+ pjmedia_conf *conf;
+ const pj_str_t name = { "Conf", 4 };
+ pj_status_t status;
+
+ /* Can only accept 16bits per sample, for now.. */
+ PJ_ASSERT_RETURN(bits_per_sample == 16, PJ_EINVAL);
+
+ PJ_LOG(5,(THIS_FILE, "Creating conference bridge with %d ports",
+ max_ports));
+
+ /* Create and init conf structure. */
+ conf = PJ_POOL_ZALLOC_T(pool, pjmedia_conf);
+ PJ_ASSERT_RETURN(conf, PJ_ENOMEM);
+
+ conf->ports = (struct conf_port**)
+ pj_pool_zalloc(pool, max_ports*sizeof(void*));
+ PJ_ASSERT_RETURN(conf->ports, PJ_ENOMEM);
+
+ conf->options = options;
+ conf->max_ports = max_ports;
+ conf->clock_rate = clock_rate;
+ conf->channel_count = channel_count;
+ conf->samples_per_frame = samples_per_frame;
+ conf->bits_per_sample = bits_per_sample;
+
+
+ /* Create and initialize the master port interface. */
+ conf->master_port = PJ_POOL_ZALLOC_T(pool, pjmedia_port);
+ PJ_ASSERT_RETURN(conf->master_port, PJ_ENOMEM);
+
+ pjmedia_port_info_init(&conf->master_port->info, &name, SIGNATURE,
+ clock_rate, channel_count, bits_per_sample,
+ samples_per_frame);
+
+ conf->master_port->port_data.pdata = conf;
+ conf->master_port->port_data.ldata = 0;
+
+ conf->master_port->get_frame = &get_frame;
+ conf->master_port->put_frame = &put_frame;
+ conf->master_port->on_destroy = &destroy_port;
+
+
+ /* Create port zero for sound device. */
+ status = create_sound_port(pool, conf);
+ if (status != PJ_SUCCESS) {
+ pjmedia_conf_destroy(conf);
+ return status;
+ }
+
+ /* Create mutex. */
+ status = pj_mutex_create_recursive(pool, "conf", &conf->mutex);
+ if (status != PJ_SUCCESS) {
+ pjmedia_conf_destroy(conf);
+ return status;
+ }
+
+ /* If sound device was created, connect sound device to the
+ * master port.
+ */
+ if (conf->snd_dev_port) {
+ status = pjmedia_snd_port_connect( conf->snd_dev_port,
+ conf->master_port );
+ if (status != PJ_SUCCESS) {
+ pjmedia_conf_destroy(conf);
+ return status;
+ }
+ }
+
+
+ /* Done */
+
+ *p_conf = conf;
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Pause sound device.
+ */
+static pj_status_t pause_sound( pjmedia_conf *conf )
+{
+ /* Do nothing. */
+ PJ_UNUSED_ARG(conf);
+ return PJ_SUCCESS;
+}
+
+/*
+ * Resume sound device.
+ */
+static pj_status_t resume_sound( pjmedia_conf *conf )
+{
+ /* Do nothing. */
+ PJ_UNUSED_ARG(conf);
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Destroy conference bridge.
+ */
+PJ_DEF(pj_status_t) pjmedia_conf_destroy( pjmedia_conf *conf )
+{
+ unsigned i, ci;
+
+ PJ_ASSERT_RETURN(conf != NULL, PJ_EINVAL);
+
+ /* Destroy sound device port. */
+ if (conf->snd_dev_port) {
+ pjmedia_snd_port_destroy(conf->snd_dev_port);
+ conf->snd_dev_port = NULL;
+ }
+
+ /* Destroy delay buf of all (passive) ports. */
+ for (i=0, ci=0; i<conf->max_ports && ci<conf->port_cnt; ++i) {
+ struct conf_port *cport;
+
+ cport = conf->ports[i];
+ if (!cport)
+ continue;
+
+ ++ci;
+ if (cport->delay_buf) {
+ pjmedia_delay_buf_destroy(cport->delay_buf);
+ cport->delay_buf = NULL;
+ }
+ }
+
+ /* Destroy mutex */
+ if (conf->mutex)
+ pj_mutex_destroy(conf->mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Destroy the master port (will destroy the conference)
+ */
+static pj_status_t destroy_port(pjmedia_port *this_port)
+{
+ pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata;
+ return pjmedia_conf_destroy(conf);
+}
+
+static pj_status_t destroy_port_pasv(pjmedia_port *this_port) {
+ pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata;
+ struct conf_port *port = conf->ports[this_port->port_data.ldata];
+ pj_status_t status;
+
+ status = pjmedia_delay_buf_destroy(port->delay_buf);
+ if (status == PJ_SUCCESS)
+ port->delay_buf = NULL;
+
+ return status;
+}
+
+/*
+ * Get port zero interface.
+ */
+PJ_DEF(pjmedia_port*) pjmedia_conf_get_master_port(pjmedia_conf *conf)
+{
+ /* Sanity check. */
+ PJ_ASSERT_RETURN(conf != NULL, NULL);
+
+ /* Can only return port interface when PJMEDIA_CONF_NO_DEVICE was
+ * present in the option.
+ */
+ PJ_ASSERT_RETURN((conf->options & PJMEDIA_CONF_NO_DEVICE) != 0, NULL);
+
+ return conf->master_port;
+}
+
+
+/*
+ * Set master port name.
+ */
+PJ_DEF(pj_status_t) pjmedia_conf_set_port0_name(pjmedia_conf *conf,
+ const pj_str_t *name)
+{
+ pj_size_t len;
+
+ /* Sanity check. */
+ PJ_ASSERT_RETURN(conf != NULL && name != NULL, PJ_EINVAL);
+
+ len = name->slen;
+ if (len > sizeof(conf->master_name_buf))
+ len = sizeof(conf->master_name_buf);
+
+ if (len > 0) pj_memcpy(conf->master_name_buf, name->ptr, len);
+
+ conf->ports[0]->name.ptr = conf->master_name_buf;
+ conf->ports[0]->name.slen = len;
+
+ if (conf->master_port)
+ conf->master_port->info.name = conf->ports[0]->name;
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Add stream port to the conference bridge.
+ */
+PJ_DEF(pj_status_t) pjmedia_conf_add_port( pjmedia_conf *conf,
+ pj_pool_t *pool,
+ pjmedia_port *strm_port,
+ const pj_str_t *port_name,
+ unsigned *p_port )
+{
+ struct conf_port *conf_port;
+ unsigned index;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(conf && pool && strm_port, PJ_EINVAL);
+
+ /* If port_name is not specified, use the port's name */
+ if (!port_name)
+ port_name = &strm_port->info.name;
+
+ /* For this version of PJMEDIA, channel(s) number MUST be:
+ * - same between port & conference bridge.
+ * - monochannel on port or conference bridge.
+ */
+ if (PJMEDIA_PIA_CCNT(&strm_port->info) != conf->channel_count &&
+ (PJMEDIA_PIA_CCNT(&strm_port->info) != 1 &&
+ conf->channel_count != 1))
+ {
+ pj_assert(!"Number of channels mismatch");
+ return PJMEDIA_ENCCHANNEL;
+ }
+
+ pj_mutex_lock(conf->mutex);
+
+ if (conf->port_cnt >= conf->max_ports) {
+ pj_assert(!"Too many ports");
+ pj_mutex_unlock(conf->mutex);
+ return PJ_ETOOMANY;
+ }
+
+ /* Find empty port in the conference bridge. */
+ for (index=0; index < conf->max_ports; ++index) {
+ if (conf->ports[index] == NULL)
+ break;
+ }
+
+ pj_assert(index != conf->max_ports);
+
+ /* Create conf port structure. */
+ status = create_conf_port(pool, conf, strm_port, port_name, &conf_port);
+ if (status != PJ_SUCCESS) {
+ pj_mutex_unlock(conf->mutex);
+ return status;
+ }
+
+ /* Put the port. */
+ conf->ports[index] = conf_port;
+ conf->port_cnt++;
+
+ /* Done. */
+ if (p_port) {
+ *p_port = index;
+ }
+
+ pj_mutex_unlock(conf->mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Add passive port.
+ */
+PJ_DEF(pj_status_t) pjmedia_conf_add_passive_port( pjmedia_conf *conf,
+ pj_pool_t *pool,
+ const pj_str_t *name,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ unsigned *p_slot,
+ pjmedia_port **p_port )
+{
+ struct conf_port *conf_port;
+ pjmedia_port *port;
+ unsigned index;
+ pj_str_t tmp;
+ pj_status_t status;
+
+ PJ_LOG(1, (THIS_FILE, "This API has been deprecated since 1.3 and will "
+ "be removed in the future release!"));
+
+ PJ_ASSERT_RETURN(conf && pool, PJ_EINVAL);
+
+ /* For this version of PJMEDIA, channel(s) number MUST be:
+ * - same between port & conference bridge.
+ * - monochannel on port or conference bridge.
+ */
+ if (channel_count != conf->channel_count &&
+ (channel_count != 1 && conf->channel_count != 1))
+ {
+ pj_assert(!"Number of channels mismatch");
+ return PJMEDIA_ENCCHANNEL;
+ }
+
+ /* For this version, options must be zero */
+ PJ_ASSERT_RETURN(options == 0, PJ_EINVAL);
+ PJ_UNUSED_ARG(options);
+
+ pj_mutex_lock(conf->mutex);
+
+ if (conf->port_cnt >= conf->max_ports) {
+ pj_assert(!"Too many ports");
+ pj_mutex_unlock(conf->mutex);
+ return PJ_ETOOMANY;
+ }
+
+ /* Find empty port in the conference bridge. */
+ for (index=0; index < conf->max_ports; ++index) {
+ if (conf->ports[index] == NULL)
+ break;
+ }
+
+ pj_assert(index != conf->max_ports);
+
+ if (name == NULL) {
+ name = &tmp;
+
+ tmp.ptr = (char*) pj_pool_alloc(pool, 32);
+ tmp.slen = pj_ansi_snprintf(tmp.ptr, 32, "ConfPort#%d", index);
+ }
+
+ /* Create and initialize the media port structure. */
+ port = PJ_POOL_ZALLOC_T(pool, pjmedia_port);
+ PJ_ASSERT_RETURN(port, PJ_ENOMEM);
+
+ pjmedia_port_info_init(&port->info, name, SIGNATURE_PORT,
+ clock_rate, channel_count, bits_per_sample,
+ samples_per_frame);
+
+ port->port_data.pdata = conf;
+ port->port_data.ldata = index;
+
+ port->get_frame = &get_frame_pasv;
+ port->put_frame = &put_frame;
+ port->on_destroy = &destroy_port_pasv;
+
+
+ /* Create conf port structure. */
+ status = create_pasv_port(conf, pool, name, port, &conf_port);
+ if (status != PJ_SUCCESS) {
+ pj_mutex_unlock(conf->mutex);
+ return status;
+ }
+
+
+ /* Put the port. */
+ conf->ports[index] = conf_port;
+ conf->port_cnt++;
+
+ /* Done. */
+ if (p_slot)
+ *p_slot = index;
+ if (p_port)
+ *p_port = port;
+
+ pj_mutex_unlock(conf->mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+
+/*
+ * Change TX and RX settings for the port.
+ */
+PJ_DEF(pj_status_t) pjmedia_conf_configure_port( pjmedia_conf *conf,
+ unsigned slot,
+ pjmedia_port_op tx,
+ pjmedia_port_op rx)
+{
+ struct conf_port *conf_port;
+
+ /* Check arguments */
+ PJ_ASSERT_RETURN(conf && slot<conf->max_ports, PJ_EINVAL);
+
+ pj_mutex_lock(conf->mutex);
+
+ /* Port must be valid. */
+ conf_port = conf->ports[slot];
+ if (conf_port == NULL) {
+ pj_mutex_unlock(conf->mutex);
+ return PJ_EINVAL;
+ }
+
+ conf_port = conf->ports[slot];
+
+ if (tx != PJMEDIA_PORT_NO_CHANGE)
+ conf_port->tx_setting = tx;
+
+ if (rx != PJMEDIA_PORT_NO_CHANGE)
+ conf_port->rx_setting = rx;
+
+ pj_mutex_unlock(conf->mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Connect port.
+ */
+PJ_DEF(pj_status_t) pjmedia_conf_connect_port( pjmedia_conf *conf,
+ unsigned src_slot,
+ unsigned sink_slot,
+ int level )
+{
+ struct conf_port *src_port, *dst_port;
+ pj_bool_t start_sound = PJ_FALSE;
+ unsigned i;
+
+ /* Check arguments */
+ PJ_ASSERT_RETURN(conf && src_slot<conf->max_ports &&
+ sink_slot<conf->max_ports, PJ_EINVAL);
+
+ /* For now, level MUST be zero. */
+ PJ_ASSERT_RETURN(level == 0, PJ_EINVAL);
+
+ pj_mutex_lock(conf->mutex);
+
+ /* Ports must be valid. */
+ src_port = conf->ports[src_slot];
+ dst_port = conf->ports[sink_slot];
+ if (!src_port || !dst_port) {
+ pj_mutex_unlock(conf->mutex);
+ return PJ_EINVAL;
+ }
+
+ /* Check if connection has been made */
+ for (i=0; i<src_port->listener_cnt; ++i) {
+ if (src_port->listener_slots[i] == sink_slot)
+ break;
+ }
+
+ if (i == src_port->listener_cnt) {
+ src_port->listener_slots[src_port->listener_cnt] = sink_slot;
+ ++conf->connect_cnt;
+ ++src_port->listener_cnt;
+ ++dst_port->transmitter_cnt;
+
+ if (conf->connect_cnt == 1)
+ start_sound = 1;
+
+ PJ_LOG(4,(THIS_FILE,"Port %d (%.*s) transmitting to port %d (%.*s)",
+ src_slot,
+ (int)src_port->name.slen,
+ src_port->name.ptr,
+ sink_slot,
+ (int)dst_port->name.slen,
+ dst_port->name.ptr));
+ }
+
+ pj_mutex_unlock(conf->mutex);
+
+ /* Sound device must be started without mutex, otherwise the
+ * sound thread will deadlock (?)
+ */
+ if (start_sound)
+ resume_sound(conf);
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Disconnect port
+ */
+PJ_DEF(pj_status_t) pjmedia_conf_disconnect_port( pjmedia_conf *conf,
+ unsigned src_slot,
+ unsigned sink_slot )
+{
+ struct conf_port *src_port, *dst_port;
+ unsigned i;
+
+ /* Check arguments */
+ PJ_ASSERT_RETURN(conf && src_slot<conf->max_ports &&
+ sink_slot<conf->max_ports, PJ_EINVAL);
+
+ pj_mutex_lock(conf->mutex);
+
+ /* Ports must be valid. */
+ src_port = conf->ports[src_slot];
+ dst_port = conf->ports[sink_slot];
+ if (!src_port || !dst_port) {
+ pj_mutex_unlock(conf->mutex);
+ return PJ_EINVAL;
+ }
+
+ /* Check if connection has been made */
+ for (i=0; i<src_port->listener_cnt; ++i) {
+ if (src_port->listener_slots[i] == sink_slot)
+ break;
+ }
+
+ if (i != src_port->listener_cnt) {
+ pj_assert(src_port->listener_cnt > 0 &&
+ src_port->listener_cnt < conf->max_ports);
+ pj_assert(dst_port->transmitter_cnt > 0 &&
+ dst_port->transmitter_cnt < conf->max_ports);
+ pj_array_erase(src_port->listener_slots, sizeof(SLOT_TYPE),
+ src_port->listener_cnt, i);
+ --conf->connect_cnt;
+ --src_port->listener_cnt;
+ --dst_port->transmitter_cnt;
+
+ PJ_LOG(4,(THIS_FILE,
+ "Port %d (%.*s) stop transmitting to port %d (%.*s)",
+ src_slot,
+ (int)src_port->name.slen,
+ src_port->name.ptr,
+ sink_slot,
+ (int)dst_port->name.slen,
+ dst_port->name.ptr));
+
+ /* if source port is passive port and has no listener, reset delaybuf */
+ if (src_port->delay_buf && src_port->listener_cnt == 0)
+ pjmedia_delay_buf_reset(src_port->delay_buf);
+ }
+
+ pj_mutex_unlock(conf->mutex);
+
+ if (conf->connect_cnt == 0) {
+ pause_sound(conf);
+ }
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Get number of ports currently registered to the conference bridge.
+ */
+PJ_DEF(unsigned) pjmedia_conf_get_port_count(pjmedia_conf *conf)
+{
+ return conf->port_cnt;
+}
+
+/*
+ * Get total number of ports connections currently set up in the bridge.
+ */
+PJ_DEF(unsigned) pjmedia_conf_get_connect_count(pjmedia_conf *conf)
+{
+ return conf->connect_cnt;
+}
+
+
+/*
+ * Remove the specified port.
+ */
+PJ_DEF(pj_status_t) pjmedia_conf_remove_port( pjmedia_conf *conf,
+ unsigned port )
+{
+ struct conf_port *conf_port;
+ unsigned i;
+
+ /* Check arguments */
+ PJ_ASSERT_RETURN(conf && port < conf->max_ports, PJ_EINVAL);
+
+ /* Suspend the sound devices.
+ * Don't want to remove port while port is being accessed by sound
+ * device's threads!
+ */
+
+ pj_mutex_lock(conf->mutex);
+
+ /* Port must be valid. */
+ conf_port = conf->ports[port];
+ if (conf_port == NULL) {
+ pj_mutex_unlock(conf->mutex);
+ return PJ_EINVAL;
+ }
+
+ conf_port->tx_setting = PJMEDIA_PORT_DISABLE;
+ conf_port->rx_setting = PJMEDIA_PORT_DISABLE;
+
+ /* Remove this port from transmit array of other ports. */
+ for (i=0; i<conf->max_ports; ++i) {
+ unsigned j;
+ struct conf_port *src_port;
+
+ src_port = conf->ports[i];
+
+ if (!src_port)
+ continue;
+
+ if (src_port->listener_cnt == 0)
+ continue;
+
+ for (j=0; j<src_port->listener_cnt; ++j) {
+ if (src_port->listener_slots[j] == port) {
+ pj_array_erase(src_port->listener_slots, sizeof(SLOT_TYPE),
+ src_port->listener_cnt, j);
+ pj_assert(conf->connect_cnt > 0);
+ --conf->connect_cnt;
+ --src_port->listener_cnt;
+ break;
+ }
+ }
+ }
+
+ /* Update transmitter_cnt of ports we're transmitting to */
+ while (conf_port->listener_cnt) {
+ unsigned dst_slot;
+ struct conf_port *dst_port;
+
+ dst_slot = conf_port->listener_slots[conf_port->listener_cnt-1];
+ dst_port = conf->ports[dst_slot];
+ --dst_port->transmitter_cnt;
+ --conf_port->listener_cnt;
+ pj_assert(conf->connect_cnt > 0);
+ --conf->connect_cnt;
+ }
+
+ /* Destroy pjmedia port if this conf port is passive port,
+ * i.e: has delay buf.
+ */
+ if (conf_port->delay_buf) {
+ pjmedia_port_destroy(conf_port->port);
+ conf_port->port = NULL;
+ }
+
+ /* Remove the port. */
+ conf->ports[port] = NULL;
+ --conf->port_cnt;
+
+ pj_mutex_unlock(conf->mutex);
+
+
+ /* Stop sound if there's no connection. */
+ if (conf->connect_cnt == 0) {
+ pause_sound(conf);
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Enum ports.
+ */
+PJ_DEF(pj_status_t) pjmedia_conf_enum_ports( pjmedia_conf *conf,
+ unsigned ports[],
+ unsigned *p_count )
+{
+ unsigned i, count=0;
+
+ PJ_ASSERT_RETURN(conf && p_count && ports, PJ_EINVAL);
+
+ /* Lock mutex */
+ pj_mutex_lock(conf->mutex);
+
+ for (i=0; i<conf->max_ports && count<*p_count; ++i) {
+ if (!conf->ports[i])
+ continue;
+
+ ports[count++] = i;
+ }
+
+ /* Unlock mutex */
+ pj_mutex_unlock(conf->mutex);
+
+ *p_count = count;
+ return PJ_SUCCESS;
+}
+
+/*
+ * Get port info
+ */
+PJ_DEF(pj_status_t) pjmedia_conf_get_port_info( pjmedia_conf *conf,
+ unsigned slot,
+ pjmedia_conf_port_info *info)
+{
+ struct conf_port *conf_port;
+
+ /* Check arguments */
+ PJ_ASSERT_RETURN(conf && slot<conf->max_ports, PJ_EINVAL);
+
+ /* Lock mutex */
+ pj_mutex_lock(conf->mutex);
+
+ /* Port must be valid. */
+ conf_port = conf->ports[slot];
+ if (conf_port == NULL) {
+ pj_mutex_unlock(conf->mutex);
+ return PJ_EINVAL;
+ }
+
+ info->slot = slot;
+ info->name = conf_port->name;
+ info->tx_setting = conf_port->tx_setting;
+ info->rx_setting = conf_port->rx_setting;
+ info->listener_cnt = conf_port->listener_cnt;
+ info->listener_slots = conf_port->listener_slots;
+ info->transmitter_cnt = conf_port->transmitter_cnt;
+ info->clock_rate = conf_port->clock_rate;
+ info->channel_count = conf_port->channel_count;
+ info->samples_per_frame = conf_port->samples_per_frame;
+ info->bits_per_sample = conf->bits_per_sample;
+ info->tx_adj_level = conf_port->tx_adj_level - NORMAL_LEVEL;
+ info->rx_adj_level = conf_port->rx_adj_level - NORMAL_LEVEL;
+
+ /* Unlock mutex */
+ pj_mutex_unlock(conf->mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pj_status_t) pjmedia_conf_get_ports_info(pjmedia_conf *conf,
+ unsigned *size,
+ pjmedia_conf_port_info info[])
+{
+ unsigned i, count=0;
+
+ PJ_ASSERT_RETURN(conf && size && info, PJ_EINVAL);
+
+ /* Lock mutex */
+ pj_mutex_lock(conf->mutex);
+
+ for (i=0; i<conf->max_ports && count<*size; ++i) {
+ if (!conf->ports[i])
+ continue;
+
+ pjmedia_conf_get_port_info(conf, i, &info[count]);
+ ++count;
+ }
+
+ /* Unlock mutex */
+ pj_mutex_unlock(conf->mutex);
+
+ *size = count;
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Get signal level.
+ */
+PJ_DEF(pj_status_t) pjmedia_conf_get_signal_level( pjmedia_conf *conf,
+ unsigned slot,
+ unsigned *tx_level,
+ unsigned *rx_level)
+{
+ struct conf_port *conf_port;
+
+ /* Check arguments */
+ PJ_ASSERT_RETURN(conf && slot<conf->max_ports, PJ_EINVAL);
+
+ /* Lock mutex */
+ pj_mutex_lock(conf->mutex);
+
+ /* Port must be valid. */
+ conf_port = conf->ports[slot];
+ if (conf_port == NULL) {
+ pj_mutex_unlock(conf->mutex);
+ return PJ_EINVAL;
+ }
+
+ if (tx_level != NULL) {
+ *tx_level = conf_port->tx_level;
+ }
+
+ if (rx_level != NULL)
+ *rx_level = conf_port->rx_level;
+
+ /* Unlock mutex */
+ pj_mutex_unlock(conf->mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Adjust RX level of individual port.
+ */
+PJ_DEF(pj_status_t) pjmedia_conf_adjust_rx_level( pjmedia_conf *conf,
+ unsigned slot,
+ int adj_level )
+{
+ struct conf_port *conf_port;
+
+ /* Check arguments */
+ PJ_ASSERT_RETURN(conf && slot<conf->max_ports, PJ_EINVAL);
+
+ /* Value must be from -128 to +127 */
+ /* Disabled, you can put more than +127, at your own risk:
+ PJ_ASSERT_RETURN(adj_level >= -128 && adj_level <= 127, PJ_EINVAL);
+ */
+ PJ_ASSERT_RETURN(adj_level >= -128, PJ_EINVAL);
+
+ /* Lock mutex */
+ pj_mutex_lock(conf->mutex);
+
+ /* Port must be valid. */
+ conf_port = conf->ports[slot];
+ if (conf_port == NULL) {
+ pj_mutex_unlock(conf->mutex);
+ return PJ_EINVAL;
+ }
+
+ /* Set normalized adjustment level. */
+ conf_port->rx_adj_level = adj_level + NORMAL_LEVEL;
+
+ /* Unlock mutex */
+ pj_mutex_unlock(conf->mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Adjust TX level of individual port.
+ */
+PJ_DEF(pj_status_t) pjmedia_conf_adjust_tx_level( pjmedia_conf *conf,
+ unsigned slot,
+ int adj_level )
+{
+ struct conf_port *conf_port;
+
+ /* Check arguments */
+ PJ_ASSERT_RETURN(conf && slot<conf->max_ports, PJ_EINVAL);
+
+ /* Value must be from -128 to +127 */
+ /* Disabled, you can put more than +127,, at your own risk:
+ PJ_ASSERT_RETURN(adj_level >= -128 && adj_level <= 127, PJ_EINVAL);
+ */
+ PJ_ASSERT_RETURN(adj_level >= -128, PJ_EINVAL);
+
+ /* Lock mutex */
+ pj_mutex_lock(conf->mutex);
+
+ /* Port must be valid. */
+ conf_port = conf->ports[slot];
+ if (conf_port == NULL) {
+ pj_mutex_unlock(conf->mutex);
+ return PJ_EINVAL;
+ }
+
+ /* Set normalized adjustment level. */
+ conf_port->tx_adj_level = adj_level + NORMAL_LEVEL;
+
+ /* Unlock mutex */
+ pj_mutex_unlock(conf->mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Read from port.
+ */
+static pj_status_t read_port( pjmedia_conf *conf,
+ struct conf_port *cport, pj_int16_t *frame,
+ pj_size_t count, pjmedia_frame_type *type )
+{
+
+ pj_assert(count == conf->samples_per_frame);
+
+ TRACE_((THIS_FILE, "read_port %.*s: count=%d",
+ (int)cport->name.slen, cport->name.ptr,
+ count));
+
+ /*
+ * If port's samples per frame and sampling rate and channel count
+ * matche conference bridge's settings, get the frame directly from
+ * the port.
+ */
+ if (cport->rx_buf_cap == 0) {
+ pjmedia_frame f;
+ pj_status_t status;
+
+ f.buf = frame;
+ f.size = count * BYTES_PER_SAMPLE;
+
+ TRACE_((THIS_FILE, " get_frame %.*s: count=%d",
+ (int)cport->name.slen, cport->name.ptr,
+ count));
+
+ status = pjmedia_port_get_frame(cport->port, &f);
+
+ *type = f.type;
+
+ return status;
+
+ } else {
+ unsigned samples_req;
+
+ /* Initialize frame type */
+ if (cport->rx_buf_count == 0) {
+ *type = PJMEDIA_FRAME_TYPE_NONE;
+ } else {
+ /* we got some samples in the buffer */
+ *type = PJMEDIA_FRAME_TYPE_AUDIO;
+ }
+
+ /*
+ * If we don't have enough samples in rx_buf, read from the port
+ * first. Remember that rx_buf may be in different clock rate and
+ * channel count!
+ */
+
+ samples_req = (unsigned) (count * 1.0 *
+ cport->clock_rate / conf->clock_rate + 0.5);
+
+ while (cport->rx_buf_count < samples_req) {
+
+ pjmedia_frame f;
+ pj_status_t status;
+
+ f.buf = cport->rx_buf + cport->rx_buf_count;
+ f.size = cport->samples_per_frame * BYTES_PER_SAMPLE;
+
+ TRACE_((THIS_FILE, " get_frame, count=%d",
+ cport->samples_per_frame));
+
+ status = pjmedia_port_get_frame(cport->port, &f);
+
+ if (status != PJ_SUCCESS) {
+ /* Fatal error! */
+ return status;
+ }
+
+ if (f.type != PJMEDIA_FRAME_TYPE_AUDIO) {
+ TRACE_((THIS_FILE, " get_frame returned non-audio"));
+ pjmedia_zero_samples( cport->rx_buf + cport->rx_buf_count,
+ cport->samples_per_frame);
+ } else {
+ /* We've got at least one frame */
+ *type = PJMEDIA_FRAME_TYPE_AUDIO;
+ }
+
+ /* Adjust channels */
+ if (cport->channel_count != conf->channel_count) {
+ if (cport->channel_count == 1) {
+ pjmedia_convert_channel_1ton((pj_int16_t*)f.buf,
+ (const pj_int16_t*)f.buf,
+ conf->channel_count,
+ cport->samples_per_frame,
+ 0);
+ cport->rx_buf_count += (cport->samples_per_frame *
+ conf->channel_count);
+ } else { /* conf->channel_count == 1 */
+ pjmedia_convert_channel_nto1((pj_int16_t*)f.buf,
+ (const pj_int16_t*)f.buf,
+ cport->channel_count,
+ cport->samples_per_frame,
+ PJMEDIA_STEREO_MIX, 0);
+ cport->rx_buf_count += (cport->samples_per_frame /
+ cport->channel_count);
+ }
+ } else {
+ cport->rx_buf_count += cport->samples_per_frame;
+ }
+
+ TRACE_((THIS_FILE, " rx buffer size is now %d",
+ cport->rx_buf_count));
+
+ pj_assert(cport->rx_buf_count <= cport->rx_buf_cap);
+ }
+
+ /*
+ * If port's clock_rate is different, resample.
+ * Otherwise just copy.
+ */
+ if (cport->clock_rate != conf->clock_rate) {
+
+ unsigned src_count;
+
+ TRACE_((THIS_FILE, " resample, input count=%d",
+ pjmedia_resample_get_input_size(cport->rx_resample)));
+
+ pjmedia_resample_run( cport->rx_resample,cport->rx_buf, frame);
+
+ src_count = (unsigned)(count * 1.0 * cport->clock_rate /
+ conf->clock_rate + 0.5);
+ cport->rx_buf_count -= src_count;
+ if (cport->rx_buf_count) {
+ pjmedia_move_samples(cport->rx_buf, cport->rx_buf+src_count,
+ cport->rx_buf_count);
+ }
+
+ TRACE_((THIS_FILE, " rx buffer size is now %d",
+ cport->rx_buf_count));
+
+ } else {
+
+ pjmedia_copy_samples(frame, cport->rx_buf, (unsigned)count);
+ cport->rx_buf_count -= (unsigned)count;
+ if (cport->rx_buf_count) {
+ pjmedia_move_samples(cport->rx_buf, cport->rx_buf+count,
+ cport->rx_buf_count);
+ }
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Write the mixed signal to the port.
+ */
+static pj_status_t write_port(pjmedia_conf *conf, struct conf_port *cport,
+ const pj_timestamp *timestamp,
+ pjmedia_frame_type *frm_type)
+{
+ pj_int16_t *buf;
+ unsigned j, ts;
+ pj_status_t status;
+ pj_int32_t adj_level;
+ pj_int32_t tx_level;
+ unsigned dst_count;
+
+ *frm_type = PJMEDIA_FRAME_TYPE_AUDIO;
+
+ /* If port is muted or nobody is transmitting to this port,
+ * transmit NULL frame.
+ */
+ if (cport->tx_setting == PJMEDIA_PORT_MUTE || cport->transmitter_cnt==0) {
+
+ pjmedia_frame frame;
+
+ /* Clear left-over samples in tx_buffer, if any, so that it won't
+ * be transmitted next time we have audio signal.
+ */
+ cport->tx_buf_count = 0;
+
+ /* Add sample counts to heart-beat samples */
+ cport->tx_heart_beat += conf->samples_per_frame * cport->clock_rate /
+ conf->clock_rate *
+ cport->channel_count / conf->channel_count;
+
+ /* Set frame timestamp */
+ frame.timestamp.u64 = timestamp->u64 * cport->clock_rate /
+ conf->clock_rate;
+ frame.type = PJMEDIA_FRAME_TYPE_NONE;
+ frame.buf = NULL;
+ frame.size = 0;
+
+ /* Transmit heart-beat frames (may transmit more than one NULL frame
+ * if port's ptime is less than bridge's ptime.
+ */
+ if (cport->port && cport->port->put_frame) {
+ while (cport->tx_heart_beat >= cport->samples_per_frame) {
+
+ pjmedia_port_put_frame(cport->port, &frame);
+
+ cport->tx_heart_beat -= cport->samples_per_frame;
+ frame.timestamp.u64 += cport->samples_per_frame;
+ }
+ }
+
+ cport->tx_level = 0;
+ *frm_type = PJMEDIA_FRAME_TYPE_NONE;
+ return PJ_SUCCESS;
+
+ } else if (cport->tx_setting != PJMEDIA_PORT_ENABLE) {
+ cport->tx_level = 0;
+ *frm_type = PJMEDIA_FRAME_TYPE_NONE;
+ return PJ_SUCCESS;
+ }
+
+ /* Reset heart-beat sample count */
+ cport->tx_heart_beat = 0;
+
+ buf = (pj_int16_t*) cport->mix_buf;
+
+ /* If there are sources in the mix buffer, convert the mixed samples
+ * from 32bit to 16bit in the mixed samples itself. This is possible
+ * because mixed sample is 32bit.
+ *
+ * In addition to this process, if we need to change the level of
+ * TX signal, we adjust is here too.
+ */
+
+ /* Calculate signal level and adjust the signal when needed.
+ * Two adjustments performed at once:
+ * 1. user setting adjustment (tx_adj_level).
+ * 2. automatic adjustment of overflowed mixed buffer (mix_adj).
+ */
+
+ /* Apply simple AGC to the mix_adj, the automatic adjust, to avoid
+ * dramatic change in the level thus causing noise because the signal
+ * is now not aligned with the signal from the previous frame.
+ */
+ SIMPLE_AGC(cport->last_mix_adj, cport->mix_adj);
+ cport->last_mix_adj = cport->mix_adj;
+
+ /* adj_level = cport->tx_adj_level * cport->mix_adj / NORMAL_LEVEL;*/
+ adj_level = cport->tx_adj_level * cport->mix_adj;
+ adj_level >>= 7;
+
+ tx_level = 0;
+
+ if (adj_level != NORMAL_LEVEL) {
+ for (j=0; j<conf->samples_per_frame; ++j) {
+ pj_int32_t itemp = cport->mix_buf[j];
+
+ /* Adjust the level */
+ /*itemp = itemp * adj_level / NORMAL_LEVEL;*/
+ itemp = (itemp * adj_level) >> 7;
+
+ /* Clip the signal if it's too loud */
+ if (itemp > MAX_LEVEL) itemp = MAX_LEVEL;
+ else if (itemp < MIN_LEVEL) itemp = MIN_LEVEL;
+
+ /* Put back in the buffer. */
+ buf[j] = (pj_int16_t) itemp;
+
+ tx_level += (buf[j]>=0? buf[j] : -buf[j]);
+ }
+ } else {
+ for (j=0; j<conf->samples_per_frame; ++j) {
+ buf[j] = (pj_int16_t) cport->mix_buf[j];
+ tx_level += (buf[j]>=0? buf[j] : -buf[j]);
+ }
+ }
+
+ tx_level /= conf->samples_per_frame;
+
+ /* Convert level to 8bit complement ulaw */
+ tx_level = pjmedia_linear2ulaw(tx_level) ^ 0xff;
+
+ cport->tx_level = tx_level;
+
+ /* If port has the same clock_rate and samples_per_frame and
+ * number of channels as the conference bridge, transmit the
+ * frame as is.
+ */
+ if (cport->clock_rate == conf->clock_rate &&
+ cport->samples_per_frame == conf->samples_per_frame &&
+ cport->channel_count == conf->channel_count)
+ {
+ if (cport->port != NULL) {
+ pjmedia_frame frame;
+
+ frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
+ frame.buf = buf;
+ frame.size = conf->samples_per_frame * BYTES_PER_SAMPLE;
+ /* No need to adjust timestamp, port has the same
+ * clock rate as conference bridge
+ */
+ frame.timestamp = *timestamp;
+
+ TRACE_((THIS_FILE, "put_frame %.*s, count=%d",
+ (int)cport->name.slen, cport->name.ptr,
+ frame.size / BYTES_PER_SAMPLE));
+
+ return pjmedia_port_put_frame(cport->port, &frame);
+ } else
+ return PJ_SUCCESS;
+ }
+
+ /* If it has different clock_rate, must resample. */
+ if (cport->clock_rate != conf->clock_rate) {
+ pjmedia_resample_run( cport->tx_resample, buf,
+ cport->tx_buf + cport->tx_buf_count );
+ dst_count = (unsigned)(conf->samples_per_frame * 1.0 *
+ cport->clock_rate / conf->clock_rate + 0.5);
+ } else {
+ /* Same clock rate.
+ * Just copy the samples to tx_buffer.
+ */
+ pjmedia_copy_samples( cport->tx_buf + cport->tx_buf_count,
+ buf, conf->samples_per_frame );
+ dst_count = conf->samples_per_frame;
+ }
+
+ /* Adjust channels */
+ if (cport->channel_count != conf->channel_count) {
+ pj_int16_t *tx_buf = cport->tx_buf + cport->tx_buf_count;
+ if (conf->channel_count == 1) {
+ pjmedia_convert_channel_1ton(tx_buf, tx_buf,
+ cport->channel_count,
+ dst_count, 0);
+ dst_count *= cport->channel_count;
+ } else { /* cport->channel_count == 1 */
+ pjmedia_convert_channel_nto1(tx_buf, tx_buf,
+ conf->channel_count,
+ dst_count, PJMEDIA_STEREO_MIX, 0);
+ dst_count /= conf->channel_count;
+ }
+ }
+
+ cport->tx_buf_count += dst_count;
+
+ pj_assert(cport->tx_buf_count <= cport->tx_buf_cap);
+
+ /* Transmit while we have enough frame in the tx_buf. */
+ status = PJ_SUCCESS;
+ ts = 0;
+ while (cport->tx_buf_count >= cport->samples_per_frame &&
+ status == PJ_SUCCESS)
+ {
+
+ TRACE_((THIS_FILE, "write_port %.*s: count=%d",
+ (int)cport->name.slen, cport->name.ptr,
+ cport->samples_per_frame));
+
+ if (cport->port) {
+ pjmedia_frame frame;
+
+ frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
+ frame.buf = cport->tx_buf;
+ frame.size = cport->samples_per_frame * BYTES_PER_SAMPLE;
+ /* Adjust timestamp as port may have different clock rate
+ * than the bridge.
+ */
+ frame.timestamp.u64 = timestamp->u64 * cport->clock_rate /
+ conf->clock_rate;
+
+ /* Add timestamp for individual frame */
+ frame.timestamp.u64 += ts;
+ ts += cport->samples_per_frame;
+
+ TRACE_((THIS_FILE, "put_frame %.*s, count=%d",
+ (int)cport->name.slen, cport->name.ptr,
+ frame.size / BYTES_PER_SAMPLE));
+
+ status = pjmedia_port_put_frame(cport->port, &frame);
+
+ } else
+ status = PJ_SUCCESS;
+
+ cport->tx_buf_count -= cport->samples_per_frame;
+ if (cport->tx_buf_count) {
+ pjmedia_move_samples(cport->tx_buf,
+ cport->tx_buf + cport->samples_per_frame,
+ cport->tx_buf_count);
+ }
+
+ TRACE_((THIS_FILE, " tx_buf count now is %d",
+ cport->tx_buf_count));
+ }
+
+ return status;
+}
+
+
+/*
+ * Player callback.
+ */
+static pj_status_t get_frame(pjmedia_port *this_port,
+ pjmedia_frame *frame)
+{
+ pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata;
+ pjmedia_frame_type speaker_frame_type = PJMEDIA_FRAME_TYPE_NONE;
+ unsigned ci, cj, i, j;
+ pj_int16_t *p_in;
+
+ TRACE_((THIS_FILE, "- clock -"));
+
+ /* Check that correct size is specified. */
+ pj_assert(frame->size == conf->samples_per_frame *
+ conf->bits_per_sample / 8);
+
+ /* Must lock mutex */
+ pj_mutex_lock(conf->mutex);
+
+ /* Reset port source count. We will only reset port's mix
+ * buffer when we have someone transmitting to it.
+ */
+ for (i=0, ci=0; i<conf->max_ports && ci < conf->port_cnt; ++i) {
+ struct conf_port *conf_port = conf->ports[i];
+
+ /* Skip empty port. */
+ if (!conf_port)
+ continue;
+
+ /* Var "ci" is to count how many ports have been visited so far. */
+ ++ci;
+
+ /* Reset buffer (only necessary if the port has transmitter) and
+ * reset auto adjustment level for mixed signal.
+ */
+ conf_port->mix_adj = NORMAL_LEVEL;
+ if (conf_port->transmitter_cnt) {
+ pj_bzero(conf_port->mix_buf,
+ conf->samples_per_frame*sizeof(conf_port->mix_buf[0]));
+ }
+ }
+
+ /* Get frames from all ports, and "mix" the signal
+ * to mix_buf of all listeners of the port.
+ */
+ for (i=0, ci=0; i < conf->max_ports && ci < conf->port_cnt; ++i) {
+ struct conf_port *conf_port = conf->ports[i];
+ pj_int32_t level = 0;
+
+ /* Skip empty port. */
+ if (!conf_port)
+ continue;
+
+ /* Var "ci" is to count how many ports have been visited so far. */
+ ++ci;
+
+ /* Skip if we're not allowed to receive from this port. */
+ if (conf_port->rx_setting == PJMEDIA_PORT_DISABLE) {
+ conf_port->rx_level = 0;
+ continue;
+ }
+
+ /* Also skip if this port doesn't have listeners. */
+ if (conf_port->listener_cnt == 0) {
+ conf_port->rx_level = 0;
+ continue;
+ }
+
+ /* Get frame from this port.
+ * For passive ports, get the frame from the delay_buf.
+ * For other ports, get the frame from the port.
+ */
+ if (conf_port->delay_buf != NULL) {
+ pj_status_t status;
+
+ status = pjmedia_delay_buf_get(conf_port->delay_buf,
+ (pj_int16_t*)frame->buf);
+ if (status != PJ_SUCCESS)
+ continue;
+
+ } else {
+
+ pj_status_t status;
+ pjmedia_frame_type frame_type;
+
+ status = read_port(conf, conf_port, (pj_int16_t*)frame->buf,
+ conf->samples_per_frame, &frame_type);
+
+ if (status != PJ_SUCCESS) {
+ /* bennylp: why do we need this????
+ * Also see comments on similar issue with write_port().
+ PJ_LOG(4,(THIS_FILE, "Port %.*s get_frame() returned %d. "
+ "Port is now disabled",
+ (int)conf_port->name.slen,
+ conf_port->name.ptr,
+ status));
+ conf_port->rx_setting = PJMEDIA_PORT_DISABLE;
+ */
+ continue;
+ }
+
+ /* Check that the port is not removed when we call get_frame() */
+ if (conf->ports[i] == NULL)
+ continue;
+
+ /* Ignore if we didn't get any frame */
+ if (frame_type != PJMEDIA_FRAME_TYPE_AUDIO)
+ continue;
+ }
+
+ p_in = (pj_int16_t*) frame->buf;
+
+ /* Adjust the RX level from this port
+ * and calculate the average level at the same time.
+ */
+ if (conf_port->rx_adj_level != NORMAL_LEVEL) {
+ for (j=0; j<conf->samples_per_frame; ++j) {
+ /* For the level adjustment, we need to store the sample to
+ * a temporary 32bit integer value to avoid overflowing the
+ * 16bit sample storage.
+ */
+ pj_int32_t itemp;
+
+ itemp = p_in[j];
+ /*itemp = itemp * adj / NORMAL_LEVEL;*/
+ /* bad code (signed/unsigned badness):
+ * itemp = (itemp * conf_port->rx_adj_level) >> 7;
+ */
+ itemp *= conf_port->rx_adj_level;
+ itemp >>= 7;
+
+ /* Clip the signal if it's too loud */
+ if (itemp > MAX_LEVEL) itemp = MAX_LEVEL;
+ else if (itemp < MIN_LEVEL) itemp = MIN_LEVEL;
+
+ p_in[j] = (pj_int16_t) itemp;
+ level += (p_in[j]>=0? p_in[j] : -p_in[j]);
+ }
+ } else {
+ for (j=0; j<conf->samples_per_frame; ++j) {
+ level += (p_in[j]>=0? p_in[j] : -p_in[j]);
+ }
+ }
+
+ level /= conf->samples_per_frame;
+
+ /* Convert level to 8bit complement ulaw */
+ level = pjmedia_linear2ulaw(level) ^ 0xff;
+
+ /* Put this level to port's last RX level. */
+ conf_port->rx_level = level;
+
+ // Ticket #671: Skipping very low audio signal may cause noise
+ // to be generated in the remote end by some hardphones.
+ /* Skip processing frame if level is zero */
+ //if (level == 0)
+ // continue;
+
+ /* Add the signal to all listeners. */
+ for (cj=0; cj < conf_port->listener_cnt; ++cj)
+ {
+ struct conf_port *listener;
+ pj_int32_t *mix_buf;
+ unsigned k;
+
+ listener = conf->ports[conf_port->listener_slots[cj]];
+
+ /* Skip if this listener doesn't want to receive audio */
+ if (listener->tx_setting != PJMEDIA_PORT_ENABLE)
+ continue;
+
+ mix_buf = listener->mix_buf;
+
+ if (listener->transmitter_cnt > 1) {
+ /* Mixing signals,
+ * and calculate appropriate level adjustment if there is
+ * any overflowed level in the mixed signal.
+ */
+ for (k=0; k < conf->samples_per_frame; ++k) {
+ mix_buf[k] += p_in[k];
+ /* Check if normalization adjustment needed. */
+ if (IS_OVERFLOW(mix_buf[k])) {
+ /* NORMAL_LEVEL * MAX_LEVEL / mix_buf[k]; */
+ int tmp_adj = (MAX_LEVEL<<7) / mix_buf[k];
+ if (tmp_adj<0) tmp_adj = -tmp_adj;
+
+ if (tmp_adj<listener->mix_adj)
+ listener->mix_adj = tmp_adj;
+
+ } /* if any overflow in the mixed signals */
+ } /* loop mixing signals */
+ } else {
+ /* Only 1 transmitter:
+ * just copy the samples to the mix buffer
+ * no mixing and level adjustment needed
+ */
+ for (k=0; k<conf->samples_per_frame; ++k) {
+ mix_buf[k] = p_in[k];
+ }
+ }
+ } /* loop the listeners of conf port */
+ } /* loop of all conf ports */
+
+ /* Time for all ports to transmit whetever they have in their
+ * buffer.
+ */
+ for (i=0, ci=0; i<conf->max_ports && ci<conf->port_cnt; ++i) {
+ struct conf_port *conf_port = conf->ports[i];
+ pjmedia_frame_type frm_type;
+ pj_status_t status;
+
+ if (!conf_port)
+ continue;
+
+ /* Var "ci" is to count how many ports have been visited. */
+ ++ci;
+
+ status = write_port( conf, conf_port, &frame->timestamp,
+ &frm_type);
+ if (status != PJ_SUCCESS) {
+ /* bennylp: why do we need this????
+ One thing for sure, put_frame()/write_port() may return
+ non-successfull status on Win32 if there's temporary glitch
+ on network interface, so disabling the port here does not
+ sound like a good idea.
+
+ PJ_LOG(4,(THIS_FILE, "Port %.*s put_frame() returned %d. "
+ "Port is now disabled",
+ (int)conf_port->name.slen,
+ conf_port->name.ptr,
+ status));
+ conf_port->tx_setting = PJMEDIA_PORT_DISABLE;
+ */
+ continue;
+ }
+
+ /* Set the type of frame to be returned to sound playback
+ * device.
+ */
+ if (i == 0)
+ speaker_frame_type = frm_type;
+ }
+
+ /* Return sound playback frame. */
+ if (conf->ports[0]->tx_level) {
+ TRACE_((THIS_FILE, "write to audio, count=%d",
+ conf->samples_per_frame));
+ pjmedia_copy_samples( (pj_int16_t*)frame->buf,
+ (const pj_int16_t*)conf->ports[0]->mix_buf,
+ conf->samples_per_frame);
+ } else {
+ /* Force frame type NONE */
+ speaker_frame_type = PJMEDIA_FRAME_TYPE_NONE;
+ }
+
+ /* MUST set frame type */
+ frame->type = speaker_frame_type;
+
+ pj_mutex_unlock(conf->mutex);
+
+#ifdef REC_FILE
+ if (fhnd_rec == NULL)
+ fhnd_rec = fopen(REC_FILE, "wb");
+ if (fhnd_rec)
+ fwrite(frame->buf, frame->size, 1, fhnd_rec);
+#endif
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * get_frame() for passive port
+ */
+static pj_status_t get_frame_pasv(pjmedia_port *this_port,
+ pjmedia_frame *frame)
+{
+ pj_assert(0);
+ PJ_UNUSED_ARG(this_port);
+ PJ_UNUSED_ARG(frame);
+ return -1;
+}
+
+
+/*
+ * Recorder (or passive port) callback.
+ */
+static pj_status_t put_frame(pjmedia_port *this_port,
+ pjmedia_frame *frame)
+{
+ pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata;
+ struct conf_port *port = conf->ports[this_port->port_data.ldata];
+ pj_status_t status;
+
+ /* Check for correct size. */
+ PJ_ASSERT_RETURN( frame->size == conf->samples_per_frame *
+ conf->bits_per_sample / 8,
+ PJMEDIA_ENCSAMPLESPFRAME);
+
+ /* Check existance of delay_buf instance */
+ PJ_ASSERT_RETURN( port->delay_buf, PJ_EBUG );
+
+ /* Skip if this port is muted/disabled. */
+ if (port->rx_setting != PJMEDIA_PORT_ENABLE) {
+ return PJ_SUCCESS;
+ }
+
+ /* Skip if no port is listening to the microphone */
+ if (port->listener_cnt == 0) {
+ return PJ_SUCCESS;
+ }
+
+ status = pjmedia_delay_buf_put(port->delay_buf, (pj_int16_t*)frame->buf);
+
+ return status;
+}
+
+#endif
diff --git a/jni/pjproject-android/.svn/pristine/f1/f166252bcb46475aef827e128af7d0ccc6403492.svn-base b/jni/pjproject-android/.svn/pristine/f1/f166252bcb46475aef827e128af7d0ccc6403492.svn-base
new file mode 100644
index 0000000..12ca4aa
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f1/f166252bcb46475aef827e128af7d0ccc6403492.svn-base
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>$title ($projectnumber)</title>
+<link href="/style/style.css" rel="stylesheet" type="text/css">
+</head><body>
+ <!--#include virtual="/header.html" -->
+ <p><A HREF="/">Home</A> --> <A HREF="/docs.htm">Documentations</A> --> PJLIB-UTIL Reference</p>
+
+
diff --git a/jni/pjproject-android/.svn/pristine/f1/f166479d55886b7f8aac94564122ed8167322012.svn-base b/jni/pjproject-android/.svn/pristine/f1/f166479d55886b7f8aac94564122ed8167322012.svn-base
new file mode 100644
index 0000000..e96f2a3
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f1/f166479d55886b7f8aac94564122ed8167322012.svn-base
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<scenario name="Basic UAS responder">
+ <recv request="INVITE" crlf="true">
+ </recv>
+
+ <send>
+ <![CDATA[
+
+ SIP/2.0 100 Trying
+ [last_Via:]
+ [last_From:]
+ [last_To:]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <send>
+ <![CDATA[
+
+ SIP/2.0 180 Ringing
+ [last_Via:]
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: <sip:192.168.0.15>
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <!-- Wait for CANCEL -->
+ <recv request="CANCEL" crlf="true">
+ </recv>
+
+ <send>
+ <![CDATA[
+ SIP/2.0 200 OK
+ [last_Via:]
+ [last_From:]
+ [last_To:]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+
+ <!-- definition of the response time repartition table (unit is ms) -->
+ <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+ <!-- definition of the call length repartition table (unit is ms) -->
+ <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+
diff --git a/jni/pjproject-android/.svn/pristine/f1/f17f6c7ddb7a1df1de25dac8854e3508e38dd2df.svn-base b/jni/pjproject-android/.svn/pristine/f1/f17f6c7ddb7a1df1de25dac8854e3508e38dd2df.svn-base
new file mode 100644
index 0000000..5ae855f
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f1/f17f6c7ddb7a1df1de25dac8854e3508e38dd2df.svn-base
@@ -0,0 +1,53 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "speex/speex_echo.h"
+#include "speex/speex_preprocess.h"
+
+
+#define NN 128
+#define TAIL 1024
+
+int main(int argc, char **argv)
+{
+ FILE *echo_fd, *ref_fd, *e_fd;
+ short echo_buf[NN], ref_buf[NN], e_buf[NN];
+ SpeexEchoState *st;
+ SpeexPreprocessState *den;
+ int sampleRate = 8000;
+
+ if (argc != 4)
+ {
+ fprintf(stderr, "testecho mic_signal.sw speaker_signal.sw output.sw\n");
+ exit(1);
+ }
+ echo_fd = fopen(argv[2], "rb");
+ ref_fd = fopen(argv[1], "rb");
+ e_fd = fopen(argv[3], "wb");
+
+ st = speex_echo_state_init(NN, TAIL);
+ den = speex_preprocess_state_init(NN, sampleRate);
+ speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate);
+ speex_preprocess_ctl(den, SPEEX_PREPROCESS_SET_ECHO_STATE, st);
+
+ while (!feof(ref_fd) && !feof(echo_fd))
+ {
+ fread(ref_buf, sizeof(short), NN, ref_fd);
+ fread(echo_buf, sizeof(short), NN, echo_fd);
+ speex_echo_cancellation(st, ref_buf, echo_buf, e_buf);
+ speex_preprocess_run(den, e_buf);
+ fwrite(e_buf, sizeof(short), NN, e_fd);
+ }
+ speex_echo_state_destroy(st);
+ speex_preprocess_state_destroy(den);
+ fclose(e_fd);
+ fclose(echo_fd);
+ fclose(ref_fd);
+ return 0;
+}
diff --git a/jni/pjproject-android/.svn/pristine/f1/f186e392ce745e27c7ae7f71490a5a4b39545786.svn-base b/jni/pjproject-android/.svn/pristine/f1/f186e392ce745e27c7ae7f71490a5a4b39545786.svn-base
new file mode 100644
index 0000000..70bf6f7
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f1/f186e392ce745e27c7ae7f71490a5a4b39545786.svn-base
@@ -0,0 +1,1033 @@
+# Doxyfile 1.3-rc3
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# General configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = "PJNATH Reference"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = $(PJ_VERSION)
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = docs/$(PJ_VERSION)
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch,
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en
+# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese,
+# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these class will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = NO
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
+# members of a class in the documentation of that class as if those members were
+# ordinary class members. Constructors, destructors and assignment operators of
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH = "c:\project\pjproject"
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower case letters. If set to YES upper case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# users are adviced to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explict @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# reimplements.
+
+INHERIT_DOCS = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consist of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C.
+# For instance some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
+# only. Doxygen will then generate output that is more tailored for Java.
+# For instance namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+TYPEDEF_HIDES_STRUCT = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = docs include/pjnath
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
+# *.h++ *.idl *.odl
+
+FILE_PATTERNS = *.h *.c
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+
+EXCLUDE_PATTERNS = "*_i.h" "*/compat/*"
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH = ../pjsip-apps/src/samples src/pjturn-client
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = YES
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH = docs
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+
+INPUT_FILTER =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .htm
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER = docs/header.html
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER = docs/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet
+
+HTML_STYLESHEET = docs/doxygen.css
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output dir.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non empty doxygen will try to run
+# the html help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the Html help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 1
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimised for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assigments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_XML = NO
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed.
+
+PREDEFINED = PJ_DECL(x)=x PJ_DEF(x)=x PJ_IDECL(x)=x \
+ PJ_IDEF(x)=x PJ_INLINE(x)=x \
+ PJ_DECL_NO_RETURN(x)=x \
+ PJ_HAS_HIGH_RES_TIMER=1 \
+ PJ_LOG_MAX_LEVEL=4 \
+ PJ_HAS_SEMAPHORE=1 \
+ PJ_HAS_EVENT_OBJ=1
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse the
+# parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tagfiles.
+
+TAGFILES = ../pjlib/docs/pjlib.tag=../../../pjlib/docs/html ../pjlib-util/docs/pjlib-util.tag=../../../pjlib-util/docs/html ../pjsip/docs/pjsip.tag=../../../pjsip/docs/html ../pjmedia/docs/pjmedia.tag=../../../pjmedia/docs/html
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE = ../pjnath/docs/pjnath.tag
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = NO
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+#PERL_PATH = /usr/bin/perl
+PERL_PATH = /c/Perl/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off. Note that this
+# option is superceded by the HAVE_DOT option below. This is only a fallback. It is
+# recommended to install and use dot, since it yield more powerful graphs.
+
+CLASS_DIAGRAMS = NO
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermedate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
+
+# The CGI_NAME tag should be the name of the CGI script that
+# starts the search engine (doxysearch) with the correct parameters.
+# A script with this name will be generated by doxygen.
+
+#CGI_NAME = search.cgi
+
+# The CGI_URL tag should be the absolute URL to the directory where the
+# cgi binaries are located. See the documentation of your http daemon for
+# details.
+
+#CGI_URL =
+
+# The DOC_URL tag should be the absolute URL to the directory where the
+# documentation is located. If left blank the absolute path to the
+# documentation, with file:// prepended to it, will be used.
+
+#DOC_URL =
+
+# The DOC_ABSPATH tag should be the absolute path to the directory where the
+# documentation is located. If left blank the directory on the local machine
+# will be used.
+
+#DOC_ABSPATH =
+
+# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
+# is installed.
+
+#BIN_ABSPATH = /usr/local/bin/
+
+# The EXT_DOC_PATHS tag can be used to specify one or more paths to
+# documentation generated for other projects. This allows doxysearch to search
+# the documentation for these projects as well.
+
+#EXT_DOC_PATHS =
diff --git a/jni/pjproject-android/.svn/pristine/f1/f19c90785b4afe174feff5747d7d650037830992.svn-base b/jni/pjproject-android/.svn/pristine/f1/f19c90785b4afe174feff5747d7d650037830992.svn-base
new file mode 100644
index 0000000..309459b
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f1/f19c90785b4afe174feff5747d7d650037830992.svn-base
@@ -0,0 +1,349 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include <pj/pool.h>
+#include "test.h"
+
+#define JB_INIT_PREFETCH 0
+#define JB_MIN_PREFETCH 0
+#define JB_MAX_PREFETCH 10
+#define JB_PTIME 20
+#define JB_BUF_SIZE 50
+
+//#define REPORT
+//#define PRINT_COMMENT
+
+typedef struct test_param_t {
+ pj_bool_t adaptive;
+ unsigned init_prefetch;
+ unsigned min_prefetch;
+ unsigned max_prefetch;
+} test_param_t;
+
+typedef struct test_cond_t {
+ int burst;
+ int discard;
+ int lost;
+ int empty;
+ int delay; /**< Average delay, in frames. */
+ int delay_min; /**< Minimum delay, in frames. */
+} test_cond_t;
+
+static pj_bool_t parse_test_headers(char *line, test_param_t *param,
+ test_cond_t *cond)
+{
+ char *p = line;
+
+ if (*p == '%') {
+ /* Test params. */
+ char mode_st[16];
+
+ sscanf(p+1, "%s %u %u %u", mode_st, ¶m->init_prefetch,
+ ¶m->min_prefetch, ¶m->max_prefetch);
+ param->adaptive = (pj_ansi_stricmp(mode_st, "adaptive") == 0);
+
+ } else if (*p == '!') {
+ /* Success condition. */
+ char cond_st[16];
+ unsigned cond_val;
+
+ sscanf(p+1, "%s %u", cond_st, &cond_val);
+ if (pj_ansi_stricmp(cond_st, "burst") == 0)
+ cond->burst = cond_val;
+ else if (pj_ansi_stricmp(cond_st, "delay") == 0)
+ cond->delay = cond_val;
+ else if (pj_ansi_stricmp(cond_st, "delay_min") == 0)
+ cond->delay_min = cond_val;
+ else if (pj_ansi_stricmp(cond_st, "discard") == 0)
+ cond->discard = cond_val;
+ else if (pj_ansi_stricmp(cond_st, "empty") == 0)
+ cond->empty = cond_val;
+ else if (pj_ansi_stricmp(cond_st, "lost") == 0)
+ cond->lost = cond_val;
+
+ } else if (*p == '=') {
+ /* Test title. */
+ ++p;
+ while (*p && isspace(*p)) ++p;
+ printf("%s", p);
+
+ } else if (*p == '#') {
+ /* Ignore comment line. */
+
+ } else {
+ /* Unknown header, perhaps this is the test data */
+
+ /* Skip spaces */
+ while (*p && isspace(*p)) ++p;
+
+ /* Test data started.*/
+ if (*p != 0)
+ return PJ_FALSE;
+ }
+
+ return PJ_TRUE;
+}
+
+static pj_bool_t process_test_data(char data, pjmedia_jbuf *jb,
+ pj_uint16_t *seq, pj_uint16_t *last_seq)
+{
+ char frame[1];
+ char f_type;
+ pj_bool_t print_state = PJ_TRUE;
+ pj_bool_t data_eos = PJ_FALSE;
+
+ switch (toupper(data)) {
+ case 'G': /* Get */
+ pjmedia_jbuf_get_frame(jb, frame, &f_type);
+ break;
+ case 'P': /* Put */
+ pjmedia_jbuf_put_frame(jb, (void*)frame, 1, *seq);
+ *last_seq = *seq;
+ ++*seq;
+ break;
+ case 'L': /* Lost */
+ *last_seq = *seq;
+ ++*seq;
+ printf("Lost\n");
+ break;
+ case 'R': /* Sequence restarts */
+ *seq = 1;
+ printf("Sequence restarting, from %u to %u\n", *last_seq, *seq);
+ break;
+ case 'J': /* Sequence jumps */
+ (*seq) += 20;
+ printf("Sequence jumping, from %u to %u\n", *last_seq, *seq);
+ break;
+ case 'D': /* Frame duplicated */
+ pjmedia_jbuf_put_frame(jb, (void*)frame, 1, *seq - 1);
+ break;
+ case 'O': /* Old/late frame */
+ pjmedia_jbuf_put_frame(jb, (void*)frame, 1, *seq - 10 - pj_rand()%40);
+ break;
+ case '.': /* End of test session. */
+ data_eos = PJ_TRUE;
+ break;
+ default:
+ print_state = PJ_FALSE;
+ printf("Unknown test data '%c'\n", data);
+ break;
+ }
+
+ if (data_eos)
+ return PJ_FALSE;
+
+#ifdef REPORT
+ if (print_state) {
+ pjmedia_jb_state state;
+
+ pjmedia_jbuf_get_state(jb, &state);
+ printf("seq=%d\t%c\tsize=%d\tprefetch=%d\n",
+ *last_seq, toupper(data), state.size, state.prefetch);
+ }
+#endif
+
+ return PJ_TRUE;
+}
+
+int jbuf_main(void)
+{
+ FILE *input;
+ pj_bool_t data_eof = PJ_FALSE;
+ int old_log_level;
+ int rc = 0;
+ const char* input_filename = "Jbtest.dat";
+ const char* input_search_path[] = {
+ "../build",
+ "pjmedia/build",
+ "build"
+ };
+
+ /* Try to open test data file in the working directory */
+ input = fopen(input_filename, "rt");
+
+ /* If that fails, try to open test data file in specified search paths */
+ if (input == NULL) {
+ char input_path[PJ_MAXPATH];
+ int i;
+
+ for (i = 0; !input && i < PJ_ARRAY_SIZE(input_search_path); ++i) {
+ pj_ansi_snprintf(input_path, PJ_MAXPATH, "%s/%s",
+ input_search_path[i],
+ input_filename);
+ input = fopen(input_path, "rt");
+ }
+ }
+
+ /* Failed to open test data file. */
+ if (input == NULL) {
+ printf("Failed to open test data file, Jbtest.dat\n");
+ return -1;
+ }
+
+ old_log_level = pj_log_get_level();
+ pj_log_set_level(5);
+
+ while (rc == 0 && !data_eof) {
+ pj_str_t jb_name = {"JBTEST", 6};
+ pjmedia_jbuf *jb;
+ pj_pool_t *pool;
+ pjmedia_jb_state state;
+ pj_uint16_t last_seq = 0;
+ pj_uint16_t seq = 1;
+ char line[1024], *p = NULL;
+
+ test_param_t param;
+ test_cond_t cond;
+
+ param.adaptive = PJ_TRUE;
+ param.init_prefetch = JB_INIT_PREFETCH;
+ param.min_prefetch = JB_MIN_PREFETCH;
+ param.max_prefetch = JB_MAX_PREFETCH;
+
+ cond.burst = -1;
+ cond.delay = -1;
+ cond.delay_min = -1;
+ cond.discard = -1;
+ cond.empty = -1;
+ cond.lost = -1;
+
+ printf("\n\n");
+
+ /* Parse test session title, param, and conditions */
+ do {
+ p = fgets(line, sizeof(line), input);
+ } while (p && parse_test_headers(line, ¶m, &cond));
+
+ /* EOF test data */
+ if (p == NULL)
+ break;
+
+ //printf("======================================================\n");
+
+ /* Initialize test session */
+ pool = pj_pool_create(mem, "JBPOOL", 256*16, 256*16, NULL);
+ pjmedia_jbuf_create(pool, &jb_name, 1, JB_PTIME, JB_BUF_SIZE, &jb);
+ pjmedia_jbuf_reset(jb);
+
+ if (param.adaptive) {
+ pjmedia_jbuf_set_adaptive(jb,
+ param.init_prefetch,
+ param.min_prefetch,
+ param.max_prefetch);
+ } else {
+ pjmedia_jbuf_set_fixed(jb, param.init_prefetch);
+ }
+
+#ifdef REPORT
+ pjmedia_jbuf_get_state(jb, &state);
+ printf("Initial\tsize=%d\tprefetch=%d\tmin.pftch=%d\tmax.pftch=%d\n",
+ state.size, state.prefetch, state.min_prefetch,
+ state.max_prefetch);
+#endif
+
+
+ /* Test session start */
+ while (1) {
+ char c;
+
+ /* Get next line of test data */
+ if (!p || *p == 0) {
+ p = fgets(line, sizeof(line), input);
+ if (p == NULL) {
+ data_eof = PJ_TRUE;
+ break;
+ }
+ }
+
+ /* Get next char of test data */
+ c = *p++;
+
+ /* Skip spaces */
+ if (isspace(c))
+ continue;
+
+ /* Print comment line */
+ if (c == '#') {
+#ifdef PRINT_COMMENT
+ while (*p && isspace(*p)) ++p;
+ if (*p) printf("..%s", p);
+#endif
+ *p = 0;
+ continue;
+ }
+
+ /* Process test data */
+ if (!process_test_data(c, jb, &seq, &last_seq))
+ break;
+ }
+
+ /* Print JB states */
+ pjmedia_jbuf_get_state(jb, &state);
+ printf("------------------------------------------------------\n");
+ printf("Summary:\n");
+ printf(" size=%d prefetch=%d\n", state.size, state.prefetch);
+ printf(" delay (min/max/avg/dev)=%d/%d/%d/%d ms\n",
+ state.min_delay, state.max_delay, state.avg_delay,
+ state.dev_delay);
+ printf(" lost=%d discard=%d empty=%d burst(avg)=%d\n",
+ state.lost, state.discard, state.empty, state.avg_burst);
+
+ /* Evaluate test session */
+ if (cond.burst >= 0 && (int)state.avg_burst > cond.burst) {
+ printf("! 'Burst' should be %d, it is %d\n",
+ cond.burst, state.avg_burst);
+ rc |= 1;
+ }
+ if (cond.delay >= 0 && (int)state.avg_delay/JB_PTIME > cond.delay) {
+ printf("! 'Delay' should be %d, it is %d\n",
+ cond.delay, state.avg_delay/JB_PTIME);
+ rc |= 2;
+ }
+ if (cond.delay_min >= 0 && (int)state.min_delay/JB_PTIME > cond.delay_min) {
+ printf("! 'Minimum delay' should be %d, it is %d\n",
+ cond.delay_min, state.min_delay/JB_PTIME);
+ rc |= 32;
+ }
+ if (cond.discard >= 0 && (int)state.discard > cond.discard) {
+ printf("! 'Discard' should be %d, it is %d\n",
+ cond.discard, state.discard);
+ rc |= 4;
+ }
+ if (cond.empty >= 0 && (int)state.empty > cond.empty) {
+ printf("! 'Empty' should be %d, it is %d\n",
+ cond.empty, state.empty);
+ rc |= 8;
+ }
+ if (cond.lost >= 0 && (int)state.lost > cond.lost) {
+ printf("! 'Lost' should be %d, it is %d\n",
+ cond.lost, state.lost);
+ rc |= 16;
+ }
+
+ pjmedia_jbuf_destroy(jb);
+ pj_pool_release(pool);
+ }
+
+ fclose(input);
+ pj_log_set_level(old_log_level);
+
+ return rc;
+}
diff --git a/jni/pjproject-android/.svn/pristine/f1/f1b629c31cb2499d2884f6defd74e077800602dc.svn-base b/jni/pjproject-android/.svn/pristine/f1/f1b629c31cb2499d2884f6defd74e077800602dc.svn-base
new file mode 100644
index 0000000..189eb00
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f1/f1b629c31cb2499d2884f6defd74e077800602dc.svn-base
@@ -0,0 +1,21 @@
+#Modify this to point to the PJSIP location.
+PJBASE=~/Desktop/project/pjproject
+
+include $(PJBASE)/build.mak
+
+CC = $(APP_CC)
+LDFLAGS = $(APP_LDFLAGS)
+LDLIBS = $(APP_LDLIBS)
+CFLAGS = $(APP_CFLAGS)
+CPPFLAGS= ${CFLAGS}
+
+# If your application is in a file named myapp.cpp or myapp.c
+# # this is the line you will need to build the binary.
+# all: myapp
+#
+cmp_wav: cmp_wav.c
+ $(CC) -o $@ $< $(CPPFLAGS) $(LDFLAGS) $(LDLIBS)
+
+clean:
+ rm -f cmp_wav.o cmp_wav
+
diff --git a/jni/pjproject-android/.svn/pristine/f1/f1d1d45e09f609a4afb70fce26c077cf2fd3d93b.svn-base b/jni/pjproject-android/.svn/pristine/f1/f1d1d45e09f609a4afb70fce26c077cf2fd3d93b.svn-base
new file mode 100644
index 0000000..a80cfeb
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f1/f1d1d45e09f609a4afb70fce26c077cf2fd3d93b.svn-base
@@ -0,0 +1,33 @@
+TARGET pjmedia_audiodev.lib
+TARGETTYPE lib
+
+SOURCEPATH ..\pjmedia\src\pjmedia-audiodev
+
+//
+// GCCE optimization setting
+//
+//OPTION GCCE -O2 -fno-unit-at-a-time
+OPTION ARMCC --gnu
+
+MACRO PJ_M_I386=1
+MACRO PJ_SYMBIAN=1
+
+SOURCE audiodev.c
+SOURCE errno.c
+SOURCE symb_aps_dev.cpp
+SOURCE symb_mda_dev.cpp
+SOURCE symb_vas_dev.cpp
+SOURCE null_dev.c
+
+SYSTEMINCLUDE ..\pjmedia\include
+SYSTEMINCLUDE ..\pjlib\include
+SYSTEMINCLUDE ..\pjlib-util\include
+
+SYSTEMINCLUDE \epoc32\include
+SYSTEMINCLUDE \epoc32\include\libc
+SYSTEMINCLUDE \epoc32\include\mmf\server
+SYSTEMINCLUDE \epoc32\include\mmf\common
+SYSTEMINCLUDE \epoc32\include\mda\common
+SYSTEMINCLUDE \epoc32\include\mmf\plugin
+
+
diff --git a/jni/pjproject-android/.svn/pristine/f1/f1f60ed301d8cac478d341dca0b456d789a398f1.svn-base b/jni/pjproject-android/.svn/pristine/f1/f1f60ed301d8cac478d341dca0b456d789a398f1.svn-base
new file mode 100644
index 0000000..eb0e390
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f1/f1f60ed301d8cac478d341dca0b456d789a398f1.svn-base
@@ -0,0 +1,78 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/*
+ * Based on implementation found in Carnegie Mellon Speech Group Software
+ * depository (ftp://ftp.cs.cmu.edu/project/fgdata/index.html). No copyright
+ * was claimed in the original source codes.
+ */
+#ifndef __PJMEDIA_CODEC_G722_ENC_H__
+#define __PJMEDIA_CODEC_G722_ENC_H__
+
+#include <pjmedia-codec/types.h>
+
+/* Encoder state */
+typedef struct g722_enc_t {
+ /* PCM low band */
+ int slow;
+ int detlow;
+ int spl;
+ int szl;
+ int rlt [3];
+ int al [3];
+ int apl [3];
+ int plt [3];
+ int dlt [7];
+ int bl [7];
+ int bpl [7];
+ int sgl [7];
+ int nbl;
+
+ /* PCM high band*/
+ int shigh;
+ int dethigh;
+ int sph;
+ int szh;
+ int rh [3];
+ int ah [3];
+ int aph [3];
+ int ph [3];
+ int dh [7];
+ int bh [7];
+ int bph [7];
+ int sgh [7];
+ int nbh;
+
+ /* QMF signal history */
+ int x[24];
+} g722_enc_t;
+
+
+PJ_DECL(pj_status_t) g722_enc_init(g722_enc_t *enc);
+
+PJ_DECL(pj_status_t) g722_enc_encode(g722_enc_t *enc,
+ pj_int16_t in[],
+ pj_size_t nsamples,
+ void *out,
+ pj_size_t *out_size);
+
+PJ_DECL(pj_status_t) g722_enc_deinit(g722_enc_t *enc);
+
+#endif /* __PJMEDIA_CODEC_G722_ENC_H__ */
+