예제 #1
0
int pa_cvolume_compatible_with_channel_map(const pa_cvolume *v, const pa_channel_map *cm) {
    pa_assert(v);
    pa_assert(cm);

    pa_return_val_if_fail(pa_cvolume_valid(v), 0);
    pa_return_val_if_fail(pa_channel_map_valid(cm), 0);

    return v->channels == cm->channels;
}
예제 #2
0
파일: volume.c 프로젝트: KimT/pulseaudio_kt
pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) {

    pa_return_val_if_fail(a != PA_VOLUME_INVALID, PA_VOLUME_INVALID);
    pa_return_val_if_fail(b != PA_VOLUME_INVALID, PA_VOLUME_INVALID);

    /* cbrt((a/PA_VOLUME_NORM)^3*(b/PA_VOLUME_NORM)^3)*PA_VOLUME_NORM = a*b/PA_VOLUME_NORM */

    return (pa_volume_t) (((uint64_t) a * (uint64_t) b + (uint64_t) PA_VOLUME_NORM / 2ULL) / (uint64_t) PA_VOLUME_NORM);
}
예제 #3
0
pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) {

    pa_return_val_if_fail(PA_VOLUME_IS_VALID(a), PA_VOLUME_INVALID);
    pa_return_val_if_fail(PA_VOLUME_IS_VALID(b), PA_VOLUME_INVALID);

    /* cbrt((a/PA_VOLUME_NORM)^3*(b/PA_VOLUME_NORM)^3)*PA_VOLUME_NORM = a*b/PA_VOLUME_NORM */

    return (pa_volume_t) PA_CLAMP_VOLUME((((uint64_t) a * (uint64_t) b + (uint64_t) PA_VOLUME_NORM / 2ULL) / (uint64_t) PA_VOLUME_NORM));
}
예제 #4
0
int pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *ss) {
    pa_assert(map);
    pa_assert(ss);

    pa_return_val_if_fail(pa_channel_map_valid(map), 0);
    pa_return_val_if_fail(pa_sample_spec_valid(ss), 0);

    return map->channels == ss->channels;
}
예제 #5
0
pa_volume_t pa_sw_volume_divide(pa_volume_t a, pa_volume_t b) {

    pa_return_val_if_fail(PA_VOLUME_IS_VALID(a), PA_VOLUME_INVALID);
    pa_return_val_if_fail(PA_VOLUME_IS_VALID(b), PA_VOLUME_INVALID);

    if (b <= PA_VOLUME_MUTED)
        return 0;

    return (pa_volume_t) (((uint64_t) a * (uint64_t) PA_VOLUME_NORM + (uint64_t) b / 2ULL) / (uint64_t) b);
}
예제 #6
0
int pa_cvolume_compatible(const pa_cvolume *v, const pa_sample_spec *ss) {

    pa_assert(v);
    pa_assert(ss);

    pa_return_val_if_fail(pa_cvolume_valid(v), 0);
    pa_return_val_if_fail(pa_sample_spec_valid(ss), 0);

    return v->channels == ss->channels;
}
예제 #7
0
int pa_channel_map_has_position(const pa_channel_map *map, pa_channel_position_t p) {
    unsigned c;

    pa_return_val_if_fail(pa_channel_map_valid(map), 0);
    pa_return_val_if_fail(p < PA_CHANNEL_POSITION_MAX, 0);

    for (c = 0; c < map->channels; c++)
        if (map->map[c] == p)
            return 1;

    return 0;
}
예제 #8
0
pa_cvolume* pa_cvolume_set_lfe_balance(pa_cvolume *v, const pa_channel_map *map, float new_balance) {
    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_balance >= -1.0f, NULL);
    pa_return_val_if_fail(new_balance <= 1.0f, NULL);

    if (!pa_channel_map_can_lfe_balance(map))
        return v;

    return set_balance(v, map, new_balance, on_hfe, on_lfe);
}
예제 #9
0
int pa_cvolume_channels_equal_to(const pa_cvolume *a, pa_volume_t v) {
    unsigned c;
    pa_assert(a);

    pa_return_val_if_fail(pa_cvolume_valid(a), 0);
    pa_return_val_if_fail(PA_VOLUME_IS_VALID(v), 0);

    for (c = 0; c < a->channels; c++)
        if (a->values[c] != v)
            return 0;

    return 1;
}
예제 #10
0
pa_cvolume *pa_cvolume_remap(pa_cvolume *v, const pa_channel_map *from, const pa_channel_map *to) {
    int a, b;
    pa_cvolume result;

    pa_assert(v);
    pa_assert(from);
    pa_assert(to);

    pa_return_val_if_fail(pa_channel_map_valid(to), NULL);
    pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, from), NULL);

    if (pa_channel_map_equal(from, to))
        return v;

    result.channels = to->channels;

    for (b = 0; b < to->channels; b++) {
        pa_volume_t k = 0;
        int n = 0;

        for (a = 0; a < from->channels; a++)
            if (from->map[a] == to->map[b]) {
                k += v->values[a];
                n ++;
            }

        if (n <= 0) {
            for (a = 0; a < from->channels; a++)
                if ((on_left(from->map[a]) && on_left(to->map[b])) ||
                    (on_right(from->map[a]) && on_right(to->map[b])) ||
                    (on_center(from->map[a]) && on_center(to->map[b])) ||
                    (on_lfe(from->map[a]) && on_lfe(to->map[b]))) {

                    k += v->values[a];
                    n ++;
                }
        }

        if (n <= 0)
            k = pa_cvolume_avg(v);
        else
            k /= n;

        result.values[b] = k;
    }

    *v = result;
    return v;
}
예제 #11
0
pa_volume_t pa_cvolume_avg_mask(const pa_cvolume *a, const pa_channel_map *cm, pa_channel_position_mask_t mask) {
    uint64_t sum = 0;
    unsigned c, n;

    pa_assert(a);

    if (!cm)
        return pa_cvolume_avg(a);

    pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(a, cm), PA_VOLUME_MUTED);

    for (c = n = 0; c < a->channels; c++) {

        if (!(PA_CHANNEL_POSITION_MASK(cm->map[c]) & mask))
            continue;

        sum += a->values[c];
        n ++;
    }

    if (n > 0)
        sum /= n;

    return (pa_volume_t) sum;
}
예제 #12
0
pa_cvolume *pa_sw_cvolume_divide_scalar(pa_cvolume *dest, const pa_cvolume *a, pa_volume_t b) {
    unsigned i;

    pa_assert(dest);
    pa_assert(a);

    pa_return_val_if_fail(pa_cvolume_valid(a), NULL);
    pa_return_val_if_fail(PA_VOLUME_IS_VALID(b), NULL);

    for (i = 0; i < a->channels; i++)
        dest->values[i] = pa_sw_volume_divide(a->values[i], b);

    dest->channels = (uint8_t) i;

    return dest;
}
예제 #13
0
float pa_cvolume_get_balance(const pa_cvolume *v, const pa_channel_map *map) {
    pa_volume_t left, right;

    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_balance(map))
        return 0.0f;

    get_avg_lr(map, v, &left, &right);

    if (left == right)
        return 0.0f;

    /*   1.0,  0.0  =>  -1.0
         0.0,  1.0  =>   1.0
         0.0,  0.0  =>   0.0
         0.5,  0.5  =>   0.0
         1.0,  0.5  =>  -0.5
         1.0,  0.25 => -0.75
         0.75, 0.25 => -0.66
         0.5,  0.25 => -0.5   */

    if (left > right)
        return -1.0f + ((float) right / (float) left);
    else
        return 1.0f - ((float) left / (float) right);
}
예제 #14
0
pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec) {
    pa_volume_t m;

    pa_assert(v);

    pa_return_val_if_fail(pa_cvolume_valid(v), NULL);
    pa_return_val_if_fail(PA_VOLUME_IS_VALID(dec), NULL);

    m = pa_cvolume_max(v);

    if (m <= PA_VOLUME_MUTED + dec)
        m = PA_VOLUME_MUTED;
    else
        m -= dec;

    return pa_cvolume_scale(v, m);
}
예제 #15
0
pa_cvolume* pa_cvolume_merge(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b) {
    unsigned i;

    pa_assert(dest);
    pa_assert(a);
    pa_assert(b);

    pa_return_val_if_fail(pa_cvolume_valid(a), NULL);
    pa_return_val_if_fail(pa_cvolume_valid(b), NULL);

    for (i = 0; i < a->channels && i < b->channels; i++)
        dest->values[i] = PA_MAX(a->values[i], b->values[i]);

    dest->channels = (uint8_t) i;

    return dest;
}
예제 #16
0
pa_cvolume* pa_cvolume_inc_clamp(pa_cvolume *v, pa_volume_t inc, pa_volume_t limit) {
    pa_volume_t m;

    pa_assert(v);

    pa_return_val_if_fail(pa_cvolume_valid(v), NULL);
    pa_return_val_if_fail(PA_VOLUME_IS_VALID(inc), NULL);

    m = pa_cvolume_max(v);

    if (m >= limit - inc)
        m = limit;
    else
        m += inc;

    return pa_cvolume_scale(v, m);
}
예제 #17
0
double pa_sw_volume_to_dB(pa_volume_t v) {

    pa_return_val_if_fail(PA_VOLUME_IS_VALID(v), PA_DECIBEL_MININFTY);

    if (v <= PA_VOLUME_MUTED)
        return PA_DECIBEL_MININFTY;

    return linear_to_dB(pa_sw_volume_to_linear(v));
}
예제 #18
0
/* For compressed streams */
pa_bool_t pa_format_info_to_sample_spec_fake(pa_format_info *f, pa_sample_spec *ss) {
    int rate;

    pa_assert(f);
    pa_assert(ss);
    pa_return_val_if_fail(f->encoding != PA_ENCODING_PCM, FALSE);

    ss->format = PA_SAMPLE_S16LE;
    ss->channels = 2;

    pa_return_val_if_fail(pa_format_info_get_prop_int(f, PA_PROP_FORMAT_RATE, &rate), FALSE);
    ss->rate = (uint32_t) rate;

    if (f->encoding == PA_ENCODING_EAC3_IEC61937)
        ss->rate *= 4;

    return TRUE;
}
예제 #19
0
int pa_channel_map_superset(const pa_channel_map *a, const pa_channel_map *b) {
    pa_channel_position_mask_t am, bm;

    pa_assert(a);
    pa_assert(b);

    pa_return_val_if_fail(pa_channel_map_valid(a), 0);

    if (PA_UNLIKELY(a == b))
        return 1;

    pa_return_val_if_fail(pa_channel_map_valid(b), 0);

    am = pa_channel_map_mask(a);
    bm = pa_channel_map_mask(b);

    return (bm & am) == bm;
}
예제 #20
0
pa_cvolume* pa_cvolume_scale(pa_cvolume *v, pa_volume_t max) {
    unsigned c;
    pa_volume_t t = 0;

    pa_assert(v);

    pa_return_val_if_fail(pa_cvolume_valid(v), NULL);
    pa_return_val_if_fail(PA_VOLUME_IS_VALID(max), NULL);

    t = pa_cvolume_max(v);

    if (t <= PA_VOLUME_MUTED)
        return pa_cvolume_set(v, v->channels, max);

    for (c = 0; c < v->channels; c++)
        v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) max) / (uint64_t) t);

    return v;
}
예제 #21
0
const char* pa_channel_map_to_pretty_name(const pa_channel_map *map) {
    pa_bitset_t in_map[PA_BITSET_ELEMENTS(PA_CHANNEL_POSITION_MAX)];
    unsigned c;

    pa_assert(map);

    pa_return_val_if_fail(pa_channel_map_valid(map), NULL);

    memset(in_map, 0, sizeof(in_map));

    for (c = 0; c < map->channels; c++)
        pa_bitset_set(in_map, map->map[c], TRUE);

    pa_init_i18n();

    if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
                         PA_CHANNEL_POSITION_MONO, -1))
        return _("Mono");

    if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
                         PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT, -1))
        return _("Stereo");

    if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
                         PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
                         PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, -1))
        return _("Surround 4.0");

    if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
                         PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
                         PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
                         PA_CHANNEL_POSITION_LFE, -1))
        return _("Surround 4.1");

    if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
                         PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
                         PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
                         PA_CHANNEL_POSITION_FRONT_CENTER, -1))
        return _("Surround 5.0");

    if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
                         PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
                         PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
                         PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE, -1))
        return _("Surround 5.1");

    if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
                         PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
                         PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
                         PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE,
                         PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT, -1))
        return _("Surround 7.1");

    return NULL;
}
예제 #22
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;
}
예제 #23
0
pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, float new_balance) {
    pa_volume_t left, nleft, right, nright, 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_balance >= -1.0f, NULL);
    pa_return_val_if_fail(new_balance <= 1.0f, NULL);

    if (!pa_channel_map_can_balance(map))
        return v;

    get_avg_lr(map, v, &left, &right);

    m = PA_MAX(left, right);

    if (new_balance <= 0) {
        nright = (new_balance + 1.0f) * m;
        nleft = m;
    } else {
        nleft = (1.0f - new_balance) * m;
        nright = m;
    }

    for (c = 0; c < map->channels; c++) {
        if (on_left(map->map[c])) {
            if (left == 0)
                v->values[c] = nleft;
            else
                v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) nleft) / (uint64_t) left);
        } else if (on_right(map->map[c])) {
            if (right == 0)
                v->values[c] = nright;
            else
                v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) nright) / (uint64_t) right);
        }
    }

    return v;
}
예제 #24
0
pa_channel_position_mask_t pa_channel_map_mask(const pa_channel_map *map) {
    unsigned c;
    pa_channel_position_mask_t r = 0;

    pa_return_val_if_fail(pa_channel_map_valid(map), 0);

    for (c = 0; c < map->channels; c++)
        r |= PA_CHANNEL_POSITION_MASK(map->map[c]);

    return r;
}
예제 #25
0
pa_volume_t pa_cvolume_get_position(
        pa_cvolume *cv,
        const pa_channel_map *map,
        pa_channel_position_t t) {

    unsigned c;
    pa_volume_t v = PA_VOLUME_MUTED;

    pa_assert(cv);
    pa_assert(map);

    pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(cv, map), PA_VOLUME_MUTED);
    pa_return_val_if_fail(t < PA_CHANNEL_POSITION_MAX, PA_VOLUME_MUTED);

    for (c = 0; c < map->channels; c++)
        if (map->map[c] == t)
            if (cv->values[c] > v)
                v = cv->values[c];

    return v;
}
예제 #26
0
int pa_channel_map_can_fade(const pa_channel_map *map) {
    pa_channel_position_mask_t m;

    pa_assert(map);
    pa_return_val_if_fail(pa_channel_map_valid(map), 0);

    m = pa_channel_map_mask(map);

    return
        (PA_CHANNEL_POSITION_MASK_FRONT & m) &&
        (PA_CHANNEL_POSITION_MASK_REAR & m);
}
예제 #27
0
const char* pa_channel_map_to_name(const pa_channel_map *map) {
    pa_bitset_t in_map[PA_BITSET_ELEMENTS(PA_CHANNEL_POSITION_MAX)];
    unsigned c;

    pa_assert(map);

    pa_return_val_if_fail(pa_channel_map_valid(map), NULL);

    memset(in_map, 0, sizeof(in_map));

    for (c = 0; c < map->channels; c++)
        pa_bitset_set(in_map, map->map[c], TRUE);

    if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
                         PA_CHANNEL_POSITION_MONO, -1))
        return "mono";

    if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
                         PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT, -1))
        return "stereo";

    if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
                         PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
                         PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, -1))
        return "surround-40";

    if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
                         PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
                         PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
                         PA_CHANNEL_POSITION_LFE, -1))
        return "surround-41";

    if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
                         PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
                         PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
                         PA_CHANNEL_POSITION_FRONT_CENTER, -1))
        return "surround-50";

    if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
                         PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
                         PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
                         PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE, -1))
        return "surround-51";

    if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
                         PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
                         PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
                         PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE,
                         PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT, -1))
        return "surround-71";

    return NULL;
}
예제 #28
0
pa_bool_t pa_format_info_get_prop_int(pa_format_info *f, const char *key, int *v) {
    const char *str;
    json_object *o;

    pa_assert(f);
    pa_assert(key);
    pa_assert(v);

    pa_return_val_if_fail(str = pa_proplist_gets(f->plist, key), FALSE);
    o = json_tokener_parse(str);
    pa_return_val_if_fail(!is_error(o), FALSE);
    if (json_object_get_type(o) != json_type_int) {
        json_object_put(o);
        return FALSE;
    }

    *v = json_object_get_int(o);
    json_object_put(o);

    return TRUE;
}
예제 #29
0
int pa_cvolume_equal(const pa_cvolume *a, const pa_cvolume *b) {
    int i;
    pa_assert(a);
    pa_assert(b);

    pa_return_val_if_fail(pa_cvolume_valid(a), 0);

    if (PA_UNLIKELY(a == b))
        return 1;

    pa_return_val_if_fail(pa_cvolume_valid(b), 0);

    if (a->channels != b->channels)
        return 0;

    for (i = 0; i < a->channels; i++)
        if (a->values[i] != b->values[i])
            return 0;

    return 1;
}
예제 #30
0
pa_volume_t pa_cvolume_min(const pa_cvolume *a) {
    pa_volume_t m = PA_VOLUME_MAX;
    unsigned c;

    pa_assert(a);
    pa_return_val_if_fail(pa_cvolume_valid(a), PA_VOLUME_MUTED);

    for (c = 0; c < a->channels; c++)
        if (a->values[c] < m)
            m = a->values[c];

    return m;
}