static void
set_from_pa_map (GvcChannelMap        *map,
                 const pa_channel_map *pa_map)
{
        g_assert (pa_channel_map_valid(pa_map));

        map->priv->can_balance = pa_channel_map_can_balance (pa_map);
        map->priv->can_fade = pa_channel_map_can_fade (pa_map);

        map->priv->pa_map = *pa_map;
        pa_cvolume_set(&map->priv->pa_volume, pa_map->channels, PA_VOLUME_NORM);
}
Esempio n. 2
0
pa_cvolume* pa_cvolume_set_fade(pa_cvolume *v, const pa_channel_map *map, float new_fade) {
    pa_assert(map);
    pa_assert(v);

    pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), NULL);
    pa_return_val_if_fail(new_fade >= -1.0f, NULL);
    pa_return_val_if_fail(new_fade <= 1.0f, NULL);

    if (!pa_channel_map_can_fade(map))
        return v;

    return set_balance(v, map, new_fade, on_rear, on_front);
}
Esempio n. 3
0
pa_cvolume* pa_cvolume_set_fade(pa_cvolume *v, const pa_channel_map *map, float new_fade) {
    pa_volume_t front, nfront, rear, nrear, m;
    unsigned c;

    pa_assert(map);
    pa_assert(v);

    pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), NULL);
    pa_return_val_if_fail(new_fade >= -1.0f, NULL);
    pa_return_val_if_fail(new_fade <= 1.0f, NULL);

    if (!pa_channel_map_can_fade(map))
        return v;

    get_avg_fr(map, v, &front, &rear);

    m = PA_MAX(front, rear);

    if (new_fade <= 0) {
        nfront = (new_fade + 1.0f) * m;
        nrear = m;
    } else {
        nrear = (1.0f - new_fade) * m;
        nfront = m;
    }

    for (c = 0; c < map->channels; c++) {
        if (on_front(map->map[c])) {
            if (front == 0)
                v->values[c] = nfront;
            else
                v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) nfront) / (uint64_t) front);
        } else if (on_rear(map->map[c])) {
            if (rear == 0)
                v->values[c] = nrear;
            else
                v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) nrear) / (uint64_t) rear);
        }
    }

    return v;
}
Esempio n. 4
0
float pa_cvolume_get_fade(const pa_cvolume *v, const pa_channel_map *map) {
    pa_volume_t front, rear;

    pa_assert(v);
    pa_assert(map);

    pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), 0.0f);

    if (!pa_channel_map_can_fade(map))
        return 0.0f;

    get_avg_fr(map, v, &front, &rear);

    if (front == rear)
        return 0.0f;

    if (rear > front)
        return -1.0f + ((float) front / (float) rear);
    else
        return 1.0f - ((float) rear / (float) front);
}
static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *core, pa_sink_input_new_data *data, struct userdata *u) {
    const char *hpos, *vpos, *role, *id;
    double f;
    char t[PA_CVOLUME_SNPRINT_MAX];
    pa_cvolume v;

    pa_assert(data);

    if (!(role = pa_proplist_gets(data->proplist, PA_PROP_MEDIA_ROLE)))
        return PA_HOOK_OK;

    if (!pa_streq(role, "event"))
        return PA_HOOK_OK;

    if ((id = pa_proplist_gets(data->proplist, PA_PROP_EVENT_ID))) {

        /* The test sounds should never be positioned in space, since
         * they might be triggered themselves to configure the speakers
         * in space, which we don't want to mess up. */

        if (pa_startswith(id, "audio-channel-"))
            return PA_HOOK_OK;

        if (pa_streq(id, "audio-volume-change"))
            return PA_HOOK_OK;

        if (pa_streq(id, "audio-test-signal"))
            return PA_HOOK_OK;
    }

    if (!(hpos = pa_proplist_gets(data->proplist, PA_PROP_EVENT_MOUSE_HPOS)))
        hpos = pa_proplist_gets(data->proplist, PA_PROP_WINDOW_HPOS);

    if (!(vpos = pa_proplist_gets(data->proplist, PA_PROP_EVENT_MOUSE_VPOS)))
        vpos = pa_proplist_gets(data->proplist, PA_PROP_WINDOW_VPOS);

    if (!hpos && !vpos)
        return PA_HOOK_OK;

    pa_cvolume_reset(&v, data->sink->sample_spec.channels);

    if (hpos) {
        if (parse_pos(hpos, &f) < 0)
            return PA_HOOK_OK;

        if (pa_channel_map_can_balance(&data->sink->channel_map)) {
            pa_log_debug("Positioning event sound '%s' horizontally at %0.2f.", pa_strnull(pa_proplist_gets(data->proplist, PA_PROP_EVENT_ID)), f);
            pa_cvolume_set_balance(&v, &data->sink->channel_map, f*2.0-1.0);
        }
    }

    if (vpos) {
        if (parse_pos(vpos, &f) < 0)
            return PA_HOOK_OK;

        if (pa_channel_map_can_fade(&data->sink->channel_map)) {
            pa_log_debug("Positioning event sound '%s' vertically at %0.2f.", pa_strnull(pa_proplist_gets(data->proplist, PA_PROP_EVENT_ID)), f);
            pa_cvolume_set_fade(&v, &data->sink->channel_map, f*2.0-1.0);
        }
    }

    pa_log_debug("Final volume factor %s.", pa_cvolume_snprint(t, sizeof(t), &v));
    pa_sink_input_new_data_add_volume_factor_sink(data, u->name, &v);

    return PA_HOOK_OK;
}