Esempio n. 1
0
char *pa_sw_cvolume_snprint_dB(char *s, size_t l, const pa_cvolume *c) {
    unsigned channel;
    pa_bool_t first = TRUE;
    char *e;

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

    pa_init_i18n();

    if (!pa_cvolume_valid(c)) {
        pa_snprintf(s, l, _("(invalid)"));
        return s;
    }

    *(e = s) = 0;

    for (channel = 0; channel < c->channels && l > 1; channel++) {
        double f = pa_sw_volume_to_dB(c->values[channel]);

        l -= pa_snprintf(e, l, "%s%u: %0.2f dB",
                         first ? "" : " ",
                         channel,
                         isinf(f) < 0 || f <= PA_DECIBEL_MININFTY ? -INFINITY : f);

        e = strchr(e, 0);
        first = FALSE;
    }

    return s;
}
Esempio n. 2
0
char *pa_cvolume_snprint(char *s, size_t l, const pa_cvolume *c) {
    unsigned channel;
    pa_bool_t first = TRUE;
    char *e;

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

    pa_init_i18n();

    if (!pa_cvolume_valid(c)) {
        pa_snprintf(s, l, _("(invalid)"));
        return s;
    }

    *(e = s) = 0;

    for (channel = 0; channel < c->channels && l > 1; channel++) {
        l -= pa_snprintf(e, l, "%s%u: %3u%%",
                      first ? "" : " ",
                      channel,
                      (c->values[channel]*100+PA_VOLUME_NORM/2)/PA_VOLUME_NORM);

        e = strchr(e, 0);
        first = FALSE;
    }

    return s;
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}
Esempio n. 5
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;
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
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;
}
Esempio n. 9
0
pa_volume_t pa_cvolume_avg(const pa_cvolume *a) {
    uint64_t sum = 0;
    unsigned c;

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

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

    sum /= a->channels;

    return (pa_volume_t) sum;
}
Esempio n. 10
0
static struct entry* read_entry(struct userdata *u, const char *name) {
    pa_datum key, data;
    struct entry *e;

    pa_assert(u);
    pa_assert(name);

    key.data = (char*) name;
    key.size = strlen(name);

    pa_zero(data);

    if (!pa_database_get(u->database, &key, &data))
        goto fail;

    if (data.size != sizeof(struct entry)) {
        pa_log_debug("Database contains entry for device %s of wrong size %lu != %lu. Probably due to upgrade, ignoring.", name, (unsigned long) data.size, (unsigned long) sizeof(struct entry));
        goto fail;
    }

    e = (struct entry*) data.data;

    if (e->version != ENTRY_VERSION) {
        pa_log_debug("Version of database entry for device %s doesn't match our version. Probably due to upgrade, ignoring.", name);
        goto fail;
    }

    if (!memchr(e->port, 0, sizeof(e->port))) {
        pa_log_warn("Database contains entry for device %s with missing NUL byte in port name", name);
        goto fail;
    }

    if (e->volume_valid && !pa_channel_map_valid(&e->channel_map)) {
        pa_log_warn("Invalid channel map stored in database for device %s", name);
        goto fail;
    }

    if (e->volume_valid && (!pa_cvolume_valid(&e->volume) || !pa_cvolume_compatible_with_channel_map(&e->volume, &e->channel_map))) {
        pa_log_warn("Volume and channel map don't match in database entry for device %s", name);
        goto fail;
    }

    return e;

fail:

