How to get the audio stream from PJSIP when there is no audio device hardware.

JD
James Doherty
Fri, Sep 15, 2017 6:13 PM

Hello,

Thanks for a great product.

I want to use PJSIP's C API to record the incoming audio to a file on a
machine with no hardware sound device. I've read the FAQ and the PJMEDIA
documentation but am still unclear about the architecture of bridges, media
ports and sound devices.

My target machines, both Windows 10 and Linux, have no hardware audio
devices installed, so I call pjsua_set_null_snd_dev() after initializing and
starting the libraries. Example code below.

Later after I make a SIP call and it is answered I attempt to attach a WAV
file writer to the DEFAULT_CAPTURE_DEV, but the
pjmedia_aud_dev_default_param(.) call returns PJMEDIA_AUD_INVALID_DEV.

Runing the code on a machine (either Win or Linux) with a hardware sound
device succeeds and things progress as I expect. Even though
pjsua_set_null_snd_dev() is invoked. Absolutely no changes to the code.

Is there a resource I can consult so to understand this better?

James

/** Code **/

#include <pjlib.h>
#include <pjlib-util.h>
#include <pjnath.h>
#include <pjsip.h>
#include <pjsip_ua.h>
#include <pjsip_simple.h>
#include <pjsua-lib/pjsua.h>
#include <pjmedia.h>
#include <pjmedia-codec.h>
#include <pj/log.h>
#include <pj/os.h>

int main(int, char **)
{
// Create pjsua first! 
        pj_status_t status = pjsua_create();
        if (status != PJ_SUCCESS)
        {
            fprintf(stderr,"pjsua_create error\n");
            return -1;
        }

// Init pjsua 
        pjsua_config cfg;
        pjsua_logging_config log_cfg;

        pjsua_config_default(&cfg);

        pjsua_logging_config_default(&log_cfg);
        log_cfg.console_level = 4;

        status = pjsua_init(&cfg, &log_cfg, NULL);
        if (status != PJ_SUCCESS)
        {
            fprintf(stderr,"pjsua_init error\n");
            return -1;
        }


// Proactively list known audio devices so we are sure there are NONE
        pjmedia_aud_dev_info info[64];
        unsigned info_count = 64;
        pjsua_enum_aud_devs(info, &info_count);

        fprintf(stderr,"Listing known sound devices, total of [%u]\n",

info_count);
for (unsigned i = 0; i<info_count; ++i)
{
fprintf(stderr,"Name [%s]", info[i].name);
}

// Add transport
        pjsua_transport_config tcfg;
        pjsua_transport_id trans_id;
        pjsua_transport_config_default(&tcfg);
        tcfg.port = 5060;
        status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &tcfg,

&trans_id);
if (status != PJ_SUCCESS)
{
fprintf(stderr, "pjsua_transport_create error\n");
return -1;
}

// Initialization is done, now start pjsua 
        status = pjsua_start();
        if (status != PJ_SUCCESS)
        {
            fprintf(stderr, "pjsua_start error\n");
            return -1;
        }

// Set NULL sound
        status = pjsua_set_null_snd_dev();
        if (status != PJ_SUCCESS)
        {
            fprintf(stderr, "pjsua_set_null_snd_dev error");
            return -1;
        }

// Register to a SIP server by creating SIP account, I happen to  use

