Пример #1
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));
}
Пример #2
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);
}
Пример #3
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));
}
Пример #4
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;
}
Пример #5
0
int pa_cvolume_valid(const pa_cvolume *v) {
    unsigned c;

    pa_assert(v);

    if (!pa_channels_valid(v->channels))
        return 0;

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

    return 1;
}
Пример #6
0
int pa_cvolume_valid(const pa_cvolume *v) {
    unsigned c;

    pa_assert(v);

    if (v->channels <= 0 || v->channels > PA_CHANNELS_MAX)
        return 0;

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

    return 1;
}
Пример #7
0
char *pa_volume_snprint(char *s, size_t l, pa_volume_t v) {
    pa_assert(s);
    pa_assert(l > 0);

    pa_init_i18n();

    if (!PA_VOLUME_IS_VALID(v)) {
        pa_snprintf(s, l, _("(invalid)"));
        return s;
    }

    pa_snprintf(s, l, "%3u%%", (v*100+PA_VOLUME_NORM/2)/PA_VOLUME_NORM);
    return s;
}
Пример #8
0
/*** Sink input ***/
static void sink_input_info_cb(pa_context *ctx, const pa_sink_input_info *i,
                               int eol, void *userdata)
{
    audio_output_t *aout = userdata;
    aout_sys_t *sys = aout->sys;

    if (eol)
        return;
    (void) ctx;

    sys->cvolume = i->volume; /* cache volume for balance preservation */
    if (PA_VOLUME_IS_VALID(sys->base_volume))
        VolumeReport(aout);
    aout_MuteReport(aout, i->mute);
}
Пример #9
0
double pa_sw_volume_to_linear(pa_volume_t v) {
    double f;

    pa_return_val_if_fail(PA_VOLUME_IS_VALID(v), 0.0);

    if (v <= PA_VOLUME_MUTED)
        return 0.0;

    if (v == PA_VOLUME_NORM)
        return 1.0;

    f = ((double) v / PA_VOLUME_NORM);

    return f*f*f;
}
Пример #10
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;
}
Пример #11
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);
}
Пример #12
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);
}
Пример #13
0
char *pa_sw_volume_snprint_dB(char *s, size_t l, pa_volume_t v) {
    double f;

    pa_assert(s);
    pa_assert(l > 0);

    pa_init_i18n();

    if (!PA_VOLUME_IS_VALID(v)) {
        pa_snprintf(s, l, _("(invalid)"));
        return s;
    }

    f = pa_sw_volume_to_dB(v);
    pa_snprintf(s, l, "%0.2f dB", isinf(f) < 0 || f <= PA_DECIBEL_MININFTY ? -INFINITY : f);

    return s;
}
Пример #14
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;
}
Пример #15
0
int main(int argc, char* argv[]) {
    // Two required arguments:
    //   - source name (ex: alsa_input.pci-0000_00_1b.0.analog-stereo)
    //   - target percentage volume (ex: 10)
    pa_volume_t volume = (pa_volume_t) (atoi(argv[2]) * (double) PA_VOLUME_NORM / 100);
    if (!PA_VOLUME_IS_VALID(volume)) {
        return 3;
    }
    char* source_name = pa_xstrdup(argv[1]);

    signal(SIGINT, set_terminate);
    signal(SIGTERM, set_terminate);

    int retcode = force_volume(source_name, volume);

    pa_xfree(source_name);

    return retcode;
}
Пример #16
0
pa_operation *pa_context_play_sample_with_proplist(pa_context *c, const char *name, const char *dev, pa_volume_t volume, pa_proplist *p, pa_context_play_sample_cb_t cb, void *userdata) {
    pa_operation *o;
    pa_tagstruct *t;
    uint32_t tag;

    pa_assert(c);
    pa_assert(PA_REFCNT_VALUE(c) >= 1);

    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
    PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
    PA_CHECK_VALIDITY_RETURN_NULL(c, !dev || *dev, PA_ERR_INVALID);
    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 13, PA_ERR_NOTSUPPORTED);

    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);

    if (!dev)
        dev = c->conf->default_sink;

    t = pa_tagstruct_command(c, PA_COMMAND_PLAY_SAMPLE, &tag);
    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
    pa_tagstruct_puts(t, dev);

    if (!PA_VOLUME_IS_VALID(volume) && c->version < 15)
        volume = PA_VOLUME_NORM;

    pa_tagstruct_putu32(t, volume);
    pa_tagstruct_puts(t, name);

    if (p)
        pa_tagstruct_put_proplist(t, p);
    else {
        p = pa_proplist_new();
        pa_tagstruct_put_proplist(t, p);
        pa_proplist_free(p);
    }

    pa_pstream_send_tagstruct(c->pstream, t);
    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, play_sample_with_proplist_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);

    return o;
}
Пример #17
0
char *pa_volume_snprint_verbose(char *s, size_t l, pa_volume_t v, int print_dB) {
    char dB[PA_SW_VOLUME_SNPRINT_DB_MAX];

    pa_assert(s);
    pa_assert(l > 0);

    pa_init_i18n();

    if (!PA_VOLUME_IS_VALID(v)) {
        pa_snprintf(s, l, _("(invalid)"));
        return s;
    }

    pa_snprintf(s, l, "%" PRIu32 " / %3u%%%s%s",
                v,
                (v * 100 + PA_VOLUME_NORM / 2) / PA_VOLUME_NORM,
                print_dB ? " / " : "",
                print_dB ? pa_sw_volume_snprint_dB(dB, sizeof(dB), v) : "");

    return s;
}
Пример #18
0
pa_cvolume* pa_cvolume_scale_mask(pa_cvolume *v, pa_volume_t max, pa_channel_map *cm, pa_channel_position_mask_t mask) {
    unsigned c;
    pa_volume_t t = 0;

    pa_assert(v);

    pa_return_val_if_fail(PA_VOLUME_IS_VALID(max), NULL);

    if (!cm)
        return pa_cvolume_scale(v, max);

    pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, cm), NULL);

    t = pa_cvolume_max_mask(v, cm, mask);

    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;
}
Пример #19
0
pa_cvolume* pa_cvolume_set_position(
        pa_cvolume *cv,
        const pa_channel_map *map,
        pa_channel_position_t t,
        pa_volume_t v) {

    unsigned c;
    pa_bool_t good = FALSE;

    pa_assert(cv);
    pa_assert(map);

    pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(cv, map), NULL);
    pa_return_val_if_fail(t < PA_CHANNEL_POSITION_MAX, NULL);
    pa_return_val_if_fail(PA_VOLUME_IS_VALID(v), NULL);

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

    return good ? cv : NULL;
}
Пример #20
0
int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t volume, pa_proplist *p, uint32_t *sink_input_idx) {
    pa_scache_entry *e;
    pa_cvolume r;
    pa_proplist *merged;
    pa_bool_t pass_volume;

    pa_assert(c);
    pa_assert(name);
    pa_assert(sink);

    if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE)))
        return -1;

    merged = pa_proplist_new();
    pa_proplist_sets(merged, PA_PROP_MEDIA_NAME, name);
    pa_proplist_sets(merged, PA_PROP_EVENT_ID, name);

    if (e->lazy && !e->memchunk.memblock) {
        pa_channel_map old_channel_map = e->channel_map;

        if (pa_sound_file_load(c->mempool, e->filename, &e->sample_spec, &e->channel_map, &e->memchunk, merged) < 0)
            goto fail;

        pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index);

        if (e->volume_is_set) {
            if (pa_cvolume_valid(&e->volume))
                pa_cvolume_remap(&e->volume, &old_channel_map, &e->channel_map);
            else
                pa_cvolume_reset(&e->volume, e->sample_spec.channels);
        }
    }

    if (!e->memchunk.memblock)
        goto fail;

    pa_log_debug("Playing sample \"%s\" on \"%s\"", name, sink->name);

    pass_volume = TRUE;

    if (e->volume_is_set && PA_VOLUME_IS_VALID(volume)) {
        pa_cvolume_set(&r, e->sample_spec.channels, volume);
        pa_sw_cvolume_multiply(&r, &r, &e->volume);
    } else if (e->volume_is_set)
        r = e->volume;
    else if (PA_VOLUME_IS_VALID(volume))
        pa_cvolume_set(&r, e->sample_spec.channels, volume);
    else
        pass_volume = FALSE;

    pa_proplist_update(merged, PA_UPDATE_REPLACE, e->proplist);

    if (p)
        pa_proplist_update(merged, PA_UPDATE_REPLACE, p);

    if (pa_play_memchunk(sink,
                         &e->sample_spec, &e->channel_map,
                         &e->memchunk,
                         pass_volume ? &r : NULL,
                         merged,
                         PA_SINK_INPUT_NO_CREATE_ON_SUSPEND|PA_SINK_INPUT_KILL_ON_SUSPEND, sink_input_idx) < 0)
        goto fail;

    pa_proplist_free(merged);

    if (e->lazy)
        time(&e->last_used_time);

    return 0;

fail:
    pa_proplist_free(merged);
    return -1;
}