1 /*
2 Copyright (c) 2005-2009, The Musepack Development Team
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 * Redistributions in binary form must reproduce the above
13 copyright notice, this list of conditions and the following
14 disclaimer in the documentation and/or other materials provided
15 with the distribution.
16
17 * Neither the name of the The Musepack Development Team nor the
18 names of its contributors may be used to endorse or promote
19 products derived from this software without specific prior
20 written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34 /// \file streaminfo.c
35 /// Implementation of streaminfo reading functions.
36
37 #include <math.h>
38 #include <mpc/mpcdec.h>
39 #include <mpc/streaminfo.h>
40 #include <stdio.h>
41 #include "internal.h"
42 #include "huffman.h"
43 #include "mpc_bits_reader.h"
44
45 unsigned long mpc_crc32(unsigned char *buf, int len);
46
47 static const char na[] = "n.a.";
48 static char const * const versionNames[] = {
49 na, "'Unstable/Experimental'", na, na, na, "'quality 0'", "'quality 1'",
50 "'Telephone'", "'Thumb'", "'Radio'", "'Standard'", "'Extreme'", "'Insane'",
51 "'BrainDead'", "'quality 9'", "'quality 10'"
52 };
53 static const mpc_int32_t samplefreqs[8] = { 44100, 48000, 37800, 32000 };
54
55 static const char *
mpc_get_version_string(float profile)56 mpc_get_version_string(float profile) // profile is 0...15, where 7...13 is used
57 {
58 return profile >= sizeof versionNames / sizeof *versionNames ? na : versionNames[(int)profile];
59 }
60
61 static void
mpc_get_encoder_string(mpc_streaminfo * si)62 mpc_get_encoder_string(mpc_streaminfo* si)
63 {
64 int ver = si->encoder_version;
65 if (si->stream_version >= 8)
66 ver = (si->encoder_version >> 24) * 100 + ((si->encoder_version >> 16) & 0xFF);
67 if (ver <= 116) {
68 if (ver == 0) {
69 sprintf(si->encoder, "Buschmann 1.7.0...9, Klemm 0.90...1.05");
70 } else {
71 switch (ver % 10) {
72 case 0:
73 sprintf(si->encoder, "Release %u.%u", ver / 100,
74 ver / 10 % 10);
75 break;
76 case 2: case 4: case 6: case 8:
77 sprintf(si->encoder, "Beta %u.%02u", ver / 100,
78 ver % 100);
79 break;
80 default:
81 sprintf(si->encoder, "--Alpha-- %u.%02u",
82 ver / 100, ver % 100);
83 break;
84 }
85 }
86 } else {
87 int major = si->encoder_version >> 24;
88 int minor = (si->encoder_version >> 16) & 0xFF;
89 int build = (si->encoder_version >> 8) & 0xFF;
90 char * tmp = "--Stable--";
91
92 if (minor & 1)
93 tmp = "--Unstable--";
94
95 sprintf(si->encoder, "%s %u.%u.%u", tmp, major, minor, build);
96 }
97 }
98
check_streaminfo(mpc_streaminfo * si)99 static mpc_status check_streaminfo(mpc_streaminfo * si)
100 {
101 if (si->max_band == 0 || si->max_band >= 32
102 || si->channels > 2 || si->channels == 0 || si->sample_freq == 0)
103 return MPC_STATUS_FAIL;
104 return MPC_STATUS_OK;
105 }
106
107 /// Reads streaminfo from SV7 header.
108 mpc_status
streaminfo_read_header_sv7(mpc_streaminfo * si,mpc_bits_reader * r)109 streaminfo_read_header_sv7(mpc_streaminfo* si, mpc_bits_reader * r)
110 {
111 mpc_uint16_t Estimatedpeak_title = 0;
112 mpc_uint32_t frames, last_frame_samples;
113
114 si->bitrate = 0;
115 frames = (mpc_bits_read(r, 16) << 16) | mpc_bits_read(r, 16);
116 mpc_bits_read(r, 1); // intensity stereo : should be 0
117 si->ms = mpc_bits_read(r, 1);
118 si->max_band = mpc_bits_read(r, 6);
119 si->profile = mpc_bits_read(r, 4);
120 si->profile_name = mpc_get_version_string(si->profile);
121 mpc_bits_read(r, 2); // Link ?
122 si->sample_freq = samplefreqs[mpc_bits_read(r, 2)];
123 Estimatedpeak_title = (mpc_uint16_t) mpc_bits_read(r, 16); // read the ReplayGain data
124 si->gain_title = (mpc_uint16_t) mpc_bits_read(r, 16);
125 si->peak_title = (mpc_uint16_t) mpc_bits_read(r, 16);
126 si->gain_album = (mpc_uint16_t) mpc_bits_read(r, 16);
127 si->peak_album = (mpc_uint16_t) mpc_bits_read(r, 16);
128 si->is_true_gapless = mpc_bits_read(r, 1); // true gapless: used?
129 last_frame_samples = mpc_bits_read(r, 11); // true gapless: valid samples for last frame
130 si->fast_seek = mpc_bits_read(r, 1); // fast seeking
131 mpc_bits_read(r, 19); // unused
132 si->encoder_version = mpc_bits_read(r, 8);
133 si->channels = 2;
134 si->block_pwr = 0;
135
136 // convert gain info
137 if (si->gain_title != 0) {
138 int tmp = (int)((MPC_OLD_GAIN_REF - (mpc_int16_t)si->gain_title / 100.) * 256. + .5);
139 if (tmp >= (1 << 16) || tmp < 0) tmp = 0;
140 si->gain_title = (mpc_int16_t) tmp;
141 }
142
143 if (si->gain_album != 0) {
144 int tmp = (int)((MPC_OLD_GAIN_REF - (mpc_int16_t)si->gain_album / 100.) * 256. + .5);
145 if (tmp >= (1 << 16) || tmp < 0) tmp = 0;
146 si->gain_album = (mpc_int16_t) tmp;
147 }
148
149 if (si->peak_title != 0)
150 si->peak_title = (mpc_uint16_t) (log10(si->peak_title) * 20 * 256 + .5);
151
152 if (si->peak_album != 0)
153 si->peak_album = (mpc_uint16_t) (log10(si->peak_album) * 20 * 256 + .5);
154
155 mpc_get_encoder_string(si);
156
157 if (last_frame_samples == 0) last_frame_samples = MPC_FRAME_LENGTH;
158 else if (last_frame_samples > MPC_FRAME_LENGTH) return MPC_STATUS_FAIL;
159 si->samples = (mpc_int64_t) frames * MPC_FRAME_LENGTH;
160 if (si->is_true_gapless)
161 si->samples -= (MPC_FRAME_LENGTH - last_frame_samples);
162 else
163 si->samples -= MPC_DECODER_SYNTH_DELAY;
164
165 si->average_bitrate = (si->tag_offset - si->header_position) * 8.0
166 * si->sample_freq / si->samples;
167
168 return check_streaminfo(si);
169 }
170
171 /// Reads replay gain datas
streaminfo_gain(mpc_streaminfo * si,const mpc_bits_reader * r_in)172 void streaminfo_gain(mpc_streaminfo* si, const mpc_bits_reader * r_in)
173 {
174 mpc_bits_reader r = *r_in;
175
176 int version = mpc_bits_read(&r, 8); // gain version
177 if (version != 1) // we only know ver 1
178 return;
179 si->gain_title = (mpc_uint16_t) mpc_bits_read(&r, 16);
180 si->peak_title = (mpc_uint16_t) mpc_bits_read(&r, 16);
181 si->gain_album = (mpc_uint16_t) mpc_bits_read(&r, 16);
182 si->peak_album = (mpc_uint16_t) mpc_bits_read(&r, 16);
183 }
184
185 /// Reads streaminfo from SV8 header.
186 mpc_status
streaminfo_read_header_sv8(mpc_streaminfo * si,const mpc_bits_reader * r_in,mpc_size_t block_size)187 streaminfo_read_header_sv8(mpc_streaminfo* si, const mpc_bits_reader * r_in,
188 mpc_size_t block_size)
189 {
190 mpc_uint32_t CRC;
191 mpc_bits_reader r = *r_in;
192
193 CRC = (mpc_bits_read(&r, 16) << 16) | mpc_bits_read(&r, 16);
194 if (CRC != mpc_crc32(r.buff + 1 - (r.count >> 3), (int)block_size - 4))
195 return MPC_STATUS_FAIL;
196
197 si->stream_version = mpc_bits_read(&r, 8);
198 if (si->stream_version != 8)
199 return MPC_STATUS_FAIL;
200
201 mpc_bits_get_size(&r, &si->samples);
202 mpc_bits_get_size(&r, &si->beg_silence);
203
204 si->is_true_gapless = 1;
205 si->sample_freq = samplefreqs[mpc_bits_read(&r, 3)];
206 si->max_band = mpc_bits_read(&r, 5) + 1;
207 si->channels = mpc_bits_read(&r, 4) + 1;
208 si->ms = mpc_bits_read(&r, 1);
209 si->block_pwr = mpc_bits_read(&r, 3) * 2;
210
211 si->bitrate = 0;
212
213 if ((si->samples - si->beg_silence) != 0)
214 si->average_bitrate = (si->tag_offset - si->header_position) * 8.0
215 * si->sample_freq / (si->samples - si->beg_silence);
216
217 return check_streaminfo(si);
218 }
219
220 /// Reads encoder informations
streaminfo_encoder_info(mpc_streaminfo * si,const mpc_bits_reader * r_in)221 void streaminfo_encoder_info(mpc_streaminfo* si, const mpc_bits_reader * r_in)
222 {
223 mpc_bits_reader r = *r_in;
224
225 si->profile = mpc_bits_read(&r, 7) / 8.;
226 si->profile_name = mpc_get_version_string(si->profile);
227 si->pns = mpc_bits_read(&r, 1);
228 si->encoder_version = mpc_bits_read(&r, 8) << 24; // major
229 si->encoder_version |= mpc_bits_read(&r, 8) << 16; // minor
230 si->encoder_version |= mpc_bits_read(&r, 8) << 8; // build
231
232
233 mpc_get_encoder_string(si);
234 }
235
236 double
mpc_streaminfo_get_length(mpc_streaminfo * si)237 mpc_streaminfo_get_length(mpc_streaminfo * si)
238 {
239 return (double) (si->samples - si->beg_silence) / si->sample_freq;
240 }
241
mpc_streaminfo_get_length_samples(mpc_streaminfo * si)242 mpc_int64_t mpc_streaminfo_get_length_samples(mpc_streaminfo *si)
243 {
244 return si->samples - si->beg_silence;
245 }
246