mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
adapter-control: add support of scale volume ramp param
This commit is contained in:
parent
8bfafaeca2
commit
e75fe4d469
1 changed files with 81 additions and 40 deletions
|
|
@ -54,10 +54,14 @@ static SPA_LOG_IMPL(default_log);
|
|||
|
||||
#define DEFAULT_DEVICE "hw:0,0"
|
||||
|
||||
#define LINEAR "linear"
|
||||
#define CUBIC "cubic"
|
||||
#define DEFAULT_SCALE SPA_AUDIO_VOLUME_RAMP_LINEAR
|
||||
|
||||
#define NON_NATIVE "non-native"
|
||||
#define NATIVE "native"
|
||||
#define DEFAULT_MODE NON_NATIVE
|
||||
#define INVALID -1
|
||||
|
||||
|
||||
struct buffer {
|
||||
struct spa_buffer buffer;
|
||||
|
|
@ -107,11 +111,12 @@ struct data {
|
|||
const char *alsa_device;
|
||||
|
||||
const char *mode;
|
||||
enum spa_audio_volume_ramp_scale scale;
|
||||
|
||||
int32_t volume_ramp_samples;
|
||||
int32_t volume_ramp_step_samples;
|
||||
int32_t volume_ramp_time;
|
||||
int32_t volume_ramp_step_time;
|
||||
uint32_t volume_ramp_samples;
|
||||
uint32_t volume_ramp_step_samples;
|
||||
uint32_t volume_ramp_time;
|
||||
uint32_t volume_ramp_step_time;
|
||||
|
||||
bool running;
|
||||
pthread_t thread;
|
||||
|
|
@ -303,13 +308,14 @@ exit_cleanup:
|
|||
dlclose(hnd);
|
||||
return res;
|
||||
}
|
||||
|
||||
static unsigned int get_ramp_samples(struct data *data)
|
||||
{
|
||||
if (data->volume_ramp_samples != INVALID)
|
||||
if (data->volume_ramp_samples)
|
||||
return data->volume_ramp_samples;
|
||||
else if (data->volume_ramp_time != INVALID) {
|
||||
else if (data->volume_ramp_time) {
|
||||
unsigned int samples = (data->volume_ramp_time * 48000) / 1000;
|
||||
printf("volume ramp samples calculated from time %d\n", samples);
|
||||
// printf("volume ramp samples calculated from time %d\n", samples);
|
||||
return samples;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -317,17 +323,26 @@ static unsigned int get_ramp_samples(struct data *data)
|
|||
|
||||
static unsigned int get_ramp_step_samples(struct data *data)
|
||||
{
|
||||
if (data->volume_ramp_step_samples != INVALID)
|
||||
if (data->volume_ramp_step_samples)
|
||||
return data->volume_ramp_step_samples;
|
||||
else if (data->volume_ramp_step_time != INVALID) {
|
||||
else if (data->volume_ramp_step_time) {
|
||||
/* convert the step time which is in nano seconds to seconds */
|
||||
unsigned int samples = (data->volume_ramp_step_time / 1000) * (48000 / 1000);
|
||||
// printf("volume ramp samples calculated from time %d\n", samples);
|
||||
return samples;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static double get_volume_at_scale(struct data *data)
|
||||
{
|
||||
if (data->scale == SPA_AUDIO_VOLUME_RAMP_LINEAR)
|
||||
return data->volume_accum;
|
||||
else if (data->scale == SPA_AUDIO_VOLUME_RAMP_CUBIC)
|
||||
return (data->volume_accum * data->volume_accum * data->volume_accum);
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
static int fade_in(struct data *data)
|
||||
{
|
||||
printf("fading in\n");
|
||||
|
|
@ -345,11 +360,11 @@ static int fade_in(struct data *data)
|
|||
spa_pod_builder_push_sequence(&b, &f[0], 0);
|
||||
data->volume_offs = 0;
|
||||
do {
|
||||
// printf("volume level %f offset %d\n", data->volume_accum, data->volume_offs);
|
||||
// printf("volume level %f offset %d\n", get_volume_at_scale(data), data->volume_offs);
|
||||
spa_pod_builder_control(&b, data->volume_offs, SPA_CONTROL_Properties);
|
||||
spa_pod_builder_add_object(&b,
|
||||
SPA_TYPE_OBJECT_Props, 0,
|
||||
SPA_PROP_volume, SPA_POD_Float(data->volume_accum));
|
||||
SPA_PROP_volume, SPA_POD_Float(get_volume_at_scale(data)));
|
||||
data->volume_accum += step_size;
|
||||
data->volume_offs += ramp_step_samples;
|
||||
} while (data->volume_accum < 1.0);
|
||||
|
|
@ -392,11 +407,11 @@ static int fade_out(struct data *data)
|
|||
spa_pod_builder_push_sequence(&b, &f[0], 0);
|
||||
data->volume_offs = ramp_step_samples;
|
||||
do {
|
||||
// printf("volume level %f offset %d\n", data->volume_accum, data->volume_offs);
|
||||
// printf("volume level %f offset %d\n", get_volume_at_scale(data), data->volume_offs);
|
||||
spa_pod_builder_control(&b, data->volume_offs, SPA_CONTROL_Properties);
|
||||
spa_pod_builder_add_object(&b,
|
||||
SPA_TYPE_OBJECT_Props, 0,
|
||||
SPA_PROP_volume, SPA_POD_Float(data->volume_accum));
|
||||
SPA_PROP_volume, SPA_POD_Float(get_volume_at_scale(data)));
|
||||
data->volume_accum -= step_size;
|
||||
data->volume_offs += ramp_step_samples;
|
||||
} while (data->volume_accum > 0.0);
|
||||
|
|
@ -638,7 +653,8 @@ static int make_nodes(struct data *data)
|
|||
SPA_PROP_volumeRampSamples, SPA_POD_Int(data->volume_ramp_samples),
|
||||
SPA_PROP_volumeRampStepSamples, SPA_POD_Int(data->volume_ramp_step_samples),
|
||||
SPA_PROP_volumeRampTime, SPA_POD_Int(data->volume_ramp_time),
|
||||
SPA_PROP_volumeRampStepTime, SPA_POD_Int(data->volume_ramp_step_time));
|
||||
SPA_PROP_volumeRampStepTime, SPA_POD_Int(data->volume_ramp_step_time),
|
||||
SPA_PROP_volumeRampScale, SPA_POD_Id(data->scale));
|
||||
if ((res = spa_node_set_param(data->sink_node, SPA_PARAM_Props, 0, props)) < 0) {
|
||||
printf("can't call volramp set params %d\n", res);
|
||||
return res;
|
||||
|
|
@ -890,6 +906,17 @@ static void run_async_sink(struct data *data)
|
|||
printf("got error %d\n", res);
|
||||
}
|
||||
|
||||
static char *getscale(uint32_t scale)
|
||||
{
|
||||
char *scale_s = NULL;
|
||||
|
||||
if (scale == SPA_AUDIO_VOLUME_RAMP_LINEAR)
|
||||
scale_s = LINEAR;
|
||||
else if (scale == SPA_AUDIO_VOLUME_RAMP_CUBIC)
|
||||
scale_s = CUBIC;
|
||||
|
||||
return scale_s;
|
||||
}
|
||||
static void show_help(struct data *data, const char *name, bool error)
|
||||
{
|
||||
fprintf(error ? stderr : stdout, "%s [options] [command]\n"
|
||||
|
|
@ -900,7 +927,7 @@ static void show_help(struct data *data, const char *name, bool error)
|
|||
" -a, --ramp-step-samples SPA_PROP_volumeRampStepSamples(Step or incremental Samples to ramp the volume over)(default %d)\n"
|
||||
" -t, --ramp-time SPA_PROP_volumeRampTime(Time to ramp the volume over in msec)(default %d)\n"
|
||||
" -i, --ramp-step-time SPA_PROP_volumeRampStepTime(Step or incremental Time to ramp the volume over in nano sec)(default %d)\n"
|
||||
" -c, --ramp-scale SPA_PROP_volumeRampScale(the scale or graph to used to ramp the volume)\n"
|
||||
" -c, --scale SPA_PROP_volumeRampScale(the scale or graph to used to ramp the volume)(\"linear\" or \"cubic\")(default %s)\n"
|
||||
"examples:\n"
|
||||
"adapter-control\n"
|
||||
"-->when invoked with out any params, ramps volume with default values\n"
|
||||
|
|
@ -910,19 +937,28 @@ static void show_help(struct data *data, const char *name, bool error)
|
|||
"-->ramps volume on \"hw:0,0\" alsa device over 70000 samples\n"
|
||||
"adapter-control --alsa-device=hw:0,0 --ramp-samples=70000 --mode=native\n"
|
||||
"-->ramps volume on \"hw:0,0\" alsa device over 70000 samples in native mode\n"
|
||||
"make;./builddir/spa/examples/adapter-control --alsa-device=hw:0,0 --ramp-time=1000 --mode=native\n"
|
||||
"adapter-control --alsa-device=hw:0,0 --ramp-time=1000 --mode=native\n"
|
||||
"-->ramps volume on \"hw:0,0\" alsa device over 1000 msec in native mode\n"
|
||||
"make;./builddir/spa/examples/adapter-control --alsa-device=hw:0,0 --ramp-time=1000 --ramp-step-time=5000 --mode=native\n"
|
||||
"adapter-control --alsa-device=hw:0,0 --ramp-time=1000 --ramp-step-time=5000 --mode=native\n"
|
||||
"-->ramps volume on \"hw:0,0\" alsa device over 1000 msec in steps of 5000 nano seconds(5 msec)in native mode\n"
|
||||
"make;./builddir/spa/examples/adapter-control --alsa-device=hw:0,0 --ramp-samples=70000 --ramp-step-samples=200 --mode=native\n"
|
||||
"-->ramps volume on \"hw:0,0\" alsa device over 70000 samples with a step size of 200 samples in native mode\n",
|
||||
"adapter-control --alsa-device=hw:0,0 --ramp-samples=70000 --ramp-step-samples=200 --mode=native\n"
|
||||
"-->ramps volume on \"hw:0,0\" alsa device over 70000 samples with a step size of 200 samples in native mode\n"
|
||||
"adapter-control --alsa-device=hw:1,0 --scale=linear\n"
|
||||
"-->ramps volume on \"hw:1,0\" in linear volume scale, one can leave choose to not use the linear scale here as it is the default\n"
|
||||
"adapter-control --alsa-device=hw:1,0 --ramp-samples=70000 --scale=cubic\n"
|
||||
"-->ramps volume on \"hw:1,0\" alsa device over 70000 samples deploying cubic volume scale\n"
|
||||
"adapter-control --alsa-device=hw:1,0 --ramp-samples=70000 --mode=native --scale=cubic\n"
|
||||
"-->ramps volume on \"hw:1,0\" alsa device over 70000 samples deploying cubic volume scale in native mode\n"
|
||||
"adapter-control --alsa-device=hw:1,0 --ramp-time=3000 --scale=cubic --mode=native\n"
|
||||
"-->ramps volume on \"hw:1,0\" alsa device over 3 seconds samples with a step size of 200 samples in native mode\n",
|
||||
name,
|
||||
DEFAULT_DEVICE,
|
||||
DEFAULT_MODE,
|
||||
DEFAULT_RAMP_SAMPLES,
|
||||
DEFAULT_RAMP_STEP_SAMPLES,
|
||||
DEFAULT_RAMP_TIME,
|
||||
DEFAULT_RAMP_STEP_TIME);
|
||||
DEFAULT_RAMP_STEP_TIME,
|
||||
getscale(DEFAULT_SCALE));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
|
@ -934,10 +970,9 @@ int main(int argc, char *argv[])
|
|||
/* default values*/
|
||||
data.volume_ramp_samples = DEFAULT_RAMP_SAMPLES;
|
||||
data.volume_ramp_step_samples = DEFAULT_RAMP_STEP_SAMPLES;
|
||||
data.volume_ramp_time = DEFAULT_RAMP_TIME;
|
||||
data.volume_ramp_step_time = DEFAULT_RAMP_STEP_TIME;
|
||||
data.alsa_device = DEFAULT_DEVICE;
|
||||
data.mode = DEFAULT_MODE;
|
||||
data.scale = DEFAULT_SCALE;
|
||||
|
||||
static const struct option long_options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
|
|
@ -947,13 +982,13 @@ int main(int argc, char *argv[])
|
|||
{ "ramp-time", required_argument, NULL, 't' },
|
||||
{ "ramp-step-samples", required_argument, NULL, 'a' },
|
||||
{ "ramp-step-time", required_argument, NULL, 'i' },
|
||||
{ "scale", required_argument, NULL, 'c' },
|
||||
{ NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
while ((c = getopt_long(argc, argv, "hdmstia:", long_options, NULL)) != -1) {
|
||||
printf("\nhere_we_are %s %s(%u) c=%c \n",__FILE__,__func__,__LINE__, c);
|
||||
while ((c = getopt_long(argc, argv, "hdmstiac:", long_options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'h':
|
||||
show_help(&data, argv[0], false);
|
||||
|
|
@ -964,28 +999,34 @@ int main(int argc, char *argv[])
|
|||
else
|
||||
data.mode = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
if (!spa_streq (optarg, LINEAR) && !spa_streq (optarg, CUBIC))
|
||||
printf("Invalid Scale(\"%s\"), using default(\"%s\")\n", optarg,
|
||||
getscale(DEFAULT_SCALE));
|
||||
else
|
||||
if (spa_streq (optarg, LINEAR))
|
||||
data.scale = SPA_AUDIO_VOLUME_RAMP_LINEAR;
|
||||
else if (spa_streq (optarg, CUBIC))
|
||||
data.scale = SPA_AUDIO_VOLUME_RAMP_CUBIC;
|
||||
break;
|
||||
case 'd':
|
||||
data.alsa_device = optarg;
|
||||
break;
|
||||
case 's':
|
||||
data.volume_ramp_samples = atoi(optarg);
|
||||
data.volume_ramp_time = INVALID;
|
||||
data.volume_ramp_step_time = INVALID;
|
||||
break;
|
||||
case 't':
|
||||
data.volume_ramp_time = atoi(optarg);
|
||||
data.volume_ramp_samples = INVALID;
|
||||
data.volume_ramp_step_samples = INVALID;
|
||||
if (!data.volume_ramp_step_time)
|
||||
data.volume_ramp_step_time = DEFAULT_RAMP_STEP_TIME;
|
||||
data.volume_ramp_samples = 0;
|
||||
data.volume_ramp_step_samples = 0;
|
||||
break;
|
||||
case 'a':
|
||||
data.volume_ramp_step_samples = atoi(optarg);
|
||||
data.volume_ramp_step_time = INVALID;
|
||||
data.volume_ramp_time = INVALID;
|
||||
break;
|
||||
case 'i':
|
||||
data.volume_ramp_step_time = atoi(optarg);
|
||||
data.volume_ramp_samples = INVALID;
|
||||
data.volume_ramp_step_samples = INVALID;
|
||||
break;
|
||||
default:
|
||||
show_help(&data, argv[0], true);
|
||||
|
|
@ -1013,12 +1054,12 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
printf("using %s mode\n", data.mode);
|
||||
if ((data.volume_ramp_samples != INVALID) && (data.volume_ramp_step_samples != INVALID))
|
||||
printf("using %d samples with a step size of %d samples to ramp volume\n",
|
||||
data.volume_ramp_samples, data.volume_ramp_step_samples);
|
||||
else if ((data.volume_ramp_time != INVALID) && (data.volume_ramp_step_time != INVALID))
|
||||
printf("using %d msec with a step size of %d msec to ramp volume\n",
|
||||
data.volume_ramp_time, (data.volume_ramp_step_time/1000));
|
||||
if (data.volume_ramp_samples && data.volume_ramp_step_samples)
|
||||
printf("using %d samples with a step size of %d samples to ramp volume at %s scale\n",
|
||||
data.volume_ramp_samples, data.volume_ramp_step_samples, getscale(data.scale));
|
||||
else if (data.volume_ramp_time && data.volume_ramp_step_time)
|
||||
printf("using %d msec with a step size of %d msec to ramp volume at %s scale\n",
|
||||
data.volume_ramp_time, (data.volume_ramp_step_time/1000), getscale(data.scale));
|
||||
|
||||
spa_loop_control_enter(data.control);
|
||||
run_async_sink(&data);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue