Загрузка данных


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(&param);
        param.ec_options = pjsua_var.media_cfg.ec_options;
        status = create_aud_param(&param.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(&param);
        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;
}