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; }
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; }
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); }
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; }