Home --> Documentations --> PJMEDIA Reference
Sample to mix multiple files in the conference bridge and play the result to sound device.
This file is pjsip-apps/src/samples/confsample.c
21#include <pjlib-util.h>
42#define THIS_FILE "confsample.c"
49static const char *desc =
56 " Demonstrate how to use conference bridge. \n"
60 " confsample [options] [file1.wav] [file2.wav] ... \n"
65 " fileN.wav are optional WAV files to be connected to the conference \n"
66 " bridge. The WAV files MUST have single channel (mono) and 16 bit PCM \n"
67 " samples. It can have arbitrary sampling rate. \n"
71 " Here we create a conference bridge, with at least one port (port zero \n"
72 " is always created for the sound device). \n"
74 " If WAV files are specified, the WAV file player ports will be connected \n"
75 " to slot starting from number one in the bridge. The WAV files can have \n"
76 " arbitrary sampling rate; the bridge will convert it to its clock rate. \n"
77 " However, the files MUST have a single audio channel only (i.e. mono). \n";
89static void monitor_level( pjmedia_conf *conf, int slot, int dir, int dur);
93static void usage( void)
106 printf( "%s (empty to cancel): ", title); fflush(stdout);
107 if (fgets(buf, ( int)len, stdin) == NULL)
112 if (*p== '\r' || *p== '\n') *p= '\0';
126int main( int argc, char *argv[])
129 int clock_rate = CLOCK_RATE;
130 int channel_count = NCHANNELS;
131 int samples_per_frame = NSAMPLES;
132 int bits_per_sample = NBITS;
139 int i, port_count, file_count;
152 if (get_snd_options(THIS_FILE, argc, argv, &dev_id, &clock_rate,
153 &channel_count, &samples_per_frame, &bits_per_sample))
178 file_count = argc - pj_optind;
179 port_count = file_count + 1 + RECORDER;
195 app_perror(THIS_FILE, "Unable to create conference bridge", status);
201 clock_rate, channel_count,
203 bits_per_sample, 0, 0,
206 app_perror(THIS_FILE, "Unable to create WAV writer", status);
217 for (i=0; i<file_count; ++i) {
230 pj_ansi_sprintf(title, "Unable to use %s", argv[i+pj_optind]);
231 app_perror(THIS_FILE, title, status);
244 app_perror(THIS_FILE, "Unable to add conference port", status);
258 dump_pool_usage(THIS_FILE, &cp);
271 int src, dst, level, dur;
277 puts( " s Show ports details");
278 puts( " c Connect one port to another");
279 puts( " d Disconnect port connection");
280 puts( " t Adjust signal level transmitted (tx) to a port");
281 puts( " r Adjust signal level received (rx) from a port");
282 puts( " v Display VU meter for a particular port");
286 printf( "Enter selection: "); fflush(stdout);
288 if (fgets(tmp, sizeof(tmp), stdin) == NULL)
299 puts( "Connect source port to destination port");
300 if (!input( "Enter source port number", tmp1, sizeof(tmp1)) )
302 src = strtol(tmp1, &err, 10);
303 if (*err || src < 0 || src >= port_count) {
304 puts( "Invalid slot number");
308 if (!input( "Enter destination port number", tmp2, sizeof(tmp2)) )
310 dst = strtol(tmp2, &err, 10);
311 if (*err || dst < 0 || dst >= port_count) {
312 puts( "Invalid slot number");
318 app_perror(THIS_FILE, "Error connecting port", status);
324 puts( "Disconnect port connection");
325 if (!input( "Enter source port number", tmp1, sizeof(tmp1)) )
327 src = strtol(tmp1, &err, 10);
328 if (*err || src < 0 || src >= port_count) {
329 puts( "Invalid slot number");
333 if (!input( "Enter destination port number", tmp2, sizeof(tmp2)) )
335 dst = strtol(tmp2, &err, 10);
336 if (*err || dst < 0 || dst >= port_count) {
337 puts( "Invalid slot number");
343 app_perror(THIS_FILE, "Error connecting port", status);
350 puts( "Adjust transmit level of a port");
351 if (!input( "Enter port number", tmp1, sizeof(tmp1)) )
353 src = strtol(tmp1, &err, 10);
354 if (*err || src < 0 || src >= port_count) {
355 puts( "Invalid slot number");
359 if (!input( "Enter level (-128 to >127, 0 for normal)",
360 tmp2, sizeof(tmp2)) )
362 level = strtol(tmp2, &err, 10);
363 if (*err || level < -128) {
364 puts( "Invalid level");
370 app_perror(THIS_FILE, "Error adjusting level", status);
376 puts( "Adjust receive level of a port");
377 if (!input( "Enter port number", tmp1, sizeof(tmp1)) )
379 src = strtol(tmp1, &err, 10);
380 if (*err || src < 0 || src >= port_count) {
381 puts( "Invalid slot number");
385 if (!input( "Enter level (-128 to >127, 0 for normal)",
386 tmp2, sizeof(tmp2)) )
388 level = strtol(tmp2, &err, 10);
389 if (*err || level < -128) {
390 puts( "Invalid level");
396 app_perror(THIS_FILE, "Error adjusting level", status);
401 puts( "Display VU meter");
402 if (!input( "Enter port number to monitor", tmp1, sizeof(tmp1)) )
404 src = strtol(tmp1, &err, 10);
405 if (*err || src < 0 || src >= port_count) {
406 puts( "Invalid slot number");
410 if (!input( "Enter r for rx level or t for tx level", tmp2, sizeof(tmp2)))
412 if (tmp2[0] != 'r' && tmp2[0] != 't') {
413 puts( "Invalid option");
417 if (!input( "Duration to monitor (in seconds)", tmp1, sizeof(tmp1)) )
419 dur = strtol(tmp1, &err, 10);
421 puts( "Invalid duration number");
425 monitor_level(conf, src, tmp2[0], dur);
432 printf( "Invalid input character '%c'\n", tmp[0]);
447 for (i=0; i<file_count; ++i) {
478 enum { MAX_PORTS = 32 };
482 printf( "Conference ports:\n");
487 for (i=0; i<count; ++i) {
488 char txlist[4*MAX_PORTS];
496 pj_ansi_strcat(txlist, s);
500 if (txlist[0] == '\0') {
506 printf( "Port #%02d %-25.*s transmitting to: %s\n",
512 unsigned tx_level, rx_level;
515 &tx_level, &rx_level);
517 printf( "Port #%02d:\n"
519 " Sampling rate : %d Hz\n"
520 " Samples per frame : %d\n"
521 " Frame time : %d ms\n"
522 " Signal level adjustment : tx=%d, rx=%d\n"
523 " Current signal level : tx=%u, rx=%u\n"
524 " Transmitting to ports : %s\n\n",
546static void monitor_level( pjmedia_conf *conf, int slot, int dir, int dur)
548 enum { SLEEP = 20, SAMP_CNT = 2};
551 unsigned level, samp_cnt;
555 printf( "Displaying VU meter for port %d for about %d seconds\n",
558 total_count = dur * 1000 / SLEEP;
563 for (i=0; i<total_count; ++i) {
564 unsigned tx_level, rx_level;
570 &tx_level, &rx_level);
572 app_perror(THIS_FILE, "Unable to read level", status);
576 level += (dir== 'r' ? rx_level : tx_level);
580 if (samp_cnt < SAMP_CNT) {
586 level = level / samp_cnt;
589 length = 20 * level / 255;
590 for (j=0; j<length; ++j)
596 printf( "Port #%02d %cx level: [%s] %d \r",
597 slot, dir, meter, level);
pj_status_t pjmedia_endpt_create(pj_pool_factory *pf, pj_ioqueue_t *ioqueue, unsigned worker_cnt, pjmedia_endpt **p_endpt) Definition: endpoint.h:127
pj_status_t pjmedia_endpt_destroy(pjmedia_endpt *endpt) Definition: endpoint.h:168
pj_status_t pj_init(void)
void pj_caching_pool_destroy(pj_caching_pool *ch_pool)
void pj_caching_pool_init(pj_caching_pool *ch_pool, const pj_pool_factory_policy *policy, pj_size_t max_capacity)
pj_pool_factory_policy pj_pool_factory_default_policy
void * pj_pool_alloc(pj_pool_t *pool, pj_size_t size)
pj_pool_t * pj_pool_create(pj_pool_factory *factory, const char *name, pj_size_t initial_size, pj_size_t increment_size, pj_pool_callback *callback)
void pj_pool_release(pj_pool_t *pool)
pj_status_t pj_thread_sleep(unsigned msec)
#define PJ_ASSERT_RETURN(expr, retval)
PJMEDIA small footprint Open Source media stack
Copyright (C) 2006-2008 Teluu Inc.
|