Example #1
0
bool
vorbis_comments_to_replay_gain(struct replay_gain_info *rgi, char **comments)
{
	const char *temp;
	bool found = false;

	replay_gain_info_init(rgi);

	while (*comments) {
		if ((temp =
		     vorbis_comment_value(*comments, "replaygain_track_gain"))) {
			rgi->tuples[REPLAY_GAIN_TRACK].gain = atof(temp);
			found = true;
		} else if ((temp = vorbis_comment_value(*comments,
							"replaygain_album_gain"))) {
			rgi->tuples[REPLAY_GAIN_ALBUM].gain = atof(temp);
			found = true;
		} else if ((temp = vorbis_comment_value(*comments,
							"replaygain_track_peak"))) {
			rgi->tuples[REPLAY_GAIN_TRACK].peak = atof(temp);
			found = true;
		} else if ((temp = vorbis_comment_value(*comments,
							"replaygain_album_peak"))) {
			rgi->tuples[REPLAY_GAIN_ALBUM].peak = atof(temp);
			found = true;
		}

		comments++;
	}

	return found;
}
static bool
wavpack_replaygain(struct replay_gain_info *replay_gain_info,
		   WavpackContext *wpc)
{
	bool found = false;

	replay_gain_info_init(replay_gain_info);

	found |= wavpack_tag_float(
		wpc, "replaygain_track_gain",
		&replay_gain_info->tuples[REPLAY_GAIN_TRACK].gain
	);
	found |= wavpack_tag_float(
		wpc, "replaygain_track_peak",
		&replay_gain_info->tuples[REPLAY_GAIN_TRACK].peak
	);
	found |= wavpack_tag_float(
		wpc, "replaygain_album_gain",
		&replay_gain_info->tuples[REPLAY_GAIN_ALBUM].gain
	);
	found |= wavpack_tag_float(
		wpc, "replaygain_album_peak",
		&replay_gain_info->tuples[REPLAY_GAIN_ALBUM].peak
	);

	return found;
}
Example #3
0
int main(int argc, char **argv)
{
	GError *error = NULL;

#ifdef HAVE_LOCALE_H
	/* initialize locale */
	setlocale(LC_CTYPE,"");
#endif

	if (argc != 2) {
		g_printerr("Usage: read_rva2 FILE\n");
		return 1;
	}

	const char *path = argv[1];

	struct id3_tag *tag = tag_id3_load(path, &error);
	if (tag == NULL) {
		if (error != NULL) {
			g_printerr("%s\n", error->message);
			g_error_free(error);
		} else
			g_printerr("No ID3 tag found\n");

		return EXIT_FAILURE;
	}

	struct replay_gain_info replay_gain;
	replay_gain_info_init(&replay_gain);

	bool success = tag_rva2_parse(tag, &replay_gain);
	id3_tag_delete(tag);

	if (!success) {
		g_printerr("No RVA2 tag found\n");
		return EXIT_FAILURE;
	}

	const struct replay_gain_tuple *tuple =
		&replay_gain.tuples[REPLAY_GAIN_ALBUM];
	if (replay_gain_tuple_defined(tuple))
		g_printerr("replay_gain[album]: gain=%f peak=%f\n",
			   tuple->gain, tuple->peak);

	tuple = &replay_gain.tuples[REPLAY_GAIN_TRACK];
	if (replay_gain_tuple_defined(tuple))
		g_printerr("replay_gain[track]: gain=%f peak=%f\n",
			   tuple->gain, tuple->peak);

	return EXIT_SUCCESS;
}
void
replay_gain_filter_set_info(struct filter *_filter,
			    const struct replay_gain_info *info)
{
	struct replay_gain_filter *filter =
		(struct replay_gain_filter *)_filter;

	if (info != NULL) {
		filter->info = *info;
		replay_gain_info_complete(&filter->info);
	} else
		replay_gain_info_init(&filter->info);

	replay_gain_filter_update(filter);
}
static struct filter *
replay_gain_filter_init(G_GNUC_UNUSED const struct config_param *param,
			G_GNUC_UNUSED GError **error_r)
{
	struct replay_gain_filter *filter = g_new(struct replay_gain_filter, 1);

	filter_init(&filter->filter, &replay_gain_filter_plugin);
	filter->mixer = NULL;

	filter->mode = replay_gain_mode;
	replay_gain_info_init(&filter->info);
	filter->volume = PCM_VOLUME_1;

	return &filter->filter;
}
Example #6
0
static bool
parse_id3_replay_gain_info(struct replay_gain_info *replay_gain_info,
			   struct id3_tag *tag)
{
	int i;
	char *key;
	char *value;
	struct id3_frame *frame;
	bool found = false;

	replay_gain_info_init(replay_gain_info);

	for (i = 0; (frame = id3_tag_findframe(tag, "TXXX", i)); i++) {
		if (frame->nfields < 3)
			continue;

		key = (char *)
		    id3_ucs4_latin1duplicate(id3_field_getstring
					     (&frame->fields[1]));
		value = (char *)
		    id3_ucs4_latin1duplicate(id3_field_getstring
					     (&frame->fields[2]));

		if (g_ascii_strcasecmp(key, "replaygain_track_gain") == 0) {
			replay_gain_info->tuples[REPLAY_GAIN_TRACK].gain = atof(value);
			found = true;
		} else if (g_ascii_strcasecmp(key, "replaygain_album_gain") == 0) {
			replay_gain_info->tuples[REPLAY_GAIN_ALBUM].gain = atof(value);
			found = true;
		} else if (g_ascii_strcasecmp(key, "replaygain_track_peak") == 0) {
			replay_gain_info->tuples[REPLAY_GAIN_TRACK].peak = atof(value);
			found = true;
		} else if (g_ascii_strcasecmp(key, "replaygain_album_peak") == 0) {
			replay_gain_info->tuples[REPLAY_GAIN_ALBUM].peak = atof(value);
			found = true;
		}

		free(key);
		free(value);
	}

	return found ||
		/* fall back on RVA2 if no replaygain tags found */
		tag_rva2_parse(tag, replay_gain_info);
}
Example #7
0
static bool
mp3_decode_first_frame(struct mp3_data *data, struct tag **tag)
{
	struct xing xing;
	struct lame lame;
	struct mad_bitptr ptr;
	int bitlen;
	enum mp3_action ret;

	/* stfu gcc */
	memset(&xing, 0, sizeof(struct xing));
	xing.flags = 0;

	while (true) {
		do {
			ret = decode_next_frame_header(data, tag);
		} while (ret == DECODE_CONT);
		if (ret == DECODE_BREAK)
			return false;
		if (ret == DECODE_SKIP) continue;

		do {
			ret = decodeNextFrame(data);
		} while (ret == DECODE_CONT);
		if (ret == DECODE_BREAK)
			return false;
		if (ret == DECODE_OK) break;
	}

	ptr = data->stream.anc_ptr;
	bitlen = data->stream.anc_bitlen;

	mp3_filesize_to_song_length(data);

	/*
	 * if an xing tag exists, use that!
	 */
	if (parse_xing(&xing, &ptr, &bitlen)) {
		data->found_xing = true;
		data->mute_frame = MUTEFRAME_SKIP;

		if ((xing.flags & XING_FRAMES) && xing.frames) {
			mad_timer_t duration = data->frame.header.duration;
			mad_timer_multiply(&duration, xing.frames);
			data->total_time = ((float)mad_timer_count(duration, MAD_UNITS_MILLISECONDS)) / 1000;
			data->max_frames = xing.frames;
		}

		if (parse_lame(&lame, &ptr, &bitlen)) {
			if (gapless_playback &&
			    data->input_stream->seekable) {
				data->drop_start_samples = lame.encoder_delay +
				                           DECODERDELAY;
				data->drop_end_samples = lame.encoder_padding;
			}

			/* Album gain isn't currently used.  See comment in
			 * parse_lame() for details. -- jat */
			if (data->decoder != NULL &&
			    !data->found_replay_gain &&
			    lame.track_gain) {
				struct replay_gain_info rgi;
				replay_gain_info_init(&rgi);
				rgi.tuples[REPLAY_GAIN_TRACK].gain = lame.track_gain;
				rgi.tuples[REPLAY_GAIN_TRACK].peak = lame.peak;
				decoder_replay_gain(data->decoder, &rgi);
			}
		}
	}

	if (!data->max_frames)
		return false;

	if (data->max_frames > 8 * 1024 * 1024) {
		g_warning("mp3 file header indicates too many frames: %lu\n",
			  data->max_frames);
		return false;
	}

	data->frame_offsets = g_malloc(sizeof(long) * data->max_frames);
	data->times = g_malloc(sizeof(mad_timer_t) * data->max_frames);

	return true;
}