diff options
author | Max Kellermann <max@duempel.org> | 2013-10-24 23:56:06 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2013-10-24 23:56:06 +0200 |
commit | ac8e5be9f4342ec6b746dfb12d21700d7409a07d (patch) | |
tree | 0ae5918a96ea467003249be0226fac0f0cb94a9c | |
parent | c76952534e0ab82b179d360f07beceb634a0a154 (diff) | |
download | mpd-ac8e5be9f4342ec6b746dfb12d21700d7409a07d.tar.gz mpd-ac8e5be9f4342ec6b746dfb12d21700d7409a07d.tar.xz mpd-ac8e5be9f4342ec6b746dfb12d21700d7409a07d.zip |
decoder/opus: support replay gain
Parse the R128_TRACK_GAIN comment string.
-rw-r--r-- | src/decoder/OpusDecoderPlugin.cxx | 7 | ||||
-rw-r--r-- | src/decoder/OpusTags.cxx | 15 | ||||
-rw-r--r-- | src/decoder/OpusTags.hxx | 3 |
3 files changed, 24 insertions, 1 deletions
diff --git a/src/decoder/OpusDecoderPlugin.cxx b/src/decoder/OpusDecoderPlugin.cxx index fd8ed4e89..a8f0703fb 100644 --- a/src/decoder/OpusDecoderPlugin.cxx +++ b/src/decoder/OpusDecoderPlugin.cxx @@ -282,12 +282,18 @@ MPDOpusDecoder::HandleBOS(const ogg_packet &packet) inline DecoderCommand MPDOpusDecoder::HandleTags(const ogg_packet &packet) { + replay_gain_info rgi; + replay_gain_info_init(&rgi); + TagBuilder tag_builder; DecoderCommand cmd; if (ScanOpusTags(packet.packet, packet.bytes, + &rgi, &add_tag_handler, &tag_builder) && !tag_builder.IsEmpty()) { + decoder_replay_gain(decoder, &rgi); + Tag tag; tag_builder.Commit(tag); cmd = decoder_tag(decoder, input_stream, std::move(tag)); @@ -439,6 +445,7 @@ mpd_opus_scan_stream(InputStream &is, break; else if (IsOpusTags(packet)) { if (!ScanOpusTags(packet.packet, packet.bytes, + nullptr, handler, handler_ctx)) result = false; diff --git a/src/decoder/OpusTags.cxx b/src/decoder/OpusTags.cxx index ed2b054b4..e0319ad48 100644 --- a/src/decoder/OpusTags.cxx +++ b/src/decoder/OpusTags.cxx @@ -23,6 +23,7 @@ #include "XiphTags.hxx" #include "tag/TagHandler.hxx" #include "tag/Tag.hxx" +#include "ReplayGainInfo.hxx" #include <stdint.h> #include <string.h> @@ -41,8 +42,19 @@ ParseOpusTagName(const char *name) static void ScanOneOpusTag(const char *name, const char *value, + replay_gain_info *rgi, const struct tag_handler *handler, void *ctx) { + if (rgi != nullptr && strcmp(name, "R128_TRACK_GAIN") == 0) { + /* R128_TRACK_GAIN is a Q7.8 fixed point number in + dB */ + + char *endptr; + long l = strtol(value, &endptr, 10); + if (endptr > value && *endptr == 0) + rgi->tuples[REPLAY_GAIN_TRACK].gain = double(l) / 256.; + } + tag_handler_invoke_pair(handler, ctx, name, value); if (handler->tag != nullptr) { @@ -54,6 +66,7 @@ ScanOneOpusTag(const char *name, const char *value, bool ScanOpusTags(const void *data, size_t size, + replay_gain_info *rgi, const struct tag_handler *handler, void *ctx) { OpusReader r(data, size); @@ -79,7 +92,7 @@ ScanOpusTags(const void *data, size_t size, if (eq != nullptr && eq > p) { *eq = 0; - ScanOneOpusTag(p, eq + 1, handler, ctx); + ScanOneOpusTag(p, eq + 1, rgi, handler, ctx); } delete[] p; diff --git a/src/decoder/OpusTags.hxx b/src/decoder/OpusTags.hxx index 2f3eec844..cec99effb 100644 --- a/src/decoder/OpusTags.hxx +++ b/src/decoder/OpusTags.hxx @@ -24,8 +24,11 @@ #include <stddef.h> +struct replay_gain_info; + bool ScanOpusTags(const void *data, size_t size, + replay_gain_info *rgi, const struct tag_handler *handler, void *ctx); #endif |