static PyObject* PulseAudio_set_volume(output_PulseAudio *self, PyObject *args)
{
    pa_cvolume cvolume;
    pa_operation *op;
    struct get_volume_cb_data cb_data = {self->mainloop, &cvolume};
    double new_volume_d;
    pa_volume_t new_volume;

    if (!PyArg_ParseTuple(args, "d", &new_volume_d))
        return NULL;

    /*ensure output stream is still running*/
    /*FIXME*/

    /*convert volume to integer pa_volume_t value between
      PA_VOLUME_MUTED and PA_VOLUME_NORM*/
    new_volume = round(new_volume_d * PA_VOLUME_NORM);

    pa_threaded_mainloop_lock(self->mainloop);

    /*query stream info for current sink*/
    op = pa_context_get_sink_info_by_index(
        self->context,
        pa_stream_get_device_index(self->stream),
        (pa_sink_info_cb_t)get_volume_callback,
        &cb_data);

    /*wait for callback to complete*/
    while (pa_operation_get_state(op) == PA_OPERATION_RUNNING) {
        pa_threaded_mainloop_wait(self->mainloop);
    }

    pa_operation_unref(op);

    /*scale values using the new volume setting*/
    pa_cvolume_scale(&cvolume, new_volume);

    /*set sink's volume values*/
    op = pa_context_set_sink_volume_by_index(
        self->context,
        pa_stream_get_device_index(self->stream),
        &cvolume,
        (pa_context_success_cb_t)set_volume_callback,
        self->mainloop);

    /*wait for callback to complete*/
    while (pa_operation_get_state(op) == PA_OPERATION_RUNNING) {
        pa_threaded_mainloop_wait(self->mainloop);
    }

    pa_operation_unref(op);

    pa_threaded_mainloop_unlock(self->mainloop);

    Py_INCREF(Py_None);
    return Py_None;
}
示例#2
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);
}
示例#3
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);
}
示例#4
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;
}