[pulseaudio-discuss] Setting the volume via API has no effect
Buddy Butterfly
buddy.butterfly at web.de
Wed Aug 20 06:18:33 PDT 2014
Am 20.08.2014 um 14:37 schrieb Hugo Osvaldo Barrera:
> Hi,
>
> First of all, sorry for the rather long and verbose email, but I'd like to be
> as specific as possible.
>
> I'm trying to write my own volume control application, and first of all,
> started fiddling with the pulseaudio api (with a threaded main loop).
>
> I've gotten the sinks, the volume, etc, but when I _set_ a volume, it has no
> effect. The API reports success, but pavucontrol reveals that it has not
> changes (also, if I set it to 0%, I can still hear stuff like vlc, etc).
>
> The code is a bit long, but pretty clear. Build with:
>
> clang -Wall pulse.c -o pulse `pkg-config --cflags --libs libpulse-simple`
>
> Here's the code in question:
>
> #include <stdio.h>
> #include <pulse/introspect.h>
> #include <pulse/context.h>
> #include <pulse/thread-mainloop.h>
> #include <pulse/error.h>
> #include <unistd.h>
> #include <stdlib.h>
>
> int sink_count = 0;
> // FIXME: list that can handle more than 5
> pa_sink_info sinks[5];
>
> void vol_success(pa_context *c, int success, void *userdata) {
> int i = *(int*) userdata;
> printf("Card %d, success: %d.\n", i, success);
> free(userdata);
> }
>
> void sinks_callback(pa_context *c, const pa_sink_info *i, int eol, void *userdata) {
> if (!eol) {
> printf("Got sink %d (mute: %d, vol: %.2fdB): %s - %s.\n", i->index, i->mute,
> pa_sw_volume_to_dB(i->volume.values[0]), i->description, i->name);
> sinks[sink_count++] = *i;
> }
> else {
> printf("Got all the sinks! :D\n\n");
> pa_volume_t volume = PA_VOLUME_NORM;
>
> for (int i = 0; i < sink_count; i++) {
> // Copy this value because we might alter it before the other thread consumes it.
> int *idx = malloc(sizeof(int)); *idx = i;
> pa_cvolume vols = sinks[i].volume;
> pa_cvolume_set(&vols, vols.channels, volume);
>
> printf("Volume being set to %d (%.2fdB) on card %d (%d channels), (was %.2fdB)\n",
> volume, pa_sw_volume_to_dB(volume), *idx, vols.channels,
> pa_sw_volume_to_dB(sinks[i].volume.values[0]));
>
> pa_operation* o = pa_context_set_sink_input_volume(c, *idx, &vols, vol_success, idx);
> if (!o) {
> printf("\nError setting volume for sink: %s\n", pa_strerror(pa_context_errno(c)));
> exit(-15);
> }
> pa_operation_unref(o);
> }
> }
> }
>
> void context_state_callback(pa_context* c, void* userdata) {
> pa_operation* o;
> switch (pa_context_get_state(c)) {
> case PA_CONTEXT_UNCONNECTED:
> case PA_CONTEXT_CONNECTING:
> case PA_CONTEXT_AUTHORIZING:
> case PA_CONTEXT_SETTING_NAME:
> printf(". "); fflush(NULL);
> break;
> case PA_CONTEXT_READY:
> printf("SUCCESS!\n\n");
> o = pa_context_get_sink_info_list(c, sinks_callback, NULL);
> if (!o) {
> printf("Error getting sinks: %s\n", pa_strerror(pa_context_errno(c)));
> exit(-13);
> }
> pa_operation_unref(o);
> break;
> case PA_CONTEXT_FAILED:
> printf("The connection failed or was disconnected.\n");
> exit(-11);
> case PA_CONTEXT_TERMINATED:
> printf("The connection was terminated cleanly.\n");
> exit(-12);
> default:
> printf("Unexpected context state.\n");
> }
> }
>
> int main(void) {
> // create loop
> pa_threaded_mainloop* loop = pa_threaded_mainloop_new();
> if (!loop) {
> printf("Failed to create main loop.\n");
> exit(-1);
> }
>
> // start loop
> if (pa_threaded_mainloop_start(loop)) {
> printf("Failed to start main loop.\n");
> exit(-2);
> }
>
> // get the api
> pa_mainloop_api* api = pa_threaded_mainloop_get_api(loop);
> if (!api) {
> printf("Failed to get api.\n");
> exit(-3);
> }
>
> // get a context
> pa_context *c = pa_context_new(api, "volctl3");
> if (!c) {
> printf("Failed to get context.\n");
> exit(-4);
> }
>
> // set a callback for context state changes
> pa_context_set_state_callback(c, context_state_callback, NULL);
>
> pa_threaded_mainloop_lock(loop);
>
> // connect
> printf("About to connect: ");
> if (pa_context_connect(c, NULL, PA_CONTEXT_NOFLAGS, NULL)) {
> printf("FAILED!\n");
> exit(-5);
> }
>
> pa_threaded_mainloop_unlock(loop);
>
> // Sleep to keep the thread alive. Note that an actuall app would do stuff
> // here.
> sleep(15);
>
> return 0;
> }
>
> // END OF CODE
>
> Am I going something wrong, or have I hit a bug?
>
> Thanks,
>
>
>
> _______________________________________________
> pulseaudio-discuss mailing list
> pulseaudio-discuss at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
>
Just a quick one. Do you have flat-volumes on or off? Don't know if that
matters. Try setting "flat-volumes = no" in /etc/pulse/daemon.conf.
More information about the pulseaudio-discuss
mailing list