gps/GPSResources/tcpmp 0.73/mpc/libmusepack/docs/html/sample_8cpp-source.html

343 lines
18 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/sample.cpp 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&nbsp;Page</a> | <a class="qindex" href="annotated.html">Class&nbsp;List</a> | <a class="qindex" href="dirs.html">Directories</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="globals.html">File&nbsp;Members</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
<div class="nav">
<a class="el" href="dir_000002.html">src</a></div>
<h1>sample.cpp</h1><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
00035 <span class="preprocessor">#include &lt;stdio.h&gt;</span>
00036 <span class="preprocessor">#include &lt;assert.h&gt;</span>
00037 <span class="preprocessor">#include &lt;time.h&gt;</span>
00038
00039 <span class="preprocessor">#include "<a class="code" href="musepack_8h.html">musepack/musepack.h</a>"</span>
00040
00041 <span class="comment">/*</span>
00042 <span class="comment"> The data bundle we pass around with our reader to store file</span>
00043 <span class="comment"> position and size etc. </span>
00044 <span class="comment">*/</span>
00045 <span class="keyword">typedef</span> <span class="keyword">struct </span>reader_data_t {
00046 FILE *file;
00047 <span class="keywordtype">long</span> size;
00048 BOOL seekable;
00049 } reader_data;
00050
00051 <span class="comment">/*</span>
00052 <span class="comment"> Our implementations of the mpc_reader callback functions.</span>
00053 <span class="comment">*/</span>
00054 mpc_int32_t
00055 read_impl(<span class="keywordtype">void</span> *data, <span class="keywordtype">void</span> *ptr, mpc_int32_t size)
00056 {
00057 reader_data *d = (reader_data *) data;
00058 <span class="keywordflow">return</span> fread(ptr, 1, size, d-&gt;file);
00059 }
00060
00061 BOOL
00062 seek_impl(<span class="keywordtype">void</span> *data, mpc_int32_t offset)
00063 {
00064 reader_data *d = (reader_data *) data;
00065 <span class="keywordflow">return</span> d-&gt;seekable ? !fseek(d-&gt;file, offset, SEEK_SET) : false;
00066 }
00067
00068 mpc_int32_t
00069 tell_impl(<span class="keywordtype">void</span> *data)
00070 {
00071 reader_data *d = (reader_data *) data;
00072 <span class="keywordflow">return</span> ftell(d-&gt;file);
00073 }
00074
00075 mpc_int32_t
00076 get_size_impl(<span class="keywordtype">void</span> *data)
00077 {
00078 reader_data *d = (reader_data *) data;
00079 <span class="keywordflow">return</span> d-&gt;size;
00080 }
00081
00082 BOOL
00083 canseek_impl(<span class="keywordtype">void</span> *data)
00084 {
00085 reader_data *d = (reader_data *) data;
00086 <span class="keywordflow">return</span> d-&gt;seekable;
00087 }
00088
00089 <span class="preprocessor">#define WFX_SIZE (2+2+4+4+2+2)</span>
00090 <span class="preprocessor"></span>
00091 <span class="preprocessor">#ifdef MPC_FIXED_POINT</span>
00092 <span class="preprocessor"></span><span class="keyword">static</span> <span class="keywordtype">int</span>
00093 shift_signed(MPC_SAMPLE_FORMAT val, <span class="keywordtype">int</span> shift)
00094 {
00095 <span class="keywordflow">if</span> (shift &gt; 0)
00096 val &lt;&lt;= shift;
00097 else if (shift &lt; 0)
00098 val &gt;&gt;= -shift;
00099 return (<span class="keywordtype">int</span>)val;
00100 }
00101 #endif
00102
00103 class WavWriter {
00104 <span class="keyword">public</span>:
00105 WavWriter(FILE * p_output, <span class="keywordtype">unsigned</span> p_nch, <span class="keywordtype">unsigned</span> p_bps,
00106 <span class="keywordtype">unsigned</span> p_srate)
00107 : m_file(p_output), m_nch(p_nch), m_bps(p_bps), m_srate(p_srate) {
00108 assert(m_bps == 16 || m_bps == 24);
00109
00110 WriteRaw(<span class="stringliteral">"RIFF"</span>, 4);
00111 WriteDword(0); <span class="comment">//fix this in destructor</span>
00112
00113 WriteRaw(<span class="stringliteral">"WAVE"</span>, 4);
00114 WriteRaw(<span class="stringliteral">"fmt "</span>, 4);
00115 WriteDword(WFX_SIZE);
00116
00117 WriteWord(1); <span class="comment">//WAVE_FORMAT_PCM</span>
00118 WriteWord(m_nch);
00119 WriteDword(m_srate);
00120 WriteDword(m_srate * m_nch * (m_bps &gt;&gt; 3));
00121 WriteWord(m_nch * (m_bps &gt;&gt; 3));
00122 WriteWord(m_bps);
00123 <span class="comment">/*</span>
00124 <span class="comment"> WORD wFormatTag; </span>
00125 <span class="comment"> WORD nChannels; </span>
00126 <span class="comment"> DWORD nSamplesPerSec; </span>
00127 <span class="comment"> DWORD nAvgBytesPerSec; </span>
00128 <span class="comment"> WORD nBlockAlign; </span>
00129 <span class="comment"> WORD wBitsPerSample; </span>
00130 <span class="comment"> */</span>
00131 WriteRaw(<span class="stringliteral">"data"</span>, 4);
00132 WriteDword(0); <span class="comment">//fix this in destructor</span>
00133
00134 m_data_bytes_written = 0;
00135 } BOOL WriteSamples(<span class="keyword">const</span> MPC_SAMPLE_FORMAT * p_buffer, <span class="keywordtype">unsigned</span> p_size) {
00136 <span class="keywordtype">unsigned</span> n;
00137 <span class="keywordtype">int</span> clip_min = -1 &lt;&lt; (m_bps - 1),
00138 clip_max = (1 &lt;&lt; (m_bps - 1)) - 1, float_scale = 1 &lt;&lt; (m_bps - 1);
00139 <span class="keywordflow">for</span> (n = 0; n &lt; p_size; n++) {
00140 <span class="keywordtype">int</span> val;
00141 <span class="preprocessor">#ifdef MPC_FIXED_POINT</span>
00142 <span class="preprocessor"></span> val =
00143 shift_signed(p_buffer[n],
00144 m_bps - MPC_FIXED_POINT_SCALE_SHIFT);
00145 <span class="preprocessor">#else</span>
00146 <span class="preprocessor"></span> val = (int)(p_buffer[n] * float_scale);
00147 <span class="preprocessor">#endif</span>
00148 <span class="preprocessor"></span> <span class="keywordflow">if</span> (val &lt; clip_min)
00149 val = clip_min;
00150 else if (val &gt; clip_max)
00151 val = clip_max;
00152 if (!WriteInt(val, m_bps))
00153 return false;
00154 }
00155 m_data_bytes_written += p_size * (m_bps &gt;&gt; 3);
00156 return true;
00157 }
00158
00159 ~WavWriter() {
00160 <span class="keywordflow">if</span> (m_data_bytes_written &amp; 1) {
00161 <span class="keywordtype">char</span> blah = 0;
00162 WriteRaw(&amp;blah, 1);
00163 m_data_bytes_written++;
00164 }
00165 Seek(4);
00166 WriteDword((<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)(m_data_bytes_written + 4 + 8 + WFX_SIZE +
00167 8));
00168 Seek(8 + 4 + 8 + WFX_SIZE + 4);
00169 WriteDword(m_data_bytes_written);
00170 }
00171
00172 <span class="keyword">private</span>:
00173
00174 BOOL Seek(<span class="keywordtype">unsigned</span> p_offset) {
00175 <span class="keywordflow">return</span> !fseek(m_file, p_offset, SEEK_SET);
00176 }
00177
00178 BOOL WriteRaw(<span class="keyword">const</span> <span class="keywordtype">void</span> *p_buffer, <span class="keywordtype">unsigned</span> p_bytes) {
00179 <span class="keywordflow">return</span> fwrite(p_buffer, 1, p_bytes, m_file) == p_bytes;
00180 }
00181
00182 BOOL WriteDword(<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> p_val) {
00183 <span class="keywordflow">return</span> WriteInt(p_val, 32);
00184 }
00185 BOOL WriteWord(<span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> p_val) {
00186 <span class="keywordflow">return</span> WriteInt(p_val, 16);
00187 }
00188
00189 <span class="comment">// write a little-endian number properly</span>
00190 BOOL WriteInt(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> p_val, <span class="keywordtype">unsigned</span> p_width_bits) {
00191 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> temp;
00192 <span class="keywordtype">unsigned</span> shift = 0;
00193 assert((p_width_bits % 8) == 0);
00194 <span class="keywordflow">do</span> {
00195 temp = (<span class="keywordtype">unsigned</span> char)((p_val &gt;&gt; shift) &amp; 0xFF);
00196 <span class="keywordflow">if</span> (!WriteRaw(&amp;temp, 1))
00197 return false;
00198 shift += 8;
00199 } while (shift &lt; p_width_bits);
00200 return true;
00201 }
00202
00203 <span class="keywordtype">unsigned</span> m_nch, m_bps, m_srate;
00204 FILE *m_file;
00205 <span class="keywordtype">unsigned</span> m_data_bytes_written;
00206 };
00207
00208
00209 static <span class="keywordtype">void</span>
00210 usage(const <span class="keywordtype">char</span> *exename)
00211 {
00212 printf
00213 (<span class="stringliteral">"Usage: %s &lt;infile.mpc&gt; [&lt;outfile.wav&gt;]\nIf &lt;outfile.wav&gt; is not specified, decoder will run in benchmark mode.\n"</span>,
00214 exename);
00215 }
00216
00217 <span class="keywordtype">int</span>
00218 main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv)
00219 {
00220 <span class="keywordflow">if</span> (argc != 2 &amp;&amp; argc != 3) {
00221 <span class="keywordflow">if</span> (argc &gt; 0)
00222 usage(argv[0]);
00223 return 0;
00224 }
00225
00226 FILE *input = fopen(argv[1], "rb");
00227 FILE *output = 0;
00228 if (input == 0) {
00229 usage(argv[0]);
00230 printf(<span class="stringliteral">"Error opening input file: \"%s\"\n"</span>, argv[1]);
00231 <span class="keywordflow">return</span> 1;
00232 }
00233
00234 <span class="keywordflow">if</span> (argc == 3) {
00235 output = fopen(argv[2], <span class="stringliteral">"wb"</span>);
00236 <span class="keywordflow">if</span> (output == 0) {
00237 fclose(input);
00238 usage(argv[0]);
00239 printf(<span class="stringliteral">"Error opening output file: \"%s\"\n"</span>, argv[2]);
00240 <span class="keywordflow">return</span> 1;
00241 }
00242 }
00243
00244 <span class="comment">/* initialize our reader_data tag the reader will carry around with it */</span>
00245 reader_data data;
00246 data.file = input;
00247 data.seekable = <span class="keyword">true</span>;
00248 fseek(data.file, 0, SEEK_END);
00249 data.size = ftell(data.file);
00250 fseek(data.file, 0, SEEK_SET);
00251
00252 <span class="comment">/* set up an mpc_reader linked to our function implementations */</span>
00253 mpc_decoder decoder;
00254 mpc_reader reader;
00255 reader.read = read_impl;
00256 reader.seek = seek_impl;
00257 reader.tell = tell_impl;
00258 reader.get_size = get_size_impl;
00259 reader.canseek = canseek_impl;
00260 reader.data = &amp;data;
00261
00262 <span class="comment">/* read file's streaminfo data */</span>
00263 mpc_streaminfo info;
00264 <a class="code" href="musepack_8h.html#a9">mpc_streaminfo_init</a>(&amp;info);
00265 <span class="keywordflow">if</span> (<a class="code" href="musepack_8h.html#a10">mpc_streaminfo_read</a>(&amp;info, &amp;reader) != ERROR_CODE_OK) {
00266 printf(<span class="stringliteral">"Not a valid musepack file: \"%s\"\n"</span>, argv[1]);
00267 <span class="keywordflow">return</span> 1;
00268 }
00269
00270 <span class="comment">/* instantiate a decoder with our file reader */</span>
00271 <a class="code" href="musepack_8h.html#a13">mpc_decoder_setup</a>(&amp;decoder, &amp;reader);
00272 <span class="keywordflow">if</span> (!<a class="code" href="musepack_8h.html#a14">mpc_decoder_initialize</a>(&amp;decoder, &amp;info)) {
00273 printf(<span class="stringliteral">"Error initializing decoder.\n"</span>, argv[1]);
00274 <span class="keywordflow">return</span> 1;
00275 }
00276
00277 <span class="comment">/* decode the file */</span>
00278 printf(<span class="stringliteral">"Decoding from:\n%s\nTo:\n%s\n"</span>, argv[1],
00279 output ? argv[2] : <span class="stringliteral">"N/A"</span>);
00280 WavWriter *wavwriter =
00281 output ? <span class="keyword">new</span> WavWriter(output, 2, 16, info.sample_freq) : 0;
00282 MPC_SAMPLE_FORMAT sample_buffer[<a class="code" href="musepack_8h.html#a19a8">MPC_DECODER_BUFFER_LENGTH</a>];
00283 clock_t begin, end;
00284 begin = clock();
00285 <span class="keywordtype">unsigned</span> total_samples = 0;
00286 BOOL successful = FALSE;
00287 <span class="keywordflow">for</span> (;;) {
00288 <span class="keywordtype">unsigned</span> status = <a class="code" href="musepack_8h.html#a16">mpc_decoder_decode</a>(&amp;decoder, sample_buffer, 0, 0);
00289 <span class="keywordflow">if</span> (status == (<span class="keywordtype">unsigned</span>)(-1)) {
00290 <span class="comment">//decode error</span>
00291 printf(<span class="stringliteral">"Error decoding file.\n"</span>);
00292 <span class="keywordflow">break</span>;
00293 }
00294 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (status == 0) <span class="comment">//EOF</span>
00295 {
00296 successful = <span class="keyword">true</span>;
00297 <span class="keywordflow">break</span>;
00298 }
00299 <span class="keywordflow">else</span> <span class="comment">//status&gt;0</span>
00300 {
00301 total_samples += status;
00302 <span class="keywordflow">if</span> (wavwriter) {
00303 <span class="keywordflow">if</span> (!wavwriter-&gt;
00304 WriteSamples(sample_buffer, status * <span class="comment">/* stereo */</span> 2)) {
00305 printf(<span class="stringliteral">"Write error.\n"</span>);
00306 <span class="keywordflow">break</span>;
00307 }
00308 }
00309 }
00310 }
00311
00312 end = clock();
00313
00314 <span class="keywordflow">if</span> (wavwriter) {
00315 <span class="keyword">delete</span> wavwriter;
00316 }
00317
00318 <span class="keywordflow">if</span> (successful) {
00319 printf(<span class="stringliteral">"\nFinished.\nTotal samples decoded: %u.\n"</span>, total_samples);
00320 <span class="keywordtype">unsigned</span> ms = (end - begin) * 1000 / CLOCKS_PER_SEC;
00321 <span class="keywordtype">unsigned</span> ratio =
00322 (unsigned)((double)total_samples / (double)info.sample_freq /
00323 ((double)ms / 1000.0) * 100.0);
00324 printf(<span class="stringliteral">"Time: %u ms (%u.%02ux).\n"</span>, ms, ratio / 100, ratio % 100);
00325 }
00326
00327 <span class="keywordflow">return</span> 0;
00328 }
</pre></div><hr size="1"><address style="align: right;"><small>Generated on Sat Jan 22 09:34:07 2005 for libmusepack by&nbsp;
<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>