[pulseaudio-discuss] [PATCH v2 2/5] volume ramp: adding volume ramping to sink-input

Sangchul Lee sangchul1011 at gmail.com
Tue Mar 28 15:31:46 UTC 2017


2017-03-28 19:36 GMT+09:00 Arun Raghavan <arun at arunraghavan.net>:
>
>
> On Sat, 27 Aug 2016, at 06:03 PM, Sangchul Lee wrote:
>> The original patch is
>>  -
>>  https://review.tizen.org/git/?p=platform/upstream/pulseaudio.git;a=commit;h=98042248fd67ce0ab3807c5c472c0d5d8b0f99d3
>>  - by Jaska Uimonen <jaska.uimonen <at> helsinki.fi>
>>
>> Signed-off-by: Sangchul Lee <sc11.lee at samsung.com>
>> ---
>>  src/pulsecore/sink-input.c | 61
>>  ++++++++++++++++++++++++++++++++++++++++++++++
>>  src/pulsecore/sink-input.h | 12 ++++++++-
>>  2 files changed, 72 insertions(+), 1 deletion(-)
>>
>> diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
>> index 435e63e..ae76c05 100644
>> --- a/src/pulsecore/sink-input.c
>> +++ b/src/pulsecore/sink-input.c
>> @@ -526,6 +526,11 @@ int pa_sink_input_new(
>>      reset_callbacks(i);
>>      i->userdata = NULL;
>>
>> +    if (data->flags & PA_SINK_INPUT_START_RAMP_MUTED)
>> +        pa_cvolume_ramp_int_init(&i->ramp, PA_VOLUME_MUTED,
>> data->sample_spec.channels);
>> +    else
>> +        pa_cvolume_ramp_int_init(&i->ramp, PA_VOLUME_NORM,
>> data->sample_spec.channels);
>> +
>>      i->thread_info.state = i->state;
>>      i->thread_info.attached = false;
>>      pa_atomic_store(&i->thread_info.drained, 1);
>> @@ -542,6 +547,8 @@ int pa_sink_input_new(
>>      i->thread_info.playing_for = 0;
>>      i->thread_info.direct_outputs =
>>      pa_hashmap_new(pa_idxset_trivial_hash_func,
>>      pa_idxset_trivial_compare_func);
>>
>> +    i->thread_info.ramp = i->ramp;
>> +
>>      pa_assert_se(pa_idxset_put(core->sink_inputs, i, &i->index) == 0);
>>      pa_assert_se(pa_idxset_put(i->sink->inputs, pa_sink_input_ref(i),
>>      NULL) == 0);
>>
>> @@ -921,6 +928,8 @@ void pa_sink_input_peek(pa_sink_input *i, size_t
>> slength /* in sink bytes */, pa
>>          while (tchunk.length > 0) {
>>              pa_memchunk wchunk;
>>              bool nvfs = need_volume_factor_sink;
>> +            pa_cvolume target;
>> +            pa_bool_t tmp;
>>
>>              wchunk = tchunk;
>>              pa_memblock_ref(wchunk.memblock);
>> @@ -957,6 +966,16 @@ void pa_sink_input_peek(pa_sink_input *i, size_t
>> slength /* in sink bytes */, pa
>>                      pa_volume_memchunk(&wchunk, &i->sink->sample_spec,
>>                      &i->volume_factor_sink);
>>                  }
>>
>> +                /* check for possible volume ramp */
>> +                if (pa_cvolume_ramp_active(&i->thread_info.ramp)) {
>> +                    pa_memchunk_make_writable(&wchunk, 0);
>> +                    pa_volume_ramp_memchunk(&wchunk,
>> &i->sink->sample_spec, &(i->thread_info.ramp));
>> +                } else if ((tmp =
>> pa_cvolume_ramp_target_active(&(i->thread_info.ramp)))) {
>> +                    pa_memchunk_make_writable(&wchunk, 0);
>> +                    pa_cvolume_ramp_get_targets(&i->thread_info.ramp,
>> &target);
>> +                    pa_volume_memchunk(&wchunk, &i->sink->sample_spec,
>> &target);
>> +                }
>> +
>>                  pa_memblockq_push_align(i->thread_info.render_memblockq,
>>                  &wchunk);
>>              } else {
>>                  pa_memchunk rchunk;
>> @@ -973,6 +992,16 @@ void pa_sink_input_peek(pa_sink_input *i, size_t
>> slength /* in sink bytes */, pa
>>                          pa_volume_memchunk(&rchunk,
>>                          &i->sink->sample_spec, &i->volume_factor_sink);
>>                      }
>>
>> +                    /* check for possible volume ramp */
>> +                    if (pa_cvolume_ramp_active(&(i->thread_info.ramp)))
>> {
>> +                        pa_memchunk_make_writable(&rchunk, 0);
>> +                        pa_volume_ramp_memchunk(&rchunk,
>> &i->sink->sample_spec, &(i->thread_info.ramp));
>> +                    } else if
>> (pa_cvolume_ramp_target_active(&(i->thread_info.ramp))) {
>> +                        pa_memchunk_make_writable(&rchunk, 0);
>> +
>> pa_cvolume_ramp_get_targets(&i->thread_info.ramp, &target);
>> +                        pa_volume_memchunk(&rchunk,
>> &i->sink->sample_spec, &target);
>> +                    }
>> +
>
> This segment is repeated twice. Would be nicer to factor out into
> something like a check_and_apply_ramp().
>

I'll try that on the next patchset version.

>>                      pa_memblockq_push_align(i->thread_info.render_memblockq,
>>                      &rchunk);
>>                      pa_memblock_unref(rchunk.memblock);
>>                  }
>> @@ -1337,6 +1366,31 @@ int
>> pa_sink_input_remove_volume_factor(pa_sink_input *i, const char *key) {
>>      return 0;
>>  }
>>
>> +/* Called from main thread */
>> +void pa_sink_input_set_volume_ramp(
>> +        pa_sink_input *i,
>> +        const pa_cvolume_ramp *ramp,
>> +        pa_bool_t send_msg,
>> +        pa_bool_t save) {
>> +
>> +    pa_sink_input_assert_ref(i);
>> +    pa_assert_ctl_context();
>> +    pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
>> +    pa_assert(ramp);
>> +
>> +    pa_cvolume_ramp_convert(ramp, &i->ramp, i->sample_spec.rate);
>> +
>> +    pa_log_debug("setting volume ramp with target vol:%d and
>> length:%ld",
>> +                i->ramp.ramps[0].target,
>> +                i->ramp.ramps[0].length);
>> +
>> +
>> +    /* This tells the sink that volume ramp changed */
>> +    if (send_msg)
>> +        pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq,
>> PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP,
>> +                                       NULL, 0, NULL) == 0);
>
> When would send_msg be false? Same question applies to your later patch
> which adds this to the ramp volume factor API.

There is a case that should not be applied ramp at first(no fade-out)
but need to be applied ramp later on (fade-in).
e.g) during trigger role's stream playing, ducking role's stream
should be duck without fade-out when it is incoming,
       but need to fade-in right after the trigger role's stream is ended.
you can check the usage in another patch regarding stream-interaction
with fading. (https://patchwork.freedesktop.org/patch/100055/)

>> +}
>> +
>>  /* Called from main context */
>>  static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v) {
>>      pa_sink_input_assert_ref(i);
>> @@ -2015,6 +2069,13 @@ int pa_sink_input_process_msg(pa_msgobject *o, int
>> code, void *userdata, int64_t
>>              }
>>              return 0;
>>
>> +        case PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP:
>> +            /* we have ongoing ramp where we take current start values
>> */
>> +            pa_cvolume_ramp_start_from(&i->thread_info.ramp, &i->ramp);
>> +            i->thread_info.ramp = i->ramp;
>> +            pa_sink_input_request_rewind(i, 0, true, false, false);
>> +            return 0;
>> +
>>          case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE:
>>              if (i->thread_info.muted != i->muted) {
>>                  i->thread_info.muted = i->muted;
>> diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h
>> index 8bbee4e..85a0e54 100644
>> --- a/src/pulsecore/sink-input.h
>> +++ b/src/pulsecore/sink-input.h
>> @@ -32,6 +32,7 @@
>>  #include <pulsecore/client.h>
>>  #include <pulsecore/sink.h>
>>  #include <pulsecore/core.h>
>> +#include <pulsecore/mix.h>
>>
>>  typedef enum pa_sink_input_state {
>>      PA_SINK_INPUT_INIT,         /*< The stream is not active yet,
>>      because pa_sink_input_put() has not been called yet */
>> @@ -58,7 +59,8 @@ typedef enum pa_sink_input_flags {
>>      PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND = 256,
>>      PA_SINK_INPUT_NO_CREATE_ON_SUSPEND = 512,
>>      PA_SINK_INPUT_KILL_ON_SUSPEND = 1024,
>> -    PA_SINK_INPUT_PASSTHROUGH = 2048
>> +    PA_SINK_INPUT_PASSTHROUGH = 2048,
>> +    PA_SINK_INPUT_START_RAMP_MUTED = 4096,
>>  } pa_sink_input_flags_t;
>>
>>  struct pa_sink_input {
>> @@ -121,6 +123,9 @@ struct pa_sink_input {
>>       * this.*/
>>      bool save_sink:1, save_volume:1, save_muted:1;
>>
>> +    /* for volume ramps */
>> +    pa_cvolume_ramp_int ramp;
>> +
>>      pa_resample_method_t requested_resample_method,
>>      actual_resample_method;
>>
>>      /* Returns the chunk of audio data and drops it from the
>> @@ -249,6 +254,8 @@ struct pa_sink_input {
>>          pa_usec_t requested_sink_latency;
>>
>>          pa_hashmap *direct_outputs;
>> +
>> +        pa_cvolume_ramp_int ramp;
>>      } thread_info;
>>
>>      void *userdata;
>> @@ -265,6 +272,7 @@ enum {
>>      PA_SINK_INPUT_MESSAGE_SET_STATE,
>>      PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY,
>>      PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY,
>> +    PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP,
>>      PA_SINK_INPUT_MESSAGE_MAX
>>  };
>>
>> @@ -368,11 +376,13 @@ void pa_sink_input_set_volume(pa_sink_input *i,
>> const pa_cvolume *volume, bool s
>>  void pa_sink_input_add_volume_factor(pa_sink_input *i, const char *key,
>>  const pa_cvolume *volume_factor);
>>  int pa_sink_input_remove_volume_factor(pa_sink_input *i, const char
>>  *key);
>>  pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume
>>  *volume, bool absolute);
>> +void pa_sink_input_set_volume_ramp(pa_sink_input *i, const
>> pa_cvolume_ramp *ramp, pa_bool_t send_msg, pa_bool_t save);
>>
>>  void pa_sink_input_set_mute(pa_sink_input *i, bool mute, bool save);
>>
>>  void pa_sink_input_set_property(pa_sink_input *i, const char *key, const
>>  char *value);
>>  void pa_sink_input_set_property_arbitrary(pa_sink_input *i, const char
>>  *key, const uint8_t *value, size_t nbytes);
>> +
>>  void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t
>>  mode, pa_proplist *p);
>>
>>  pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input
>>  *i);
>> --
>
> -- Arun


More information about the pulseaudio-discuss mailing list