decoder/opus: support replay gain
Parse the R128_TRACK_GAIN comment string.
This commit is contained in:
parent
c76952534e
commit
ac8e5be9f4
@ -282,12 +282,18 @@ MPDOpusDecoder::HandleBOS(const ogg_packet &packet)
|
|||||||
inline DecoderCommand
|
inline DecoderCommand
|
||||||
MPDOpusDecoder::HandleTags(const ogg_packet &packet)
|
MPDOpusDecoder::HandleTags(const ogg_packet &packet)
|
||||||
{
|
{
|
||||||
|
replay_gain_info rgi;
|
||||||
|
replay_gain_info_init(&rgi);
|
||||||
|
|
||||||
TagBuilder tag_builder;
|
TagBuilder tag_builder;
|
||||||
|
|
||||||
DecoderCommand cmd;
|
DecoderCommand cmd;
|
||||||
if (ScanOpusTags(packet.packet, packet.bytes,
|
if (ScanOpusTags(packet.packet, packet.bytes,
|
||||||
|
&rgi,
|
||||||
&add_tag_handler, &tag_builder) &&
|
&add_tag_handler, &tag_builder) &&
|
||||||
!tag_builder.IsEmpty()) {
|
!tag_builder.IsEmpty()) {
|
||||||
|
decoder_replay_gain(decoder, &rgi);
|
||||||
|
|
||||||
Tag tag;
|
Tag tag;
|
||||||
tag_builder.Commit(tag);
|
tag_builder.Commit(tag);
|
||||||
cmd = decoder_tag(decoder, input_stream, std::move(tag));
|
cmd = decoder_tag(decoder, input_stream, std::move(tag));
|
||||||
@ -439,6 +445,7 @@ mpd_opus_scan_stream(InputStream &is,
|
|||||||
break;
|
break;
|
||||||
else if (IsOpusTags(packet)) {
|
else if (IsOpusTags(packet)) {
|
||||||
if (!ScanOpusTags(packet.packet, packet.bytes,
|
if (!ScanOpusTags(packet.packet, packet.bytes,
|
||||||
|
nullptr,
|
||||||
handler, handler_ctx))
|
handler, handler_ctx))
|
||||||
result = false;
|
result = false;
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "XiphTags.hxx"
|
#include "XiphTags.hxx"
|
||||||
#include "tag/TagHandler.hxx"
|
#include "tag/TagHandler.hxx"
|
||||||
#include "tag/Tag.hxx"
|
#include "tag/Tag.hxx"
|
||||||
|
#include "ReplayGainInfo.hxx"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -41,8 +42,19 @@ ParseOpusTagName(const char *name)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
ScanOneOpusTag(const char *name, const char *value,
|
ScanOneOpusTag(const char *name, const char *value,
|
||||||
|
replay_gain_info *rgi,
|
||||||
const struct tag_handler *handler, void *ctx)
|
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);
|
tag_handler_invoke_pair(handler, ctx, name, value);
|
||||||
|
|
||||||
if (handler->tag != nullptr) {
|
if (handler->tag != nullptr) {
|
||||||
@ -54,6 +66,7 @@ ScanOneOpusTag(const char *name, const char *value,
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
ScanOpusTags(const void *data, size_t size,
|
ScanOpusTags(const void *data, size_t size,
|
||||||
|
replay_gain_info *rgi,
|
||||||
const struct tag_handler *handler, void *ctx)
|
const struct tag_handler *handler, void *ctx)
|
||||||
{
|
{
|
||||||
OpusReader r(data, size);
|
OpusReader r(data, size);
|
||||||
@ -79,7 +92,7 @@ ScanOpusTags(const void *data, size_t size,
|
|||||||
if (eq != nullptr && eq > p) {
|
if (eq != nullptr && eq > p) {
|
||||||
*eq = 0;
|
*eq = 0;
|
||||||
|
|
||||||
ScanOneOpusTag(p, eq + 1, handler, ctx);
|
ScanOneOpusTag(p, eq + 1, rgi, handler, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] p;
|
delete[] p;
|
||||||
|
@ -24,8 +24,11 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
struct replay_gain_info;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ScanOpusTags(const void *data, size_t size,
|
ScanOpusTags(const void *data, size_t size,
|
||||||
|
replay_gain_info *rgi,
|
||||||
const struct tag_handler *handler, void *ctx);
|
const struct tag_handler *handler, void *ctx);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user