<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <title>PulseAudio: paplay.c</title> <link href="doxygen.css" rel="stylesheet" type="text/css"> <link href="tabs.css" rel="stylesheet" type="text/css"> </head><body> <!-- Generated by Doxygen 1.5.5 --> <div class="navigation" id="top"> <div class="tabs"> <ul> <li><a href="main.html"><span>Main Page</span></a></li> <li><a href="pages.html"><span>Related Pages</span></a></li> <li><a href="classes.html"><span>Data Structures</span></a></li> <li><a href="files.html"><span>Files</span></a></li> <li><a href="examples.html"><span>Examples</span></a></li> </ul> </div> </div> <div class="contents"> <h1>paplay.c</h1>A sound file playback tool using the asynchronous API, based on libsndfile<p> <div class="fragment"><pre class="fragment"><span class="comment">/* $Id: paplay.c 2025 2007-11-05 23:56:30Z lennart $ */</span> <span class="comment">/***</span> <span class="comment"> This file is part of PulseAudio.</span> <span class="comment"></span> <span class="comment"> Copyright 2004-2006 Lennart Poettering</span> <span class="comment"> Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB</span> <span class="comment"></span> <span class="comment"> PulseAudio is free software; you can redistribute it and/or modify</span> <span class="comment"> it under the terms of the GNU Lesser General Public License as published</span> <span class="comment"> by the Free Software Foundation; either version 2 of the License,</span> <span class="comment"> or (at your option) any later version.</span> <span class="comment"></span> <span class="comment"> PulseAudio is distributed in the hope that it will be useful, but</span> <span class="comment"> WITHOUT ANY WARRANTY; without even the implied warranty of</span> <span class="comment"> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU</span> <span class="comment"> General Public License for more details.</span> <span class="comment"></span> <span class="comment"> You should have received a copy of the GNU Lesser General Public License</span> <span class="comment"> along with PulseAudio; if not, write to the Free Software</span> <span class="comment"> Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307</span> <span class="comment"> USA.</span> <span class="comment">***/</span> <span class="preprocessor">#ifdef HAVE_CONFIG_H</span> <span class="preprocessor"></span><span class="preprocessor">#include <config.h></span> <span class="preprocessor">#endif</span> <span class="preprocessor"></span> <span class="preprocessor">#include <signal.h></span> <span class="preprocessor">#include <string.h></span> <span class="preprocessor">#include <errno.h></span> <span class="preprocessor">#include <unistd.h></span> <span class="preprocessor">#include <assert.h></span> <span class="preprocessor">#include <stdio.h></span> <span class="preprocessor">#include <stdlib.h></span> <span class="preprocessor">#include <getopt.h></span> <span class="preprocessor">#include <locale.h></span> <span class="preprocessor">#include <sndfile.h></span> <span class="preprocessor">#include <<a class="code" href="pulseaudio_8h.html" title="Include all libpulse header files at once.">pulse/pulseaudio.h</a>></span> <span class="preprocessor">#if PA_API_VERSION < 9</span> <span class="preprocessor"></span><span class="preprocessor">#error Invalid PulseAudio API version</span> <span class="preprocessor"></span><span class="preprocessor">#endif</span> <span class="preprocessor"></span> <span class="keyword">static</span> <a name="a0"></a><a class="code" href="context_8h.html#ff56e9b3dd442a88227da084bb5c380a" title="An opaque connection context to a daemon.">pa_context</a> *context = NULL; <span class="keyword">static</span> <a name="a1"></a><a class="code" href="stream_8h.html#960d798980692a2ff01e5a70553d4f29" title="An opaque stream for playback or recording.">pa_stream</a> *stream = NULL; <span class="keyword">static</span> <a name="_a2"></a><a class="code" href="structpa__mainloop__api.html" title="An abstract mainloop API vtable.">pa_mainloop_api</a> *mainloop_api = NULL; <span class="keyword">static</span> <span class="keywordtype">char</span> *stream_name = NULL, *client_name = NULL, *device = NULL; <span class="keyword">static</span> <span class="keywordtype">int</span> verbose = 0; <span class="keyword">static</span> <a name="a3"></a><a class="code" href="volume_8h.html#6d671c65284ff2e94d3773c7368a0352" title="Volume specification: PA_VOLUME_MUTED: silence; &lt; PA_VOLUME_NORM: decreased volume;...">pa_volume_t</a> volume = <a name="a4"></a><a class="code" href="volume_8h.html#ded56902e68e0f8ab576339bde55960e" title="Normal volume (100%).">PA_VOLUME_NORM</a>; <span class="keyword">static</span> SNDFILE* sndfile = NULL; <span class="keyword">static</span> <a name="_a5"></a><a class="code" href="structpa__sample__spec.html" title="A sample format and attribute specification.">pa_sample_spec</a> sample_spec = { 0, 0, 0 }; <span class="keyword">static</span> <a name="_a6"></a><a class="code" href="structpa__channel__map.html" title="A channel map which can be used to attach labels to specific channels of a stream...">pa_channel_map</a> channel_map; <span class="keyword">static</span> <span class="keywordtype">int</span> channel_map_set = 0; <span class="keyword">static</span> sf_count_t (*readf_function)(SNDFILE *_sndfile, <span class="keywordtype">void</span> *ptr, sf_count_t frames) = NULL; <span class="comment">/* A shortcut for terminating the application */</span> <span class="keyword">static</span> <span class="keywordtype">void</span> quit(<span class="keywordtype">int</span> ret) { assert(mainloop_api); mainloop_api-><a name="a7"></a><a class="code" href="structpa__mainloop__api.html#6931949737d103f7b34628fedf5661cb" title="Exit the main loop and return the specfied retval.">quit</a>(mainloop_api, ret); } <span class="comment">/* Connection draining complete */</span> <span class="keyword">static</span> <span class="keywordtype">void</span> context_drain_complete(<a class="code" href="context_8h.html#ff56e9b3dd442a88227da084bb5c380a" title="An opaque connection context to a daemon.">pa_context</a>*c, <span class="keywordtype">void</span> *userdata) { <a name="a8"></a><a class="code" href="context_8h.html#154b9d8057adfbb2cecfbd9406a27660" title="Terminate the context connection immediately.">pa_context_disconnect</a>(c); } <span class="comment">/* Stream draining complete */</span> <span class="keyword">static</span> <span class="keywordtype">void</span> stream_drain_complete(<a class="code" href="stream_8h.html#960d798980692a2ff01e5a70553d4f29" title="An opaque stream for playback or recording.">pa_stream</a>*s, <span class="keywordtype">int</span> success, <span class="keywordtype">void</span> *userdata) { <a name="a9"></a><a class="code" href="operation_8h.html#5614a07f2e7a129e4cb16596ed452a0c" title="An asynchronous operation object.">pa_operation</a> *o; <span class="keywordflow">if</span> (!success) { fprintf(stderr, <span class="stringliteral">"Failed to drain stream: %s\n"</span>, <a name="a10"></a><a class="code" href="error_8h.html#593deb681fba75fad4b3a2d65d0ac2b2" title="Return a human readable error message for the specified numeric error code.">pa_strerror</a>(<a name="a11"></a><a class="code" href="context_8h.html#a8262c715ef8c48bcd2fbc5ae57a6df9" title="Return the error number of the last failed operation.">pa_context_errno</a>(context))); quit(1); } <span class="keywordflow">if</span> (verbose) fprintf(stderr, <span class="stringliteral">"Playback stream drained.\n"</span>); <a name="a12"></a><a class="code" href="stream_8h.html#a4e0c83264f3935911e6b30e6f8ef2b1" title="Disconnect a stream from a source/sink.">pa_stream_disconnect</a>(stream); <a name="a13"></a><a class="code" href="stream_8h.html#7780fa5438f31152b0a6aeae31b63264" title="Decrease the reference counter by one.">pa_stream_unref</a>(stream); stream = NULL; <span class="keywordflow">if</span> (!(o = <a name="a14"></a><a class="code" href="context_8h.html#b94b42b05c233e010432888b7c496c50" title="Drain the context.">pa_context_drain</a>(context, context_drain_complete, NULL))) <a class="code" href="context_8h.html#154b9d8057adfbb2cecfbd9406a27660" title="Terminate the context connection immediately.">pa_context_disconnect</a>(context); <span class="keywordflow">else</span> { <a name="a15"></a><a class="code" href="operation_8h.html#8d2ef9bb2ff961ee31675882bf125227" title="Decrease the reference count by one.">pa_operation_unref</a>(o); <span class="keywordflow">if</span> (verbose) fprintf(stderr, <span class="stringliteral">"Draining connection to server.\n"</span>); } } <span class="comment">/* This is called whenever new data may be written to the stream */</span> <span class="keyword">static</span> <span class="keywordtype">void</span> stream_write_callback(<a class="code" href="stream_8h.html#960d798980692a2ff01e5a70553d4f29" title="An opaque stream for playback or recording.">pa_stream</a> *s, <span class="keywordtype">size_t</span> length, <span class="keywordtype">void</span> *userdata) { sf_count_t bytes; <span class="keywordtype">void</span> *data; assert(s && length); <span class="keywordflow">if</span> (!sndfile) <span class="keywordflow">return</span>; data = <a name="a16"></a><a class="code" href="xmalloc_8h.html#9f71c8451cc397b80e12fc8868f0900a" title="Allocate the specified number of bytes, just like malloc() does.">pa_xmalloc</a>(length); <span class="keywordflow">if</span> (readf_function) { <span class="keywordtype">size_t</span> k = <a name="a17"></a><a class="code" href="sample_8h.html#035d79171e183f6315e6e65436f5e939" title="Return the size of a frame with the specific sample type.">pa_frame_size</a>(&sample_spec); <span class="keywordflow">if</span> ((bytes = readf_function(sndfile, data, length/k)) > 0) bytes *= k; } <span class="keywordflow">else</span> bytes = sf_read_raw(sndfile, data, length); <span class="keywordflow">if</span> (bytes > 0) <a name="a18"></a><a class="code" href="stream_8h.html#0f6ac01f306711bd2623a073060e91bc" title="Write some data to the server (for playback sinks), if free_cb is non-NULL this routine...">pa_stream_write</a>(s, data, bytes, <a name="a19"></a><a class="code" href="xmalloc_8h.html#975c3f1d400a40ede0d5e79bb8876008" title="Free allocated memory.">pa_xfree</a>, 0, <a name="a20"></a><a class="code" href="def_8h.html#eb8e6973350d158e982985c1d19eef3ba2e4cfb8fb37554e73855242729edf13" title="Seek relatively to the write index.">PA_SEEK_RELATIVE</a>); <span class="keywordflow">else</span> <a class="code" href="xmalloc_8h.html#975c3f1d400a40ede0d5e79bb8876008" title="Free allocated memory.">pa_xfree</a>(data); <span class="keywordflow">if</span> (bytes < (sf_count_t) length) { sf_close(sndfile); sndfile = NULL; <a class="code" href="operation_8h.html#8d2ef9bb2ff961ee31675882bf125227" title="Decrease the reference count by one.">pa_operation_unref</a>(<a name="a21"></a><a class="code" href="stream_8h.html#8d263f188073f244b3820f3f50db4ba5" title="Drain a playback stream.">pa_stream_drain</a>(s, stream_drain_complete, NULL)); } } <span class="comment">/* This routine is called whenever the stream state changes */</span> <span class="keyword">static</span> <span class="keywordtype">void</span> stream_state_callback(<a class="code" href="stream_8h.html#960d798980692a2ff01e5a70553d4f29" title="An opaque stream for playback or recording.">pa_stream</a> *s, <span class="keywordtype">void</span> *userdata) { assert(s); <span class="keywordflow">switch</span> (<a name="a22"></a><a class="code" href="stream_8h.html#b1da38d494d6485e35f0715f40dff0ab" title="Return the current state of the stream.">pa_stream_get_state</a>(s)) { <span class="keywordflow">case</span> <a name="a23"></a><a class="code" href="def_8h.html#71341d6e189549fc0bd25ab669016df940f85224ae979275dfa75c6e7632c2d8" title="The stream is being created.">PA_STREAM_CREATING</a>: <span class="keywordflow">case</span> <a name="a24"></a><a class="code" href="def_8h.html#71341d6e189549fc0bd25ab669016df9da6b24e840e5a13408d89b8ce9b3dac4" title="The stream has been terminated cleanly.">PA_STREAM_TERMINATED</a>: <span class="keywordflow">break</span>; <span class="keywordflow">case</span> <a name="a25"></a><a class="code" href="def_8h.html#71341d6e189549fc0bd25ab669016df91e72fb989b308e2317c0b0949afe5446" title="The stream is established, you may pass audio data to it now.">PA_STREAM_READY</a>: <span class="keywordflow">if</span> (verbose) fprintf(stderr, <span class="stringliteral">"Stream successfully created\n"</span>); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> <a name="a26"></a><a class="code" href="def_8h.html#71341d6e189549fc0bd25ab669016df917035675606742a577107e86dc14495a" title="An error occured that made the stream invalid.">PA_STREAM_FAILED</a>: <span class="keywordflow">default</span>: fprintf(stderr, <span class="stringliteral">"Stream errror: %s\n"</span>, <a class="code" href="error_8h.html#593deb681fba75fad4b3a2d65d0ac2b2" title="Return a human readable error message for the specified numeric error code.">pa_strerror</a>(<a class="code" href="context_8h.html#a8262c715ef8c48bcd2fbc5ae57a6df9" title="Return the error number of the last failed operation.">pa_context_errno</a>(<a name="a27"></a><a class="code" href="stream_8h.html#d995ede5ff0edefe068b6c7e53940e90" title="Return the context this stream is attached to.">pa_stream_get_context</a>(s)))); quit(1); } } <span class="comment">/* This is called whenever the context status changes */</span> <span class="keyword">static</span> <span class="keywordtype">void</span> context_state_callback(<a class="code" href="context_8h.html#ff56e9b3dd442a88227da084bb5c380a" title="An opaque connection context to a daemon.">pa_context</a> *c, <span class="keywordtype">void</span> *userdata) { assert(c); <span class="keywordflow">switch</span> (<a name="a28"></a><a class="code" href="context_8h.html#439b9a712321194390584737a0a7003f" title="Return the current context status.">pa_context_get_state</a>(c)) { <span class="keywordflow">case</span> <a name="a29"></a><a class="code" href="def_8h.html#892684c03cf9edaed1a95e609ec7573c9a30a992d40cfcfc19867049e99004c1" title="A connection is being established.">PA_CONTEXT_CONNECTING</a>: <span class="keywordflow">case</span> <a name="a30"></a><a class="code" href="def_8h.html#892684c03cf9edaed1a95e609ec7573cbd55965cd2d6cfea52cc982c8837e857" title="The client is authorizing itself to the daemon.">PA_CONTEXT_AUTHORIZING</a>: <span class="keywordflow">case</span> <a name="a31"></a><a class="code" href="def_8h.html#892684c03cf9edaed1a95e609ec7573c222cd7356d0f906a88598d09b6ed0208" title="The client is passing its application name to the daemon.">PA_CONTEXT_SETTING_NAME</a>: <span class="keywordflow">break</span>; <span class="keywordflow">case</span> <a name="a32"></a><a class="code" href="def_8h.html#892684c03cf9edaed1a95e609ec7573c281febf058e211cb87dfdadf146d9670" title="The connection is established, the context is ready to execute operations.">PA_CONTEXT_READY</a>: { <a name="_a33"></a><a class="code" href="structpa__cvolume.html" title="A structure encapsulating a per-channel volume.">pa_cvolume</a> cv; assert(c && !stream); <span class="keywordflow">if</span> (verbose) fprintf(stderr, <span class="stringliteral">"Connection established.\n"</span>); stream = <a name="a34"></a><a class="code" href="stream_8h.html#b95a64207d12a1da61d31289d8b3ff3f" title="Create a new, unconnected stream with the specified name and sample type.">pa_stream_new</a>(c, stream_name, &sample_spec, channel_map_set ? &channel_map : NULL); assert(stream); <a name="a35"></a><a class="code" href="stream_8h.html#295da6cbb032850600598d59fed2cc18" title="Set the callback function that is called whenever the state of the stream changes...">pa_stream_set_state_callback</a>(stream, stream_state_callback, NULL); <a name="a36"></a><a class="code" href="stream_8h.html#2dcc985c65964da290a0c2e1bf103175" title="Set the callback function that is called when new data may be written to the stream...">pa_stream_set_write_callback</a>(stream, stream_write_callback, NULL); <a name="a37"></a><a class="code" href="stream_8h.html#e13072bc6107aa050f2ff4d50dd49640" title="Connect the stream to a sink.">pa_stream_connect_playback</a>(stream, device, NULL, 0, <a name="a38"></a><a class="code" href="volume_8h.html#0777581d85a1d4bf9c831bdacaac51ac" title="Set the volume of all channels to the specified parameter.">pa_cvolume_set</a>(&cv, sample_spec.<a name="a39"></a><a class="code" href="structpa__sample__spec.html#625155d20d7e50a3808b889e314d25fa" title="Audio channels.">channels</a>, volume), NULL); <span class="keywordflow">break</span>; } <span class="keywordflow">case</span> <a name="a40"></a><a class="code" href="def_8h.html#892684c03cf9edaed1a95e609ec7573c904a83b99b3ccd6bb870b3f86f0f3cfd" title="The connection was terminated cleanly.">PA_CONTEXT_TERMINATED</a>: quit(0); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> <a name="a41"></a><a class="code" href="def_8h.html#892684c03cf9edaed1a95e609ec7573c10d4edadad12e6e49edb591b06c649ae" title="The connection failed or was disconnected.">PA_CONTEXT_FAILED</a>: <span class="keywordflow">default</span>: fprintf(stderr, <span class="stringliteral">"Connection failure: %s\n"</span>, <a class="code" href="error_8h.html#593deb681fba75fad4b3a2d65d0ac2b2" title="Return a human readable error message for the specified numeric error code.">pa_strerror</a>(<a class="code" href="context_8h.html#a8262c715ef8c48bcd2fbc5ae57a6df9" title="Return the error number of the last failed operation.">pa_context_errno</a>(c))); quit(1); } } <span class="comment">/* UNIX signal to quit recieved */</span> <span class="keyword">static</span> <span class="keywordtype">void</span> exit_signal_callback(<a class="code" href="structpa__mainloop__api.html" title="An abstract mainloop API vtable.">pa_mainloop_api</a>*m, <a name="a42"></a><a class="code" href="mainloop-signal_8h.html#8346c68814daec286cef332fa9df302c" title="An opaque UNIX signal event source object.">pa_signal_event</a> *e, <span class="keywordtype">int</span> sig, <span class="keywordtype">void</span> *userdata) { <span class="keywordflow">if</span> (verbose) fprintf(stderr, <span class="stringliteral">"Got SIGINT, exiting.\n"</span>); quit(0); } <span class="keyword">static</span> <span class="keywordtype">void</span> help(<span class="keyword">const</span> <span class="keywordtype">char</span> *argv0) { printf(<span class="stringliteral">"%s [options] [FILE]\n\n"</span> <span class="stringliteral">" -h, --help Show this help\n"</span> <span class="stringliteral">" --version Show version\n\n"</span> <span class="stringliteral">" -v, --verbose Enable verbose operation\n\n"</span> <span class="stringliteral">" -s, --server=SERVER The name of the server to connect to\n"</span> <span class="stringliteral">" -d, --device=DEVICE The name of the sink to connect to\n"</span> <span class="stringliteral">" -n, --client-name=NAME How to call this client on the server\n"</span> <span class="stringliteral">" --stream-name=NAME How to call this stream on the server\n"</span> <span class="stringliteral">" --volume=VOLUME Specify the initial (linear) volume in range 0...65536\n"</span> <span class="stringliteral">" --channel-map=CHANNELMAP Set the channel map to the use\n"</span>, argv0); } <span class="keyword">enum</span> { ARG_VERSION = 256, ARG_STREAM_NAME, ARG_VOLUME, ARG_CHANNELMAP }; <span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[]) { <a name="a43"></a><a class="code" href="mainloop_8h.html#adf8d428d3e2f00ed762017c7b587cc9" title="An opaque main loop object.">pa_mainloop</a>* m = NULL; <span class="keywordtype">int</span> ret = 1, r, c; <span class="keywordtype">char</span> *bn, *server = NULL; <span class="keyword">const</span> <span class="keywordtype">char</span> *filename; SF_INFO sfinfo; <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">struct </span>option long_options[] = { {<span class="stringliteral">"device"</span>, 1, NULL, <span class="charliteral">'d'</span>}, {<span class="stringliteral">"server"</span>, 1, NULL, <span class="charliteral">'s'</span>}, {<span class="stringliteral">"client-name"</span>, 1, NULL, <span class="charliteral">'n'</span>}, {<span class="stringliteral">"stream-name"</span>, 1, NULL, ARG_STREAM_NAME}, {<span class="stringliteral">"version"</span>, 0, NULL, ARG_VERSION}, {<span class="stringliteral">"help"</span>, 0, NULL, <span class="charliteral">'h'</span>}, {<span class="stringliteral">"verbose"</span>, 0, NULL, <span class="charliteral">'v'</span>}, {<span class="stringliteral">"volume"</span>, 1, NULL, ARG_VOLUME}, {<span class="stringliteral">"channel-map"</span>, 1, NULL, ARG_CHANNELMAP}, {NULL, 0, NULL, 0} }; setlocale(LC_ALL, <span class="stringliteral">""</span>); <span class="keywordflow">if</span> (!(bn = strrchr(argv[0], <span class="charliteral">'/'</span>))) bn = argv[0]; <span class="keywordflow">else</span> bn++; <span class="keywordflow">while</span> ((c = getopt_long(argc, argv, <span class="stringliteral">"d:s:n:hv"</span>, long_options, NULL)) != -1) { <span class="keywordflow">switch</span> (c) { <span class="keywordflow">case</span> <span class="charliteral">'h'</span> : help(bn); ret = 0; <span class="keywordflow">goto</span> quit; <span class="keywordflow">case</span> ARG_VERSION: printf(<span class="stringliteral">"paplay "</span>PACKAGE_VERSION<span class="stringliteral">"\nCompiled with libpulse %s\nLinked with libpulse %s\n"</span>, <a name="a44"></a><a class="code" href="version_8h.html#ebde117e52b7ee3756e82c457de5fbbf" title="Return the version of the header files.">pa_get_headers_version</a>(), <a name="a45"></a><a class="code" href="version_8h.html#b257a40a36b29b77452957a130b6c076" title="Return the version of the library the current application is linked to.">pa_get_library_version</a>()); ret = 0; <span class="keywordflow">goto</span> quit; <span class="keywordflow">case</span> <span class="charliteral">'d'</span>: <a class="code" href="xmalloc_8h.html#975c3f1d400a40ede0d5e79bb8876008" title="Free allocated memory.">pa_xfree</a>(device); device = <a name="a46"></a><a class="code" href="xmalloc_8h.html#2ba114796ecf3ea774b440bd9a5ccd80" title="Duplicate the specified string, allocating memory with pa_xmalloc().">pa_xstrdup</a>(optarg); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> <span class="charliteral">'s'</span>: <a class="code" href="xmalloc_8h.html#975c3f1d400a40ede0d5e79bb8876008" title="Free allocated memory.">pa_xfree</a>(server); server = <a class="code" href="xmalloc_8h.html#2ba114796ecf3ea774b440bd9a5ccd80" title="Duplicate the specified string, allocating memory with pa_xmalloc().">pa_xstrdup</a>(optarg); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> <span class="charliteral">'n'</span>: <a class="code" href="xmalloc_8h.html#975c3f1d400a40ede0d5e79bb8876008" title="Free allocated memory.">pa_xfree</a>(client_name); client_name = <a class="code" href="xmalloc_8h.html#2ba114796ecf3ea774b440bd9a5ccd80" title="Duplicate the specified string, allocating memory with pa_xmalloc().">pa_xstrdup</a>(optarg); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> ARG_STREAM_NAME: <a class="code" href="xmalloc_8h.html#975c3f1d400a40ede0d5e79bb8876008" title="Free allocated memory.">pa_xfree</a>(stream_name); stream_name = <a class="code" href="xmalloc_8h.html#2ba114796ecf3ea774b440bd9a5ccd80" title="Duplicate the specified string, allocating memory with pa_xmalloc().">pa_xstrdup</a>(optarg); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> <span class="charliteral">'v'</span>: verbose = 1; <span class="keywordflow">break</span>; <span class="keywordflow">case</span> ARG_VOLUME: { <span class="keywordtype">int</span> v = atoi(optarg); volume = v < 0 ? 0 : v; <span class="keywordflow">break</span>; } <span class="keywordflow">case</span> ARG_CHANNELMAP: <span class="keywordflow">if</span> (!<a name="a47"></a><a class="code" href="channelmap_8h.html#66d10dda716c59960d6100c2774e6a36" title="Parse a channel position list into a channel map structure.">pa_channel_map_parse</a>(&channel_map, optarg)) { fprintf(stderr, <span class="stringliteral">"Invalid channel map\n"</span>); <span class="keywordflow">goto</span> quit; } channel_map_set = 1; <span class="keywordflow">break</span>; <span class="keywordflow">default</span>: <span class="keywordflow">goto</span> quit; } } filename = optind < argc ? argv[optind] : <span class="stringliteral">"STDIN"</span>; memset(&sfinfo, 0, <span class="keyword">sizeof</span>(sfinfo)); <span class="keywordflow">if</span> (optind < argc) sndfile = sf_open(filename, SFM_READ, &sfinfo); <span class="keywordflow">else</span> sndfile = sf_open_fd(STDIN_FILENO, SFM_READ, &sfinfo, 0); <span class="keywordflow">if</span> (!sndfile) { fprintf(stderr, <span class="stringliteral">"Failed to open file '%s'\n"</span>, filename); <span class="keywordflow">goto</span> quit; } sample_spec.<a name="a48"></a><a class="code" href="structpa__sample__spec.html#4fd5a1ef48c1cbea95a94b20a5cc02b0" title="The sample rate.">rate</a> = sfinfo.samplerate; sample_spec.<a class="code" href="structpa__sample__spec.html#625155d20d7e50a3808b889e314d25fa" title="Audio channels.">channels</a> = sfinfo.channels; readf_function = NULL; <span class="keywordflow">switch</span> (sfinfo.format & 0xFF) { <span class="keywordflow">case</span> SF_FORMAT_PCM_16: <span class="keywordflow">case</span> SF_FORMAT_PCM_U8: <span class="keywordflow">case</span> SF_FORMAT_PCM_S8: sample_spec.<a name="a49"></a><a class="code" href="structpa__sample__spec.html#6f37954f1b7ac9d9bff4683171a10a99" title="The sample format.">format</a> = <a name="a50"></a><a class="code" href="sample_8h.html#292c1d8ebd4ca0de1d5d5379ee7be38a" title="Signed 16 Bit PCM, native endian.">PA_SAMPLE_S16NE</a>; readf_function = (sf_count_t (*)(SNDFILE *_sndfile, <span class="keywordtype">void</span> *ptr, sf_count_t frames)) sf_readf_short; <span class="keywordflow">break</span>; <span class="keywordflow">case</span> SF_FORMAT_ULAW: sample_spec.<a class="code" href="structpa__sample__spec.html#6f37954f1b7ac9d9bff4683171a10a99" title="The sample format.">format</a> = <a name="a51"></a><a class="code" href="sample_8h.html#3c622fc51f4fc6ebfdcc7b454ac9c05f83116fc70f8577fdcf694474a60c2e1f" title="8 Bit mu-Law">PA_SAMPLE_ULAW</a>; <span class="keywordflow">break</span>; <span class="keywordflow">case</span> SF_FORMAT_ALAW: sample_spec.<a class="code" href="structpa__sample__spec.html#6f37954f1b7ac9d9bff4683171a10a99" title="The sample format.">format</a> = <a name="a52"></a><a class="code" href="sample_8h.html#3c622fc51f4fc6ebfdcc7b454ac9c05f267f6542eb6f66ca61c4cccf61326522" title="8 Bit a-Law">PA_SAMPLE_ALAW</a>; <span class="keywordflow">break</span>; <span class="keywordflow">case</span> SF_FORMAT_FLOAT: <span class="keywordflow">case</span> SF_FORMAT_DOUBLE: <span class="keywordflow">default</span>: sample_spec.<a class="code" href="structpa__sample__spec.html#6f37954f1b7ac9d9bff4683171a10a99" title="The sample format.">format</a> = <a name="a53"></a><a class="code" href="sample_8h.html#25befbdbf9fdc57012ce00dcc1756eac" title="32 Bit IEEE floating point, native endian">PA_SAMPLE_FLOAT32NE</a>; readf_function = (sf_count_t (*)(SNDFILE *_sndfile, <span class="keywordtype">void</span> *ptr, sf_count_t frames)) sf_readf_float; <span class="keywordflow">break</span>; } assert(<a name="a54"></a><a class="code" href="sample_8h.html#0d9ad972ee71ef6bff8aaafd44fdb229" title="Return non-zero when the sample type specification is valid.">pa_sample_spec_valid</a>(&sample_spec)); <span class="keywordflow">if</span> (channel_map_set && channel_map.<a name="a55"></a><a class="code" href="structpa__channel__map.html#91670676065c5fd4405d4d15b26b82d3" title="Number of channels.">channels</a> != sample_spec.<a class="code" href="structpa__sample__spec.html#625155d20d7e50a3808b889e314d25fa" title="Audio channels.">channels</a>) { fprintf(stderr, <span class="stringliteral">"Channel map doesn't match file.\n"</span>); <span class="keywordflow">goto</span> quit; } <span class="keywordflow">if</span> (!client_name) { client_name = <a name="a56"></a><a class="code" href="utf8_8h.html#9c00367174d98424a3385402ec53d2b5" title="Convert a string in the current locale to UTF-8.">pa_locale_to_utf8</a>(bn); <span class="keywordflow">if</span> (!client_name) client_name = <a name="a57"></a><a class="code" href="utf8_8h.html#0685ca8e79a2e26a588bccda535d0676" title="Filter all invalid UTF8 characters from the specified string, returning a new fully...">pa_utf8_filter</a>(bn); } <span class="keywordflow">if</span> (!stream_name) { <span class="keyword">const</span> <span class="keywordtype">char</span> *n; n = sf_get_string(sndfile, SF_STR_TITLE); <span class="keywordflow">if</span> (!n) n = filename; stream_name = <a class="code" href="utf8_8h.html#9c00367174d98424a3385402ec53d2b5" title="Convert a string in the current locale to UTF-8.">pa_locale_to_utf8</a>(n); <span class="keywordflow">if</span> (!stream_name) stream_name = <a class="code" href="utf8_8h.html#0685ca8e79a2e26a588bccda535d0676" title="Filter all invalid UTF8 characters from the specified string, returning a new fully...">pa_utf8_filter</a>(n); } <span class="keywordflow">if</span> (verbose) { <span class="keywordtype">char</span> t[<a name="a58"></a><a class="code" href="sample_8h.html#61844a6fa4a5a91bbeca1049c4969bb8" title="Maximum required string length for pa_sample_spec_snprint().">PA_SAMPLE_SPEC_SNPRINT_MAX</a>]; <a name="a59"></a><a class="code" href="sample_8h.html#3dd4815bbd51d5467b40e28d05ad948d" title="Pretty print a sample type specification to a string.">pa_sample_spec_snprint</a>(t, <span class="keyword">sizeof</span>(t), &sample_spec); fprintf(stderr, <span class="stringliteral">"Using sample spec '%s'\n"</span>, t); } <span class="comment">/* Set up a new main loop */</span> <span class="keywordflow">if</span> (!(m = <a name="a60"></a><a class="code" href="mainloop_8h.html#d6c767781474275159c0a5f3f7e2ecb5" title="Allocate a new main loop object.">pa_mainloop_new</a>())) { fprintf(stderr, <span class="stringliteral">"pa_mainloop_new() failed.\n"</span>); <span class="keywordflow">goto</span> quit; } mainloop_api = <a name="a61"></a><a class="code" href="mainloop_8h.html#9e5b510dabb4eb1a01645c4db65b9ddb" title="Return the abstract main loop abstraction layer vtable for this main loop.">pa_mainloop_get_api</a>(m); r = <a name="a62"></a><a class="code" href="mainloop-signal_8h.html#08bd75b482aabc45114dbcb53f004fe6" title="Initialize the UNIX signal subsystem and bind it to the specified main loop.">pa_signal_init</a>(mainloop_api); assert(r == 0); <a name="a63"></a><a class="code" href="mainloop-signal_8h.html#dd63a54f46fbe92df924362e3b38add1" title="Create a new UNIX signal event source object.">pa_signal_new</a>(SIGINT, exit_signal_callback, NULL); <span class="preprocessor">#ifdef SIGPIPE</span> <span class="preprocessor"></span> signal(SIGPIPE, SIG_IGN); <span class="preprocessor">#endif</span> <span class="preprocessor"></span> <span class="comment">/* Create a new connection context */</span> <span class="keywordflow">if</span> (!(context = <a name="a64"></a><a class="code" href="context_8h.html#2784c754947a97f02c78b73d7b1c2d5f" title="Instantiate a new connection context with an abstract mainloop API and an application...">pa_context_new</a>(mainloop_api, client_name))) { fprintf(stderr, <span class="stringliteral">"pa_context_new() failed.\n"</span>); <span class="keywordflow">goto</span> quit; } <a name="a65"></a><a class="code" href="context_8h.html#eb7b395fd3a345fc181d6bfcdbe5f3d8" title="Set a callback function that is called whenever the context status changes.">pa_context_set_state_callback</a>(context, context_state_callback, NULL); <span class="comment">/* Connect the context */</span> <a name="a66"></a><a class="code" href="context_8h.html#983ce13d45c5f4b0db8e1a34e21f9fce" title="Connect the context to the specified server.">pa_context_connect</a>(context, server, 0, NULL); <span class="comment">/* Run the main loop */</span> <span class="keywordflow">if</span> (<a name="a67"></a><a class="code" href="mainloop_8h.html#fbcd8f4eba09cdfd5323ac9db3718ae8" title="Run unlimited iterations of the main loop object until the main loop&#39;s quit()...">pa_mainloop_run</a>(m, &ret) < 0) { fprintf(stderr, <span class="stringliteral">"pa_mainloop_run() failed.\n"</span>); <span class="keywordflow">goto</span> quit; } quit: <span class="keywordflow">if</span> (stream) <a class="code" href="stream_8h.html#7780fa5438f31152b0a6aeae31b63264" title="Decrease the reference counter by one.">pa_stream_unref</a>(stream); <span class="keywordflow">if</span> (context) <a name="a68"></a><a class="code" href="context_8h.html#344c4ccf14d6a8842e83154a0aa99311" title="Decrease the reference counter of the context by one.">pa_context_unref</a>(context); <span class="keywordflow">if</span> (m) { <a name="a69"></a><a class="code" href="mainloop-signal_8h.html#e75dbfe9876a5482a5c644bac5abf479" title="Cleanup the signal subsystem.">pa_signal_done</a>(); <a name="a70"></a><a class="code" href="mainloop_8h.html#6c6ea37ce2815640f7f1a133f845f8e7" title="Free a main loop object.">pa_mainloop_free</a>(m); } <a class="code" href="xmalloc_8h.html#975c3f1d400a40ede0d5e79bb8876008" title="Free allocated memory.">pa_xfree</a>(server); <a class="code" href="xmalloc_8h.html#975c3f1d400a40ede0d5e79bb8876008" title="Free allocated memory.">pa_xfree</a>(device); <a class="code" href="xmalloc_8h.html#975c3f1d400a40ede0d5e79bb8876008" title="Free allocated memory.">pa_xfree</a>(client_name); <a class="code" href="xmalloc_8h.html#975c3f1d400a40ede0d5e79bb8876008" title="Free allocated memory.">pa_xfree</a>(stream_name); <span class="keywordflow">if</span> (sndfile) sf_close(sndfile); <span class="keywordflow">return</span> ret; } </pre></div> </div> <hr size="1"><address style="text-align: right;"><small>Generated on Wed Mar 26 12:02:40 2008 for PulseAudio by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.5 </small></address> </body> </html>