Index: /pjproject/trunk/pjmedia/build/pjmedia.dsp
===================================================================
--- /pjproject/trunk/pjmedia/build/pjmedia.dsp	(revision 221)
+++ /pjproject/trunk/pjmedia/build/pjmedia.dsp	(revision 222)
@@ -109,4 +109,8 @@
 # Begin Source File
 
+SOURCE=..\src\pjmedia\file_port.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\src\pjmedia\g711.c
 # End Source File
@@ -194,4 +198,8 @@
 # Begin Source File
 
+SOURCE=..\include\pjmedia\file_port.h
+# End Source File
+# Begin Source File
+
 SOURCE=..\include\pjmedia\jbuf.h
 # End Source File
@@ -243,4 +251,8 @@
 
 SOURCE=..\include\pjmedia\vad.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjmedia\wave.h
 # End Source File
 # End Group
Index: /pjproject/trunk/pjmedia/include/pjmedia.h
===================================================================
--- /pjproject/trunk/pjmedia/include/pjmedia.h	(revision 221)
+++ /pjproject/trunk/pjmedia/include/pjmedia.h	(revision 222)
@@ -30,4 +30,5 @@
 #include <pjmedia/endpoint.h>
 #include <pjmedia/errno.h>
+#include <pjmedia/file_port.h>
 #include <pjmedia/jbuf.h>
 #include <pjmedia/port.h>
@@ -38,4 +39,5 @@
 #include <pjmedia/session.h>
 #include <pjmedia/sound.h>
+#include <pjmedia/wave.h>
 
 #endif	/* __PJMEDIA_H__ */
