summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libmusepack/streaminfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libmusepack/streaminfo.c')
-rw-r--r--lib/rbcodec/codecs/libmusepack/streaminfo.c255
1 files changed, 255 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libmusepack/streaminfo.c b/lib/rbcodec/codecs/libmusepack/streaminfo.c
new file mode 100644
index 0000000000..6b4d3df0c1
--- /dev/null
+++ b/lib/rbcodec/codecs/libmusepack/streaminfo.c
@@ -0,0 +1,255 @@
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 "mpcdec.h"
39#include "streaminfo.h"
40#include <stdio.h>
41#include "internal.h"
42#include "huffman.h"
43#include "mpc_bits_reader.h"
44
45/* rockbox: not used
46static const char na[] = "n.a.";
47static char const * const versionNames[] = {
48 na, "'Unstable/Experimental'", na, na, na, "'quality 0'", "'quality 1'",
49 "'Telephone'", "'Thumb'", "'Radio'", "'Standard'", "'Extreme'", "'Insane'",
50 "'BrainDead'", "'quality 9'", "'quality 10'"
51};
52*/
53static const mpc_int32_t samplefreqs[8] = { 44100, 48000, 37800, 32000 };
54/* rockbox: not used
55static const char *
56mpc_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/* rockbox: not used
62static void
63mpc_get_encoder_string(mpc_streaminfo* si)
64{
65 int ver = si->encoder_version;
66 if (si->stream_version >= 8)
67 ver = (si->encoder_version >> 24) * 100 + ((si->encoder_version >> 16) & 0xFF);
68 if (ver <= 116) {
69 if (ver == 0) {
70 sprintf(si->encoder, "Buschmann 1.7.0...9, Klemm 0.90...1.05");
71 } else {
72 switch (ver % 10) {
73 case 0:
74 sprintf(si->encoder, "Release %u.%u", ver / 100,
75 ver / 10 % 10);
76 break;
77 case 2: case 4: case 6: case 8:
78 sprintf(si->encoder, "Beta %u.%02u", ver / 100,
79 ver % 100);
80 break;
81 default:
82 sprintf(si->encoder, "--Alpha-- %u.%02u",
83 ver / 100, ver % 100);
84 break;
85 }
86 }
87 } else {
88 int major = si->encoder_version >> 24;
89 int minor = (si->encoder_version >> 16) & 0xFF;
90 int build = (si->encoder_version >> 8) & 0xFF;
91 char * tmp = "--Stable--";
92
93 if (minor & 1)
94 tmp = "--Unstable--";
95
96 sprintf(si->encoder, "%s %u.%u.%u", tmp, major, minor, build);
97 }
98}
99*/
100
101static mpc_status check_streaminfo(mpc_streaminfo * si)
102{
103 if (si->max_band == 0 || si->max_band >= 32
104 || si->channels > 2 || si->channels == 0 || si->sample_freq == 0)
105 return MPC_STATUS_FAIL;
106 return MPC_STATUS_OK;
107}
108
109/// Reads streaminfo from SV7 header.
110mpc_status
111streaminfo_read_header_sv7(mpc_streaminfo* si, mpc_bits_reader * r)
112{
113 mpc_uint32_t frames, last_frame_samples;
114
115 si->bitrate = 0;
116 frames = (mpc_bits_read(r, 16) << 16) | mpc_bits_read(r, 16);
117 mpc_bits_read(r, 1); // intensity stereo : should be 0
118 si->ms = mpc_bits_read(r, 1);
119 si->max_band = mpc_bits_read(r, 6);
120 si->profile = mpc_bits_read(r, 4);
121/* rockbox: not used
122 si->profile_name = mpc_get_version_string(si->profile);
123*/
124 mpc_bits_read(r, 2); // Link ?
125 si->sample_freq = samplefreqs[mpc_bits_read(r, 2)];
126 mpc_bits_read(r, 16); // Estimatedpeak_title
127 si->gain_title = (mpc_uint16_t) mpc_bits_read(r, 16);
128 si->peak_title = (mpc_uint16_t) mpc_bits_read(r, 16);
129 si->gain_album = (mpc_uint16_t) mpc_bits_read(r, 16);
130 si->peak_album = (mpc_uint16_t) mpc_bits_read(r, 16);
131 si->is_true_gapless = mpc_bits_read(r, 1); // true gapless: used?
132 last_frame_samples = mpc_bits_read(r, 11); // true gapless: valid samples for last frame
133 si->fast_seek = mpc_bits_read(r, 1); // fast seeking
134 mpc_bits_read(r, 19); // unused
135 si->encoder_version = mpc_bits_read(r, 8);
136 si->channels = 2;
137 si->block_pwr = 0;
138
139/* rockbox: not used
140 // convert gain info
141 if (si->gain_title != 0) {
142 int tmp = (int)((MPC_OLD_GAIN_REF - (mpc_int16_t)si->gain_title / 100.) * 256. + .5);
143 if (tmp >= (1 << 16) || tmp < 0) tmp = 0;
144 si->gain_title = (mpc_int16_t) tmp;
145 }
146
147 if (si->gain_album != 0) {
148 int tmp = (int)((MPC_OLD_GAIN_REF - (mpc_int16_t)si->gain_album / 100.) * 256. + .5);
149 if (tmp >= (1 << 16) || tmp < 0) tmp = 0;
150 si->gain_album = (mpc_int16_t) tmp;
151 }
152
153 if (si->peak_title != 0)
154 si->peak_title = (mpc_uint16_t) (log10(si->peak_title) * 20 * 256 + .5);
155
156 if (si->peak_album != 0)
157 si->peak_album = (mpc_uint16_t) (log10(si->peak_album) * 20 * 256 + .5);
158
159 mpc_get_encoder_string(si);
160*/
161
162 if (last_frame_samples == 0) last_frame_samples = MPC_FRAME_LENGTH;
163 else if (last_frame_samples > MPC_FRAME_LENGTH) return MPC_STATUS_FAIL;
164 si->samples = (mpc_int64_t) frames * MPC_FRAME_LENGTH;
165 if (si->is_true_gapless)
166 si->samples -= (MPC_FRAME_LENGTH - last_frame_samples);
167 else
168 si->samples -= MPC_DECODER_SYNTH_DELAY;
169
170 si->average_bitrate = 8LL * (si->tag_offset - si->header_position)
171 * si->sample_freq / si->samples;
172
173 return check_streaminfo(si);
174}
175
176/// Reads replay gain datas
177void streaminfo_gain(mpc_streaminfo* si, const mpc_bits_reader * r_in)
178{
179 mpc_bits_reader r = *r_in;
180
181 int version = mpc_bits_read(&r, 8); // gain version
182 if (version != 1) // we only know ver 1
183 return;
184 si->gain_title = (mpc_uint16_t) mpc_bits_read(&r, 16);
185 si->peak_title = (mpc_uint16_t) mpc_bits_read(&r, 16);
186 si->gain_album = (mpc_uint16_t) mpc_bits_read(&r, 16);
187 si->peak_album = (mpc_uint16_t) mpc_bits_read(&r, 16);
188}
189
190/// Reads streaminfo from SV8 header.
191mpc_status
192streaminfo_read_header_sv8(mpc_streaminfo* si, const mpc_bits_reader * r_in,
193 mpc_size_t block_size)
194{
195 mpc_uint32_t CRC;
196 mpc_bits_reader r = *r_in;
197
198 CRC = (mpc_bits_read(&r, 16) << 16) | mpc_bits_read(&r, 16);
199 if (CRC != mpc_crc32(r.buff + 1 - (r.count >> 3), (int)block_size - 4))
200 return MPC_STATUS_FAIL;
201
202 si->stream_version = mpc_bits_read(&r, 8);
203 if (si->stream_version != 8)
204 return MPC_STATUS_FAIL;
205
206 mpc_bits_get_size(&r, &si->samples);
207 mpc_bits_get_size(&r, &si->beg_silence);
208
209 si->is_true_gapless = 1;
210 si->sample_freq = samplefreqs[mpc_bits_read(&r, 3)];
211 si->max_band = mpc_bits_read(&r, 5) + 1;
212 si->channels = mpc_bits_read(&r, 4) + 1;
213 si->ms = mpc_bits_read(&r, 1);
214 si->block_pwr = mpc_bits_read(&r, 3) * 2;
215
216 si->bitrate = 0;
217
218 if ((si->samples - si->beg_silence) != 0)
219 si->average_bitrate = 8LL * (si->tag_offset - si->header_position)
220 * si->sample_freq / (si->samples - si->beg_silence);
221
222 return check_streaminfo(si);
223}
224
225/// Reads encoder informations
226void streaminfo_encoder_info(mpc_streaminfo* si, const mpc_bits_reader * r_in)
227{
228 mpc_bits_reader r = *r_in;
229
230 si->profile = mpc_bits_read(&r, 7); // to be divided by 8
231/* rockbox: not used
232 si->profile_name = mpc_get_version_string(si->profile);
233*/
234 si->pns = mpc_bits_read(&r, 1);
235 si->encoder_version = mpc_bits_read(&r, 8) << 24; // major
236 si->encoder_version |= mpc_bits_read(&r, 8) << 16; // minor
237 si->encoder_version |= mpc_bits_read(&r, 8) << 8; // build
238
239/* rockbox: not used
240 mpc_get_encoder_string(si);
241*/
242}
243
244/* rockbox: not used
245double
246mpc_streaminfo_get_length(mpc_streaminfo * si)
247{
248 return (double) (si->samples - si->beg_silence) / si->sample_freq;
249}
250
251mpc_int64_t mpc_streaminfo_get_length_samples(mpc_streaminfo *si)
252{
253 return si->samples - si->beg_silence;
254}
255*/