mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	audioconvert: make volume ramp parameters non-sticky
This mean the volume ramp parameters will have to be issued along with volume every time. They will not be persistant.
This commit is contained in:
		
							parent
							
								
									737bc89ab9
								
							
						
					
					
						commit
						74872250e8
					
				
					 1 changed files with 84 additions and 82 deletions
				
			
		| 
						 | 
					@ -62,6 +62,14 @@ static void init_volumes(struct volumes *vol)
 | 
				
			||||||
		vol->volumes[i] = DEFAULT_VOLUME;
 | 
							vol->volumes[i] = DEFAULT_VOLUME;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct volume_ramp_params {
 | 
				
			||||||
 | 
						unsigned int volume_ramp_samples;
 | 
				
			||||||
 | 
						unsigned int volume_ramp_step_samples;
 | 
				
			||||||
 | 
						unsigned int volume_ramp_time;
 | 
				
			||||||
 | 
						unsigned int volume_ramp_step_time;
 | 
				
			||||||
 | 
						enum spa_audio_volume_ramp_scale scale;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct props {
 | 
					struct props {
 | 
				
			||||||
	float volume;
 | 
						float volume;
 | 
				
			||||||
	float prev_volume;
 | 
						float prev_volume;
 | 
				
			||||||
| 
						 | 
					@ -70,15 +78,10 @@ struct props {
 | 
				
			||||||
	struct volumes channel;
 | 
						struct volumes channel;
 | 
				
			||||||
	struct volumes soft;
 | 
						struct volumes soft;
 | 
				
			||||||
	struct volumes monitor;
 | 
						struct volumes monitor;
 | 
				
			||||||
	unsigned int volume_ramp_samples;
 | 
						struct volume_ramp_params vrp;
 | 
				
			||||||
	unsigned int volume_ramp_step_samples;
 | 
					 | 
				
			||||||
	unsigned int volume_ramp_time;
 | 
					 | 
				
			||||||
	unsigned int volume_ramp_step_time;
 | 
					 | 
				
			||||||
	enum spa_audio_volume_ramp_scale scale;
 | 
					 | 
				
			||||||
	unsigned int have_soft_volume:1;
 | 
						unsigned int have_soft_volume:1;
 | 
				
			||||||
	unsigned int mix_disabled:1;
 | 
						unsigned int mix_disabled:1;
 | 
				
			||||||
	unsigned int resample_disabled:1;
 | 
						unsigned int resample_disabled:1;
 | 
				
			||||||
	unsigned int volume_ramp_enabled:1;
 | 
					 | 
				
			||||||
	unsigned int resample_quality;
 | 
						unsigned int resample_quality;
 | 
				
			||||||
	double rate;
 | 
						double rate;
 | 
				
			||||||
	char wav_path[512];
 | 
						char wav_path[512];
 | 
				
			||||||
| 
						 | 
					@ -97,7 +100,6 @@ static void props_reset(struct props *props)
 | 
				
			||||||
	props->have_soft_volume = false;
 | 
						props->have_soft_volume = false;
 | 
				
			||||||
	props->mix_disabled = false;
 | 
						props->mix_disabled = false;
 | 
				
			||||||
	props->resample_disabled = false;
 | 
						props->resample_disabled = false;
 | 
				
			||||||
	props->volume_ramp_enabled = false;
 | 
					 | 
				
			||||||
	props->resample_quality = RESAMPLE_DEFAULT_QUALITY;
 | 
						props->resample_quality = RESAMPLE_DEFAULT_QUALITY;
 | 
				
			||||||
	props->rate = 1.0;
 | 
						props->rate = 1.0;
 | 
				
			||||||
	spa_zero(props->wav_path);
 | 
						spa_zero(props->wav_path);
 | 
				
			||||||
| 
						 | 
					@ -870,13 +872,13 @@ static int parse_prop_params(struct impl *this, struct spa_pod *params)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static unsigned int get_ramp_samples(struct impl *this)
 | 
					static unsigned int get_ramp_samples(struct impl *this)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct props p = this->props;
 | 
						struct volume_ramp_params *vrp = &this->props.vrp;
 | 
				
			||||||
	if (p.volume_ramp_samples)
 | 
						if (vrp->volume_ramp_samples)
 | 
				
			||||||
		return p.volume_ramp_samples;
 | 
							return vrp->volume_ramp_samples;
 | 
				
			||||||
	else if (p.volume_ramp_time) {
 | 
						else if (vrp->volume_ramp_time) {
 | 
				
			||||||
		struct dir *d = &this->dir[SPA_DIRECTION_OUTPUT];
 | 
							struct dir *d = &this->dir[SPA_DIRECTION_OUTPUT];
 | 
				
			||||||
		unsigned int sample_rate = d->format.info.raw.rate;
 | 
							unsigned int sample_rate = d->format.info.raw.rate;
 | 
				
			||||||
		unsigned int samples = (p.volume_ramp_time * sample_rate) / 1000;
 | 
							unsigned int samples = (vrp->volume_ramp_time * sample_rate) / 1000;
 | 
				
			||||||
		spa_log_info(this->log, "volume ramp samples calculated from time is %d", samples);
 | 
							spa_log_info(this->log, "volume ramp samples calculated from time is %d", samples);
 | 
				
			||||||
		return samples;
 | 
							return samples;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -885,15 +887,15 @@ static unsigned int get_ramp_samples(struct impl *this)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static unsigned int get_ramp_step_samples(struct impl *this)
 | 
					static unsigned int get_ramp_step_samples(struct impl *this)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct props p = this->props;
 | 
						struct volume_ramp_params *vrp = &this->props.vrp;
 | 
				
			||||||
	if (p.volume_ramp_step_samples)
 | 
						if (vrp->volume_ramp_step_samples)
 | 
				
			||||||
		return p.volume_ramp_step_samples;
 | 
							return vrp->volume_ramp_step_samples;
 | 
				
			||||||
	else if (p.volume_ramp_step_time) {
 | 
						else if (vrp->volume_ramp_step_time) {
 | 
				
			||||||
		struct dir *d = &this->dir[SPA_DIRECTION_OUTPUT];
 | 
							struct dir *d = &this->dir[SPA_DIRECTION_OUTPUT];
 | 
				
			||||||
		int sample_rate = d->format.info.raw.rate;
 | 
							int sample_rate = d->format.info.raw.rate;
 | 
				
			||||||
		/* convert the step time which is in nano seconds to seconds */
 | 
							/* convert the step time which is in nano seconds to seconds */
 | 
				
			||||||
		unsigned int samples = (p.volume_ramp_step_time/1000) * (sample_rate/1000);
 | 
							unsigned int samples = (vrp->volume_ramp_step_time/1000) * (sample_rate/1000);
 | 
				
			||||||
		spa_log_info(this->log, "volume ramp step samples calculated from time is %d", samples);
 | 
							spa_log_debug(this->log, "volume ramp step samples calculated from time is %d", samples);
 | 
				
			||||||
		return samples;
 | 
							return samples;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -901,34 +903,33 @@ static unsigned int get_ramp_step_samples(struct impl *this)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static double get_volume_at_scale(struct impl *this, double value)
 | 
					static double get_volume_at_scale(struct impl *this, double value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct props p = this->props;
 | 
						struct volume_ramp_params *vrp = &this->props.vrp;
 | 
				
			||||||
	if (p.scale == SPA_AUDIO_VOLUME_RAMP_LINEAR)
 | 
						if (vrp->scale == SPA_AUDIO_VOLUME_RAMP_LINEAR)
 | 
				
			||||||
		return value;
 | 
							return value;
 | 
				
			||||||
	else if (p.scale == SPA_AUDIO_VOLUME_RAMP_CUBIC)
 | 
						else if (vrp->scale == SPA_AUDIO_VOLUME_RAMP_CUBIC)
 | 
				
			||||||
		return (value * value * value);
 | 
							return (value * value * value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0.0;
 | 
						return 0.0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct spa_pod *generate_vol_ramp_up_sequence(struct impl *this, const struct props *p)
 | 
					static struct spa_pod *generate_ramp_up_seq(struct impl *this)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint8_t buffer[64 * 1024];
 | 
					 | 
				
			||||||
	struct spa_pod_dynamic_builder b;
 | 
						struct spa_pod_dynamic_builder b;
 | 
				
			||||||
	struct spa_pod_frame f[1];
 | 
						struct spa_pod_frame f[1];
 | 
				
			||||||
 | 
						struct props *p = &this->props;
 | 
				
			||||||
	double volume_accum = p->prev_volume;
 | 
						double volume_accum = p->prev_volume;
 | 
				
			||||||
	unsigned int ramp_samples = get_ramp_samples(this);
 | 
						unsigned int ramp_samples = get_ramp_samples(this);
 | 
				
			||||||
	unsigned int ramp_step_samples = get_ramp_step_samples(this);
 | 
						unsigned int ramp_step_samples = get_ramp_step_samples(this);
 | 
				
			||||||
	double volume_step = ((p->volume - p->prev_volume) / (ramp_samples / ramp_step_samples));
 | 
						double volume_step = ((p->volume - p->prev_volume) / (ramp_samples / ramp_step_samples));
 | 
				
			||||||
	uint32_t volume_offs = 0;
 | 
						uint32_t volume_offs = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
 | 
						spa_pod_dynamic_builder_init(&b, NULL, 0, 4096);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_pod_builder_push_sequence(&b.b, &f[0], 0);
 | 
						spa_pod_builder_push_sequence(&b.b, &f[0], 0);
 | 
				
			||||||
	spa_log_info(this->log, "generating ramp up sequence from %f to %f with a step value %f at scale %d",
 | 
						spa_log_info(this->log, "generating ramp up sequence from %f to %f with a step value %f at scale %d",
 | 
				
			||||||
			p->prev_volume,p->volume, volume_step, p->scale);
 | 
								p->prev_volume,p->volume, volume_step, p->scale);
 | 
				
			||||||
	do {
 | 
						do {
 | 
				
			||||||
		// spa_log_info(this->log, "volume level %f offset %d", get_volume_at_scale(this, volume_accum), volume_offs);
 | 
							spa_log_info(this->log, "volume accum %f", get_volume_at_scale(this, volume_accum));
 | 
				
			||||||
 | 
					 | 
				
			||||||
		spa_pod_builder_control(&b.b, volume_offs, SPA_CONTROL_Properties);
 | 
							spa_pod_builder_control(&b.b, volume_offs, SPA_CONTROL_Properties);
 | 
				
			||||||
		spa_pod_builder_add_object(&b.b,
 | 
							spa_pod_builder_add_object(&b.b,
 | 
				
			||||||
				SPA_TYPE_OBJECT_Props, 0,
 | 
									SPA_TYPE_OBJECT_Props, 0,
 | 
				
			||||||
| 
						 | 
					@ -937,29 +938,27 @@ static struct spa_pod *generate_vol_ramp_up_sequence(struct impl *this, const st
 | 
				
			||||||
		volume_accum += volume_step;
 | 
							volume_accum += volume_step;
 | 
				
			||||||
		volume_offs += ramp_step_samples;
 | 
							volume_offs += ramp_step_samples;
 | 
				
			||||||
	} while (volume_accum < p->volume);
 | 
						} while (volume_accum < p->volume);
 | 
				
			||||||
	spa_pod_builder_pop(&b.b, &f[0]);
 | 
					 | 
				
			||||||
	return spa_pod_builder_pop(&b.b, &f[0]);
 | 
						return spa_pod_builder_pop(&b.b, &f[0]);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct spa_pod *generate_vol_ramp_down_sequence(struct impl *this, const struct props *p)
 | 
					static struct spa_pod *generate_ramp_down_seq(struct impl *this)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint8_t buffer[64 * 1024];
 | 
					 | 
				
			||||||
	struct spa_pod_dynamic_builder b;
 | 
						struct spa_pod_dynamic_builder b;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct spa_pod_frame f[1];
 | 
						struct spa_pod_frame f[1];
 | 
				
			||||||
	unsigned int ramp_samples = get_ramp_samples(this);
 | 
						unsigned int ramp_samples = get_ramp_samples(this);
 | 
				
			||||||
	unsigned int ramp_step_samples = get_ramp_step_samples(this);
 | 
						unsigned int ramp_step_samples = get_ramp_step_samples(this);
 | 
				
			||||||
 | 
						struct props *p = &this->props;
 | 
				
			||||||
	double volume_accum = p->prev_volume;
 | 
						double volume_accum = p->prev_volume;
 | 
				
			||||||
	double volume_step = ((p->prev_volume - p->volume) / (ramp_samples / ramp_step_samples));
 | 
						double volume_step = ((p->prev_volume - p->volume) / (ramp_samples / ramp_step_samples));
 | 
				
			||||||
	uint32_t volume_offs = 0;
 | 
						uint32_t volume_offs = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096);
 | 
						spa_pod_dynamic_builder_init(&b, NULL, 0, 4096);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_pod_builder_push_sequence(&b.b, &f[0], 0);
 | 
						spa_pod_builder_push_sequence(&b.b, &f[0], 0);
 | 
				
			||||||
	spa_log_info(this->log, "generating ramp down sequence from %f to %f with a step value %f at scale %d",
 | 
						spa_log_info(this->log, "generating ramp down sequence from %f to %f with a step value %f at scale %d",
 | 
				
			||||||
			p->prev_volume, p->volume, volume_step, p->scale);
 | 
								p->prev_volume, p->volume, volume_step, p->vrp.scale);
 | 
				
			||||||
	do {
 | 
						do {
 | 
				
			||||||
		// spa_log_info(this->log, "volume level %f offset %d", get_volume_at_scale(this, volume_accum), volume_offs);
 | 
							spa_log_info(this->log, "volume accum %f", get_volume_at_scale(this, volume_accum));
 | 
				
			||||||
		spa_pod_builder_control(&b.b, volume_offs, SPA_CONTROL_Properties);
 | 
							spa_pod_builder_control(&b.b, volume_offs, SPA_CONTROL_Properties);
 | 
				
			||||||
		spa_pod_builder_add_object(&b.b,
 | 
							spa_pod_builder_add_object(&b.b,
 | 
				
			||||||
				SPA_TYPE_OBJECT_Props, 0,
 | 
									SPA_TYPE_OBJECT_Props, 0,
 | 
				
			||||||
| 
						 | 
					@ -969,16 +968,17 @@ static struct spa_pod *generate_vol_ramp_down_sequence(struct impl *this, const
 | 
				
			||||||
		volume_accum -= volume_step;
 | 
							volume_accum -= volume_step;
 | 
				
			||||||
		volume_offs += ramp_step_samples;
 | 
							volume_offs += ramp_step_samples;
 | 
				
			||||||
	} while (volume_accum > p->volume);
 | 
						} while (volume_accum > p->volume);
 | 
				
			||||||
	spa_pod_builder_pop(&b.b, &f[0]);
 | 
					 | 
				
			||||||
	return spa_pod_builder_pop(&b.b, &f[0]);
 | 
						return spa_pod_builder_pop(&b.b, &f[0]);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct spa_pod *generate_vol_ramp_sequence(struct impl *this, const struct props *p)
 | 
					static struct volume_ramp_params *reset_volume_ramp_params(struct impl *this)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (p->volume > p->prev_volume)
 | 
						if (!this->vol_ramp_sequence) {
 | 
				
			||||||
		return generate_vol_ramp_up_sequence(this, p);
 | 
							struct volume_ramp_params *vrp = &this->props.vrp;
 | 
				
			||||||
	else
 | 
							spa_zero(this->props.vrp);
 | 
				
			||||||
		return generate_vol_ramp_down_sequence(this, p);
 | 
							return vrp;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int apply_props(struct impl *this, const struct spa_pod *param)
 | 
					static int apply_props(struct impl *this, const struct spa_pod *param)
 | 
				
			||||||
| 
						 | 
					@ -989,6 +989,8 @@ static int apply_props(struct impl *this, const struct spa_pod *param)
 | 
				
			||||||
	bool have_channel_volume = false;
 | 
						bool have_channel_volume = false;
 | 
				
			||||||
	bool have_soft_volume = false;
 | 
						bool have_soft_volume = false;
 | 
				
			||||||
	int changed = 0;
 | 
						int changed = 0;
 | 
				
			||||||
 | 
						int vol_ramp_params_changed = 0;
 | 
				
			||||||
 | 
						struct volume_ramp_params *vrp = reset_volume_ramp_params(this);
 | 
				
			||||||
	uint32_t n;
 | 
						uint32_t n;
 | 
				
			||||||
	int32_t value;
 | 
						int32_t value;
 | 
				
			||||||
	uint32_t id;
 | 
						uint32_t id;
 | 
				
			||||||
| 
						 | 
					@ -997,20 +999,10 @@ static int apply_props(struct impl *this, const struct spa_pod *param)
 | 
				
			||||||
		switch (prop->key) {
 | 
							switch (prop->key) {
 | 
				
			||||||
		case SPA_PROP_volume:
 | 
							case SPA_PROP_volume:
 | 
				
			||||||
			p->prev_volume = p->volume;
 | 
								p->prev_volume = p->volume;
 | 
				
			||||||
			spa_log_debug(this->log, "%p previous volume %f", this, p->prev_volume);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (spa_pod_get_float(&prop->value, &p->volume) == 0) {
 | 
								if (spa_pod_get_float(&prop->value, &p->volume) == 0) {
 | 
				
			||||||
				spa_log_debug(this->log, "%p current volume %f", this, p->volume);
 | 
									spa_log_debug(this->log, "%p new volume %f", this, p->volume);
 | 
				
			||||||
				if (p->volume_ramp_enabled && !this->vol_ramp_sequence) {
 | 
									changed++;
 | 
				
			||||||
					this->vol_ramp_sequence = (struct spa_pod_sequence *) generate_vol_ramp_sequence (this, p);
 | 
					 | 
				
			||||||
					if (!this->vol_ramp_sequence) {
 | 
					 | 
				
			||||||
						spa_log_error(this->log, "unable to generate sequence");
 | 
					 | 
				
			||||||
						return EIO;
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					this->vol_ramp_offset = 0;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				else
 | 
					 | 
				
			||||||
					changed++;
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case SPA_PROP_mute:
 | 
							case SPA_PROP_mute:
 | 
				
			||||||
| 
						 | 
					@ -1020,74 +1012,66 @@ static int apply_props(struct impl *this, const struct spa_pod *param)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case SPA_PROP_volumeRampSamples:
 | 
							case SPA_PROP_volumeRampSamples:
 | 
				
			||||||
 | 
								if (this->vol_ramp_sequence) {
 | 
				
			||||||
			if (p->volume_ramp_enabled && this->vol_ramp_sequence) {
 | 
					 | 
				
			||||||
				spa_log_error(this->log, "%p volume ramp sequence is being "
 | 
									spa_log_error(this->log, "%p volume ramp sequence is being "
 | 
				
			||||||
						"applied try again", this);
 | 
											"applied try again", this);
 | 
				
			||||||
				return EAGAIN;
 | 
									return -EAGAIN;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (spa_pod_get_int(&prop->value, &value) == 0 && value) {
 | 
								if (spa_pod_get_int(&prop->value, &value) == 0 && value) {
 | 
				
			||||||
				p->volume_ramp_samples = value;
 | 
									vrp->volume_ramp_samples = value;
 | 
				
			||||||
				spa_log_info(this->log, "%p volume ramp samples %d", this,
 | 
									spa_log_info(this->log, "%p volume ramp samples %d", this, value);
 | 
				
			||||||
						p->volume_ramp_samples);
 | 
									vol_ramp_params_changed++;
 | 
				
			||||||
				p->volume_ramp_enabled = true;
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case SPA_PROP_volumeRampStepSamples:
 | 
							case SPA_PROP_volumeRampStepSamples:
 | 
				
			||||||
			if (p->volume_ramp_enabled && this->vol_ramp_sequence) {
 | 
								if (this->vol_ramp_sequence) {
 | 
				
			||||||
				spa_log_error(this->log, "%p volume ramp sequence is being "
 | 
									spa_log_error(this->log, "%p volume ramp sequence is being "
 | 
				
			||||||
						"applied try again", this);
 | 
											"applied try again", this);
 | 
				
			||||||
				return EAGAIN;
 | 
									return -EAGAIN;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (spa_pod_get_int(&prop->value, &value) == 0 && value) {
 | 
								if (spa_pod_get_int(&prop->value, &value) == 0 && value) {
 | 
				
			||||||
				p->volume_ramp_step_samples = value;
 | 
									vrp->volume_ramp_step_samples = value;
 | 
				
			||||||
				spa_log_info(this->log, "%p volume ramp step samples is %d",
 | 
									spa_log_info(this->log, "%p volume ramp step samples is %d",
 | 
				
			||||||
						this, p->volume_ramp_step_samples);
 | 
											this, value);
 | 
				
			||||||
				p->volume_ramp_enabled = true;
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case SPA_PROP_volumeRampTime:
 | 
							case SPA_PROP_volumeRampTime:
 | 
				
			||||||
			if (p->volume_ramp_enabled && this->vol_ramp_sequence) {
 | 
								if (this->vol_ramp_sequence) {
 | 
				
			||||||
				spa_log_error(this->log, "%p volume ramp sequence is being "
 | 
									spa_log_error(this->log, "%p volume ramp sequence is being "
 | 
				
			||||||
						"applied try again", this);
 | 
											"applied try again", this);
 | 
				
			||||||
				return EAGAIN;
 | 
									return -EAGAIN;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (spa_pod_get_int(&prop->value, &value) == 0 && value) {
 | 
								if (spa_pod_get_int(&prop->value, &value) == 0 && value) {
 | 
				
			||||||
				p->volume_ramp_time = value;
 | 
									vrp->volume_ramp_time = value;
 | 
				
			||||||
				spa_log_info(this->log, "%p volume ramp time %d", this,
 | 
									spa_log_info(this->log, "%p volume ramp time %d", this, value);
 | 
				
			||||||
						p->volume_ramp_time);
 | 
									vol_ramp_params_changed++;
 | 
				
			||||||
				p->volume_ramp_enabled = true;
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case SPA_PROP_volumeRampStepTime:
 | 
							case SPA_PROP_volumeRampStepTime:
 | 
				
			||||||
			if (p->volume_ramp_enabled && this->vol_ramp_sequence) {
 | 
								if (this->vol_ramp_sequence) {
 | 
				
			||||||
				spa_log_error(this->log, "%p volume ramp sequence is being "
 | 
									spa_log_error(this->log, "%p volume ramp sequence is being "
 | 
				
			||||||
						"applied try again", this);
 | 
											"applied try again", this);
 | 
				
			||||||
				return EAGAIN;
 | 
									return -EAGAIN;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (spa_pod_get_int(&prop->value, &value) == 0 && value) {
 | 
								if (spa_pod_get_int(&prop->value, &value) == 0 && value) {
 | 
				
			||||||
				p->volume_ramp_step_time = value;
 | 
									vrp->volume_ramp_step_time = value;
 | 
				
			||||||
				spa_log_info(this->log, "%p volume ramp time %d", this,
 | 
									spa_log_info(this->log, "%p volume ramp time %d", this, value);
 | 
				
			||||||
						p->volume_ramp_step_samples);
 | 
					 | 
				
			||||||
				p->volume_ramp_enabled = true;
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case SPA_PROP_volumeRampScale:
 | 
							case SPA_PROP_volumeRampScale:
 | 
				
			||||||
			if (p->volume_ramp_enabled && this->vol_ramp_sequence) {
 | 
								if (this->vol_ramp_sequence) {
 | 
				
			||||||
				spa_log_error(this->log, "%p volume ramp sequence is being "
 | 
									spa_log_error(this->log, "%p volume ramp sequence is being "
 | 
				
			||||||
						"applied try again", this);
 | 
											"applied try again", this);
 | 
				
			||||||
					return EAGAIN;
 | 
										return -EAGAIN;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (spa_pod_get_id(&prop->value, &id) == 0) {
 | 
								if (spa_pod_get_id(&prop->value, &id) == 0) {
 | 
				
			||||||
				p->scale = id;
 | 
									vrp->scale = id;
 | 
				
			||||||
				spa_log_info(this->log, "%p volume ramp scale %d", this,
 | 
									spa_log_info(this->log, "%p volume ramp scale %d", this, id);
 | 
				
			||||||
						p->scale);
 | 
					 | 
				
			||||||
				p->volume_ramp_enabled = true;
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case SPA_PROP_channelVolumes:
 | 
							case SPA_PROP_channelVolumes:
 | 
				
			||||||
| 
						 | 
					@ -1153,6 +1137,24 @@ static int apply_props(struct impl *this, const struct spa_pod *param)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		set_volume(this);
 | 
							set_volume(this);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (vol_ramp_params_changed) {
 | 
				
			||||||
 | 
							void *sequence = NULL;
 | 
				
			||||||
 | 
							if (p->volume == p->prev_volume) {
 | 
				
			||||||
 | 
								spa_log_error(this->log, "no change in volume, cannot ramp volume");
 | 
				
			||||||
 | 
								return EIO;
 | 
				
			||||||
 | 
							} else if (p->volume > p->prev_volume)
 | 
				
			||||||
 | 
								sequence = generate_ramp_up_seq(this);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								sequence = generate_ramp_down_seq(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!sequence) {
 | 
				
			||||||
 | 
								spa_log_error(this->log, "unable to generate sequence");
 | 
				
			||||||
 | 
								return EIO;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							this->vol_ramp_sequence = (struct spa_pod_sequence *) sequence;
 | 
				
			||||||
 | 
							this->vol_ramp_offset = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return changed;
 | 
						return changed;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1449,7 +1451,7 @@ static void set_volume(struct impl *this)
 | 
				
			||||||
	float volumes[SPA_AUDIO_MAX_CHANNELS];
 | 
						float volumes[SPA_AUDIO_MAX_CHANNELS];
 | 
				
			||||||
	struct dir *dir = &this->dir[this->direction];
 | 
						struct dir *dir = &this->dir[this->direction];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_log_debug(this->log, "%p set volume %f have_format:%d", this, this->props.volume, dir->have_format);
 | 
						spa_log_info(this->log, "%p set volume %f have_format:%d", this, this->props.volume, dir->have_format);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (dir->have_format)
 | 
						if (dir->have_format)
 | 
				
			||||||
		remap_volumes(this, &dir->format);
 | 
							remap_volumes(this, &dir->format);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue