1 /*
2 * mp3plot - Bitrate analysis tool
3 *
4 * Copyright (C) 2007, 2009 Toni Corvera
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 // $Id: bitrate.cc 1342 2009-06-21 23:41:45Z toni $
22
23 #include "bitrate.h"
24
25 #include <iostream>
26 #include <bitset>
27 #include <cassert>
28
29 #include <map>
30
31 namespace {
32 using namespace mp3plot;
33 using namespace std;
34
35 typedef uint8_t bitrate_index_t;
36
37 typedef pair<mpeg_version_t, mpeg_layer_t> bitrate_map_key;
38 typedef vector<bitrate_t> bitrate_list;
39 typedef map<bitrate_map_key, bitrate_list> bitrate_map_t;
40
41 #define BAD_BITRATE mp3plot::mp3::bitrate_translator::bad_bitrate()
42
43 static const bitrate_t v1l1_brs[] = {
44 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, BAD_BITRATE
45 };
46 static const bitrate_t v1l2_brs[] = {
47 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, BAD_BITRATE
48 };
49 static const bitrate_t v1l3_brs[] = {
50 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, BAD_BITRATE
51 };
52 static const bitrate_t v2l1_brs[] = {
53 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, BAD_BITRATE
54 };
55 // MPEG2 Layer II and Layer III use the same table
56 static const bitrate_t v2l2_brs[] = {
57 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, BAD_BITRATE
58 };
59
get_mpeg1_layer1(uint8_t header_index)60 inline bitrate_t get_mpeg1_layer1(uint8_t header_index) {
61 return v1l1_brs[header_index];
62 }
63
get_mpeg1_layer2(uint8_t header_index)64 inline bitrate_t get_mpeg1_layer2(uint8_t header_index) {
65 return v1l2_brs[header_index];
66 }
67
get_mpeg1_layer3(uint8_t header_index)68 inline bitrate_t get_mpeg1_layer3(uint8_t header_index) {
69 return v1l3_brs[header_index];
70 }
71
get_mpeg2_layer1(uint8_t header_index)72 inline bitrate_t get_mpeg2_layer1(uint8_t header_index) {
73 return v2l1_brs[header_index];
74 }
75
get_mpeg2_layer2(uint8_t header_index)76 inline bitrate_t get_mpeg2_layer2(uint8_t header_index) {
77 return v2l2_brs[header_index];
78 }
79
get_mpeg2_layer3(uint8_t header_index)80 inline bitrate_t get_mpeg2_layer3(uint8_t header_index) {
81 return get_mpeg2_layer2(header_index);
82 }
83 }
84
85 namespace mp3plot {
86
87 namespace mp3 {
88
89 // All methods in standard_bitrates are static
90
91 #if 0
92 bool standard_bitrates::init_done = false;
93 standard_bitrates::bitrate_vector standard_bitrates::bitrates;
94 #endif
95
get(uint8_t brindex,mpeg_version_t ver,mpeg_layer_t lyr)96 bitrate_t bitrate_translator::get(uint8_t brindex, mpeg_version_t ver, mpeg_layer_t lyr) {
97 if (ver == MPEG1) {
98 if (lyr == LAYER_III)
99 return get_mpeg1_layer3(brindex);
100 if (lyr == LAYER_II)
101 return get_mpeg1_layer2(brindex);
102 if (lyr == LAYER_I)
103 return get_mpeg1_layer1(brindex);
104 }
105 else if (ver == MPEG2 || ver == MPEG2_5) {
106 if (lyr == LAYER_III)
107 return get_mpeg2_layer3(brindex);
108 if (lyr == LAYER_II)
109 return get_mpeg2_layer2(brindex);
110 if (lyr == LAYER_I)
111 return get_mpeg2_layer1(brindex);
112 }
113 // XXX: What to do?
114 // Since broken files might produce bad versions, return the MP3 value, just in case
115 return get_mpeg1_layer3(brindex);
116 }
117 #if 0
118 void standard_bitrates::init() {
119 if (init_done) return;
120
121 // Invariant
122 assert( bad_bitrate() < 0 );
123
124 // The indices match the 4-bit header indication of bitrate
125 // FIXME: This table is only valid for Layer III, see references
126 static const bitrate_t BITRATES[] = {
127 0, // Free-form bitrate. Free form streams are CBR and no indication
128 // of the bitrate is made explicitly, so it must be derived from the
129 // frame size.
130 // Although they're CBR, it is legal (or at least not-uncommon) for
131 // mp3 files to be concatenated so a change in size is not impossible
132 32,
133 40,
134 48,
135 56,
136 64,
137 80,
138 96,
139 112,
140 128,
141 160,
142 192,
143 224,
144 256,
145 320,
146 bad_bitrate(), // Bad bitrate, the frame header cannot contain a bad bitrate
147 // identifier, its presence is an indication of an error
148 };
149
150 bitrates = std::vector<bitrate_t>(BITRATES, BITRATES+sizeof(BITRATES)/sizeof(bitrate_t));
151
152 init_done = true;
153 }
154
155 const std::vector<bitrate_t> standard_bitrates::as_vector() {
156 init();
157 return bitrates;
158 }
159
160 bitrate_t standard_bitrates::bad_bitrate() {
161 assert( ((bitrate_t)0xFF) != ((bitrate_t)-1) );
162 return -1;
163 }
164
165 bitrate_t standard_bitrates::get(uint8_t bitrate_header_id) {
166 assert( as_vector()[bitrate_header_id] == get_mpeg1_layer3(bitrate_header_id) );
167 return as_vector()[ bitrate_header_id ];
168 }
169
170 std::ostream & operator<<(std::ostream & os, const standard_bitrates::bitrate_vector & v) {
171 int n=0;
172 for (std::vector<bitrate_t>::const_iterator it = v.begin();
173 it != v.end();
174 ++it)
175 {
176 os << "[" << std::bitset<4>(n++) << "] = " << *it;
177 if (*it == standard_bitrates::bad_bitrate()) {
178 os << " (invalid)";
179 }
180 else if (*it == 0) {
181 os << " (free-form)";
182 }
183 os << "\n";
184 }
185
186 return os;
187 }
188 #endif
189 } // namespace mp3
190
191 } // namespace mp3plot
192
193 // vim:set ts=4 et ai:
194
195