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.
..................................................................................................................................................
- 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.
- 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.
..................................................................................................................................................
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);
}