Bug 1049478 - Fix volume handling in cubeb's PulseAudio backend: revert to soft-volume when needed. r=kinetik

--HG--
extra : rebase_source : 16c2702a4304047e266c07c02f868510c9860f75
This commit is contained in:
Paul Adenot 2014-08-08 13:26:02 +02:00
Родитель 452dc51b37
Коммит b73923ad6a
1 изменённых файлов: 45 добавлений и 13 удалений

Просмотреть файл

@ -91,8 +91,11 @@ struct cubeb_stream {
pa_time_event * drain_timer;
pa_sample_spec sample_spec;
int shutdown;
float volume;
};
const float PULSE_NO_GAIN = -1.0;
enum cork_state {
UNCORK = 0,
CORK = 1 << 0,
@ -196,6 +199,23 @@ stream_request_callback(pa_stream * s, size_t nbytes, void * u)
return;
}
if (stm->volume != PULSE_NO_GAIN) {
uint32_t samples = size * stm->sample_spec.channels / frame_size ;
if (stm->sample_spec.format == PA_SAMPLE_S16LE ||
stm->sample_spec.format == PA_SAMPLE_S16LE) {
short * b = buffer;
for (uint32_t i = 0; i < samples; i++) {
b[i] *= stm->volume;
}
} else {
float * b = buffer;
for (uint32_t i = 0; i < samples; i++) {
b[i] *= stm->volume;
}
}
}
r = WRAP(pa_stream_write)(s, buffer, got * frame_size, NULL, 0, PA_SEEK_RELATIVE);
assert(r == 0);
@ -555,6 +575,7 @@ pulse_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_n
stm->user_ptr = user_ptr;
stm->sample_spec = ss;
stm->volume = PULSE_NO_GAIN;
battr.maxlength = -1;
battr.tlength = WRAP(pa_usec_to_bytes)(latency * PA_USEC_PER_MSEC, &stm->sample_spec);
@ -698,20 +719,31 @@ pulse_stream_set_volume(cubeb_stream * stm, float volume)
WRAP(pa_threaded_mainloop_lock)(stm->context->mainloop);
ss = WRAP(pa_stream_get_sample_spec)(stm->stream);
vol = WRAP(pa_sw_volume_from_linear)(volume);
WRAP(pa_cvolume_set)(&cvol, ss->channels, vol);
index = WRAP(pa_stream_get_index)(stm->stream);
op = WRAP(pa_context_set_sink_input_volume)(stm->context->context,
index, &cvol, volume_success,
stm);
if (op) {
operation_wait(stm->context, stm->stream, op);
WRAP(pa_operation_unref)(op);
while (!stm->context->default_sink_info) {
WRAP(pa_threaded_mainloop_wait)(stm->context->mainloop);
}
/* if the pulse daemon is configured to use flat volumes,
* apply our own gain instead of changing the input volume on the sink. */
if (stm->context->default_sink_info->flags & PA_SINK_FLAT_VOLUME) {
stm->volume = volume;
} else {
ss = WRAP(pa_stream_get_sample_spec)(stm->stream);
vol = WRAP(pa_sw_volume_from_linear)(volume);
WRAP(pa_cvolume_set)(&cvol, ss->channels, vol);
index = WRAP(pa_stream_get_index)(stm->stream);
op = WRAP(pa_context_set_sink_input_volume)(stm->context->context,
index, &cvol, volume_success,
stm);
if (op) {
operation_wait(stm->context, stm->stream, op);
WRAP(pa_operation_unref)(op);
}
}
WRAP(pa_threaded_mainloop_unlock)(stm->context->mainloop);
return CUBEB_OK;