|
|
|
@ -35,7 +35,7 @@ |
|
|
|
|
#include "avformat.h" |
|
|
|
|
#include "replaygain.h" |
|
|
|
|
|
|
|
|
|
static int32_t parse_gain(const char *gain) |
|
|
|
|
static int32_t parse_value(const char *value, int32_t min) |
|
|
|
|
{ |
|
|
|
|
char *fraction; |
|
|
|
|
int scale = 10000; |
|
|
|
@ -43,15 +43,15 @@ static int32_t parse_gain(const char *gain) |
|
|
|
|
int sign = 1; |
|
|
|
|
int db; |
|
|
|
|
|
|
|
|
|
if (!gain) |
|
|
|
|
return INT32_MIN; |
|
|
|
|
if (!value) |
|
|
|
|
return min; |
|
|
|
|
|
|
|
|
|
gain += strspn(gain, " \t"); |
|
|
|
|
value += strspn(value, " \t"); |
|
|
|
|
|
|
|
|
|
if (*gain == '-') |
|
|
|
|
if (*value == '-') |
|
|
|
|
sign = -1; |
|
|
|
|
|
|
|
|
|
db = strtol(gain, &fraction, 0); |
|
|
|
|
db = strtol(value, &fraction, 0); |
|
|
|
|
if (*fraction++ == '.') { |
|
|
|
|
while (av_isdigit(*fraction) && scale) { |
|
|
|
|
mb += scale * (*fraction - '0'); |
|
|
|
@ -61,43 +61,11 @@ static int32_t parse_gain(const char *gain) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (abs(db) > (INT32_MAX - mb) / 100000) |
|
|
|
|
return INT32_MIN; |
|
|
|
|
return min; |
|
|
|
|
|
|
|
|
|
return db * 100000 + sign * mb; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static uint32_t parse_peak(const uint8_t *peak) |
|
|
|
|
{ |
|
|
|
|
int64_t val = 0; |
|
|
|
|
int64_t scale = 1; |
|
|
|
|
|
|
|
|
|
if (!peak) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
peak += strspn(peak, " \t"); |
|
|
|
|
|
|
|
|
|
if (peak[0] == '1' && peak[1] == '.') |
|
|
|
|
return UINT32_MAX; |
|
|
|
|
else if (!(peak[0] == '0' && peak[1] == '.')) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
peak += 2; |
|
|
|
|
|
|
|
|
|
while (av_isdigit(*peak)) { |
|
|
|
|
int digit = *peak - '0'; |
|
|
|
|
|
|
|
|
|
if (scale > INT64_MAX / 10) |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
val = 10 * val + digit; |
|
|
|
|
scale *= 10; |
|
|
|
|
|
|
|
|
|
peak++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return av_rescale(val, UINT32_MAX, scale); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int replaygain_export(AVStream *st, |
|
|
|
|
const uint8_t *track_gain, const uint8_t *track_peak, |
|
|
|
|
const uint8_t *album_gain, const uint8_t *album_peak) |
|
|
|
@ -107,10 +75,10 @@ static int replaygain_export(AVStream *st, |
|
|
|
|
int32_t tg, ag; |
|
|
|
|
uint32_t tp, ap; |
|
|
|
|
|
|
|
|
|
tg = parse_gain(track_gain); |
|
|
|
|
ag = parse_gain(album_gain); |
|
|
|
|
tp = parse_peak(track_peak); |
|
|
|
|
ap = parse_peak(album_peak); |
|
|
|
|
tg = parse_value(track_gain, INT32_MIN); |
|
|
|
|
ag = parse_value(album_gain, INT32_MIN); |
|
|
|
|
tp = parse_value(track_peak, 0); |
|
|
|
|
ap = parse_value(album_peak, 0); |
|
|
|
|
|
|
|
|
|
if (tg == INT32_MIN && ag == INT32_MIN) |
|
|
|
|
return 0; |
|
|
|
|