Hello everyone
Please help! My wav_writer is just writing silence (of the correct length) when trying to use pjsua-lib with 1 conference bridge per call, as explained in the FAQ here: https://trac.pjsip.org/repos/wiki/FAQ#pjsua-lib-perf. Note that when I use the default pjsua conference bridge everything works fine for me.
I've saved the code and a log file to a github public gist here: https://gist.github.com/MikeLeonard/6b8b4986d6529ae751ebd2af5bf4d29f
I would *really* appreciate it if someone could look through call_media_init function I've written (also pasted below) and tell me what I'm doing wrong.
If it takes someone a lot of time I'd be happy to buy them a coffee (or amazon voucher!) to say thank you.
Thanks very much in advance
Mike
More information:
..................................................................................................................................................
**I think I've ruled out problems with my setup
- I'm trying to create a server that makes calls to a regular mobile or landline from a server (ie no voip phone so no sound device), and records the speech of the receiver to a wav file.
I'm running this on ubuntu, inside a docker container, on a macbook, and am making an outbound call to a mobile number via a twilio sip trunk. I'm also compiling this using C++ (because I need various C++ libraries for what I have in mind once I get the basics working).
The above setup ALL works fine - I modified samples/simple_pjsua.c and got a wav_writer and a wav_player working no problem with the default pjsua conference bridge. So I'm pretty sure the problem is with how I've tried to follow the pjsua-lib-perf FAQ.
**I can't see any issues in the log file, and I've confirmed the key 'on_' callbacks all definitely run
- The log file prints out the following - which to me looks like I've connected the right ports, but I don't really understand this to be honest I've just be copying examples:
09:59:05.565 APP .......Call 0 state=CALLING
09:59:05.572 wav_writer.c .......File writer 'testingtesting.wav' created: samp.rate=16000, bufsize=4KB
09:59:05.572 conference.c .......Port 0 (Master/sound) transmitting to port 1 (testingtesting.wav)
09:59:05.579 wav_player.c .......File player 'message.wav' created: samp.rate=16000, ch=1, bufsize=4KB, filesize=56KB
09:59:05.579 conference.c .......Port 2 (message.wav) transmitting to port 0 (Master/sound)
- I'm just trying one call at the moment - I haven't tried multiple calls yet.
- I've confirmed that the key callbacks all run: on_call_state, on_call_media_state, on_stream_created and on_stream_destroyed
- I've added lots of "if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}" into the code, but don't get any "STATUS ERROR" messages in the log.
**A wav file is indeed written
- ...it just contains silence. It seems to be silence of the length of the call however.
I've also tried looping back the audio, and playing a wav file to the receiver, but I just get silence. These all work in my basic samples/simple_pjsua.c version with the default pjsua conference bridge.
..................................................................................................................................................
Key piece of code... see github public gist for full code + log file https://gist.github.com/MikeLeonard/6b8b4986d6529ae751ebd2af5bf4d29f
struct call_data {
pj_pool_t *pool;
pjmedia_conf *conf;
pjmedia_port *cport;
pjmedia_port *null;
pjmedia_port *writer;
pjmedia_port *player;
pjmedia_master_port *m;
unsigned int call_slot;
unsigned int writer_slot;
unsigned int player_slot;
};
static void call_media_init(pjsua_call_id call_id){
log_message("RUNNING... call_media_init\n");
pj_pool_t *pool;
struct call_data *cd;
pj_status_t status;
pool = pjsua_pool_create("mycall", 4000, 4000);
cd = PJ_POOL_ZALLOC_T(pool, struct call_data);
cd->pool = pool;
pjsua_call_set_user_data(call_id, (void*)cd);
pjsua_media_config media_cfg;
pjsua_media_config_default(&media_cfg);
status = pjmedia_conf_create(
cd->pool,
media_cfg.max_media_ports, //max media ports
media_cfg.clock_rate,
media_cfg.channel_count,
media_cfg.clock_rate * media_cfg.channel_count * media_cfg.audio_frame_ptime / 1000, //mconf_cfg.samples_per_frame,
16, //mconf_cfg.bits_per_sample,
PJMEDIA_CONF_NO_DEVICE | PJMEDIA_CONF_NO_MIC, //options
&cd->conf //pointer to conference bridge instance
);
if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}
cd->cport = pjmedia_conf_get_master_port(cd->conf);
status = pjmedia_null_port_create(
cd->pool,
media_cfg.clock_rate,
media_cfg.channel_count,
media_cfg.clock_rate * media_cfg.channel_count * media_cfg.audio_frame_ptime / 1000, //mconf_cfg.samples_per_frame,
16, //mconf_cfg.bits_per_sample,
&cd->null);
if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}
status = pjmedia_master_port_create(cd->pool, cd->null, cd->cport, 0, &cd->m);
if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}
status = pjmedia_master_port_start(cd->m);
if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}
//todo(mike) handle errors, see pjsua_aud.c
/* wav writer */
status = pjmedia_wav_writer_port_create(
cd->pool,
"testingtesting.wav", //path
media_cfg.clock_rate,
media_cfg.channel_count,
media_cfg.clock_rate * media_cfg.channel_count * media_cfg.audio_frame_ptime / 1000, //mconf_cfg.samples_per_frame,
16, //mconf_cfg.bits_per_sample,
0, //options
0, //buf_size defaults to 4kb if set to 0
&cd->writer //yes this should be a pjmedia_port **
);
if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}
status = pjmedia_conf_add_port(cd->conf, cd->pool, cd->writer, NULL, &cd->writer_slot);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);
pjmedia_port_destroy(cd->writer);
}
pjmedia_conf_connect_port(cd->conf, cd->call_slot, cd->writer_slot, 0);
/* wav player */
status = pjmedia_wav_player_port_create(
cd->pool,
"message.wav",
media_cfg.audio_frame_ptime,
0,
0,
&cd->player //yes this should be a pjmedia_port **
);
if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}
status = pjmedia_conf_add_port(cd->conf, cd->pool, cd->player, NULL, &cd->player_slot);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);
pjmedia_port_destroy(cd->player);
}
pjmedia_conf_connect_port(cd->conf, cd->player_slot, cd->call_slot, 0);
//uncomment to loop back remote audio (also doesn't work)
//pjmedia_conf_connect_port(cd->conf, cd->call_slot, cd->call_slot, 0);
}
_______________________________________________ Visit our blog: http://blog.pjsip.org pjsip mailing list pjsip@xxxxxxxxxxxxxxx http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org