aboutsummaryrefslogtreecommitdiff
path: root/src/tag_rva2.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2010-07-20 18:39:57 +0200
committerMax Kellermann <max@duempel.org>2010-07-20 23:05:06 +0200
commit43a840552f085af15af3f058c62035b9468cd730 (patch)
treeaadb691c5300d934f38268d20170df19d672cb75 /src/tag_rva2.c
parent2f16f8e9f7ae0b631bcc7c6499aa201fe23d13e0 (diff)
tag_rva2: add struct rva2_data
.. and several accessor inline functions, to simplify the calling code.
Diffstat (limited to 'src/tag_rva2.c')
-rw-r--r--src/tag_rva2.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/src/tag_rva2.c b/src/tag_rva2.c
index bcc78500..95f1b546 100644
--- a/src/tag_rva2.c
+++ b/src/tag_rva2.c
@@ -21,6 +21,7 @@
#include "tag_rva2.h"
#include "replay_gain_info.h"
+#include <stdint.h>
#include <glib.h>
#include <id3tag.h>
@@ -36,6 +37,40 @@ enum rva2_channel {
CHANNEL_SUBWOOFER = 0x08
};
+struct rva2_data {
+ uint8_t type;
+ uint8_t volume_adjustment[2];
+ uint8_t peak_bits;
+};
+
+static inline id3_length_t
+rva2_peak_bytes(const struct rva2_data *data)
+{
+ return (data->peak_bits + 7) / 8;
+}
+
+static inline int
+rva2_fixed_volume_adjustment(const struct rva2_data *data)
+{
+ signed int voladj_fixed;
+ voladj_fixed = (data->volume_adjustment[0] << 8) |
+ data->volume_adjustment[1];
+ voladj_fixed |= -(voladj_fixed & 0x8000);
+ return voladj_fixed;
+}
+
+static inline float
+rva2_float_volume_adjustment(const struct rva2_data *data)
+{
+ /*
+ * "The volume adjustment is encoded as a fixed point decibel
+ * value, 16 bit signed integer representing (adjustment*512),
+ * giving +/- 64 dB with a precision of 0.001953125 dB."
+ */
+
+ return (float)rva2_fixed_volume_adjustment(data) / (float)512;
+}
+
bool
tag_rva2_parse(struct id3_tag *tag, struct replay_gain_info *replay_gain_info)
{
@@ -70,27 +105,13 @@ tag_rva2_parse(struct id3_tag *tag, struct replay_gain_info *replay_gain_info)
*/
while (length >= 4) {
- unsigned int peak_bytes;
-
- peak_bytes = (data[3] + 7) / 8;
+ const struct rva2_data *d = (const struct rva2_data *)data;
+ unsigned int peak_bytes = rva2_peak_bytes(d);
if (4 + peak_bytes > length)
break;
- if (data[0] == CHANNEL_MASTER_VOLUME) {
- signed int voladj_fixed;
- double voladj_float;
-
- /*
- * "The volume adjustment is encoded as a fixed
- * point decibel value, 16 bit signed integer
- * representing (adjustment*512), giving +/- 64
- * dB with a precision of 0.001953125 dB."
- */
-
- voladj_fixed = (data[1] << 8) | (data[2] << 0);
- voladj_fixed |= -(voladj_fixed & 0x8000);
-
- voladj_float = (double) voladj_fixed / 512;
+ if (d->type == CHANNEL_MASTER_VOLUME) {
+ double voladj_float = rva2_float_volume_adjustment(d);
replay_gain_info->tuples[REPLAY_GAIN_TRACK].gain = voladj_float;
replay_gain_info->tuples[REPLAY_GAIN_ALBUM].gain = voladj_float;