~schnouki/pustule

101b430f2a3588aad611582b36cd66d4678f8f19 — Thomas Jost 4 years ago 4ca44dc
Add functions to get/set the default device
3 files changed, 79 insertions(+), 1 deletions(-)

M guile.c
M pulse.c
M pustule.h
M guile.c => guile.c +44 -1
@@ 45,6 45,10 @@ struct pustule_exported_func {
    {"pustule-set-device-volume", 2, 0, 0, &pustule_set_device_volume,
     "Sets the volume of the device whose index is DEVICE-IDX (an integer) to\n"
     "VOLUME (a number between 0 and 1)."},
    {"pustule-get-default-device", 0, 0, 0, &pustule_get_default_device,
     "Gets the name of the default device."},
    {"pustule-set-default-device", 1, 0, 0, &pustule_set_default_device,
     "Sets the default device to NAME."},
    {NULL, 0, 0, 0, NULL}
};



@@ 99,7 103,8 @@ SCM pustule_get_device_volume(SCM idx) {
    pthread_mutex_destroy(&(vol.mutex));
    pthread_cond_destroy(&(vol.cond));

    return scm_from_double(vol.volume);}
    return scm_from_double(vol.volume);
}

/* Set the volume for the specified device */
SCM pustule_set_device_volume(SCM idx, SCM volume) {


@@ 115,6 120,44 @@ SCM pustule_set_device_volume(SCM idx, SCM volume) {
    return volume;
}

/* Get the default device (by name) */
SCM pustule_get_default_device() {
    pustule_server_info_t info = {NULL, NULL, NULL, NULL, NULL,
                                  PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER};

    /* Query the server info with PulseAudio */
    pthread_mutex_lock(&(info.mutex));
    server_get_info(&info);
    pthread_cond_wait(&(info.cond), &(info.mutex));

    /* Result! */
    SCM res = scm_from_utf8_string(info.default_sink_name);

    /* Cleanup */
    free(info.user_name);
    free(info.host_name);
    free(info.server_version);
    free(info.server_name);
    free(info.default_sink_name);
    pthread_mutex_unlock(&(info.mutex));
    pthread_mutex_destroy(&(info.mutex));
    pthread_cond_destroy(&(info.cond));

    return res;
}

/* Set a device as the default device */
SCM pustule_set_default_device(SCM name) {
      scm_dynwind_begin(0);
      char* device_name = scm_to_utf8_stringn(name, NULL);
      scm_dynwind_free(device_name);

      pa_operation* op = pa_context_set_default_sink(pactx, device_name, NULL, NULL);
      pa_operation_unref(op);
      scm_dynwind_end();
      return SCM_BOOL_T;
}

/* Helpers */
static SCM _alist_add_str(SCM info, const char* name, const char* value) {
    return scm_acons(scm_from_utf8_string(name), scm_from_utf8_string(value), info);

M pulse.c => pulse.c +22 -0
@@ 165,3 165,25 @@ void device_get_volume(uint32_t idx, pustule_volume_t* vol) {
    pa_operation_unref(op);
    pa_threaded_mainloop_unlock(paloop);
}

/* Query info about the server */
static void server_info_callback(pa_context* ctx, const pa_server_info *i, void* userdata) {
    if (!i) return;
    pustule_server_info_t* info = (pustule_server_info_t*) userdata;
    pthread_mutex_lock(&(info->mutex));

    info->user_name = strdup(i->user_name);
    info->host_name = strdup(i->host_name);
    info->server_version = strdup(i->server_version);
    info->server_name = strdup(i->server_name);
    info->default_sink_name = strdup(i->default_sink_name);

    pthread_cond_broadcast(&(info->cond));
    pthread_mutex_unlock(&(info->mutex));
}
void server_get_info(pustule_server_info_t* info) {
    pa_threaded_mainloop_lock(paloop);
    pa_operation* op = pa_context_get_server_info(pactx, server_info_callback, (void*) info);
    pa_operation_unref(op);
    pa_threaded_mainloop_unlock(paloop);
}

M pustule.h => pustule.h +13 -0
@@ 64,6 64,16 @@ typedef struct {
    pthread_cond_t cond;
} pustule_volume_t;

typedef struct {
    char* user_name;
    char* host_name;
    char* server_name;
    char* server_version;
    char* default_sink_name;
    pthread_mutex_t mutex;
    pthread_cond_t cond;
} pustule_server_info_t;

/* PulseAudio callbacks */
void event_callback(pa_context* ctx, pa_subscription_event_type_t t, uint32_t idx, void* userdata);
void input_info_callback(pa_context* ctx, const pa_sink_input_info* i, int eol, void* userdata);


@@ 73,12 83,15 @@ void state_callback(pa_context* ctx, void* userdata);
/* PulseAudio functions */
void input_get_volume(uint32_t idx, pustule_volume_t* vol);
void device_get_volume(uint32_t idx, pustule_volume_t* vol);
void server_get_info(pustule_server_info_t* info);

/* Guile functions */
SCM pustule_get_input_volume(SCM idx);
SCM pustule_set_input_volume(SCM idx, SCM volume);
SCM pustule_get_device_volume(SCM idx);
SCM pustule_set_device_volume(SCM idx, SCM volume);
SCM pustule_get_default_device();
SCM pustule_set_default_device(SCM name);

/* Guile helpers */
void pustule_init_guile();