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
22 #include <pjlib-util.h>
43 #define THIS_FILE "confsample.c"
50 static const char *desc =
57 " Demonstrate how to use conference bridge. \n"
61 " confsample [options] [file1.wav] [file2.wav] ... \n"
66 " fileN.wav are optional WAV files to be connected to the conference \n"
67 " bridge. The WAV files MUST have single channel (mono) and 16 bit PCM \n"
68 " samples. It can have arbitrary sampling rate. \n"
72 " Here we create a conference bridge, with at least one port (port zero \n"
73 " is always created for the sound device). \n"
75 " If WAV files are specified, the WAV file player ports will be connected \n"
76 " to slot starting from number one in the bridge. The WAV files can have \n"
77 " arbitrary sampling rate; the bridge will convert it to its clock rate. \n"
78 " However, the files MUST have a single audio channel only (i.e. mono). \n";
90 static void monitor_level( pjmedia_conf *conf, int slot, int dir, int dur);
94 static void usage( void)
107 printf( "%s (empty to cancel): ", title); fflush(stdout);
108 if (fgets(buf, ( int)len, stdin) == NULL)
113 if (*p== '\r' || *p== '\n') *p= '\0';
127 int main( int argc, char *argv[])
130 int clock_rate = CLOCK_RATE;
131 int channel_count = NCHANNELS;
132 int samples_per_frame = NSAMPLES;
133 int bits_per_sample = NBITS;
140 int i, port_count, file_count;
153 if (get_snd_options(THIS_FILE, argc, argv, &dev_id, &clock_rate,
154 &channel_count, &samples_per_frame, &bits_per_sample))
179 file_count = argc - pj_optind;
180 port_count = file_count + 1 + RECORDER;
196 app_perror(THIS_FILE, "Unable to create conference bridge", status);
202 clock_rate, channel_count,
204 bits_per_sample, 0, 0,
207 app_perror(THIS_FILE, "Unable to create WAV writer", status);
218 for (i=0; i<file_count; ++i) {
231 pj_ansi_sprintf(title, "Unable to use %s", argv[i+pj_optind]);
232 app_perror(THIS_FILE, title, status);
245 app_perror(THIS_FILE, "Unable to add conference port", status);
259 dump_pool_usage(THIS_FILE, &cp);
272 int src, dst, level, dur;
278 puts( " s Show ports details");
279 puts( " c Connect one port to another");
280 puts( " d Disconnect port connection");
281 puts( " t Adjust signal level transmitted (tx) to a port");
282 puts( " r Adjust signal level received (rx) from a port");
283 puts( " v Display VU meter for a particular port");
287 printf( "Enter selection: "); fflush(stdout);
289 if (fgets(tmp, sizeof(tmp), stdin) == NULL)
300 puts( "Connect source port to destination port");
301 if (!input( "Enter source port number", tmp1, sizeof(tmp1)) )
303 src = strtol(tmp1, &err, 10);
304 if (*err || src < 0 || src >= port_count) {
305 puts( "Invalid slot number");
309 if (!input( "Enter destination port number", tmp2, sizeof(tmp2)) )
311 dst = strtol(tmp2, &err, 10);
312 if (*err || dst < 0 || dst >= port_count) {
313 puts( "Invalid slot number");
319 app_perror(THIS_FILE, "Error connecting port", status);
325 puts( "Disconnect port connection");
326 if (!input( "Enter source port number", tmp1, sizeof(tmp1)) )
328 src = strtol(tmp1, &err, 10);
329 if (*err || src < 0 || src >= port_count) {
330 puts( "Invalid slot number");
334 if (!input( "Enter destination port number", tmp2, sizeof(tmp2)) )
336 dst = strtol(tmp2, &err, 10);
337 if (*err || dst < 0 || dst >= port_count) {
338 puts( "Invalid slot number");
344 app_perror(THIS_FILE, "Error connecting port", status);
351 puts( "Adjust transmit level of a port");
352 if (!input( "Enter port number", tmp1, sizeof(tmp1)) )
354 src = strtol(tmp1, &err, 10);
355 if (*err || src < 0 || src >= port_count) {
356 puts( "Invalid slot number");
360 if (!input( "Enter level (-128 to >127, 0 for normal)",
361 tmp2, sizeof(tmp2)) )
363 level = strtol(tmp2, &err, 10);
364 if (*err || level < -128) {
365 puts( "Invalid level");
371 app_perror(THIS_FILE, "Error adjusting level", status);
377 puts( "Adjust receive level of a port");
378 if (!input( "Enter port number", tmp1, sizeof(tmp1)) )
380 src = strtol(tmp1, &err, 10);
381 if (*err || src < 0 || src >= port_count) {
382 puts( "Invalid slot number");
386 if (!input( "Enter level (-128 to >127, 0 for normal)",
387 tmp2, sizeof(tmp2)) )
389 level = strtol(tmp2, &err, 10);
390 if (*err || level < -128) {
391 puts( "Invalid level");
397 app_perror(THIS_FILE, "Error adjusting level", status);
402 puts( "Display VU meter");
403 if (!input( "Enter port number to monitor", tmp1, sizeof(tmp1)) )
405 src = strtol(tmp1, &err, 10);
406 if (*err || src < 0 || src >= port_count) {
407 puts( "Invalid slot number");
411 if (!input( "Enter r for rx level or t for tx level", tmp2, sizeof(tmp2)))
413 if (tmp2[0] != 'r' && tmp2[0] != 't') {
414 puts( "Invalid option");
418 if (!input( "Duration to monitor (in seconds)", tmp1, sizeof(tmp1)) )
420 dur = strtol(tmp1, &err, 10);
422 puts( "Invalid duration number");
426 monitor_level(conf, src, tmp2[0], dur);
433 printf( "Invalid input character '%c'\n", tmp[0]);
448 for (i=0; i<file_count; ++i) {
479 enum { MAX_PORTS = 32 };
483 printf( "Conference ports:\n");
488 for (i=0; i<count; ++i) {
489 char txlist[4*MAX_PORTS];
497 pj_ansi_strcat(txlist, s);
501 if (txlist[0] == '\0') {
507 printf( "Port #%02d %-25.*s transmitting to: %s\n",
513 unsigned tx_level, rx_level;
516 &tx_level, &rx_level);
518 printf( "Port #%02d:\n"
520 " Sampling rate : %d Hz\n"
521 " Samples per frame : %d\n"
522 " Frame time : %d ms\n"
523 " Signal level adjustment : tx=%d, rx=%d\n"
524 " Current signal level : tx=%u, rx=%u\n"
525 " Transmitting to ports : %s\n\n",
547 static void monitor_level( pjmedia_conf *conf, int slot, int dir, int dur)
549 enum { SLEEP = 20, SAMP_CNT = 2};
552 unsigned level, samp_cnt;
556 printf( "Displaying VU meter for port %d for about %d seconds\n",
559 total_count = dur * 1000 / SLEEP;
564 for (i=0; i<total_count; ++i) {
565 unsigned tx_level, rx_level;
571 &tx_level, &rx_level);
573 app_perror(THIS_FILE, "Unable to read level", status);
577 level += (dir== 'r' ? rx_level : tx_level);
581 if (samp_cnt < SAMP_CNT) {
587 level = level / samp_cnt;
590 length = 20 * level / 255;
591 for (j=0; j<length; ++j)
597 printf( "Port #%02d %cx level: [%s] %d \r",
598 slot, dir, meter, level);
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)
pj_status_t pjmedia_endpt_destroy(pjmedia_endpt *endpt) Definition: endpoint.h:146
pj_pool_factory_policy pj_pool_factory_default_policy
pj_status_t pj_thread_sleep(unsigned msec)
void pj_caching_pool_init(pj_caching_pool *ch_pool, const pj_pool_factory_policy *policy, pj_size_t max_capacity)
void pj_pool_release(pj_pool_t *pool)
void * pj_pool_alloc(pj_pool_t *pool, pj_size_t size)
pj_status_t pjmedia_endpt_create(pj_pool_factory *pf, pj_ioqueue_t *ioqueue, unsigned worker_cnt, pjmedia_endpt **p_endpt) Definition: endpoint.h:105
void pj_caching_pool_destroy(pj_caching_pool *ch_pool)
#define PJ_ASSERT_RETURN(expr, retval)
pj_status_t pj_init(void)
PJMEDIA small footprint Open Source media stack
Copyright (C) 2006-2008 Teluu Inc.
|