Asterisk
pjsua_acc_id acc_id;
fprintf(stderr, "Setting up SIP server registration\n");
{
pjsua_acc_config cfg;
pjsua_acc_config_default(&cfg);
cfg.id = pj_str("sip:6001@10.0.0.21");
cfg.reg_uri = cfg.id; // same as ID
cfg.cred_count = 1;

            cfg.cred_info[0].realm = pj_str("*");
            cfg.cred_info[0].scheme = pj_str("digest"); 
            cfg.cred_info[0].username = pj_str("6001");
            cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
            cfg.cred_info[0].data = pj_str("password");

            status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id);
            if (status != PJ_SUCCESS)
            {
                fprintf(stderr, "pjsua_acc_add error\n");
                return -1;
            }
        }

        fprintf(stderr, "Waiting for SIP server registration to

complete....\n");

        Sleep(2000); // sleep 2 seconds

// Call extension 9 on my Asterisk server at 10.0.0.21:5060
        pj_str_t sip_target(pj_str("sip:9@10.0.0.21"));
        fprintf(stderr, "Making call to [%s]\n", sip_target.ptr);

        pjsua_call_id call_id;
        status = pjsua_call_make_call(acc_id, &sip_target, 0, NULL,

NULL, &call_id);
if (status != PJ_SUCCESS)
{
fprintf(stderr, "pjsua_call_make_call error\n");
return -1;
}

        pj_pool_t * pool = nullptr;
        pjmedia_port * wav = nullptr;
        pjmedia_aud_stream *strm = nullptr;
        pool = pj_pool_create(pjmedia_aud_subsys_get_pool_factory(),

"wav-audio", 1000, 1000, NULL);

        if (nullptr == pool)
        {
            fprintf(stderr,"Pool creation failed\n");
            return -1;
        }

// 8kHz, single channel 16bit MS WAV format file
        status = pjmedia_wav_writer_port_create(pool, "test.wav", 8000,

1, 320, 16, PJMEDIA_FILE_WRITE_PCM, 0, &wav);
if (status != PJ_SUCCESS)
{
fprintf(stderr, "Error creating WAV file\n");
return -1;
}

        pjmedia_aud_param param; 
//////////////////////////////////////////////////////
// FAILURE HERE : This is the function call which returns

PJMEDIA_AUD_INVALID_DEV
//////////////////////////////////////////////////////
status =
pjmedia_aud_dev_default_param(PJMEDIA_AUD_DEFAULT_CAPTURE_DEV, &param);
if (status != PJ_SUCCESS)
{
fprintf(stderr, "pjmedia_aud_dev_default_param()");
return -1;
}

        param.dir = PJMEDIA_DIR_CAPTURE;
        param.clock_rate = PJMEDIA_PIA_SRATE(&wav->info);
        param.samples_per_frame = PJMEDIA_PIA_SPF(&wav->info);
        param.channel_count = PJMEDIA_PIA_CCNT(&wav->info);
        param.bits_per_sample = PJMEDIA_PIA_BITS(&wav->info);

        status = pjmedia_aud_stream_create(&param, &test_rec_cb,

&test_play_cb, wav, &strm);
if (status != PJ_SUCCESS)
{
fprintf(stderr, "Error opening the sound stream");
return -1;
}

        status = pjmedia_aud_stream_start(strm);
        if (status != PJ_SUCCESS)
        {
            fprintf(stderr, "Error starting the sound device");
            return -1;
        }

// Spend some time allowing the called party to pick up and recording to

proceed
Sleep(10000); // sleep 10 seconds

// Clean up code omitted
return 0;
}
Hello, Thanks for a great product. I want to use PJSIP's C API to record the incoming audio to a file on a machine with _no_ hardware sound device. I've read the FAQ and the PJMEDIA documentation but am still unclear about the architecture of bridges, media ports and sound devices. My target machines, both Windows 10 and Linux, have no hardware audio devices installed, so I call pjsua_set_null_snd_dev() after initializing and starting the libraries. Example code below. Later after I make a SIP call and it is answered I attempt to attach a WAV file writer to the DEFAULT_CAPTURE_DEV, but the pjmedia_aud_dev_default_param(.) call returns PJMEDIA_AUD_INVALID_DEV. Runing the code on a machine (either Win or Linux) _with_ a hardware sound device succeeds and things progress as I expect. Even though pjsua_set_null_snd_dev() is invoked. Absolutely no changes to the code. Is there a resource I can consult so to understand this better? James /** Code **/ #include <pjlib.h> #include <pjlib-util.h> #include <pjnath.h> #include <pjsip.h> #include <pjsip_ua.h> #include <pjsip_simple.h> #include <pjsua-lib/pjsua.h> #include <pjmedia.h> #include <pjmedia-codec.h> #include <pj/log.h> #include <pj/os.h> int main(int, char **) { // Create pjsua first! pj_status_t status = pjsua_create(); if (status != PJ_SUCCESS) { fprintf(stderr,"pjsua_create error\n"); return -1; } // Init pjsua pjsua_config cfg; pjsua_logging_config log_cfg; pjsua_config_default(&cfg); pjsua_logging_config_default(&log_cfg); log_cfg.console_level = 4; status = pjsua_init(&cfg, &log_cfg, NULL); if (status != PJ_SUCCESS) { fprintf(stderr,"pjsua_init error\n"); return -1; } // Proactively list known audio devices so we are sure there are NONE pjmedia_aud_dev_info info[64]; unsigned info_count = 64; pjsua_enum_aud_devs(info, &info_count); fprintf(stderr,"Listing known sound devices, total of [%u]\n", info_count); for (unsigned i = 0; i<info_count; ++i) { fprintf(stderr,"Name [%s]", info[i].name); } // Add transport pjsua_transport_config tcfg; pjsua_transport_id trans_id; pjsua_transport_config_default(&tcfg); tcfg.port = 5060; status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &tcfg, &trans_id); if (status != PJ_SUCCESS) { fprintf(stderr, "pjsua_transport_create error\n"); return -1; } // Initialization is done, now start pjsua status = pjsua_start(); if (status != PJ_SUCCESS) { fprintf(stderr, "pjsua_start error\n"); return -1; } // Set NULL sound status = pjsua_set_null_snd_dev(); if (status != PJ_SUCCESS) { fprintf(stderr, "pjsua_set_null_snd_dev error"); return -1; } // Register to a SIP server by creating SIP account, I happen to use Asterisk pjsua_acc_id acc_id; fprintf(stderr, "Setting up SIP server registration\n"); { pjsua_acc_config cfg; pjsua_acc_config_default(&cfg); cfg.id = pj_str("sip:6001@10.0.0.21"); cfg.reg_uri = cfg.id; // same as ID cfg.cred_count = 1; cfg.cred_info[0].realm = pj_str("*"); cfg.cred_info[0].scheme = pj_str("digest"); cfg.cred_info[0].username = pj_str("6001"); cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD; cfg.cred_info[0].data = pj_str("password"); status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id); if (status != PJ_SUCCESS) { fprintf(stderr, "pjsua_acc_add error\n"); return -1; } } fprintf(stderr, "Waiting for SIP server registration to complete....\n"); Sleep(2000); // sleep 2 seconds // Call extension 9 on my Asterisk server at 10.0.0.21:5060 pj_str_t sip_target(pj_str("sip:9@10.0.0.21")); fprintf(stderr, "Making call to [%s]\n", sip_target.ptr); pjsua_call_id call_id; status = pjsua_call_make_call(acc_id, &sip_target, 0, NULL, NULL, &call_id); if (status != PJ_SUCCESS) { fprintf(stderr, "pjsua_call_make_call error\n"); return -1; } pj_pool_t * pool = nullptr; pjmedia_port * wav = nullptr; pjmedia_aud_stream *strm = nullptr; pool = pj_pool_create(pjmedia_aud_subsys_get_pool_factory(), "wav-audio", 1000, 1000, NULL); if (nullptr == pool) { fprintf(stderr,"Pool creation failed\n"); return -1; } // 8kHz, single channel 16bit MS WAV format file status = pjmedia_wav_writer_port_create(pool, "test.wav", 8000, 1, 320, 16, PJMEDIA_FILE_WRITE_PCM, 0, &wav); if (status != PJ_SUCCESS) { fprintf(stderr, "Error creating WAV file\n"); return -1; } pjmedia_aud_param param; ////////////////////////////////////////////////////// // FAILURE HERE : This is the function call which returns PJMEDIA_AUD_INVALID_DEV ////////////////////////////////////////////////////// status = pjmedia_aud_dev_default_param(PJMEDIA_AUD_DEFAULT_CAPTURE_DEV, &param); if (status != PJ_SUCCESS) { fprintf(stderr, "pjmedia_aud_dev_default_param()"); return -1; } param.dir = PJMEDIA_DIR_CAPTURE; param.clock_rate = PJMEDIA_PIA_SRATE(&wav->info); param.samples_per_frame = PJMEDIA_PIA_SPF(&wav->info); param.channel_count = PJMEDIA_PIA_CCNT(&wav->info); param.bits_per_sample = PJMEDIA_PIA_BITS(&wav->info); status = pjmedia_aud_stream_create(&param, &test_rec_cb, &test_play_cb, wav, &strm); if (status != PJ_SUCCESS) { fprintf(stderr, "Error opening the sound stream"); return -1; } status = pjmedia_aud_stream_start(strm); if (status != PJ_SUCCESS) { fprintf(stderr, "Error starting the sound device"); return -1; } // Spend some time allowing the called party to pick up and recording to proceed Sleep(10000); // sleep 10 seconds // Clean up code omitted return 0; }
GL
Gang Liu
Tue, Sep 19, 2017 3:31 AM

pjsua sample app already has this feature. take a look pjsua manule
http://www.pjsip.org/pjsua.htm and have a try

--null-audio        Use NULL audio device

--rec-file=file    Open file recorder (extension can be .wav or .mp3
--auto-rec          Automatically record conversation

On Sat, Sep 16, 2017 at 2:13 AM, James Doherty james@tenderwire.com wrote:

Hello,

Thanks for a great product.

I want to use PJSIP's C API to record the incoming audio to a file on a
machine with no hardware sound device. I’ve read the FAQ and the
PJMEDIA documentation but am still unclear about the architecture of
bridges, media ports and sound devices.

My target machines, both Windows 10 and Linux, have no hardware audio
devices installed, so I call pjsua_set_null_snd_dev() after initializing
and starting the libraries. Example code below.

Later after I make a SIP call and it is answered I attempt to attach a WAV file writer to the DEFAULT_CAPTURE_DEV, but the pjmedia_aud_dev_default_param(…) call returns PJMEDIA_AUD_INVALID_DEV.

Runing the code on a machine (either Win or Linux) with a hardware sound device succeeds and things progress as I expect. Even though pjsua_set_null_snd_dev() is invoked. Absolutely no changes to the code.

Is there a resource I can consult so to understand this better?

James

/** Code **/

#include <pjlib.h>

#include <pjlib-util.h>

#include <pjnath.h>

#include <pjsip.h>

#include <pjsip_ua.h>

#include <pjsip_simple.h>

#include <pjsua-lib/pjsua.h>

#include <pjmedia.h>

#include <pjmedia-codec.h>

#include <pj/log.h>

#include <pj/os.h>

 int main(int, char **)

 {

 // Create pjsua first!

         pj_status_t status = pjsua_create();

         if (status != PJ_SUCCESS)

         {

             fprintf(stderr,"pjsua_create error\n");

             return -1;

         }



 // Init pjsua

         pjsua_config cfg;

         pjsua_logging_config log_cfg;



         pjsua_config_default(&cfg);



         pjsua_logging_config_default(&log_cfg);

         log_cfg.console_level = 4;



         status = pjsua_init(&cfg, &log_cfg, NULL);

         if (status != PJ_SUCCESS)

         {

             fprintf(stderr,"pjsua_init error\n");

             return -1;

         }





 // Proactively list known audio devices so we are sure there are NONE

         pjmedia_aud_dev_info info[64];

         unsigned info_count = 64;

         pjsua_enum_aud_devs(info, &info_count);



         fprintf(stderr,"Listing known sound devices, total of [%u]\n", info_count);

         for (unsigned i = 0; i<info_count; ++i)

         {

             fprintf(stderr,"Name [%s]", info[i].name);

         }



 // Add transport

         pjsua_transport_config tcfg;

         pjsua_transport_id trans_id;

         pjsua_transport_config_default(&tcfg);

         tcfg.port = 5060;

         status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &tcfg, &trans_id);

         if (status != PJ_SUCCESS)

         {

             fprintf(stderr, "pjsua_transport_create error\n");

             return -1;

         }



 // Initialization is done, now start pjsua

         status = pjsua_start();

         if (status != PJ_SUCCESS)

         {

             fprintf(stderr, "pjsua_start error\n");

             return -1;

         }



 // Set NULL sound

         status = pjsua_set_null_snd_dev();

         if (status != PJ_SUCCESS)

         {

             fprintf(stderr, "pjsua_set_null_snd_dev error");

             return -1;

         }



 // Register to a SIP server by creating SIP account, I happen to  use Asterisk

         pjsua_acc_id acc_id;

         fprintf(stderr, "Setting up SIP server registration\n");

         {

             pjsua_acc_config cfg;

             pjsua_acc_config_default(&cfg);

             cfg.id = pj_str("sip:6001@10.0.0.21");

             cfg.reg_uri = cfg.id; // same as ID

             cfg.cred_count = 1;



             cfg.cred_info[0].realm = pj_str("*");

             cfg.cred_info[0].scheme = pj_str("digest");

             cfg.cred_info[0].username = pj_str("6001");

             cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;

             cfg.cred_info[0].data = pj_str("password");



             status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id);

             if (status != PJ_SUCCESS)

             {

                 fprintf(stderr, "pjsua_acc_add error\n");

                 return -1;

             }

         }



         fprintf(stderr, "Waiting for SIP server registration to complete....\n");



         Sleep(2000); // sleep 2 seconds



 // Call extension 9 on my Asterisk server at 10.0.0.21:5060

         pj_str_t sip_target(pj_str("sip:9@10.0.0.21"));

         fprintf(stderr, "Making call to [%s]\n", sip_target.ptr);



         pjsua_call_id call_id;

         status = pjsua_call_make_call(acc_id, &sip_target, 0, NULL, NULL, &call_id);

         if (status != PJ_SUCCESS)

         {

             fprintf(stderr, "pjsua_call_make_call error\n");

             return -1;

         }



         pj_pool_t * pool = nullptr;

         pjmedia_port * wav = nullptr;

         pjmedia_aud_stream *strm = nullptr;

         pool = pj_pool_create(pjmedia_aud_subsys_get_pool_factory(), "wav-audio", 1000, 1000, NULL);



         if (nullptr == pool)

         {

             fprintf(stderr,"Pool creation failed\n");

             return -1;

         }



 // 8kHz, single channel 16bit MS WAV format file

         status = pjmedia_wav_writer_port_create(pool, "test.wav", 8000, 1, 320, 16, PJMEDIA_FILE_WRITE_PCM, 0, &wav);

         if (status != PJ_SUCCESS)

         {

             fprintf(stderr, "Error creating WAV file\n");

             return -1;

         }



         pjmedia_aud_param param;

 //////////////////////////////////////////////////////

 // FAILURE HERE : This is the function call which returns PJMEDIA_AUD_INVALID_DEV

 //////////////////////////////////////////////////////

         status = pjmedia_aud_dev_default_param(PJMEDIA_AUD_DEFAULT_CAPTURE_DEV, &param);

         if (status != PJ_SUCCESS)

         {

             fprintf(stderr, "pjmedia_aud_dev_default_param()");

             return -1;

         }



         param.dir = PJMEDIA_DIR_CAPTURE;

         param.clock_rate = PJMEDIA_PIA_SRATE(&wav->info);

         param.samples_per_frame = PJMEDIA_PIA_SPF(&wav->info);

         param.channel_count = PJMEDIA_PIA_CCNT(&wav->info);

         param.bits_per_sample = PJMEDIA_PIA_BITS(&wav->info);



         status = pjmedia_aud_stream_create(&param, &test_rec_cb, &test_play_cb, wav, &strm);

         if (status != PJ_SUCCESS)

         {

             fprintf(stderr, "Error opening the sound stream");

             return -1;

         }



         status = pjmedia_aud_stream_start(strm);

         if (status != PJ_SUCCESS)

         {

             fprintf(stderr, "Error starting the sound device");

             return -1;

         }



 // Spend some time allowing the called party to pick up and recording to proceed

         Sleep(10000); // sleep 10 seconds



 // Clean up code omitted

 return 0;

 }

Visit our blog: http://blog.pjsip.org

pjsip mailing list
pjsip@lists.pjsip.org
http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org

pjsua sample app already has this feature. take a look pjsua manule http://www.pjsip.org/pjsua.htm and have a try --null-audio Use NULL audio device --rec-file=file Open file recorder (extension can be .wav or .mp3 --auto-rec Automatically record conversation On Sat, Sep 16, 2017 at 2:13 AM, James Doherty <james@tenderwire.com> wrote: > Hello, > > > > Thanks for a great product. > > > > I want to use PJSIP's C API to record the incoming audio to a file on a > machine with _*no*_ hardware sound device. I’ve read the FAQ and the > PJMEDIA documentation but am still unclear about the architecture of > bridges, media ports and sound devices. > > > > My target machines, both Windows 10 and Linux, have no hardware audio > devices installed, so I call pjsua_set_null_snd_dev() after initializing > and starting the libraries. Example code below. > > > > Later after I make a SIP call and it is answered I attempt to attach a WAV file writer to the DEFAULT_CAPTURE_DEV, but the pjmedia_aud_dev_default_param(…) call returns PJMEDIA_AUD_INVALID_DEV. > > > > Runing the code on a machine (either Win or Linux) _*with*_ a hardware sound device succeeds and things progress as I expect. Even though pjsua_set_null_snd_dev() is invoked. Absolutely no changes to the code. > > > > Is there a resource I can consult so to understand this better? > > > > James > > > > /** Code **/ > > > > #include <pjlib.h> > > #include <pjlib-util.h> > > #include <pjnath.h> > > #include <pjsip.h> > > #include <pjsip_ua.h> > > #include <pjsip_simple.h> > > #include <pjsua-lib/pjsua.h> > > #include <pjmedia.h> > > #include <pjmedia-codec.h> > > #include <pj/log.h> > > #include <pj/os.h> > > > > int main(int, char **) > > { > > // Create pjsua first! > > pj_status_t status = pjsua_create(); > > if (status != PJ_SUCCESS) > > { > > fprintf(stderr,"pjsua_create error\n"); > > return -1; > > } > > > > // Init pjsua > > pjsua_config cfg; > > pjsua_logging_config log_cfg; > > > > pjsua_config_default(&cfg); > > > > pjsua_logging_config_default(&log_cfg); > > log_cfg.console_level = 4; > > > > status = pjsua_init(&cfg, &log_cfg, NULL); > > if (status != PJ_SUCCESS) > > { > > fprintf(stderr,"pjsua_init error\n"); > > return -1; > > } > > > > > > // Proactively list known audio devices so we are sure there are NONE > > pjmedia_aud_dev_info info[64]; > > unsigned info_count = 64; > > pjsua_enum_aud_devs(info, &info_count); > > > > fprintf(stderr,"Listing known sound devices, total of [%u]\n", info_count); > > for (unsigned i = 0; i<info_count; ++i) > > { > > fprintf(stderr,"Name [%s]", info[i].name); > > } > > > > // Add transport > > pjsua_transport_config tcfg; > > pjsua_transport_id trans_id; > > pjsua_transport_config_default(&tcfg); > > tcfg.port = 5060; > > status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &tcfg, &trans_id); > > if (status != PJ_SUCCESS) > > { > > fprintf(stderr, "pjsua_transport_create error\n"); > > return -1; > > } > > > > // Initialization is done, now start pjsua > > status = pjsua_start(); > > if (status != PJ_SUCCESS) > > { > > fprintf(stderr, "pjsua_start error\n"); > > return -1; > > } > > > > // Set NULL sound > > status = pjsua_set_null_snd_dev(); > > if (status != PJ_SUCCESS) > > { > > fprintf(stderr, "pjsua_set_null_snd_dev error"); > > return -1; > > } > > > > // Register to a SIP server by creating SIP account, I happen to use Asterisk > > pjsua_acc_id acc_id; > > fprintf(stderr, "Setting up SIP server registration\n"); > > { > > pjsua_acc_config cfg; > > pjsua_acc_config_default(&cfg); > > cfg.id = pj_str("sip:6001@10.0.0.21"); > > cfg.reg_uri = cfg.id; // same as ID > > cfg.cred_count = 1; > > > > cfg.cred_info[0].realm = pj_str("*"); > > cfg.cred_info[0].scheme = pj_str("digest"); > > cfg.cred_info[0].username = pj_str("6001"); > > cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD; > > cfg.cred_info[0].data = pj_str("password"); > > > > status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id); > > if (status != PJ_SUCCESS) > > { > > fprintf(stderr, "pjsua_acc_add error\n"); > > return -1; > > } > > } > > > > fprintf(stderr, "Waiting for SIP server registration to complete....\n"); > > > > Sleep(2000); // sleep 2 seconds > > > > // Call extension 9 on my Asterisk server at 10.0.0.21:5060 > > pj_str_t sip_target(pj_str("sip:9@10.0.0.21")); > > fprintf(stderr, "Making call to [%s]\n", sip_target.ptr); > > > > pjsua_call_id call_id; > > status = pjsua_call_make_call(acc_id, &sip_target, 0, NULL, NULL, &call_id); > > if (status != PJ_SUCCESS) > > { > > fprintf(stderr, "pjsua_call_make_call error\n"); > > return -1; > > } > > > > pj_pool_t * pool = nullptr; > > pjmedia_port * wav = nullptr; > > pjmedia_aud_stream *strm = nullptr; > > pool = pj_pool_create(pjmedia_aud_subsys_get_pool_factory(), "wav-audio", 1000, 1000, NULL); > > > > if (nullptr == pool) > > { > > fprintf(stderr,"Pool creation failed\n"); > > return -1; > > } > > > > // 8kHz, single channel 16bit MS WAV format file > > status = pjmedia_wav_writer_port_create(pool, "test.wav", 8000, 1, 320, 16, PJMEDIA_FILE_WRITE_PCM, 0, &wav); > > if (status != PJ_SUCCESS) > > { > > fprintf(stderr, "Error creating WAV file\n"); > > return -1; > > } > > > > pjmedia_aud_param param; > > ////////////////////////////////////////////////////// > > // FAILURE HERE : This is the function call which returns PJMEDIA_AUD_INVALID_DEV > > ////////////////////////////////////////////////////// > > status = pjmedia_aud_dev_default_param(PJMEDIA_AUD_DEFAULT_CAPTURE_DEV, &param); > > if (status != PJ_SUCCESS) > > { > > fprintf(stderr, "pjmedia_aud_dev_default_param()"); > > return -1; > > } > > > > param.dir = PJMEDIA_DIR_CAPTURE; > > param.clock_rate = PJMEDIA_PIA_SRATE(&wav->info); > > param.samples_per_frame = PJMEDIA_PIA_SPF(&wav->info); > > param.channel_count = PJMEDIA_PIA_CCNT(&wav->info); > > param.bits_per_sample = PJMEDIA_PIA_BITS(&wav->info); > > > > status = pjmedia_aud_stream_create(&param, &test_rec_cb, &test_play_cb, wav, &strm); > > if (status != PJ_SUCCESS) > > { > > fprintf(stderr, "Error opening the sound stream"); > > return -1; > > } > > > > status = pjmedia_aud_stream_start(strm); > > if (status != PJ_SUCCESS) > > { > > fprintf(stderr, "Error starting the sound device"); > > return -1; > > } > > > > // Spend some time allowing the called party to pick up and recording to proceed > > Sleep(10000); // sleep 10 seconds > > > > // Clean up code omitted > > return 0; > > } > > > > > > _______________________________________________ > Visit our blog: http://blog.pjsip.org > > pjsip mailing list > pjsip@lists.pjsip.org > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org > >