Skip to content

Instantly share code, notes, and snippets.

@saivert
Created March 29, 2021 20:34
Show Gist options
  • Select an option

  • Save saivert/9953e78fe9eab2168a0a834176669556 to your computer and use it in GitHub Desktop.

Select an option

Save saivert/9953e78fe9eab2168a0a834176669556 to your computer and use it in GitHub Desktop.
// Our global variable
static int gotfirstvolumeupdate;
static void
set_volume(int dolock) {
if (data.stream) {
float plvol;
float vol[SPA_AUDIO_MAX_CHANNELS];
int i;
if (plugin.has_volume) {
plvol = get_player_volume_as_float();
} else {
plvol = 1.0f;
}
for (i = 0; i < get_player_channels(); i++) {
vol[i] = plvol;
}
if (dolock) pw_thread_loop_lock(data.loop);
pw_stream_set_control(data.stream, SPA_PROP_channelVolumes, get_player_channels(), vol, 0);
if (dolock) pw_thread_loop_unlock(data.loop);
}
}
static int _apply_volume(struct spa_loop *loop,
bool async,
uint32_t seq,
const void *_data,
size_t size,
void *user_data)
{
set_volume(0);
gotfirstvolumeupdate=1;
trace("_apply_volume\n");
return 0;
}
static void on_control_info(void *_data, uint32_t id, const struct pw_stream_control *control) {
// We need to ignore the first volume update which is sent by pipewire to restore volume
// This conflicts with the saved volume in the player
// This is because the volume isn't updated when user adjusts volume while playback is stopped,
// for this to work we would need to connect a dummy stream just to do this.
if (!strcmp(control->name, "Channel Volumes")) {
if (gotfirstvolumeupdate && plugin.has_volume) {
deadbeef->volume_set_amp(control->values[0]);
} else {
trace("PipeWire: ignored volume update\n");
// Instead we set our own volume here
// Apparently we cannot call pw_stream_set_control() directly here or it may crash
pw_loop_invoke(pw_thread_loop_get_loop(data.loop), _apply_volume, 1, NULL, 0, false, NULL);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment