Загрузка данных
typedef struct pjsua_snd_dev_param
{
int capture_dev;
int playback_dev;
unsigned mode;
pj_bool_t use_default_settings;
} pjsua_snd_dev_param;
PJ_DEF(pj_status_t) pjsua_set_snd_dev2(const pjsua_snd_dev_param *snd_param)
{
unsigned alt_cr_cnt = 1;
unsigned alt_cr[] = {0, 44100, 48000, 32000, 16000, 8000};
unsigned i;
pj_status_t status = PJ_SUCCESS;
unsigned orig_snd_dev_mode = pjsua_var.snd_mode;
PJ_ASSERT_RETURN(snd_param, PJ_EINVAL);
PJ_LOG(4,(THIS_FILE, "Set sound device: capture=%d, playback=%d, mode=%d, "
"use_default_settings=%d",
snd_param->capture_dev, snd_param->playback_dev,
snd_param->mode, snd_param->use_default_settings));
pj_log_push_indent();
PJSUA_LOCK();
/* Check if there are no changes in sound device settings */
if (pjsua_var.cap_dev == snd_param->capture_dev &&
pjsua_var.play_dev == snd_param->playback_dev &&
pjsua_var.snd_mode == snd_param->mode)
{
/* If sound device is already opened, just print log and return.
* Also if PJSUA_SND_DEV_NO_IMMEDIATE_OPEN is set.
*/
if (pjsua_var.snd_is_on || (snd_param->mode &
PJSUA_SND_DEV_NO_IMMEDIATE_OPEN))
{
PJ_LOG(4,(THIS_FILE,"No changes in capture and playback devices"));
PJSUA_UNLOCK();
pj_log_pop_indent();
return PJ_SUCCESS;
}
}
/* No sound */
if (snd_param->capture_dev == PJSUA_SND_NO_DEV &&
snd_param->playback_dev == PJSUA_SND_NO_DEV)
{
PJSUA_UNLOCK();
PJ_LOG(4, (THIS_FILE, "No sound device, mode setting is ignored"));
if (!pjsua_var.no_snd)
PJ_ASSERT_RETURN(pjsua_set_no_snd_dev(), PJ_ENOTFOUND);
pj_log_pop_indent();
return status;
}
/* Null-sound */
if (snd_param->capture_dev == PJSUA_SND_NULL_DEV &&
snd_param->playback_dev == PJSUA_SND_NULL_DEV)
{
PJSUA_UNLOCK();
PJ_LOG(4, (THIS_FILE, "Null sound device, mode setting is ignored"));
status = pjsua_set_null_snd_dev();
pj_log_pop_indent();
return status;
}
pjsua_var.snd_mode = snd_param->mode;
/* Just update the IDs if app does not want to open now and currently
* audio is off.
*/
if (!pjsua_var.snd_is_on &&
(snd_param->mode & PJSUA_SND_DEV_NO_IMMEDIATE_OPEN))
{
pjsua_var.cap_dev = snd_param->capture_dev;
pjsua_var.play_dev = snd_param->playback_dev;
pjsua_var.no_snd = PJ_FALSE;
PJSUA_UNLOCK();
pj_log_pop_indent();
return PJ_SUCCESS;
}
/* Set default clock rate */
alt_cr[0] = pjsua_var.media_cfg.snd_clock_rate;
if (alt_cr[0] == 0)
alt_cr[0] = pjsua_var.media_cfg.clock_rate;
/* Allow retrying of different clock rate if we're using conference
* bridge (meaning audio format is always PCM), otherwise lock on
* to one clock rate.
*/
if (pjsua_var.is_mswitch) {
alt_cr_cnt = 1;
} else {
alt_cr_cnt = PJ_ARRAY_SIZE(alt_cr);
}
/* Attempts to open the sound device with different clock rates */
for (i=0; i<alt_cr_cnt; ++i) {
pjmedia_snd_port_param param;
unsigned samples_per_frame;
/* Create the default audio param */
samples_per_frame = alt_cr[i] *
pjsua_var.media_cfg.audio_frame_ptime *
pjsua_var.media_cfg.channel_count / 1000;
pjmedia_snd_port_param_default(¶m);
param.ec_options = pjsua_var.media_cfg.ec_options;
status = create_aud_param(¶m.base, snd_param->capture_dev,
snd_param->playback_dev,
alt_cr[i], pjsua_var.media_cfg.channel_count,
samples_per_frame, 16,
snd_param->use_default_settings);
if (status != PJ_SUCCESS)
goto on_error;
/* Open! */
param.options = 0;
if (pjsua_var.media_cfg.snd_use_sw_clock)
param.options |= PJMEDIA_SND_PORT_USE_SW_CLOCK;
status = open_snd_dev(¶m);
if (status == PJ_SUCCESS)
break;
}
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to open sound device", status);
goto on_error;
}
pjsua_var.no_snd = PJ_FALSE;
pjsua_var.snd_is_on = PJ_TRUE;
PJSUA_UNLOCK();
pj_log_pop_indent();
return PJ_SUCCESS;
on_error:
pjsua_var.snd_mode = orig_snd_dev_mode;
PJSUA_UNLOCK();
pj_log_pop_indent();
return status;
}