mixramp: Adjust MixRamp threshold to account for ReplayGain.
This commit is contained in:
		 Tim Phipps
					Tim Phipps
				
			
				
					committed by
					
						 Avuton Olrich
						Avuton Olrich
					
				
			
			
				
	
			
			
			 Avuton Olrich
						Avuton Olrich
					
				
			
						parent
						
							eb5208c4f9
						
					
				
				
					commit
					0ac5b6e613
				
			| @@ -91,6 +91,7 @@ static float mixramp_interpolate(char *ramp_list, float required_db) | ||||
|  | ||||
| unsigned cross_fade_calc(float duration, float total_time, | ||||
| 			 float mixramp_db, float mixramp_delay, | ||||
| 			 float replay_gain_db, float replay_gain_prev_db, | ||||
| 			 char *mixramp_start, char *mixramp_prev_end, | ||||
| 			 const struct audio_format *af, | ||||
| 			 const struct audio_format *old_format, | ||||
| @@ -113,10 +114,9 @@ unsigned cross_fade_calc(float duration, float total_time, | ||||
| 	if (isnan(mixramp_delay) || !(mixramp_start) || !(mixramp_prev_end)) { | ||||
| 		chunks = (chunks_f * duration + 0.5); | ||||
| 	} else { | ||||
| 		/* Calculate mixramp overlap. | ||||
| 		 * FIXME factor in ReplayGain for both songs. */ | ||||
| 		mixramp_overlap = mixramp_interpolate(mixramp_start, mixramp_db) | ||||
| 		  + mixramp_interpolate(mixramp_prev_end, mixramp_db); | ||||
| 		/* Calculate mixramp overlap. */ | ||||
| 		mixramp_overlap = mixramp_interpolate(mixramp_start, mixramp_db - replay_gain_db) | ||||
| 		  + mixramp_interpolate(mixramp_prev_end, mixramp_db - replay_gain_prev_db); | ||||
| 		if (!isnan(mixramp_overlap) && (mixramp_delay <= mixramp_overlap)) { | ||||
| 			chunks = (chunks_f * (mixramp_overlap - mixramp_delay)); | ||||
| 			g_debug("will overlap %d chunks, %fs", chunks, | ||||
|   | ||||
| @@ -30,6 +30,8 @@ struct music_chunk; | ||||
|  * @param total_time total_time the duration of the new song | ||||
|  * @param mixramp_db the current mixramp_db setting | ||||
|  * @param mixramp_delay the current mixramp_delay setting | ||||
|  * @param replay_gain_db the ReplayGain adjustment used for this song | ||||
|  * @param replay_gain_prev_db the ReplayGain adjustment used on the last song | ||||
|  * @param mixramp_start the next songs mixramp_start tag | ||||
|  * @param mixramp_prev_end the last songs mixramp_end setting | ||||
|  * @param af the audio format of the new song | ||||
| @@ -40,6 +42,7 @@ struct music_chunk; | ||||
|  */ | ||||
| unsigned cross_fade_calc(float duration, float total_time, | ||||
| 			 float mixramp_db, float mixramp_delay, | ||||
| 			 float replay_gain_db, float replay_gain_prev_db, | ||||
| 			 char *mixramp_start, char *mixramp_prev_end, | ||||
| 			 const struct audio_format *af, | ||||
| 			 const struct audio_format *old_format, | ||||
|   | ||||
| @@ -114,6 +114,7 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block, | ||||
| 	struct replay_gain_info rgi; | ||||
| 	char *mixramp_start; | ||||
| 	char *mixramp_end; | ||||
| 	float replay_gain_db = 0; | ||||
|  | ||||
| 	switch (block->type) { | ||||
| 	case FLAC__METADATA_TYPE_STREAMINFO: | ||||
| @@ -122,10 +123,11 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block, | ||||
|  | ||||
| 	case FLAC__METADATA_TYPE_VORBIS_COMMENT: | ||||
| 		if (flac_parse_replay_gain(&rgi, block)) | ||||
| 			decoder_replay_gain(data->decoder, &rgi); | ||||
| 			replay_gain_db = decoder_replay_gain(data->decoder, &rgi); | ||||
| 		if (flac_parse_mixramp(&mixramp_start, &mixramp_end, block)) { | ||||
| 			g_debug("setting mixramp_tags"); | ||||
| 			decoder_mixramp(data->decoder, mixramp_start, mixramp_end); | ||||
| 			decoder_mixramp(data->decoder, replay_gain_db, | ||||
| 					mixramp_start, mixramp_end); | ||||
| 		} | ||||
|  | ||||
| 		if (data->tag != NULL) | ||||
|   | ||||
| @@ -446,13 +446,16 @@ static void mp3_parse_id3(struct mp3_data *data, size_t tagsize, | ||||
| 		struct replay_gain_info rgi; | ||||
| 		char *mixramp_start; | ||||
| 		char *mixramp_end; | ||||
| 		float replay_gain_db = 0; | ||||
|  | ||||
| 		if (parse_id3_replay_gain_info(&rgi, id3_tag)) { | ||||
| 			decoder_replay_gain(data->decoder, &rgi); | ||||
| 			replay_gain_db = decoder_replay_gain(data->decoder, &rgi); | ||||
| 			data->found_replay_gain = true; | ||||
| 		} | ||||
| 		if (parse_id3_mixramp(&mixramp_start, &mixramp_end, id3_tag)) { | ||||
| 			g_debug("setting mixramp_tags"); | ||||
| 			decoder_mixramp(data->decoder, mixramp_start, mixramp_end); | ||||
| 			decoder_mixramp(data->decoder, replay_gain_db, | ||||
| 					mixramp_start, mixramp_end); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -27,6 +27,7 @@ | ||||
| #include "buffer.h" | ||||
| #include "pipe.h" | ||||
| #include "chunk.h" | ||||
| #include "replay_gain_config.h" | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| @@ -403,10 +404,11 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder, struct input_stream *is, | ||||
| 	return cmd; | ||||
| } | ||||
|  | ||||
| void | ||||
| float | ||||
| decoder_replay_gain(struct decoder *decoder, | ||||
| 		    const struct replay_gain_info *replay_gain_info) | ||||
| { | ||||
| 	float return_db = 0; | ||||
| 	assert(decoder != NULL); | ||||
|  | ||||
| 	if (replay_gain_info != NULL) { | ||||
| @@ -414,6 +416,13 @@ decoder_replay_gain(struct decoder *decoder, | ||||
| 		if (++serial == 0) | ||||
| 			serial = 1; | ||||
|  | ||||
| 		if (REPLAY_GAIN_OFF != replay_gain_mode) { | ||||
| 			return_db = 20.0 * log10f( | ||||
| 				replay_gain_tuple_scale( | ||||
| 					&replay_gain_info->tuples[replay_gain_mode], | ||||
| 					replay_gain_preamp)); | ||||
| 		} | ||||
|  | ||||
| 		decoder->replay_gain_info = *replay_gain_info; | ||||
| 		decoder->replay_gain_serial = serial; | ||||
|  | ||||
| @@ -426,16 +435,19 @@ decoder_replay_gain(struct decoder *decoder, | ||||
| 		} | ||||
| 	} else | ||||
| 		decoder->replay_gain_serial = 0; | ||||
|  | ||||
| 	return return_db; | ||||
| } | ||||
|  | ||||
| void | ||||
| decoder_mixramp(struct decoder *decoder, | ||||
| decoder_mixramp(struct decoder *decoder, float replay_gain_db, | ||||
| 		char *mixramp_start, char *mixramp_end) | ||||
| { | ||||
| 	assert(decoder != NULL); | ||||
| 	struct decoder_control *dc = decoder->dc; | ||||
| 	assert(dc != NULL); | ||||
|  | ||||
| 	dc->replay_gain_db = replay_gain_db; | ||||
| 	dc_mixramp_start(dc, mixramp_start); | ||||
| 	dc_mixramp_end(dc, mixramp_end); | ||||
| } | ||||
|   | ||||
| @@ -152,8 +152,9 @@ decoder_tag(struct decoder *decoder, struct input_stream *is, | ||||
|  * @param decoder the decoder object | ||||
|  * @param rgi the replay_gain_info object; may be NULL to invalidate | ||||
|  * the previous replay gain values | ||||
|  * @return the replay gain adjustment used | ||||
|  */ | ||||
| void | ||||
| float | ||||
| decoder_replay_gain(struct decoder *decoder, | ||||
| 		    const struct replay_gain_info *replay_gain_info); | ||||
|  | ||||
| @@ -161,11 +162,12 @@ decoder_replay_gain(struct decoder *decoder, | ||||
|  * Store MixRamp tags. | ||||
|  * | ||||
|  * @param decoder the decoder object | ||||
|  * @param replay_gain_db the ReplayGain adjustment used for this song | ||||
|  * @param mixramp_start the mixramp_start tag; may be NULL to invalidate | ||||
|  * @param mixramp_end the mixramp_end tag; may be NULL to invalidate | ||||
|  */ | ||||
| void | ||||
| decoder_mixramp(struct decoder *decoder, | ||||
| decoder_mixramp(struct decoder *decoder, float replay_gain_db, | ||||
| 		char *mixramp_start, char *mixramp_end); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -38,6 +38,8 @@ dc_init(struct decoder_control *dc) | ||||
| 	dc->state = DECODE_STATE_STOP; | ||||
| 	dc->command = DECODE_COMMAND_NONE; | ||||
|  | ||||
| 	dc->replay_gain_db = 0; | ||||
| 	dc->replay_gain_prev_db = 0; | ||||
| 	dc->mixramp_start = NULL; | ||||
| 	dc->mixramp_end = NULL; | ||||
| 	dc->mixramp_prev_end = NULL; | ||||
|   | ||||
| @@ -90,6 +90,8 @@ struct decoder_control { | ||||
| 	 */ | ||||
| 	struct music_pipe *pipe; | ||||
|  | ||||
| 	float replay_gain_db; | ||||
| 	float replay_gain_prev_db; | ||||
| 	char *mixramp_start; | ||||
| 	char *mixramp_end; | ||||
| 	char *mixramp_prev_end; | ||||
|   | ||||
| @@ -438,6 +438,8 @@ decoder_task(gpointer arg) | ||||
| 			dc_mixramp_start(dc, NULL); | ||||
| 			dc_mixramp_prev_end(dc, dc->mixramp_end); | ||||
| 			dc->mixramp_end = NULL; /* Don't free, it's copied above. */ | ||||
| 			dc->replay_gain_prev_db = dc->replay_gain_db; | ||||
| 			dc->replay_gain_db = 0; | ||||
|  | ||||
|                         /* fall through */ | ||||
|  | ||||
|   | ||||
| @@ -895,6 +895,8 @@ static void do_play(struct decoder_control *dc) | ||||
| 				cross_fade_calc(pc.cross_fade_seconds, dc->total_time, | ||||
| 						pc.mixramp_db, | ||||
| 						pc.mixramp_delay_seconds, | ||||
| 						dc->replay_gain_db, | ||||
| 						dc->replay_gain_prev_db, | ||||
| 						dc->mixramp_start, | ||||
| 						dc->mixramp_prev_end, | ||||
| 						&dc->out_audio_format, | ||||
|   | ||||
| @@ -115,14 +115,16 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder, | ||||
| 	return DECODE_COMMAND_NONE; | ||||
| } | ||||
|  | ||||
| void | ||||
| float | ||||
| decoder_replay_gain(G_GNUC_UNUSED struct decoder *decoder, | ||||
| 		    G_GNUC_UNUSED const struct replay_gain_info *replay_gain_info) | ||||
| { | ||||
| 	return 0.0; | ||||
| } | ||||
|  | ||||
| void | ||||
| decoder_mixramp(G_GNUC_UNUSED struct decoder *decoder, | ||||
| 		G_GNUC_UNUSED float replay_gain_db, | ||||
| 		char *mixramp_start, char *mixramp_end) | ||||
| { | ||||
| 	g_free(mixramp_start); | ||||
|   | ||||
| @@ -136,14 +136,16 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder, | ||||
| 	return DECODE_COMMAND_NONE; | ||||
| } | ||||
|  | ||||
| void | ||||
| float | ||||
| decoder_replay_gain(G_GNUC_UNUSED struct decoder *decoder, | ||||
| 		    G_GNUC_UNUSED const struct replay_gain_info *replay_gain_info) | ||||
| { | ||||
| 	return 0.0; | ||||
| } | ||||
|  | ||||
| void | ||||
| decoder_mixramp(G_GNUC_UNUSED struct decoder *decoder, | ||||
| 		G_GNUC_UNUSED float replay_gain_db, | ||||
| 		char *mixramp_start, char *mixramp_end) | ||||
| { | ||||
| 	g_free(mixramp_start); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user