mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	core: add an additional volume factor that is applied after resampling took place
This commit is contained in:
		
							parent
							
								
									6fa2445e11
								
							
						
					
					
						commit
						a015d56fac
					
				
					 2 changed files with 56 additions and 10 deletions
				
			
		| 
						 | 
				
			
			@ -92,6 +92,18 @@ void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data *data, co
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void pa_sink_input_new_data_apply_volume_factor_sink(pa_sink_input_new_data *data, const pa_cvolume *volume_factor) {
 | 
			
		||||
    pa_assert(data);
 | 
			
		||||
    pa_assert(volume_factor);
 | 
			
		||||
 | 
			
		||||
    if (data->volume_factor_sink_is_set)
 | 
			
		||||
        pa_sw_cvolume_multiply(&data->volume_factor_sink, &data->volume_factor_sink, volume_factor);
 | 
			
		||||
    else {
 | 
			
		||||
        data->volume_factor_sink_is_set = TRUE;
 | 
			
		||||
        data->volume_factor_sink = *volume_factor;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute) {
 | 
			
		||||
    pa_assert(data);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -176,7 +188,6 @@ int pa_sink_input_new(
 | 
			
		|||
            pa_channel_map_init_extend(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pa_return_val_if_fail(pa_channel_map_valid(&data->channel_map), -PA_ERR_INVALID);
 | 
			
		||||
    pa_return_val_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec), -PA_ERR_INVALID);
 | 
			
		||||
 | 
			
		||||
    if (!data->volume_is_set) {
 | 
			
		||||
| 
						 | 
				
			
			@ -185,15 +196,18 @@ int pa_sink_input_new(
 | 
			
		|||
        data->save_volume = FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pa_return_val_if_fail(pa_cvolume_valid(&data->volume), -PA_ERR_INVALID);
 | 
			
		||||
    pa_return_val_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec), -PA_ERR_INVALID);
 | 
			
		||||
 | 
			
		||||
    if (!data->volume_factor_is_set)
 | 
			
		||||
        pa_cvolume_reset(&data->volume_factor, data->sample_spec.channels);
 | 
			
		||||
 | 
			
		||||
    pa_return_val_if_fail(pa_cvolume_valid(&data->volume_factor), -PA_ERR_INVALID);
 | 
			
		||||
    pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor, &data->sample_spec), -PA_ERR_INVALID);
 | 
			
		||||
 | 
			
		||||
    if (!data->volume_factor_sink_is_set)
 | 
			
		||||
        pa_cvolume_reset(&data->volume_factor_sink, data->sink->sample_spec.channels);
 | 
			
		||||
 | 
			
		||||
    pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor_sink, &data->sink->sample_spec), -PA_ERR_INVALID);
 | 
			
		||||
 | 
			
		||||
    if (!data->muted_is_set)
 | 
			
		||||
        data->muted = FALSE;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -283,6 +297,7 @@ int pa_sink_input_new(
 | 
			
		|||
        i->volume = data->volume;
 | 
			
		||||
 | 
			
		||||
    i->volume_factor = data->volume_factor;
 | 
			
		||||
    i->volume_factor_sink = data->volume_factor_sink;
 | 
			
		||||
    i->real_ratio = i->reference_ratio = data->volume;
 | 
			
		||||
    pa_cvolume_reset(&i->soft_volume, i->sample_spec.channels);
 | 
			
		||||
    pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
 | 
			
		||||
| 
						 | 
				
			
			@ -576,7 +591,7 @@ pa_usec_t pa_sink_input_get_latency(pa_sink_input *i, pa_usec_t *sink_latency) {
 | 
			
		|||
 | 
			
		||||
/* Called from thread context */
 | 
			
		||||
void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, pa_memchunk *chunk, pa_cvolume *volume) {
 | 
			
		||||
    pa_bool_t do_volume_adj_here;
 | 
			
		||||
    pa_bool_t do_volume_adj_here, need_volume_factor_sink;
 | 
			
		||||
    pa_bool_t volume_is_norm;
 | 
			
		||||
    size_t block_size_max_sink, block_size_max_sink_input;
 | 
			
		||||
    size_t ilength;
 | 
			
		||||
| 
						 | 
				
			
			@ -624,6 +639,7 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
 | 
			
		|||
 | 
			
		||||
    do_volume_adj_here = !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map);
 | 
			
		||||
    volume_is_norm = pa_cvolume_is_norm(&i->thread_info.soft_volume) && !i->thread_info.muted;
 | 
			
		||||
    need_volume_factor_sink = !pa_cvolume_is_norm(&i->volume_factor_sink);
 | 
			
		||||
 | 
			
		||||
    while (!pa_memblockq_is_readable(i->thread_info.render_memblockq)) {
 | 
			
		||||
        pa_memchunk tchunk;
 | 
			
		||||
| 
						 | 
				
			
			@ -655,6 +671,7 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
 | 
			
		|||
 | 
			
		||||
        while (tchunk.length > 0) {
 | 
			
		||||
            pa_memchunk wchunk;
 | 
			
		||||
            pa_bool_t nvfs = need_volume_factor_sink;
 | 
			
		||||
 | 
			
		||||
            wchunk = tchunk;
 | 
			
		||||
            pa_memblock_ref(wchunk.memblock);
 | 
			
		||||
| 
						 | 
				
			
			@ -666,18 +683,41 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
 | 
			
		|||
            if (do_volume_adj_here && !volume_is_norm) {
 | 
			
		||||
                pa_memchunk_make_writable(&wchunk, 0);
 | 
			
		||||
 | 
			
		||||
                if (i->thread_info.muted)
 | 
			
		||||
                if (i->thread_info.muted) {
 | 
			
		||||
                    pa_silence_memchunk(&wchunk, &i->thread_info.sample_spec);
 | 
			
		||||
                else
 | 
			
		||||
                    nvfs = FALSE;
 | 
			
		||||
 | 
			
		||||
                } else if (!i->thread_info.resampler && nvfs) {
 | 
			
		||||
                    pa_cvolume v;
 | 
			
		||||
 | 
			
		||||
                    /* If we don't need a resampler we can merge the
 | 
			
		||||
                     * post and the pre volume adjustment into one */
 | 
			
		||||
 | 
			
		||||
                    pa_sw_cvolume_multiply(&v, &i->thread_info.soft_volume, &i->volume_factor_sink);
 | 
			
		||||
                    pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &v);
 | 
			
		||||
                    nvfs = FALSE;
 | 
			
		||||
 | 
			
		||||
                } else
 | 
			
		||||
                    pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &i->thread_info.soft_volume);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!i->thread_info.resampler)
 | 
			
		||||
            if (!i->thread_info.resampler) {
 | 
			
		||||
 | 
			
		||||
                if (nvfs) {
 | 
			
		||||
                    pa_memchunk_make_writable(&wchunk, 0);
 | 
			
		||||
                    pa_volume_memchunk(&wchunk, &i->sink->sample_spec, &i->volume_factor_sink);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                pa_memblockq_push_align(i->thread_info.render_memblockq, &wchunk);
 | 
			
		||||
            else {
 | 
			
		||||
            } else {
 | 
			
		||||
                pa_memchunk rchunk;
 | 
			
		||||
                pa_resampler_run(i->thread_info.resampler, &wchunk, &rchunk);
 | 
			
		||||
 | 
			
		||||
                if (nvfs) {
 | 
			
		||||
                    pa_memchunk_make_writable(&rchunk, 0);
 | 
			
		||||
                    pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
/*                 pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
 | 
			
		||||
 | 
			
		||||
                if (rchunk.memblock) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1186,6 +1226,7 @@ int pa_sink_input_start_move(pa_sink_input *i) {
 | 
			
		|||
    pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_START_MOVE, i, 0, NULL) == 0);
 | 
			
		||||
 | 
			
		||||
    pa_sink_update_status(i->sink);
 | 
			
		||||
    pa_cvolume_remap(&i->volume_factor_sink, &i->sink->channel_map, &i->channel_map);
 | 
			
		||||
    i->sink = NULL;
 | 
			
		||||
 | 
			
		||||
    pa_sink_input_unref(i);
 | 
			
		||||
| 
						 | 
				
			
			@ -1240,6 +1281,8 @@ int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
 | 
			
		|||
    i->save_sink = save;
 | 
			
		||||
    pa_idxset_put(dest->inputs, pa_sink_input_ref(i), NULL);
 | 
			
		||||
 | 
			
		||||
    pa_cvolume_remap(&i->volume_factor_sink, &i->channel_map, &i->sink->channel_map);
 | 
			
		||||
 | 
			
		||||
    if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
 | 
			
		||||
        i->sink->n_corked++;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue