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.