Index: /pjproject/trunk/pjmedia/include/pjmedia/conference.h
===================================================================
--- /pjproject/trunk/pjmedia/include/pjmedia/conference.h	(revision 221)
+++ /pjproject/trunk/pjmedia/include/pjmedia/conference.h	(revision 222)
@@ -41,4 +41,5 @@
 typedef struct pjmedia_conf_port_info
 {
+    unsigned		slot;
     pj_str_t		name;
     pjmedia_port_op	tx_setting;
@@ -151,8 +152,30 @@
 /**
  * Get port info.
+ *
+ * @param conf		The conference bridge.
+ * @param slot		Port index.
+ * @param info		Pointer to receive the info.
+ *
+ * @return		PJ_SUCCESS on success.
  */
 PJ_DECL(pj_status_t) pjmedia_conf_get_port_info( pjmedia_conf *conf,
 						 unsigned slot,
 						 pjmedia_conf_port_info *info);
+
+
+/**
+ * Get occupied ports info.
+ *
+ * @param conf		The conference bridge.
+ * @param size		On input, contains maximum number of infos
+ *			to be retrieved. On output, contains the actual
+ *			number of infos that have been copied.
+ * @param info		Array of info.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_get_ports_info(pjmedia_conf *conf,
+						 unsigned *size,
+						 pjmedia_conf_port_info info[]);
 
 
Index: /pjproject/trunk/pjmedia/include/pjmedia/errno.h
===================================================================
--- /pjproject/trunk/pjmedia/include/pjmedia/errno.h	(revision 221)
+++ /pjproject/trunk/pjmedia/include/pjmedia/errno.h	(revision 222)
@@ -407,4 +407,23 @@
 
 
+/************************************************************
+ * FILE ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Not a valid WAVE file.
+ */
+#define PJMEDIA_ENOTVALIDWAVE	    (PJMEDIA_ERRNO_START+180)    /* 220180 */
+/**
+ * @hideinitializer
+ * Unsupported WAVE file.
+ */
+#define PJMEDIA_EWAVEUNSUPP	    (PJMEDIA_ERRNO_START+181)    /* 220181 */
+/**
+ * @hideinitializer
+ * Wave file too short.
+ */
+#define PJMEDIA_EWAVETOOSHORT	    (PJMEDIA_ERRNO_START+182)    /* 220182 */
+
 
 PJ_END_DECL
Index: /pjproject/trunk/pjmedia/include/pjmedia/file_port.h
===================================================================
--- /pjproject/trunk/pjmedia/include/pjmedia/file_port.h	(revision 222)
+++ /pjproject/trunk/pjmedia/include/pjmedia/file_port.h	(revision 222)
@@ -0,0 +1,47 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2003-2006 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 
+ */
+#ifndef __PJMEDIA_FILE_PORT_H__
+#define __PJMEDIA_FILE_PORT_H__
+
+/**
+ * @file file_port.h
+ * @brief File player and recorder.
+ */
+#include <pjmedia/port.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Create file player port.
+ */
+PJ_DECL(pj_status_t) pjmedia_file_player_port_create( pj_pool_t *pool,
+						      const char *filename,
+						      unsigned flags,
+						      pj_ssize_t buff_size,
+						      void *user_data,
+						      pjmedia_port **p_port );
+
+
+
+PJ_END_DECL
+
+
+#endif	/* __PJMEDIA_FILE_PORT_H__ */
Index: /pjproject/trunk/pjmedia/include/pjmedia/vad.h
===================================================================
--- /pjproject/trunk/pjmedia/include/pjmedia/vad.h	(revision 221)
+++ /pjproject/trunk/pjmedia/include/pjmedia/vad.h	(revision 222)
@@ -23,5 +23,5 @@
 /**
  * @file vad.h
- * @brief Voice Activity Detector.
+ * @brief Simple, adaptive silence detector.
  */
 #include <pjmedia/types.h>
Index: /pjproject/trunk/pjmedia/include/pjmedia/wave.h
===================================================================
--- /pjproject/trunk/pjmedia/include/pjmedia/wave.h	(revision 222)
+++ /pjproject/trunk/pjmedia/include/pjmedia/wave.h	(revision 222)
@@ -0,0 +1,80 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2003-2006 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 
+ */
+#ifndef __PJMEDIA_WAVE_H__
+#define __PJMEDIA_WAVE_H__
+
+
+/**
+ * @file wave.h
+ * @brief WAVE file manipulation.
+ */
+#include <pjmedia/types.h>
+
+
+PJ_BEGIN_DECL
+
+#if PJ_IS_BIG_ENDIAN
+#   define PJMEDIA_RIFF_TAG	('R'<<24|'I'<<16|'F'<<8|'F')
+#   define PJMEDIA_WAVE_TAG	('W'<<24|'A'<<16|'V'<<8|'E')
+#   define PJMEDIA_FMT_TAG	('f'<<24|'m'<<16|'t'<<8|' ')
+#else
+#   define PJMEDIA_RIFF_TAG	('F'<<24|'F'<<16|'I'<<8|'R')
+#   define PJMEDIA_WAVE_TAG	('E'<<24|'V'<<16|'A'<<8|'W')
+#   define PJMEDIA_FMT_TAG	(' '<<24|'t'<<16|'m'<<8|'f')
+#endif
+
+
+/**
+ * This file describes the simpler/canonical version of a WAVE file.
+ * It does not support the full RIFF format specification.
+ */
+struct pjmedia_wave_hdr
+{
+    struct {
+	pj_uint32_t riff;
+	pj_uint32_t file_len;
+	pj_uint32_t wave;
+    } riff_hdr;
+
+    struct {
+	pj_uint32_t fmt;
+	pj_uint32_t len;
+	pj_uint16_t fmt_tag;
+	pj_uint16_t nchan;
+	pj_uint32_t sample_rate;
+	pj_uint32_t bytes_per_sec;
+	pj_uint16_t block_align;
+	pj_uint16_t bits_per_sample;
+    } fmt_hdr;
+
+    struct {
+	pj_uint32_t data;
+	pj_uint32_t len;
+    } data_hdr;
+};
+
+/**
+ * @see pjmedia_wave_hdr
+ */
+typedef struct pjmedia_wave_hdr pjmedia_wave_hdr;
+
+
+PJ_END_DECL
+
+#endif	/* __PJMEDIA_WAVE_H__ */
Index: /pjproject/trunk/pjmedia/src/pjmedia/conference.c
===================================================================
--- /pjproject/trunk/pjmedia/src/pjmedia/conference.c	(revision 221)
+++ /pjproject/trunk/pjmedia/src/pjmedia/conference.c	(revision 222)
@@ -600,4 +600,5 @@
     conf_port = conf->ports[slot];
 
+    info->slot = slot;
     info->name = conf_port->name;
     info->tx_setting = conf_port->tx_setting;
@@ -605,4 +606,25 @@
     info->listener = conf_port->listeners;
 
+    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);
+
+    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;
+    }
+
+    *size = count;
     return PJ_SUCCESS;
 }
Index: /pjproject/trunk/pjmedia/src/pjmedia/errno.c
===================================================================
--- /pjproject/trunk/pjmedia/src/pjmedia/errno.c	(revision 221)
+++ /pjproject/trunk/pjmedia/src/pjmedia/errno.c	(revision 222)
@@ -113,4 +113,9 @@
     { PJMEDIA_ENCBITS,		    "Media ports have incompatible bits per sample" },
     { PJMEDIA_ENCBYTES,		    "Media ports have incompatible bytes per frame" },
+
+    /* Media file errors: */
+    { PJMEDIA_ENOTVALIDWAVE,	    "Not a valid WAVE file" },
+    { PJMEDIA_EWAVEUNSUPP,	    "Unsupported WAVE file format" },
+    { PJMEDIA_EWAVETOOSHORT,	    "WAVE file too short" },
 };
 
Index: /pjproject/trunk/pjmedia/src/pjmedia/file_port.c
===================================================================
--- /pjproject/trunk/pjmedia/src/pjmedia/file_port.c	(revision 222)
+++ /pjproject/trunk/pjmedia/src/pjmedia/file_port.c	(revision 222)
@@ -0,0 +1,261 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2003-2006 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/file_port.h>
+#include <pjmedia/errno.h>
+#include <pjmedia/wave.h>
+#include <pj/assert.h>
+#include <pj/file_access.h>
+#include <pj/file_io.h>
+#include <pj/pool.h>
+#include <pj/string.h>
+
+
+#define SIGNATURE	('F'<<24|'I'<<16|'L'<<8|'E')
+#define BUF_SIZE	(320*10)
+
+struct file_port
+{
+    pjmedia_port     base;
+    pj_size_t	     bufsize;
+    char	    *buf;
+    char	    *readpos;
+};
+
+
+static pj_status_t file_put_frame(pjmedia_port *this_port, 
+				  const pjmedia_frame *frame);
+static pj_status_t file_get_frame(pjmedia_port *this_port, 
+				  pjmedia_frame *frame);
+static pj_status_t file_on_destroy(pjmedia_port *this_port);
+static pj_status_t read_buffer(struct file_port *port);
+
+static struct file_port *create_file_port(pj_pool_t *pool)
+{
+    struct file_port *port;
+
+    port = pj_pool_zalloc(pool, sizeof(struct file_port));
+    if (!port)
+	return NULL;
+
+    port->base.info.name = pj_str("file");
+    port->base.info.signature = SIGNATURE;
+    port->base.info.type = PJMEDIA_TYPE_AUDIO;
+    port->base.info.has_info = PJ_TRUE;
+    port->base.info.need_info = PJ_FALSE;
+    port->base.info.pt = 0xFF;
+    port->base.info.encoding_name = pj_str("pcm");
+    port->base.info.sample_rate = 8000;
+    port->base.info.bits_per_sample = 16;
+    port->base.info.samples_per_frame = 160;
+    port->base.info.bytes_per_frame = 320;
+
+    port->base.put_frame = &file_put_frame;
+    port->base.get_frame = &file_get_frame;
+    port->base.on_destroy = &file_on_destroy;
+
+    return port;
+}
+
+/*
+ * Create WAVE player port.
+ */
+PJ_DEF(pj_status_t) pjmedia_file_player_port_create( pj_pool_t *pool,
+						     const char *filename,
+						     unsigned flags,
+						     pj_ssize_t buff_size,
+						     void *user_data,
+						     pjmedia_port **p_port )
+{
+    pj_off_t file_size;
+    pj_oshandle_t fd = NULL;
+    pjmedia_wave_hdr wave_hdr;
+    pj_ssize_t size_read;
+    struct file_port *file_port;
+    pj_status_t status;
+
+
+    PJ_UNUSED_ARG(flags);
+    PJ_UNUSED_ARG(buff_size);
+
+    /* Check arguments. */
+    PJ_ASSERT_RETURN(pool && filename && p_port, PJ_EINVAL);
+
+    /* Check the file really exists. */
+    if (!pj_file_exists(filename)) {
+	return PJ_ENOTFOUND;
+    }
+
+    /* Get the file size. */
+    file_size = pj_file_size(filename);
+
+    /* Size must be more than WAVE header size */
+    if (file_size <= sizeof(pjmedia_wave_hdr)) {
+	return PJMEDIA_ENOTVALIDWAVE;
+    }
+
+    /* Open file. */
+    status = pj_file_open( pool, filename, PJ_O_RDONLY, &fd);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Read the WAVE header. */
+    size_read = sizeof(wave_hdr);
+    status = pj_file_read( fd, &wave_hdr, &size_read);
+    if (status != PJ_SUCCESS) {
+	pj_file_close(fd);
+	return status;
+    }
+    if (size_read != sizeof(wave_hdr)) {
+	pj_file_close(fd);
+	return PJMEDIA_ENOTVALIDWAVE;
+    }
+
+    /* Validate WAVE file. */
+    if (wave_hdr.riff_hdr.riff != PJMEDIA_RIFF_TAG ||
+	wave_hdr.riff_hdr.wave != PJMEDIA_WAVE_TAG ||
+	wave_hdr.fmt_hdr.fmt != PJMEDIA_FMT_TAG)
+    {
+	pj_file_close(fd);
+	return PJMEDIA_ENOTVALIDWAVE;
+    }
+
+    if (wave_hdr.fmt_hdr.fmt_tag != 1 ||
+	wave_hdr.fmt_hdr.nchan != 1 ||
+	wave_hdr.fmt_hdr.sample_rate != 8000 ||
+	wave_hdr.fmt_hdr.bytes_per_sec != 16000 ||
+	wave_hdr.fmt_hdr.block_align != 2 ||
+	wave_hdr.fmt_hdr.bits_per_sample != 16)
+    {
+	pj_file_close(fd);
+	return PJMEDIA_EWAVEUNSUPP;
+    }
+
+    /* Validate length. */
+    if (wave_hdr.data_hdr.len != file_size-sizeof(pjmedia_wave_hdr)) {
+	pj_file_close(fd);
+	return PJMEDIA_EWAVEUNSUPP;
+    }
+    if (wave_hdr.data_hdr.len < 400) {
+	pj_file_close(fd);
+	return PJMEDIA_EWAVETOOSHORT;
+    }
+
+    /* It seems like we have a valid WAVE file. */
+
+    /* Create file_port instance. */
+    file_port = create_file_port(pool);
+    if (!file_port) {
+	pj_file_close(fd);
+	return PJ_ENOMEM;
+    }
+
+    /* Initialize */
+    file_port->base.user_data = user_data;
+
+    /* For this version, we only support reading the whole
+     * contents of the file.
+     */
+    file_port->bufsize = wave_hdr.data_hdr.len - 8;
+
+    /* Create buffer. */
+    file_port->buf = pj_pool_alloc(pool, file_port->bufsize);
+    if (!file_port->buf) {
+	pj_file_close(fd);
+	return PJ_ENOMEM;
+    }
+
+    file_port->readpos = file_port->buf;
+
+    /* Read the the file. */
+    size_read = file_port->bufsize;
+    status = pj_file_read(fd, file_port->buf, &size_read);
+    if (status != PJ_SUCCESS) {
+	pj_file_close(fd);
+	return status;
+    }
+
+    if (size_read != (pj_ssize_t)file_port->bufsize) {
+	pj_file_close(fd);
+	return PJMEDIA_ENOTVALIDWAVE;
+    }
+
+
+    /* Done. */
+    pj_file_close(fd);
+
+    *p_port = &file_port->base;
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Put frame to file.
+ */
+static pj_status_t file_put_frame(pjmedia_port *this_port, 
+				  const pjmedia_frame *frame)
+{
+    PJ_UNUSED_ARG(this_port);
+    PJ_UNUSED_ARG(frame);
+    return PJ_EINVALIDOP;
+}
+
+/*
+ * Get frame from file.
+ */
+static pj_status_t file_get_frame(pjmedia_port *this_port, 
+				  pjmedia_frame *frame)
+{
+    struct file_port *port = (struct file_port*)this_port;
+
+    pj_assert(port->base.info.signature == SIGNATURE);
+
+    /* Copy frame from buffer. */
+    frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
+    frame->size = 320;
+    frame->timestamp.u64 = 0;
+
+    if (port->readpos + 320 <= port->buf + port->bufsize) {
+	pj_memcpy(frame->buf, port->readpos, 320);
+	port->readpos += 320;
+	if (port->readpos == port->buf + port->bufsize)
+	    port->readpos = port->buf;
+    } else {
+	unsigned endread;
+
+	endread = (port->buf+port->bufsize) - port->readpos;
+	pj_memcpy(frame->buf, port->readpos, endread);
+	pj_memcpy(((char*)frame->buf)+endread, port->buf, 320-endread);
+	port->readpos = port->buf + (320-endread);
+    }
+
+    return PJ_SUCCESS;
+}
+
+/*
+ *
+ */
+static pj_status_t file_on_destroy(pjmedia_port *this_port)
+{
+    PJ_UNUSED_ARG(this_port);
+
+    pj_assert(this_port->info.signature == SIGNATURE);
+
+    return PJ_SUCCESS;
+}
Index: /pjproject/trunk/pjsip/src/pjsua/main.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua/main.c	(revision 221)
+++ /pjproject/trunk/pjsip/src/pjsua/main.c	(revision 222)
@@ -262,19 +262,32 @@
 static void conf_list(void)
 {
-    pjmedia_conf_port_info info;
-    struct pjsua_inv_data *inv_data;
+    unsigned i, count;
+    pjmedia_conf_port_info info[16];
 
     printf("Conference ports:\n");
 
-    inv_data = pjsua.inv_list.next;
-    while (inv_data != &pjsua.inv_list) {
+    count = PJ_ARRAY_SIZE(info);
+    pjmedia_conf_get_ports_info(pjsua.mconf, &count, info);
+    for (i=0; i<count; ++i) {
+	char txlist[80];
+	unsigned j;
+	pjmedia_conf_port_info *port_info = &info[i];	
 	
-	pjmedia_conf_get_port_info(pjsua.mconf, inv_data->conf_slot, &info);
-
-	printf("Port %2d %.*s\n", inv_data->conf_slot, 
-				  (int)info.name.slen, info.name.ptr);
-
-	inv_data = inv_data->next;
-    }
+	txlist[0] = '\0';
+	for (j=0; j<pjsua.max_ports; ++j) {
+	    char s[10];
+	    if (port_info->listener[j]) {
+		pj_sprintf(s, "#%d ", j);
+		pj_ansi_strcat(txlist, s);
+	    }
+	}
+	printf("Port #%02d %20.*s  tx to: %s\n", 
+	       port_info->slot, 
+	       (int)port_info->name.slen, 
+	       port_info->name.ptr,
+	       txlist);
+
+    }
+    puts("");
 }
 
Index: /pjproject/trunk/pjsip/src/pjsua/pjsua.h
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua/pjsua.h	(revision 221)
+++ /pjproject/trunk/pjsip/src/pjsua/pjsua.h	(revision 222)
@@ -116,6 +116,9 @@
 
     pjmedia_endpt   *med_endpt;	    /**< Media endpoint.		*/
+    unsigned	     max_ports;	    /**< Max ports in conf.		*/
     pjmedia_conf    *mconf;	    /**< Media conference.		*/
     pj_bool_t	     null_audio;    /**< Null audio flag.		*/
+    char	    *wav_file;	    /**< WAV file name to play.		*/
+    unsigned	     wav_slot;	    /**< WAV player slot in bridge	*/
 
 
Index: /pjproject/trunk/pjsip/src/pjsua/pjsua_core.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua/pjsua_core.c	(revision 221)
+++ /pjproject/trunk/pjsip/src/pjsua/pjsua_core.c	(revision 222)
@@ -76,4 +76,8 @@
 
     pjsua.reg_timeout = 55;
+
+    /* Default maximum conference ports: */
+
+    pjsua.max_ports = 8;
 
     /* Init route set list: */
@@ -518,5 +522,6 @@
     /* Init conference bridge. */
 
-    status = pjmedia_conf_create(pjsua.pool, 8, 8000, 160, 16, &pjsua.mconf);
+    status = pjmedia_conf_create(pjsua.pool, pjsua.max_ports, 
+				 8000, 160, 16, &pjsua.mconf);
     if (status != PJ_SUCCESS) {
 	pj_caching_pool_destroy(&pjsua.cp);
@@ -554,4 +559,33 @@
     pjsip_transport *udp_transport;
     pj_status_t status = PJ_SUCCESS;
+
+    /* Create WAV file player if required: */
+
+    if (pjsua.wav_file) {
+	pjmedia_port *port;
+	pj_str_t port_name;
+
+	/* Create the file player port. */
+	status = pjmedia_file_player_port_create( pjsua.pool, pjsua.wav_file,
+						  0, -1, NULL, &port);
+	if (status != PJ_SUCCESS) {
+	    pjsua_perror(THIS_FILE, 
+			 "Error playing media file", 
+			 status);
+	    return status;
+	}
+
+	/* Add port to conference bridge: */
+	status = pjmedia_conf_add_port(pjsua.mconf, pjsua.pool, port, 
+				       pj_cstr(&port_name, pjsua.wav_file),
+				       &pjsua.wav_slot);
+	if (status != PJ_SUCCESS) {
+	    pjsua_perror(THIS_FILE, 
+			 "Unable to add file player to conference bridge", 
+			 status);
+	    return status;
+	}
+    }
+
 
     /* Init sockets (STUN etc): */
Index: /pjproject/trunk/pjsip/src/pjsua/pjsua_opt.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua/pjsua_opt.c	(revision 221)
+++ /pjproject/trunk/pjsip/src/pjsua/pjsua_opt.c	(revision 222)
@@ -56,4 +56,6 @@
     puts("Media options:");
     puts("  --null-audio        Use NULL audio device");
+    puts("  --wav-file=file     Play WAV file in conference bridge");
+    puts("");
     //puts("");
     //puts("User Agent options:");
@@ -197,5 +199,5 @@
 	   OPT_USE_STUN1, OPT_USE_STUN2, 
 	   OPT_ADD_BUDDY, OPT_OFFER_X_MS_MSG, OPT_NO_PRESENCE,
-	   OPT_AUTO_ANSWER, OPT_AUTO_HANGUP};
+	   OPT_AUTO_ANSWER, OPT_AUTO_HANGUP, OPT_WAV_FILE};
     struct option long_options[] = {
 	{ "config-file",1, 0, OPT_CONFIG_FILE},
@@ -223,4 +225,5 @@
 	{ "auto-answer",1, 0, OPT_AUTO_ANSWER},
 	{ "auto-hangup",1, 0, OPT_AUTO_HANGUP},
+	{ "wav-file",  1, 0, OPT_WAV_FILE},
 	{ NULL, 0, 0, 0}
     };
@@ -405,4 +408,8 @@
 	    }
 	    pjsua.buddies[pjsua.buddy_cnt++].uri = pj_str(optarg);
+	    break;
+
+	case OPT_WAV_FILE:
+	    pjsua.wav_file = optarg;
 	    break;
 	}
