static void VolumeReport(audio_output_t *aout) { aout_sys_t *sys = aout->sys; pa_volume_t volume = pa_cvolume_max(&sys->cvolume); aout_VolumeReport(aout, (float)volume / PA_VOLUME_NORM); }
void pa_source_output_cb(pa_context *c, const pa_source_output_info *i, int eol, void *userdata) { if (eol > 0) { return; } char buf[1024]; const char *prop_key = NULL; void *prop_state = NULL; printf("index: %d\n", i->index); printf("name: %s\n", i->name); printf("module: %d\n", i->owner_module); printf("client: %d\n", i->client); printf("source: %d\n", i->source); printf("volume: channels:%d, min:%d, max:%d\n", i->volume.channels, pa_cvolume_min(&i->volume), pa_cvolume_max(&i->volume)); printf("resample_method: %s", i->resample_method); printf("driver: %s\n", i->driver); printf("mute: %d\n", i->mute); printf("corked: %d\n", i->corked); printf("has_volume: %d\n", i->has_volume); printf("volume_writable: %d\n", i->volume_writable); while ((prop_key=pa_proplist_iterate(i->proplist, &prop_state))) { printf(" %s: %s\n", prop_key, pa_proplist_gets(i->proplist, prop_key)); } printf("format_info: %s\n", pa_format_info_snprint(buf, 1000, i->format)); printf("------------------------------\n"); }
static void sink_set_volume_cb(pa_sink *s) { struct userdata *u = s->userdata; pa_cvolume hw; pa_volume_t v; char t[PA_CVOLUME_SNPRINT_VERBOSE_MAX]; pa_assert(u); /* If we're muted we don't need to do anything */ if (s->muted) return; /* Calculate the max volume of all channels. We'll use this as our (single) volume on the APEX device and emulate any variation in channel volumes in software */ v = pa_cvolume_max(&s->real_volume); /* Create a pa_cvolume version of our single value */ pa_cvolume_set(&hw, s->sample_spec.channels, v); /* Perform any software manipulation of the volume needed */ pa_sw_cvolume_divide(&s->soft_volume, &s->real_volume, &hw); pa_log_debug("Requested volume: %s", pa_cvolume_snprint_verbose(t, sizeof(t), &s->real_volume, &s->channel_map, false)); pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint_verbose(t, sizeof(t), &hw, &s->channel_map, false)); pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint_verbose(t, sizeof(t), &s->soft_volume, &s->channel_map, true)); /* Any necessary software volume manipulation is done so set our hw volume (or v as a single value) on the device */ pa_raop_client_set_volume(u->raop, v); }
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); }
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); }
/*** Sink input ***/ static void sink_input_info_cb(pa_context *ctx, const pa_sink_input_info *i, int eol, void *userdata) { audio_output_t *aout = userdata; aout_sys_t *sys = aout->sys; if (eol) return; (void) ctx; sys->cvolume = i->volume; /* cache volume for balance preservation */ pa_volume_t volume = pa_cvolume_max(&i->volume); volume = pa_sw_volume_divide(volume, sys->base_volume); aout_VolumeReport(aout, (float)volume / PA_VOLUME_NORM); aout_MuteReport(aout, i->mute); }
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; }
static void source_set_volume(pa_source *s) { struct userdata *u; audio_info_t info; pa_assert_se(u = s->userdata); if (u->fd >= 0) { AUDIO_INITINFO(&info); info.play.gain = pa_cvolume_max(&s->real_volume) * AUDIO_MAX_GAIN / PA_VOLUME_NORM; assert(info.play.gain <= AUDIO_MAX_GAIN); if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) { if (errno == EINVAL) pa_log("AUDIO_SETINFO: Unsupported volume."); else pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); } } }
pa_volume_t pa_cvolume_max_mask(const pa_cvolume *a, const pa_channel_map *cm, pa_channel_position_mask_t mask) { pa_volume_t m = PA_VOLUME_MUTED; unsigned c; pa_assert(a); if (!cm) return pa_cvolume_max(a); pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(a, cm), PA_VOLUME_MUTED); for (c = 0; c < a->channels; c++) { if (!(PA_CHANNEL_POSITION_MASK(cm->map[c]) & mask)) continue; if (a->values[c] > m) m = a->values[c]; } return m; }
static void gst_pulsesrc_source_output_info_cb (pa_context * c, const pa_source_output_info * i, int eol, void *userdata) { GstPulseSrc *psrc; psrc = GST_PULSESRC_CAST (userdata); if (!i) goto done; /* If the index doesn't match our current stream, * it implies we just recreated the stream (caps change) */ if (i->index == psrc->source_output_idx) { psrc->volume = pa_sw_volume_to_linear (pa_cvolume_max (&i->volume)); psrc->mute = i->mute; } done: pa_threaded_mainloop_signal (psrc->mainloop, 0); }
static PyObject* PulseAudio_get_volume(output_PulseAudio *self, PyObject *args) { pa_cvolume cvolume; pa_operation *op; struct get_volume_cb_data cb_data = {self->mainloop, &cvolume}; double max_volume; double norm_volume; pa_threaded_mainloop_lock(self->mainloop); /*ensure outuput stream is still running*/ /*FIXME*/ /*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); } /*ensure operation has completed successfully before using cvolume*/ /*FIXME*/ pa_operation_unref(op); pa_threaded_mainloop_unlock(self->mainloop); /*convert cvolume to double*/ max_volume = pa_cvolume_max(&cvolume); norm_volume = PA_VOLUME_NORM; /*return double converted to Python object*/ return PyFloat_FromDouble(max_volume / norm_volume); }
const gdouble * gvc_channel_map_get_volume (GvcChannelMap *map) { g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), NULL); if (!pa_channel_map_valid(&map->priv->pa_map)) return NULL; map->priv->extern_volume[VOLUME] = (gdouble) pa_cvolume_max (&map->priv->pa_volume); if (gvc_channel_map_can_balance (map)) map->priv->extern_volume[BALANCE] = (gdouble) pa_cvolume_get_balance (&map->priv->pa_volume, &map->priv->pa_map); else map->priv->extern_volume[BALANCE] = 0; if (gvc_channel_map_can_fade (map)) map->priv->extern_volume[FADE] = (gdouble) pa_cvolume_get_fade (&map->priv->pa_volume, &map->priv->pa_map); else map->priv->extern_volume[FADE] = 0; if (gvc_channel_map_has_lfe (map)) map->priv->extern_volume[LFE] = (gdouble) pa_cvolume_get_position (&map->priv->pa_volume, &map->priv->pa_map, PA_CHANNEL_POSITION_LFE); else map->priv->extern_volume[LFE] = 0; return map->priv->extern_volume; }