跳转至

pa_alsa_path_probe

int pa_alsa_path_probe(pa_alsa_path *p, pa_alsa_mapping *mapping, snd_mixer_t *m, bool ignore_dB) {
    pa_alsa_element *e;
    pa_alsa_jack *j;
    double min_dB[PA_CHANNEL_POSITION_MAX], max_dB[PA_CHANNEL_POSITION_MAX];
    pa_channel_position_t t;
    pa_channel_position_mask_t path_volume_channels = 0;

    pa_assert(p);
    pa_assert(m);

    // 如果路径已经被探测过,返回其是否受支持的状态
    if (p->probed)
        return p->supported ? 0 : -1;
    p->probed = true;

    // 初始化 min_dB 和 max_dB 数组
    pa_zero(min_dB);
    pa_zero(max_dB);

    // 输出调试信息,表示正在探测此路径
    pa_log_debug("Probing path '%s'", p->name);

    // 遍历路径中的所有插孔,进行探测
    PA_LLIST_FOREACH(j, p->jacks) {
        // 调用 jack_probe 函数对插孔进行探测
        if (jack_probe(j, mapping, m) < 0) {
            // 插孔探测失败,标记路径不受支持,并返回错误
            p->supported = false;
            pa_log_debug("Probe of jack '%s' failed.", j->alsa_name);
            return -1;
        }
        // 输出调试信息,表示插孔探测成功
        pa_log_debug("Probe of jack '%s' succeeded (%s)", j->alsa_name, j->has_control ? "found!" : "not found");
    }

    // 遍历路径中的所有元素,进行探测
    PA_LLIST_FOREACH(e, p->elements) {
        // 调用 element_probe 函数对元素进行探测
        if (element_probe(e, m) < 0) {
            // 元素探测失败,标记路径不受支持,并返回错误
            p->supported = false;
            pa_log_debug("Probe of element '%s' failed.", e->alsa_name);
            return -1;
        }
        // 输出调试信息,表示元素探测成功,并显示其音量、开关和枚举使用情况
        pa_log_debug("Probe of element '%s' succeeded (volume=%d, switch=%d, enumeration=%d).", e->alsa_name, e->volume_use, e->switch_use, e->enumeration_use);

        // 如果忽略 dB 信息,将 has_dB 设置为 false
        if (ignore_dB)
            e->has_dB = false;

        if (e->volume_use == PA_ALSA_VOLUME_MERGE) {
            // 处理合并音量的情况

            // 如果路径中尚无音量信息,初始化 min_volume 和 max_volume
            if (!p->has_volume) {
                p->min_volume = e->min_volume;
                p->max_volume = e->max_volume;
            }

            if (e->has_dB) {
                // 如果元素有 dB 信息,处理 dB 音量

                // 如果路径中尚无音量信息,初始化 min_dB 和 max_dB,并记录音量通道位置
                if (!p->has_volume) {
                    for (t = 0; t < PA_CHANNEL_POSITION_MAX; t++)
                        if (PA_CHANNEL_POSITION_MASK(t) & e->merged_mask) {
                            min_dB[t] = e->min_dB;
                            max_dB[t] = e->max_dB;
                            path_volume_channels |= PA_CHANNEL_POSITION_MASK(t);
                        }

                    p->has_dB = true;
                } else {
                    // 如果路径中已经存在音量信息,更新 min_dB 和 max_dB,以及音量通道位置
                    if (p->has_dB) {
                        for (t = 0; t < PA_CHANNEL_POSITION_MAX; t++)
                            if (PA_CHANNEL_POSITION_MASK(t) & e->merged_mask) {
                                min_dB[t] += e->min_dB;
                                max_dB[t] += e->max_dB;
                                path_volume_channels |= PA_CHANNEL_POSITION_MASK(t);
                            }
                    } else {
                        /* 哎呀,我们前面有另一个元素无法使用 dB 音量,所以我们需要 "中和" 这个滑块 */
                        e->volume_use = PA_ALSA_VOLUME_ZERO;
                        pa_log_info("Zeroing volume of '%s' on path '%s'", e->alsa_name, p->name);
                    }
                }
            } else if (p->has_volume) {
                /* 我们无法使用这个音量,所以我们将其忽略 */
                e->volume_use = PA_ALSA_VOLUME_IGNORE;
                pa_log_info("Ignoring volume of '%s' on path '%s' (missing dB info)", e->alsa_name, p->name);
            }
            p->has_volume = true;
        }

        if (e->switch_use == PA_ALSA_SWITCH_MUTE)
            p->has_mute = true;
    }

    // 如果路径需要任何元素,但没有预置的元素,则标记路径不受支持
    if (p->has_req_any && !p->req_any_present) {
        p->supported = false;
        pa_log_debug("Skipping path '%s', none of required-any elements preset.", p->name);
        return -1;
    }

    // 丢弃不受支持的元素
    path_drop_unsupported(p);
    // 确保路径选项唯一
    path_make_options_unique(p);
    // 为路径创建设置项

    // 标记路径受支持
    p->supported = true;

    // 初始化路径的最小和最大 dB 值
    p->min_dB = INFINITY;
    p->max_dB = -INFINITY;

    // 计算路径的最小和最大 dB 值
    for (t = 0; t < PA_CHANNEL_POSITION_MAX; t++) {
        if (path_volume_channels & PA_CHANNEL_POSITION_MASK(t)) {
            if (p->min_dB > min_dB[t])
                p->min_dB = min_dB[t];

            if (p->max_dB < max_dB[t])
                p->max_dB = max_dB[t];
        }
    }

    return 0;
}

💬 评论