Commit 0e7f975c authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

pulse: keep track of base volume of each sink

parent 0d4bbb74
...@@ -60,6 +60,7 @@ struct sink ...@@ -60,6 +60,7 @@ struct sink
{ {
struct sink *next; struct sink *next;
uint32_t index; uint32_t index;
pa_volume_t base_volume;
char name[1]; char name[1];
}; };
...@@ -89,6 +90,14 @@ static void VolumeReport(audio_output_t *aout) ...@@ -89,6 +90,14 @@ static void VolumeReport(audio_output_t *aout)
} }
/*** Sink ***/ /*** Sink ***/
static struct sink *sink_find(aout_sys_t *sys, uint32_t index)
{
for (struct sink *sink = sys->sinks; sink != NULL; sink = sink->next)
if (sink->index == index)
return sink;
return NULL;
}
static void sink_add_cb(pa_context *ctx, const pa_sink_info *i, int eol, static void sink_add_cb(pa_context *ctx, const pa_sink_info *i, int eol,
void *userdata) void *userdata)
{ {
...@@ -110,6 +119,15 @@ static void sink_add_cb(pa_context *ctx, const pa_sink_info *i, int eol, ...@@ -110,6 +119,15 @@ static void sink_add_cb(pa_context *ctx, const pa_sink_info *i, int eol,
sink->next = sys->sinks; sink->next = sys->sinks;
sink->index = i->index; sink->index = i->index;
/* PulseAudio flat volume NORM / 100% / 0dB corresponds to no software
* amplification and maximum hardware amplification.
* VLC maps DEFAULT / 100% to no gain at all (software/hardware).
* Thus we need to use the sink base_volume as a multiplier,
* if and only if flat volume is active for our current sink. */
if (i->flags & PA_SINK_FLAT_VOLUME)
sink->base_volume = i->base_volume;
else
sink->base_volume = PA_VOLUME_NORM;
memcpy(sink->name, i->name, namelen + 1); memcpy(sink->name, i->name, namelen + 1);
sys->sinks = sink; sys->sinks = sink;
} }
...@@ -118,6 +136,7 @@ static void sink_mod_cb(pa_context *ctx, const pa_sink_info *i, int eol, ...@@ -118,6 +136,7 @@ static void sink_mod_cb(pa_context *ctx, const pa_sink_info *i, int eol,
void *userdata) void *userdata)
{ {
audio_output_t *aout = userdata; audio_output_t *aout = userdata;
aout_sys_t *sys = aout->sys;
if (eol) if (eol)
return; return;
...@@ -126,6 +145,15 @@ static void sink_mod_cb(pa_context *ctx, const pa_sink_info *i, int eol, ...@@ -126,6 +145,15 @@ static void sink_mod_cb(pa_context *ctx, const pa_sink_info *i, int eol,
msg_Dbg(aout, "changing sink %"PRIu32": %s (%s)", i->index, i->name, msg_Dbg(aout, "changing sink %"PRIu32": %s (%s)", i->index, i->name,
i->description); i->description);
aout_HotplugReport(aout, i->name, i->description); aout_HotplugReport(aout, i->name, i->description);
struct sink *sink = sink_find(sys, i->index);
if (unlikely(sink == NULL))
return;
if (i->flags & PA_SINK_FLAT_VOLUME)
sink->base_volume = i->base_volume;
else
sink->base_volume = PA_VOLUME_NORM;
} }
static void sink_del(uint32_t index, audio_output_t *aout) static void sink_del(uint32_t index, audio_output_t *aout)
...@@ -169,36 +197,6 @@ static void sink_event(pa_context *ctx, unsigned type, uint32_t idx, ...@@ -169,36 +197,6 @@ static void sink_event(pa_context *ctx, unsigned type, uint32_t idx,
pa_operation_unref(op); pa_operation_unref(op);
} }
static void sink_info_cb(pa_context *c, const pa_sink_info *i, int eol,
void *userdata)
{
audio_output_t *aout = userdata;
aout_sys_t *sys = aout->sys;
pa_stream *s = sys->stream;
if (eol)
return;
if (unlikely(s == NULL))
return; /* race condition: stream stopped already */
if (unlikely(pa_stream_get_device_index(s) != i->index))
return; /* race condition: stream moved again already */
(void) c;
/* PulseAudio flat volume NORM / 100% / 0dB corresponds to no software
* amplification and maximum hardware amplification.
* VLC maps DEFAULT / 100% to no gain at all (software/hardware).
* Thus we need to use the sink base_volume as a multiplier,
* if and only if flat volume is active for our current sink. */
if (i->flags & PA_SINK_FLAT_VOLUME)
sys->base_volume = i->base_volume;
else
sys->base_volume = PA_VOLUME_NORM;
msg_Dbg(aout, "base volume: %"PRIu32, sys->base_volume);
if (pa_cvolume_valid(&sys->cvolume))
VolumeReport(aout);
}
/*** Latency management and lip synchronization ***/ /*** Latency management and lip synchronization ***/
static void stream_start_now(pa_stream *s, audio_output_t *aout) static void stream_start_now(pa_stream *s, audio_output_t *aout)
...@@ -347,15 +345,16 @@ static void stream_moved_cb(pa_stream *s, void *userdata) ...@@ -347,15 +345,16 @@ static void stream_moved_cb(pa_stream *s, void *userdata)
audio_output_t *aout = userdata; audio_output_t *aout = userdata;
aout_sys_t *sys = aout->sys; aout_sys_t *sys = aout->sys;
const char *name = pa_stream_get_device_name(s); const char *name = pa_stream_get_device_name(s);
pa_operation *op; struct sink *sink = sink_find(sys, pa_stream_get_device_index(s));
msg_Dbg(aout, "connected to sink %s", name); msg_Dbg(aout, "connected to sink %s", name);
aout_DeviceReport(aout, name); aout_DeviceReport(aout, name);
op = pa_context_get_sink_info_by_name(sys->context, name, sink_info_cb, sys->base_volume = likely(sink != NULL) ? sink->base_volume
aout); : PA_VOLUME_INVALID;
if (likely(op != NULL)) msg_Dbg(aout, "base volume: %"PRIu32, sys->base_volume);
pa_operation_unref(op); if (pa_cvolume_valid(&sys->cvolume))
VolumeReport(aout);
} }
static void stream_overflow_cb(pa_stream *s, void *userdata) static void stream_overflow_cb(pa_stream *s, void *userdata)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment