292 lines
17 KiB
HTML
Executable File
292 lines
17 KiB
HTML
Executable File
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
|
|
<title>libmusepack: src/streaminfo.c Source File</title>
|
|
<link href="custom.css" rel="stylesheet" type="text/css">
|
|
</head><body>
|
|
<!-- Generated by Doxygen 1.4.1 -->
|
|
<div class="qindex"><a class="qindex" href="index.html">Main Page</a> | <a class="qindex" href="annotated.html">Class List</a> | <a class="qindex" href="dirs.html">Directories</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="globals.html">File Members</a> | <a class="qindex" href="pages.html">Related Pages</a></div>
|
|
<div class="nav">
|
|
<a class="el" href="dir_000002.html">src</a></div>
|
|
<h1>streaminfo.c</h1><a href="streaminfo_8c.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment">00001 <span class="comment">/*</span>
|
|
00002 <span class="comment"> Copyright (c) 2005, The Musepack Development Team</span>
|
|
00003 <span class="comment"> All rights reserved.</span>
|
|
00004 <span class="comment"></span>
|
|
00005 <span class="comment"> Redistribution and use in source and binary forms, with or without</span>
|
|
00006 <span class="comment"> modification, are permitted provided that the following conditions are</span>
|
|
00007 <span class="comment"> met:</span>
|
|
00008 <span class="comment"></span>
|
|
00009 <span class="comment"> * Redistributions of source code must retain the above copyright</span>
|
|
00010 <span class="comment"> notice, this list of conditions and the following disclaimer.</span>
|
|
00011 <span class="comment"></span>
|
|
00012 <span class="comment"> * Redistributions in binary form must reproduce the above</span>
|
|
00013 <span class="comment"> copyright notice, this list of conditions and the following</span>
|
|
00014 <span class="comment"> disclaimer in the documentation and/or other materials provided</span>
|
|
00015 <span class="comment"> with the distribution.</span>
|
|
00016 <span class="comment"></span>
|
|
00017 <span class="comment"> * Neither the name of the The Musepack Development Team nor the</span>
|
|
00018 <span class="comment"> names of its contributors may be used to endorse or promote</span>
|
|
00019 <span class="comment"> products derived from this software without specific prior</span>
|
|
00020 <span class="comment"> written permission.</span>
|
|
00021 <span class="comment"></span>
|
|
00022 <span class="comment"> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS</span>
|
|
00023 <span class="comment"> "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT</span>
|
|
00024 <span class="comment"> LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR</span>
|
|
00025 <span class="comment"> A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT</span>
|
|
00026 <span class="comment"> OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,</span>
|
|
00027 <span class="comment"> SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT</span>
|
|
00028 <span class="comment"> LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,</span>
|
|
00029 <span class="comment"> DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY</span>
|
|
00030 <span class="comment"> THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT</span>
|
|
00031 <span class="comment"> (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE</span>
|
|
00032 <span class="comment"> OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span>
|
|
00033 <span class="comment">*/</span>
|
|
00034
|
|
00037
|
|
00038 <span class="preprocessor">#include "<a class="code" href="musepack_8h.html">musepack/musepack.h</a>"</span>
|
|
00039 <span class="preprocessor">#include "musepack/internal.h"</span>
|
|
00040
|
|
00041 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> *
|
|
00042 Stringify(mpc_uint32_t profile) <span class="comment">// profile is 0...15, where 7...13 is used</span>
|
|
00043 {
|
|
00044 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> na[] = <span class="stringliteral">"n.a."</span>;
|
|
00045 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> *Names[] = {
|
|
00046 na, <span class="stringliteral">"'Unstable/Experimental'"</span>, na, na,
|
|
00047 na, <span class="stringliteral">"'quality 0'"</span>, <span class="stringliteral">"'quality 1'"</span>, <span class="stringliteral">"'Telephone'"</span>,
|
|
00048 <span class="stringliteral">"'Thumb'"</span>, <span class="stringliteral">"'Radio'"</span>, <span class="stringliteral">"'Standard'"</span>, <span class="stringliteral">"'Xtreme'"</span>,
|
|
00049 <span class="stringliteral">"'Insane'"</span>, <span class="stringliteral">"'BrainDead'"</span>, <span class="stringliteral">"'quality 9'"</span>, <span class="stringliteral">"'quality 10'"</span>
|
|
00050 };
|
|
00051
|
|
00052 <span class="keywordflow">return</span> profile >= <span class="keyword">sizeof</span>(Names) / <span class="keyword">sizeof</span>(*Names) ? na : Names[profile];
|
|
00053 }
|
|
00054
|
|
00055 <span class="keywordtype">void</span>
|
|
<a name="l00056"></a><a class="code" href="streaminfo_8c.html#a1">00056</a> <a class="code" href="musepack_8h.html#a9">mpc_streaminfo_init</a>(mpc_streaminfo * si)
|
|
00057 {
|
|
00058 memset(si, 0, <span class="keyword">sizeof</span>(mpc_streaminfo));
|
|
00059 }
|
|
00060
|
|
00061 <span class="comment">// read information from SV8 header</span>
|
|
00062 <span class="comment">// not yet implemented</span>
|
|
00063 <span class="keyword">static</span> mpc_int32_t
|
|
00064 streaminfo_read_header_sv8(mpc_streaminfo * si, mpc_reader * fp)
|
|
00065 {
|
|
00066 <span class="keywordflow">return</span> 0;
|
|
00067 }
|
|
00068
|
|
00070 <span class="keyword">static</span> mpc_int32_t
|
|
00071 streaminfo_read_header_sv7(mpc_streaminfo * si, mpc_uint32_t HeaderData[8])
|
|
00072 {
|
|
00073 <span class="keyword">const</span> mpc_int32_t samplefreqs[4] = { 44100, 48000, 37800, 32000 };
|
|
00074
|
|
00075 <span class="comment">//mpc_uint32_t HeaderData [8];</span>
|
|
00076 mpc_uint16_t Estimatedpeak_title = 0;
|
|
00077
|
|
00078 <span class="keywordflow">if</span> (si->stream_version > 0x71) {
|
|
00079 <span class="comment">// Update (si->stream_version);</span>
|
|
00080 <span class="keywordflow">return</span> 0;
|
|
00081 }
|
|
00082
|
|
00083 <span class="comment">/*</span>
|
|
00084 <span class="comment"> if ( !fp->seek ( si->header_position ) ) // seek to header start</span>
|
|
00085 <span class="comment"> return ERROR_CODE_FILE;</span>
|
|
00086 <span class="comment"> if ( fp->read ( HeaderData, sizeof HeaderData) != sizeof HeaderData )</span>
|
|
00087 <span class="comment"> return ERROR_CODE_FILE;</span>
|
|
00088 <span class="comment"> */</span>
|
|
00089
|
|
00090 si->bitrate = 0;
|
|
00091 si->frames = HeaderData[1];
|
|
00092 si->is = 0;
|
|
00093 si->ms = (HeaderData[2] >> 30) & 0x0001;
|
|
00094 si->max_band = (HeaderData[2] >> 24) & 0x003F;
|
|
00095 si->block_size = 1;
|
|
00096 si->profile = (HeaderData[2] << 8) >> 28;
|
|
00097 si->profile_name = Stringify(si->profile);
|
|
00098 si->sample_freq = samplefreqs[(HeaderData[2] >> 16) & 0x0003];
|
|
00099 Estimatedpeak_title = (mpc_uint16_t) (HeaderData[2] & 0xFFFF); <span class="comment">// read the ReplayGain data</span>
|
|
00100 si->gain_title = (mpc_uint16_t) ((HeaderData[3] >> 16) & 0xFFFF);
|
|
00101 si->peak_title = (mpc_uint16_t) (HeaderData[3] & 0xFFFF);
|
|
00102 si->gain_album = (mpc_uint16_t) ((HeaderData[4] >> 16) & 0xFFFF);
|
|
00103 si->peak_album = (mpc_uint16_t) (HeaderData[4] & 0xFFFF);
|
|
00104 si->is_true_gapless = (HeaderData[5] >> 31) & 0x0001; <span class="comment">// true gapless: used?</span>
|
|
00105 si->last_frame_samples = (HeaderData[5] >> 20) & 0x07FF; <span class="comment">// true gapless: valid samples for last frame</span>
|
|
00106 si->encoder_version = (HeaderData[6] >> 24) & 0x00FF;
|
|
00107
|
|
00108 <span class="keywordflow">if</span> (si->encoder_version == 0) {
|
|
00109 sprintf(si->encoder, <span class="stringliteral">"Buschmann 1.7.0...9, Klemm 0.90...1.05"</span>);
|
|
00110 }
|
|
00111 <span class="keywordflow">else</span> {
|
|
00112 <span class="keywordflow">switch</span> (si->encoder_version % 10) {
|
|
00113 <span class="keywordflow">case</span> 0:
|
|
00114 sprintf(si->encoder, <span class="stringliteral">"Release %u.%u"</span>, si->encoder_version / 100,
|
|
00115 si->encoder_version / 10 % 10);
|
|
00116 <span class="keywordflow">break</span>;
|
|
00117 <span class="keywordflow">case</span> 2:
|
|
00118 <span class="keywordflow">case</span> 4:
|
|
00119 <span class="keywordflow">case</span> 6:
|
|
00120 <span class="keywordflow">case</span> 8:
|
|
00121 sprintf(si->encoder, <span class="stringliteral">"Beta %u.%02u"</span>, si->encoder_version / 100,
|
|
00122 si->encoder_version % 100);
|
|
00123 <span class="keywordflow">break</span>;
|
|
00124 <span class="keywordflow">default</span>:
|
|
00125 sprintf(si->encoder, <span class="stringliteral">"--Alpha-- %u.%02u"</span>,
|
|
00126 si->encoder_version / 100, si->encoder_version % 100);
|
|
00127 <span class="keywordflow">break</span>;
|
|
00128 }
|
|
00129 }
|
|
00130
|
|
00131 <span class="comment">// if ( si->peak_title == 0 ) // there is no correct peak_title contained within header</span>
|
|
00132 <span class="comment">// si->peak_title = (mpc_uint16_t)(Estimatedpeak_title * 1.18);</span>
|
|
00133 <span class="comment">// if ( si->peak_album == 0 )</span>
|
|
00134 <span class="comment">// si->peak_album = si->peak_title; // no correct peak_album, use peak_title</span>
|
|
00135
|
|
00136 <span class="comment">//si->sample_freq = 44100; // AB: used by all files up to SV7</span>
|
|
00137 si->channels = 2;
|
|
00138
|
|
00139 <span class="keywordflow">return</span> ERROR_CODE_OK;
|
|
00140 }
|
|
00141
|
|
00142 <span class="comment">// read information from SV4-SV6 header</span>
|
|
00143 <span class="keyword">static</span> mpc_int32_t
|
|
00144 streaminfo_read_header_sv6(mpc_streaminfo * si, mpc_uint32_t HeaderData[8])
|
|
00145 {
|
|
00146 <span class="comment">//mpc_uint32_t HeaderData [8];</span>
|
|
00147
|
|
00148 <span class="comment">/*</span>
|
|
00149 <span class="comment"> if ( !fp->seek ( si->header_position ) ) // seek to header start</span>
|
|
00150 <span class="comment"> return ERROR_CODE_FILE;</span>
|
|
00151 <span class="comment"> if ( fp->read ( HeaderData, sizeof HeaderData ) != sizeof HeaderData )</span>
|
|
00152 <span class="comment"> return ERROR_CODE_FILE;</span>
|
|
00153 <span class="comment"> */</span>
|
|
00154
|
|
00155 si->bitrate = (HeaderData[0] >> 23) & 0x01FF; <span class="comment">// read the file-header (SV6 and below)</span>
|
|
00156 si->is = (HeaderData[0] >> 22) & 0x0001;
|
|
00157 si->ms = (HeaderData[0] >> 21) & 0x0001;
|
|
00158 si->stream_version = (HeaderData[0] >> 11) & 0x03FF;
|
|
00159 si->max_band = (HeaderData[0] >> 6) & 0x001F;
|
|
00160 si->block_size = (HeaderData[0]) & 0x003F;
|
|
00161 si->profile = 0;
|
|
00162 si->profile_name = Stringify((mpc_uint32_t) (-1));
|
|
00163 <span class="keywordflow">if</span> (si->stream_version >= 5)
|
|
00164 si->frames = HeaderData[1]; <span class="comment">// 32 bit</span>
|
|
00165 else
|
|
00166 si->frames = (HeaderData[1] >> 16); <span class="comment">// 16 bit</span>
|
|
00167
|
|
00168 si->gain_title = 0; <span class="comment">// not supported</span>
|
|
00169 si->peak_title = 0;
|
|
00170 si->gain_album = 0;
|
|
00171 si->peak_album = 0;
|
|
00172
|
|
00173 si->last_frame_samples = 0;
|
|
00174 si->is_true_gapless = 0;
|
|
00175
|
|
00176 si->encoder_version = 0;
|
|
00177 si->encoder[0] = '\0';
|
|
00178
|
|
00179 if (si->stream_version == 7)
|
|
00180 return ERROR_CODE_SV7BETA; <span class="comment">// are there any unsupported parameters used?</span>
|
|
00181 if (si->bitrate != 0)
|
|
00182 return ERROR_CODE_CBR;
|
|
00183 if (si->is != 0)
|
|
00184 return ERROR_CODE_IS;
|
|
00185 if (si->block_size != 1)
|
|
00186 return ERROR_CODE_BLOCKSIZE;
|
|
00187
|
|
00188 if (si->stream_version < 6) <span class="comment">// Bugfix: last frame was invalid for up to SV5</span>
|
|
00189 si->frames -= 1;
|
|
00190
|
|
00191 si->sample_freq = 44100; <span class="comment">// AB: used by all files up to SV7</span>
|
|
00192 si->channels = 2;
|
|
00193
|
|
00194 if (si->stream_version < 4 || si->stream_version > 7)
|
|
00195 return ERROR_CODE_INVALIDSV;
|
|
00196
|
|
00197 return ERROR_CODE_OK;
|
|
00198 }
|
|
00199
|
|
00200 <span class="comment">// reads file header and tags</span>
|
|
00201 mpc_int32_t
|
|
<a name="l00202"></a><a class="code" href="streaminfo_8c.html#a5">00202</a> mpc_streaminfo_read(mpc_streaminfo * si, mpc_reader * r)
|
|
00203 {
|
|
00204 mpc_uint32_t HeaderData[8];
|
|
00205 mpc_int32_t Error = 0;
|
|
00206
|
|
00207 <span class="comment">// get header position</span>
|
|
00208 <span class="keywordflow">if</span> ((si->header_position = JumpID3v2(r)) < 0) {
|
|
00209 <span class="keywordflow">return</span> ERROR_CODE_FILE;
|
|
00210 }
|
|
00211 <span class="comment">// seek to first byte of mpc data</span>
|
|
00212 <span class="keywordflow">if</span> (!r->seek(r->data, si->header_position)) {
|
|
00213 <span class="keywordflow">return</span> ERROR_CODE_FILE;
|
|
00214 }
|
|
00215 <span class="keywordflow">if</span> (r->read(r->data, HeaderData, 8 * 4) != 8 * 4) {
|
|
00216 <span class="keywordflow">return</span> ERROR_CODE_FILE;
|
|
00217 }
|
|
00218 <span class="keywordflow">if</span> (!r->seek(r->data, si->header_position + 6 * 4)) {
|
|
00219 <span class="keywordflow">return</span> ERROR_CODE_FILE;
|
|
00220 }
|
|
00221
|
|
00222 si->total_file_length = r->get_size(r->data);
|
|
00223 si->tag_offset = si->total_file_length;
|
|
00224 <span class="keywordflow">if</span> (memcmp(HeaderData, <span class="stringliteral">"MP+"</span>, 3) == 0) {
|
|
00225 <span class="preprocessor">#ifndef MPC_LITTLE_ENDIAN</span>
|
|
00226 <span class="preprocessor"></span> mpc_uint32_t ptr;
|
|
00227 <span class="keywordflow">for</span> (ptr = 0; ptr < 8; ptr++) {
|
|
00228 HeaderData[ptr] = swap32(HeaderData[ptr]);
|
|
00229 }
|
|
00230 <span class="preprocessor">#endif</span>
|
|
00231 <span class="preprocessor"></span> si->stream_version = HeaderData[0] >> 24;
|
|
00232
|
|
00233 <span class="comment">// stream version 8</span>
|
|
00234 <span class="keywordflow">if</span> ((si->stream_version & 15) >= 8) {
|
|
00235 Error = streaminfo_read_header_sv8(si, r);
|
|
00236 }
|
|
00237 <span class="comment">// stream version 7</span>
|
|
00238 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ((si->stream_version & 15) == 7) {
|
|
00239 Error = streaminfo_read_header_sv7(si, HeaderData);
|
|
00240 }
|
|
00241 }
|
|
00242 <span class="keywordflow">else</span> {
|
|
00243 <span class="comment">// stream version 4-6</span>
|
|
00244 Error = streaminfo_read_header_sv6(si, HeaderData);
|
|
00245 }
|
|
00246
|
|
00247 <span class="comment">// estimation, exact value needs too much time</span>
|
|
00248 si->pcm_samples = 1152 * si->frames - 576;
|
|
00249
|
|
00250 <span class="keywordflow">if</span> (si->pcm_samples > 0) {
|
|
00251 si->average_bitrate =
|
|
00252 (si->tag_offset -
|
|
00253 si->header_position) * 8.0 * si->sample_freq / si->pcm_samples;
|
|
00254 }
|
|
00255 <span class="keywordflow">else</span> {
|
|
00256 si->average_bitrate = 0;
|
|
00257 }
|
|
00258
|
|
00259 <span class="keywordflow">return</span> Error;
|
|
00260 }
|
|
00261
|
|
00262 <span class="keywordtype">double</span>
|
|
<a name="l00263"></a><a class="code" href="streaminfo_8c.html#a6">00263</a> <a class="code" href="musepack_8h.html#a11">mpc_streaminfo_get_length</a>(mpc_streaminfo * si)
|
|
00264 {
|
|
00265 <span class="keywordflow">return</span> (<span class="keywordtype">double</span>)<a class="code" href="musepack_8h.html#a12">mpc_streaminfo_get_length_samples</a>(si) /
|
|
00266 (double)si->sample_freq;
|
|
00267 }
|
|
00268
|
|
00269 mpc_int64_t
|
|
<a name="l00270"></a><a class="code" href="streaminfo_8c.html#a7">00270</a> <a class="code" href="musepack_8h.html#a12">mpc_streaminfo_get_length_samples</a>(mpc_streaminfo * si)
|
|
00271 {
|
|
00272 mpc_int64_t samples = (mpc_int64_t) si->frames * MPC_FRAME_LENGTH;
|
|
00273 <span class="keywordflow">if</span> (si->is_true_gapless) {
|
|
00274 samples -= (MPC_FRAME_LENGTH - si->last_frame_samples);
|
|
00275 }
|
|
00276 <span class="keywordflow">else</span> {
|
|
00277 samples -= MPC_DECODER_SYNTH_DELAY;
|
|
00278 }
|
|
00279 <span class="keywordflow">return</span> samples;
|
|
00280 }
|
|
</pre></div><hr size="1"><address style="align: right;"><small>Generated on Sat Jan 22 09:34:07 2005 for libmusepack by
|
|
<a href="http://www.doxygen.org/index.html">
|
|
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.1 </small></address>
|
|
</body>
|
|
</html>
|