61
|
1 /*
|
|
2 * Handle Xing vbr header
|
|
3 */
|
|
4 #include "config.h"
|
|
5 #include "dxhead.h"
|
|
6 #include <stdlib.h>
|
|
7 #include <float.h>
|
|
8 #include <math.h>
|
|
9 #include <string.h>
|
|
10 #include <glib.h>
|
|
11
|
|
12 #define GET_INT32BE(b) \
|
|
13 (i = (b[0] << 24) | (b[1] << 16) | b[2] << 8 | b[3], b += 4, i)
|
|
14
|
|
15 int
|
|
16 mpg123_get_xing_header(xing_header_t * xing, unsigned char *buf)
|
|
17 {
|
|
18 int i, head_flags;
|
|
19 int id, mode;
|
|
20
|
|
21 memset(xing, 0, sizeof(xing_header_t));
|
|
22
|
|
23 /* get selected MPEG header data */
|
|
24 id = (buf[1] >> 3) & 1;
|
|
25 mode = (buf[3] >> 6) & 3;
|
|
26 buf += 4;
|
|
27
|
|
28 /* Skip the sub band data */
|
|
29 if (id) {
|
|
30 /* mpeg1 */
|
|
31 if (mode != 3)
|
|
32 buf += 32;
|
|
33 else
|
|
34 buf += 17;
|
|
35 }
|
|
36 else {
|
|
37 /* mpeg2 */
|
|
38 if (mode != 3)
|
|
39 buf += 17;
|
|
40 else
|
|
41 buf += 9;
|
|
42 }
|
|
43
|
|
44 if (strncmp((char *) buf, "Xing", 4))
|
|
45 return 0;
|
|
46 buf += 4;
|
|
47
|
|
48 head_flags = GET_INT32BE(buf);
|
|
49
|
|
50 if (head_flags & FRAMES_FLAG)
|
|
51 xing->frames = GET_INT32BE(buf);
|
|
52 if (xing->frames < 1)
|
|
53 return 0;
|
|
54 if (head_flags & BYTES_FLAG)
|
|
55 xing->bytes = GET_INT32BE(buf);
|
|
56
|
|
57 if (head_flags & TOC_FLAG) {
|
|
58 for (i = 0; i < 100; i++) {
|
|
59 xing->toc[i] = buf[i];
|
|
60 if (i > 0 && xing->toc[i] < xing->toc[i - 1])
|
|
61 return 0;
|
|
62 }
|
|
63 if (xing->toc[99] == 0)
|
|
64 return 0;
|
|
65 buf += 100;
|
|
66 }
|
|
67 else
|
|
68 for (i = 0; i < 100; i++)
|
|
69 xing->toc[i] = (i * 256) / 100;
|
|
70
|
|
71 #ifdef XING_DEBUG
|
|
72 for (i = 0; i < 100; i++) {
|
|
73 if ((i % 10) == 0)
|
|
74 fprintf(stderr, "\n");
|
|
75 fprintf(stderr, " %3d", xing->toc[i]);
|
|
76 }
|
|
77 #endif
|
|
78
|
|
79 return 1;
|
|
80 }
|
|
81
|
|
82 int
|
|
83 mpg123_seek_point(xing_header_t * xing, float percent)
|
|
84 {
|
|
85 /* interpolate in TOC to get file seek point in bytes */
|
|
86 int a, seekpoint;
|
|
87 float fa, fb, fx;
|
|
88
|
|
89 percent = CLAMP(percent, 0, 100);
|
|
90 a = MIN(percent, 99);
|
|
91
|
|
92 fa = xing->toc[a];
|
|
93
|
|
94 if (a < 99)
|
|
95 fb = xing->toc[a + 1];
|
|
96 else
|
|
97 fb = 256;
|
|
98
|
|
99 fx = fa + (fb - fa) * (percent - a);
|
|
100 seekpoint = (1.0f / 256.0f) * fx * xing->bytes;
|
|
101
|
|
102 return seekpoint;
|
|
103 }
|