replay_gain_info: allocate the struct statically
Don't allocate each replay_gain_info object on the heap. Those objects who held a pointer now store a full replay_gain_info object. This reduces the number of allocations and heap fragmentation.
This commit is contained in:
parent
c05e6a1275
commit
5e0117b444
|
@ -116,7 +116,7 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
|
|||
if (data->unsupported)
|
||||
return;
|
||||
|
||||
struct replay_gain_info *rgi;
|
||||
struct replay_gain_info rgi;
|
||||
|
||||
switch (block->type) {
|
||||
case FLAC__METADATA_TYPE_STREAMINFO:
|
||||
|
@ -124,11 +124,8 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
|
|||
break;
|
||||
|
||||
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
|
||||
rgi = flac_parse_replay_gain(block);
|
||||
if (rgi != NULL) {
|
||||
decoder_replay_gain(data->decoder, rgi);
|
||||
replay_gain_info_free(rgi);
|
||||
}
|
||||
if (flac_parse_replay_gain(&rgi, block))
|
||||
decoder_replay_gain(data->decoder, &rgi);
|
||||
|
||||
if (data->tag != NULL)
|
||||
flac_vorbis_comments_to_tag(data->tag, NULL,
|
||||
|
|
|
@ -56,13 +56,13 @@ flac_find_float_comment(const FLAC__StreamMetadata *block,
|
|||
return true;
|
||||
}
|
||||
|
||||
struct replay_gain_info *
|
||||
flac_parse_replay_gain(const FLAC__StreamMetadata *block)
|
||||
bool
|
||||
flac_parse_replay_gain(struct replay_gain_info *rgi,
|
||||
const FLAC__StreamMetadata *block)
|
||||
{
|
||||
struct replay_gain_info *rgi;
|
||||
bool found = false;
|
||||
|
||||
rgi = replay_gain_info_new();
|
||||
replay_gain_info_init(rgi);
|
||||
|
||||
if (flac_find_float_comment(block, "replaygain_album_gain",
|
||||
&rgi->tuples[REPLAY_GAIN_ALBUM].gain))
|
||||
|
@ -77,12 +77,7 @@ flac_parse_replay_gain(const FLAC__StreamMetadata *block)
|
|||
&rgi->tuples[REPLAY_GAIN_TRACK].peak))
|
||||
found = true;
|
||||
|
||||
if (!found) {
|
||||
replay_gain_info_free(rgi);
|
||||
rgi = NULL;
|
||||
}
|
||||
|
||||
return rgi;
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,9 +20,11 @@
|
|||
#ifndef MPD_FLAC_METADATA_H
|
||||
#define MPD_FLAC_METADATA_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <FLAC/metadata.h>
|
||||
|
||||
struct tag;
|
||||
struct replay_gain_info;
|
||||
|
||||
static inline unsigned
|
||||
flac_duration(const FLAC__StreamMetadata_StreamInfo *stream_info)
|
||||
|
@ -31,8 +33,9 @@ flac_duration(const FLAC__StreamMetadata_StreamInfo *stream_info)
|
|||
stream_info->sample_rate;
|
||||
}
|
||||
|
||||
struct replay_gain_info *
|
||||
flac_parse_replay_gain(const FLAC__StreamMetadata *block);
|
||||
bool
|
||||
flac_parse_replay_gain(struct replay_gain_info *rgi,
|
||||
const FLAC__StreamMetadata *block);
|
||||
|
||||
void
|
||||
flac_vorbis_comments_to_tag(struct tag *tag, const char *char_tnum,
|
||||
|
|
|
@ -300,17 +300,17 @@ static int parse_rva2(struct id3_tag * tag, struct replay_gain_info * replay_gai
|
|||
#endif
|
||||
|
||||
#ifdef HAVE_ID3TAG
|
||||
static struct replay_gain_info *
|
||||
parse_id3_replay_gain_info(struct id3_tag *tag)
|
||||
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;
|
||||
struct replay_gain_info *replay_gain_info;
|
||||
|
||||
replay_gain_info = replay_gain_info_new();
|
||||
replay_gain_info_init(replay_gain_info);
|
||||
|
||||
for (i = 0; (frame = id3_tag_findframe(tag, "TXXX", i)); i++) {
|
||||
if (frame->nfields < 3)
|
||||
|
@ -341,15 +341,9 @@ parse_id3_replay_gain_info(struct id3_tag *tag)
|
|||
free(value);
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
return found ||
|
||||
/* fall back on RVA2 if no replaygain tags found */
|
||||
found = parse_rva2(tag, replay_gain_info);
|
||||
}
|
||||
|
||||
if (found)
|
||||
return replay_gain_info;
|
||||
replay_gain_info_free(replay_gain_info);
|
||||
return NULL;
|
||||
parse_rva2(tag, replay_gain_info);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -408,11 +402,9 @@ static void mp3_parse_id3(struct mp3_data *data, size_t tagsize,
|
|||
}
|
||||
|
||||
if (data->decoder != NULL) {
|
||||
struct replay_gain_info *tmp_rgi =
|
||||
parse_id3_replay_gain_info(id3_tag);
|
||||
if (tmp_rgi != NULL) {
|
||||
decoder_replay_gain(data->decoder, tmp_rgi);
|
||||
replay_gain_info_free(tmp_rgi);
|
||||
struct replay_gain_info rgi;
|
||||
if (parse_id3_replay_gain_info(&rgi, id3_tag)) {
|
||||
decoder_replay_gain(data->decoder, &rgi);
|
||||
data->found_replay_gain = true;
|
||||
}
|
||||
}
|
||||
|
@ -879,15 +871,14 @@ mp3_decode_first_frame(struct mp3_data *data, struct tag **tag)
|
|||
if (data->decoder != NULL &&
|
||||
!data->found_replay_gain &&
|
||||
lame.track_gain) {
|
||||
struct replay_gain_info *rgi
|
||||
= replay_gain_info_new();
|
||||
rgi->tuples[REPLAY_GAIN_TRACK].gain = lame.track_gain;
|
||||
rgi->tuples[REPLAY_GAIN_TRACK].peak = lame.peak;
|
||||
decoder_replay_gain(data->decoder, rgi);
|
||||
replay_gain_info_free(rgi);
|
||||
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;
|
||||
|
|
|
@ -154,7 +154,6 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is)
|
|||
long bit_rate = 0;
|
||||
mpc_uint32_t vbr_update_acc;
|
||||
mpc_uint32_t vbr_update_bits;
|
||||
struct replay_gain_info *replay_gain_info = NULL;
|
||||
enum decoder_command cmd = DECODE_COMMAND_NONE;
|
||||
|
||||
data.is = is;
|
||||
|
@ -205,13 +204,13 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is)
|
|||
return;
|
||||
}
|
||||
|
||||
replay_gain_info = replay_gain_info_new();
|
||||
replay_gain_info->tuples[REPLAY_GAIN_ALBUM].gain = info.gain_album * 0.01;
|
||||
replay_gain_info->tuples[REPLAY_GAIN_ALBUM].peak = info.peak_album / 32767.0;
|
||||
replay_gain_info->tuples[REPLAY_GAIN_TRACK].gain = info.gain_title * 0.01;
|
||||
replay_gain_info->tuples[REPLAY_GAIN_TRACK].peak = info.peak_title / 32767.0;
|
||||
decoder_replay_gain(mpd_decoder, replay_gain_info);
|
||||
replay_gain_info_free(replay_gain_info);
|
||||
struct replay_gain_info replay_gain_info;
|
||||
replay_gain_info_init(&replay_gain_info);
|
||||
replay_gain_info.tuples[REPLAY_GAIN_ALBUM].gain = info.gain_album * 0.01;
|
||||
replay_gain_info.tuples[REPLAY_GAIN_ALBUM].peak = info.peak_album / 32767.0;
|
||||
replay_gain_info.tuples[REPLAY_GAIN_TRACK].gain = info.gain_title * 0.01;
|
||||
replay_gain_info.tuples[REPLAY_GAIN_TRACK].peak = info.peak_title / 32767.0;
|
||||
decoder_replay_gain(mpd_decoder, &replay_gain_info);
|
||||
|
||||
decoder_initialized(mpd_decoder, &audio_format,
|
||||
is->seekable,
|
||||
|
|
|
@ -134,14 +134,13 @@ vorbis_comment_value(const char *comment, const char *needle)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct replay_gain_info *
|
||||
vorbis_comments_to_replay_gain(char **comments)
|
||||
static bool
|
||||
vorbis_comments_to_replay_gain(struct replay_gain_info *rgi, char **comments)
|
||||
{
|
||||
struct replay_gain_info *rgi;
|
||||
const char *temp;
|
||||
bool found = false;
|
||||
|
||||
rgi = replay_gain_info_new();
|
||||
replay_gain_info_init(rgi);
|
||||
|
||||
while (*comments) {
|
||||
if ((temp =
|
||||
|
@ -165,12 +164,7 @@ vorbis_comments_to_replay_gain(char **comments)
|
|||
comments++;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
replay_gain_info_free(rgi);
|
||||
rgi = NULL;
|
||||
}
|
||||
|
||||
return rgi;
|
||||
return found;
|
||||
}
|
||||
|
||||
static const char *VORBIS_COMMENT_TRACK_KEY = "tracknumber";
|
||||
|
@ -334,7 +328,6 @@ vorbis_stream_decode(struct decoder *decoder,
|
|||
|
||||
if (current_section != prev_section) {
|
||||
char **comments;
|
||||
struct replay_gain_info *new_rgi;
|
||||
|
||||
vi = ov_info(&vf, -1);
|
||||
if (vi == NULL) {
|
||||
|
@ -352,11 +345,10 @@ vorbis_stream_decode(struct decoder *decoder,
|
|||
|
||||
comments = ov_comment(&vf, -1)->user_comments;
|
||||
vorbis_send_comments(decoder, input_stream, comments);
|
||||
new_rgi = vorbis_comments_to_replay_gain(comments);
|
||||
if (new_rgi != NULL) {
|
||||
decoder_replay_gain(decoder, new_rgi);
|
||||
replay_gain_info_free(new_rgi);
|
||||
}
|
||||
|
||||
struct replay_gain_info rgi;
|
||||
if (vorbis_comments_to_replay_gain(&rgi, comments))
|
||||
decoder_replay_gain(decoder, &rgi);
|
||||
|
||||
prev_section = current_section;
|
||||
}
|
||||
|
|
|
@ -256,13 +256,13 @@ wavpack_tag_float(WavpackContext *wpc, const char *key, float *value_r)
|
|||
return true;
|
||||
}
|
||||
|
||||
static struct replay_gain_info *
|
||||
wavpack_replaygain(WavpackContext *wpc)
|
||||
static bool
|
||||
wavpack_replaygain(struct replay_gain_info *replay_gain_info,
|
||||
WavpackContext *wpc)
|
||||
{
|
||||
struct replay_gain_info *replay_gain_info;
|
||||
bool found = false;
|
||||
|
||||
replay_gain_info = replay_gain_info_new();
|
||||
replay_gain_info_init(replay_gain_info);
|
||||
|
||||
found |= wavpack_tag_float(
|
||||
wpc, "replaygain_track_gain",
|
||||
|
@ -281,13 +281,7 @@ wavpack_replaygain(WavpackContext *wpc)
|
|||
&replay_gain_info->tuples[REPLAY_GAIN_ALBUM].peak
|
||||
);
|
||||
|
||||
if (found) {
|
||||
return replay_gain_info;
|
||||
}
|
||||
|
||||
replay_gain_info_free(replay_gain_info);
|
||||
|
||||
return NULL;
|
||||
return found;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -554,7 +548,6 @@ wavpack_filedecode(struct decoder *decoder, const char *fname)
|
|||
{
|
||||
char error[ERRORLEN];
|
||||
WavpackContext *wpc;
|
||||
struct replay_gain_info *replay_gain_info;
|
||||
|
||||
wpc = WavpackOpenFileInput(
|
||||
fname, error,
|
||||
|
@ -568,11 +561,9 @@ wavpack_filedecode(struct decoder *decoder, const char *fname)
|
|||
return;
|
||||
}
|
||||
|
||||
replay_gain_info = wavpack_replaygain(wpc);
|
||||
if (replay_gain_info != NULL) {
|
||||
decoder_replay_gain(decoder, replay_gain_info);
|
||||
replay_gain_info_free(replay_gain_info);
|
||||
}
|
||||
struct replay_gain_info replay_gain_info;
|
||||
if (wavpack_replaygain(&replay_gain_info, wpc))
|
||||
decoder_replay_gain(decoder, &replay_gain_info);
|
||||
|
||||
wavpack_decode(decoder, wpc, true);
|
||||
|
||||
|
|
|
@ -20,33 +20,6 @@
|
|||
#include "config.h"
|
||||
#include "replay_gain_info.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
struct replay_gain_info *
|
||||
replay_gain_info_new(void)
|
||||
{
|
||||
struct replay_gain_info *ret = g_new(struct replay_gain_info, 1);
|
||||
|
||||
for (unsigned i = 0; i < G_N_ELEMENTS(ret->tuples); ++i) {
|
||||
ret->tuples[i].gain = INFINITY;
|
||||
ret->tuples[i].peak = 0.0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct replay_gain_info *
|
||||
replay_gain_info_dup(const struct replay_gain_info *src)
|
||||
{
|
||||
return g_memdup(src, sizeof(*src));
|
||||
}
|
||||
|
||||
void
|
||||
replay_gain_info_free(struct replay_gain_info *info)
|
||||
{
|
||||
g_free(info);
|
||||
}
|
||||
|
||||
float
|
||||
replay_gain_tuple_scale(const struct replay_gain_tuple *tuple, float preamp)
|
||||
{
|
||||
|
|
|
@ -40,17 +40,19 @@ struct replay_gain_info {
|
|||
struct replay_gain_tuple tuples[2];
|
||||
};
|
||||
|
||||
struct replay_gain_info *
|
||||
replay_gain_info_new(void);
|
||||
static inline void
|
||||
replay_gain_tuple_init(struct replay_gain_tuple *tuple)
|
||||
{
|
||||
tuple->gain = INFINITY;
|
||||
tuple->peak = 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate a #replay_gain_info object.
|
||||
*/
|
||||
struct replay_gain_info *
|
||||
replay_gain_info_dup(const struct replay_gain_info *src);
|
||||
|
||||
void
|
||||
replay_gain_info_free(struct replay_gain_info *info);
|
||||
static inline void
|
||||
replay_gain_info_init(struct replay_gain_info *info)
|
||||
{
|
||||
replay_gain_tuple_init(&info->tuples[REPLAY_GAIN_ALBUM]);
|
||||
replay_gain_tuple_init(&info->tuples[REPLAY_GAIN_TRACK]);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
replay_gain_tuple_defined(const struct replay_gain_tuple *tuple)
|
||||
|
|
|
@ -30,7 +30,7 @@ struct replay_gain_state {
|
|||
|
||||
enum replay_gain_mode mode;
|
||||
|
||||
struct replay_gain_info *info;
|
||||
struct replay_gain_info info;
|
||||
|
||||
float scale;
|
||||
};
|
||||
|
@ -43,7 +43,7 @@ replay_gain_state_new(float preamp, float missing_preamp)
|
|||
state->preamp = preamp;
|
||||
state->scale = state->missing_preamp = missing_preamp;
|
||||
state->mode = REPLAY_GAIN_OFF;
|
||||
state->info = NULL;
|
||||
replay_gain_info_init(&state->info);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
@ -53,9 +53,6 @@ replay_gain_state_free(struct replay_gain_state *state)
|
|||
{
|
||||
assert(state != NULL);
|
||||
|
||||
if (state->info != NULL)
|
||||
replay_gain_info_free(state->info);
|
||||
|
||||
g_free(state);
|
||||
}
|
||||
|
||||
|
@ -64,11 +61,11 @@ replay_gain_state_calc_scale(struct replay_gain_state *state)
|
|||
{
|
||||
assert(state != NULL);
|
||||
|
||||
if (state->mode == REPLAY_GAIN_OFF || state->info == NULL)
|
||||
if (state->mode == REPLAY_GAIN_OFF)
|
||||
return;
|
||||
|
||||
const struct replay_gain_tuple *tuple =
|
||||
&state->info->tuples[state->mode];
|
||||
&state->info.tuples[state->mode];
|
||||
if (replay_gain_tuple_defined(tuple)) {
|
||||
g_debug("computing ReplayGain scale with gain %f, peak %f",
|
||||
tuple->gain, tuple->peak);
|
||||
|
@ -98,12 +95,10 @@ replay_gain_state_set_info(struct replay_gain_state *state,
|
|||
{
|
||||
assert(state != NULL);
|
||||
|
||||
if (state->info != NULL)
|
||||
replay_gain_info_free(state->info);
|
||||
|
||||
state->info = info != NULL
|
||||
? replay_gain_info_dup(info)
|
||||
: NULL;
|
||||
if (info != NULL)
|
||||
state->info = *info;
|
||||
else
|
||||
replay_gain_info_init(&state->info);
|
||||
|
||||
replay_gain_state_calc_scale(state);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue