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