    pa_datum_free(&data);
    return NULL;
}
Esempio n. 11
0
File: pulse.c Progetto: Devil399/vlc
static void stream_moved_cb(pa_stream *s, void *userdata)
{
    audio_output_t *aout = userdata;
    aout_sys_t *sys = aout->sys;
    const char *name = pa_stream_get_device_name(s);
    struct sink *sink = sink_find(sys, pa_stream_get_device_index(s));

    msg_Dbg(aout, "connected to sink %s", name);
    aout_DeviceReport(aout, name);

    sys->base_volume = likely(sink != NULL) ? sink->base_volume
                                            : PA_VOLUME_INVALID;
    msg_Dbg(aout, "base volume: %"PRIu32, sys->base_volume);
    if (pa_cvolume_valid(&sys->cvolume))
        VolumeReport(aout);
}
Esempio n. 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;
}
Esempio n. 13
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);
}
Esempio n. 14
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);
}
Esempio n. 15
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;
}
Esempio n. 16
0
char *pa_cvolume_snprint_verbose(char *s, size_t l, const pa_cvolume *c, const pa_channel_map *map, int print_dB) {
    char *current = s;
    bool first = true;

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

    pa_init_i18n();

    if (!pa_cvolume_valid(c)) {
        pa_snprintf(s, l, _("(invalid)"));
        return s;
    }

    pa_assert(!map || (map->channels == c->channels));
    pa_assert(!map || pa_channel_map_valid(map));

    current[0] = 0;

    for (unsigned channel = 0; channel < c->channels && l > 1; channel++) {
        char channel_position[32];
        size_t bytes_printed;
        char buf[PA_VOLUME_SNPRINT_VERBOSE_MAX];

        if (map)
            pa_snprintf(channel_position, sizeof(channel_position), "%s", pa_channel_position_to_string(map->map[channel]));
        else
            pa_snprintf(channel_position, sizeof(channel_position), "%u", channel);

        bytes_printed = pa_snprintf(current, l, "%s%s: %s",
                                    first ? "" : ",   ",
                                    channel_position,
                                    pa_volume_snprint_verbose(buf, sizeof(buf), c->values[channel], print_dB));
        l -= bytes_printed;
        current += bytes_printed;
        first = false;
    }

    return s;
}
Esempio n. 17
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 && volume != PA_VOLUME_INVALID) {
        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 (volume != PA_VOLUME_INVALID)
        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;
}
Esempio n. 18
0
/* Called from main context */
pa_source* pa_source_new(
        pa_core *core,
        pa_source_new_data *data,
        pa_source_flags_t flags) {

    pa_source *s;
    const char *name;
    char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
    char *pt;

    pa_assert(core);
    pa_assert(data);
    pa_assert(data->name);
    pa_assert_ctl_context();

    s = pa_msgobject_new(pa_source);

    if (!(name = pa_namereg_register(core, data->name, PA_NAMEREG_SOURCE, s, data->namereg_fail))) {
        pa_log_debug("Failed to register name %s.", data->name);
        pa_xfree(s);
        return NULL;
    }

    pa_source_new_data_set_name(data, name);

    if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_NEW], data) < 0) {
        pa_xfree(s);
        pa_namereg_unregister(core, name);
        return NULL;
    }

    /* FIXME, need to free s here on failure */

    pa_return_null_if_fail(!data->driver || pa_utf8_valid(data->driver));
    pa_return_null_if_fail(data->name && pa_utf8_valid(data->name) && data->name[0]);

    pa_return_null_if_fail(data->sample_spec_is_set && pa_sample_spec_valid(&data->sample_spec));

    if (!data->channel_map_is_set)
        pa_return_null_if_fail(pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT));

    pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map));
    pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels);

    if (!data->volume_is_set)
        pa_cvolume_reset(&data->volume, data->sample_spec.channels);

    pa_return_null_if_fail(pa_cvolume_valid(&data->volume));
    pa_return_null_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec));

    if (!data->muted_is_set)
        data->muted = FALSE;

    if (data->card)
        pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->card->proplist);

    pa_device_init_description(data->proplist);
    pa_device_init_icon(data->proplist, FALSE);
    pa_device_init_intended_roles(data->proplist);

    if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_FIXATE], data) < 0) {
        pa_xfree(s);
        pa_namereg_unregister(core, name);
        return NULL;
    }

    s->parent.parent.free = source_free;
    s->parent.process_msg = pa_source_process_msg;

    s->core = core;
    s->state = PA_SOURCE_INIT;
    s->flags = flags;
    s->priority = 0;
    s->suspend_cause = 0;
    s->name = pa_xstrdup(name);
    s->proplist = pa_proplist_copy(data->proplist);
    s->driver = pa_xstrdup(pa_path_get_filename(data->driver));
    s->module = data->module;
    s->card = data->card;

    s->priority = pa_device_init_priority(s->proplist);

    s->sample_spec = data->sample_spec;
    s->channel_map = data->channel_map;

    s->outputs = pa_idxset_new(NULL, NULL);
    s->n_corked = 0;
    s->monitor_of = NULL;
    s->output_from_master = NULL;

    s->volume = data->volume;
    pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
    s->base_volume = PA_VOLUME_NORM;
    s->n_volume_steps = PA_VOLUME_NORM+1;
    s->muted = data->muted;
    s->refresh_volume = s->refresh_muted = FALSE;

    reset_callbacks(s);
    s->userdata = NULL;

    s->asyncmsgq = NULL;

    /* As a minor optimization we just steal the list instead of
     * copying it here */
    s->ports = data->ports;
    data->ports = NULL;

    s->active_port = NULL;
    s->save_port = FALSE;

    if (data->active_port && s->ports)
        if ((s->active_port = pa_hashmap_get(s->ports, data->active_port)))
            s->save_port = data->save_port;

    if (!s->active_port && s->ports) {
        void *state;
        pa_device_port *p;

        PA_HASHMAP_FOREACH(p, s->ports, state)
            if (!s->active_port || p->priority > s->active_port->priority)
                s->active_port = p;
    }