<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> <title>libfishsound: Decoding audio data</title> <link href="tabs.css" rel="stylesheet" type="text/css"/> <link href="doxygen.css" rel="stylesheet" type="text/css"/> </head> <body> <!-- Generated by Doxygen 1.6.2-20100208 --> <div class="navigation" id="top"> <div class="tabs"> <ul> <li><a href="index.html"><span>Main Page</span></a></li> <li><a href="modules.html"><span>Modules</span></a></li> <li><a href="annotated.html"><span>Data Structures</span></a></li> <li><a href="files.html"><span>Files</span></a></li> </ul> </div> </div> <div class="contents"> <h1>Decoding audio data</h1> <p>To decode audio data using libfishsound:. <a href="#_details">More...</a></p> <table border="0" cellpadding="0" cellspacing="0"> </table> <p>To decode audio data using libfishsound:. </p> <ul> <li>create a FishSound* object with mode FISH_SOUND_DECODE. <a class="el" href="fishsound_8h.html#adecddfef35cbbddcc8a76b28c365c527" title="Instantiate a new FishSound* handle.">fish_sound_new()</a> will return a new FishSound* object, initialised for decoding, and the <a class="el" href="structFishSoundInfo.html" title="Info about a particular encoder/decoder instance.">FishSoundInfo</a> structure will be cleared.</li> <li>provide a FishSoundDecoded_* callback for libfishsound to call when it has decoded audio.</li> <li>(optionally) specify whether you want to receive interleaved or per-channel PCM data, using a <a class="el" href="deprecated_8h.html#a8e6b76134675d948015fe4afa3fe4104" title="DEPRECATED FUNCTION.">fish_sound_set_interleave()</a>. The default is for per-channel (non-interleaved) PCM.</li> <li>feed encoded audio data to libfishsound via <a class="el" href="decode_8h.html#a070a1843d6990a00e2471945d40645c7" title="Decode a block of compressed data.">fish_sound_decode()</a>. libfishsound will decode the audio for you, calling the FishSoundDecoded_* callback you provided earlier each time it has a block of audio ready.</li> <li>when finished, call <a class="el" href="fishsound_8h.html#a002e2dee1a7f736699dba5bec0a81426" title="Delete a FishSound object.">fish_sound_delete()</a>.</li> </ul> <p>This procedure is illustrated in src/examples/fishsound-decode.c. Note that this example additionally:</p> <ul> <li>uses <a href="http://www.annodex.net/software/liboggz/">liboggz</a> to demultiplex audio data from an Ogg encapsulated FLAC, Speex or Vorbis stream. The step of feeding encoded data to libfishsound is done within the OggzReadPacket callback.</li> <li>uses <a href="http://www.mega-nerd.com/libsndfile/">libsndfile</a> to write the decoded audio to a WAV file.</li> </ul> <p>Hence this example code demonstrates all that is needed to decode Ogg FLAC, Speex or Ogg Vorbis files:</p> <div class="fragment"><pre class="fragment"><span class="comment">/*</span> <span class="comment"> Copyright (C) 2003 Commonwealth Scientific and Industrial Research</span> <span class="comment"> Organisation (CSIRO) Australia</span> <span class="comment"></span> <span class="comment"> Redistribution and use in source and binary forms, with or without</span> <span class="comment"> modification, are permitted provided that the following conditions</span> <span class="comment"> are met:</span> <span class="comment"></span> <span class="comment"> - Redistributions of source code must retain the above copyright</span> <span class="comment"> notice, this list of conditions and the following disclaimer.</span> <span class="comment"></span> <span class="comment"> - Redistributions in binary form must reproduce the above copyright</span> <span class="comment"> notice, this list of conditions and the following disclaimer in the</span> <span class="comment"> documentation and/or other materials provided with the distribution.</span> <span class="comment"></span> <span class="comment"> - Neither the name of CSIRO Australia nor the names of its</span> <span class="comment"> contributors may be used to endorse or promote products derived from</span> <span class="comment"> this software without specific prior written permission.</span> <span class="comment"></span> <span class="comment"> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS</span> <span class="comment"> ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT</span> <span class="comment"> LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A</span> <span class="comment"> PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR</span> <span class="comment"> CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,</span> <span class="comment"> EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,</span> <span class="comment"> PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR</span> <span class="comment"> PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF</span> <span class="comment"> LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING</span> <span class="comment"> NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS</span> <span class="comment"> SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span> <span class="comment">*/</span> <span class="preprocessor">#include "config.h"</span> <span class="preprocessor">#include <stdio.h></span> <span class="preprocessor">#include <stdlib.h></span> <span class="preprocessor">#include <string.h></span> <span class="preprocessor">#include <oggz/oggz.h></span> <span class="preprocessor">#include <<a class="code" href="fishsound_8h.html" title="The libfishsound C API.">fishsound/fishsound.h</a>></span> <span class="preprocessor">#include <sndfile.h></span> <span class="keyword">static</span> <span class="keywordtype">char</span> * infilename, * outfilename; <span class="keyword">static</span> <span class="keywordtype">int</span> begun = 0; <span class="keyword">static</span> <a class="code" href="structFishSoundInfo.html" title="Info about a particular encoder/decoder instance.">FishSoundInfo</a> fsinfo; <span class="keyword">static</span> SNDFILE * sndfile; <span class="comment">/* In general, an Ogg file may contain multiple audio tracks in parallel.</span> <span class="comment"> * To keep this example simple, we only decode the first track that we find.</span> <span class="comment"> * Tracks ("logical bitstreams" in the Ogg documentations) are identified by</span> <span class="comment"> * a serialno.</span> <span class="comment"> */</span> <span class="keyword">static</span> <span class="keywordtype">long</span> decode_serialno = -1; <span class="keyword">static</span> <span class="keywordtype">int</span> open_output (<span class="keywordtype">int</span> samplerate, <span class="keywordtype">int</span> channels) { SF_INFO sfinfo; sfinfo.samplerate = samplerate; sfinfo.channels = channels; sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; sndfile = sf_open (outfilename, SFM_WRITE, &sfinfo); <span class="keywordflow">return</span> 0; } <span class="keyword">static</span> <span class="keywordtype">int</span> decoded_float (<a class="code" href="fishsound_8h.html#a8cfb7dfb102ad1af9ff35046aed3ccd9" title="An opaque handle to a FishSound.">FishSound</a> * fsound, <span class="keywordtype">float</span> ** pcm, <span class="keywordtype">long</span> frames, <span class="keywordtype">void</span> * user_data) { <span class="keywordflow">if</span> (!begun) { <a class="code" href="fishsound_8h.html#a35c5182901b71a2514bc9a8f2ec839c7" title="Command interface.">fish_sound_command</a> (fsound, <a class="code" href="constants_8h.html#a7a185639e7fea0051f22b28fdb852048acd9f0a7348d01ca7ea3ce461245ac1dd" title="Retrieve the FishSoundInfo.">FISH_SOUND_GET_INFO</a>, &fsinfo, <span class="keyword">sizeof</span> (<a class="code" href="structFishSoundInfo.html" title="Info about a particular encoder/decoder instance.">FishSoundInfo</a>)); open_output (fsinfo.<a class="code" href="structFishSoundInfo.html#a9b19fb535b78f4df6cd4a275a595e736" title="Sample rate of audio data in Hz.">samplerate</a>, fsinfo.<a class="code" href="structFishSoundInfo.html#ac1e2bc71184e6311f54ff6bcd9160123" title="Count of channels.">channels</a>); begun = 1; } sf_writef_float (sndfile, (<span class="keywordtype">float</span> *)pcm, frames); <span class="keywordflow">return</span> 0; } <span class="keyword">static</span> <span class="keywordtype">int</span> read_packet (OGGZ * oggz, ogg_packet * op, <span class="keywordtype">long</span> serialno, <span class="keywordtype">void</span> * user_data) { <a class="code" href="fishsound_8h.html#a8cfb7dfb102ad1af9ff35046aed3ccd9" title="An opaque handle to a FishSound.">FishSound</a> * fsound = (<a class="code" href="fishsound_8h.html#a8cfb7dfb102ad1af9ff35046aed3ccd9" title="An opaque handle to a FishSound.">FishSound</a> *)user_data; <span class="comment">/* If we have not yet selected an audio track to decode, then try</span> <span class="comment"> * to identify this one. If it is a known audio codec, then remember its</span> <span class="comment"> * serialno.</span> <span class="comment"> * NB. We only try this if we are processing a BOS (beginning of stream)</span> <span class="comment"> * packet, and it contains at least 8 bytes of data. If it contained less</span> <span class="comment"> * than 8 bytes of data, fish_sound_identify would simply return</span> <span class="comment"> * FISH_SOUND_ERR_SHORT_IDENTIFY.</span> <span class="comment"> */</span> <span class="keywordflow">if</span> (decode_serialno == -1 && op->b_o_s && op->bytes >= 8) { <span class="keywordflow">if</span> (<a class="code" href="fishsound_8h.html#a2776f39cfa1540b1da3c9d423de15ae9" title="Identify a codec based on the first few bytes of data.">fish_sound_identify</a> (op->packet, op->bytes) != <a class="code" href="constants_8h.html#aff8c305ecaa5b4dc29894d5d3fefbc08a1d6c7c1c4837bc1953fe3ae1962206cb" title="Unknown.">FISH_SOUND_UNKNOWN</a>) decode_serialno = serialno; } <span class="comment">/* If this is the track we are decoding, go ahead and decode it */</span> <span class="keywordflow">if</span> (serialno == decode_serialno) { <a class="code" href="fishsound_8h.html#a6f4818e09b8323d8461331f46f13ab6a" title="Prepare truncation details for the next block of data.">fish_sound_prepare_truncation</a> (fsound, op->granulepos, op->e_o_s); <a class="code" href="decode_8h.html#a070a1843d6990a00e2471945d40645c7" title="Decode a block of compressed data.">fish_sound_decode</a> (fsound, op->packet, op->bytes); } <span class="keywordflow">return</span> 0; } <span class="keywordtype">int</span> main (<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> ** argv) { OGGZ * oggz; <a class="code" href="fishsound_8h.html#a8cfb7dfb102ad1af9ff35046aed3ccd9" title="An opaque handle to a FishSound.">FishSound</a> * fsound; <span class="keywordtype">long</span> n; <span class="keywordflow">if</span> (argc < 3) { printf (<span class="stringliteral">"usage: %s infilename outfilename\n"</span>, argv[0]); printf (<span class="stringliteral">"*** FishSound example program. ***\n"</span>); printf (<span class="stringliteral">"Decodes an Ogg FLAC, Speex or Ogg Vorbis file producing a PCM wav file.\n"</span>); exit (1); } infilename = argv[1]; outfilename = argv[2]; fsound = <a class="code" href="fishsound_8h.html#adecddfef35cbbddcc8a76b28c365c527" title="Instantiate a new FishSound* handle.">fish_sound_new</a> (<a class="code" href="constants_8h.html#ac949e5a5c7f16cc7fd9d096a39608f34a6c1e6f5a1f6342f9c36416d9ee9753ae" title="Decode.">FISH_SOUND_DECODE</a>, NULL); <a class="code" href="deprecated_8h.html#a8e6b76134675d948015fe4afa3fe4104" title="DEPRECATED FUNCTION.">fish_sound_set_interleave</a> (fsound, 1); <a class="code" href="decode_8h.html#a3a4055f579b841a5c05d2a2865f5e939" title="Set the callback for libfishsound to call when it has a block of decoded PCM audio...">fish_sound_set_decoded_float_ilv</a> (fsound, decoded_float, NULL); <span class="keywordflow">if</span> ((oggz = oggz_open ((<span class="keywordtype">char</span> *) infilename, OGGZ_READ)) == NULL) { printf (<span class="stringliteral">"unable to open file %s\n"</span>, infilename); exit (1); } oggz_set_read_callback (oggz, -1, read_packet, fsound); <span class="keywordflow">while</span> ((n = oggz_read (oggz, 1024)) > 0); oggz_close (oggz); <a class="code" href="fishsound_8h.html#a002e2dee1a7f736699dba5bec0a81426" title="Delete a FishSound object.">fish_sound_delete</a> (fsound); sf_close (sndfile); exit (0); } </pre></div> </div> <hr class="footer"/><address style="text-align: right;"><small>Generated by <a href="http://www.doxygen.org/index.html"> <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.6.2-20100208 </small></address> </body> </html>