<!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: pacat.c</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.5.8 --> <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="annotated.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>pacat.c</h1>A playback and recording tool using the asynchronous API<p> <div class="fragment"><pre class="fragment"><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.1 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 <fcntl.h></span> <span class="preprocessor">#include <locale.h></span> <span class="preprocessor">#include <pulse/i18n.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">#define TIME_EVENT_USEC 50000</span> <span class="preprocessor"></span> <span class="preprocessor">#define CLEAR_LINE "\x1B[K"</span> <span class="preprocessor"></span> <span class="keyword">static</span> <span class="keyword">enum</span> { RECORD, PLAYBACK } mode = PLAYBACK; <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">void</span> *buffer = NULL; <span class="keyword">static</span> <span class="keywordtype">size_t</span> buffer_length = 0, buffer_index = 0; <span class="keyword">static</span> <a name="a3"></a><a class="code" href="mainloop-api_8h.html#e7acb1df28956a7761ee5488167840a3" title="An opaque IO event source object.">pa_io_event</a>* stdio_event = 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="a4"></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="a5"></a><a class="code" href="volume_8h.html#ded56902e68e0f8ab576339bde55960e" title="Normal volume (100%, 0 dB).">PA_VOLUME_NORM</a>; <span class="keyword">static</span> <span class="keywordtype">int</span> volume_is_set = 0; <span class="keyword">static</span> <a name="_a6"></a><a class="code" href="structpa__sample__spec.html" title="A sample format and attribute specification.">pa_sample_spec</a> sample_spec = { .format = <a name="a7"></a><a class="code" href="sample_8h.html#3c622fc51f4fc6ebfdcc7b454ac9c05f50e4a2b43c258e559fa9d252275131ce" title="Signed 16 Bit PCM, little endian (PC).">PA_SAMPLE_S16LE</a>, .rate = 44100, .channels = 2 }; <span class="keyword">static</span> <a name="_a8"></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> <a name="a9"></a><a class="code" href="def_8h.html#9328c83d983878efb0627b99d949a3cc" title="Some special flags for stream connections.">pa_stream_flags_t</a> flags = 0; <span class="keyword">static</span> <span class="keywordtype">size_t</span> latency = 0, process_time=0; <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="a10"></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">/* Write some data to the stream */</span> <span class="keyword">static</span> <span class="keywordtype">void</span> do_stream_write(<span class="keywordtype">size_t</span> length) { <span class="keywordtype">size_t</span> l; assert(length); <span class="keywordflow">if</span> (!buffer || !buffer_length) <span class="keywordflow">return</span>; l = length; <span class="keywordflow">if</span> (l > buffer_length) l = buffer_length; <span class="keywordflow">if</span> (<a name="a11"></a><a class="code" href="stream_8h.html#4fc69dec0cc202fcc174125dc88dada7" title="Write some data to the server (for playback sinks), if free_cb is non-NULL this routine...">pa_stream_write</a>(stream, (uint8_t*) buffer + buffer_index, l, NULL, 0, <a name="a12"></a><a class="code" href="def_8h.html#eb8e6973350d158e982985c1d19eef3ba2e4cfb8fb37554e73855242729edf13" title="Seek relatively to the write index.">PA_SEEK_RELATIVE</a>) < 0) { fprintf(stderr, _(<span class="stringliteral">"pa_stream_write() failed: %s\n"</span>), <a name="a13"></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="a14"></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">return</span>; } buffer_length -= l; buffer_index += l; <span class="keywordflow">if</span> (!buffer_length) { <a name="a15"></a><a class="code" href="xmalloc_8h.html#975c3f1d400a40ede0d5e79bb8876008" title="Free allocated memory.">pa_xfree</a>(buffer); buffer = NULL; buffer_index = buffer_length = 0; } } <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) { assert(s); assert(length > 0); <span class="keywordflow">if</span> (stdio_event) mainloop_api-><a name="a16"></a><a class="code" href="structpa__mainloop__api.html#c8372ccaf7b5291008d6f59cf40ce3aa" title="Enable or disable IO events on this object.">io_enable</a>(stdio_event, <a name="a17"></a><a class="code" href="mainloop-api_8h.html#6769e3c8a68703a81a68d5d72b32d1faba9fbd1e6cb3031098a2aaa144c78336" title="Input event.">PA_IO_EVENT_INPUT</a>); <span class="keywordflow">if</span> (!buffer) <span class="keywordflow">return</span>; do_stream_write(length); } <span class="comment">/* This is called whenever new data may is available */</span> <span class="keyword">static</span> <span class="keywordtype">void</span> stream_read_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) { <span class="keyword">const</span> <span class="keywordtype">void</span> *data; assert(s); assert(length > 0); <span class="keywordflow">if</span> (stdio_event) mainloop_api-><a class="code" href="structpa__mainloop__api.html#c8372ccaf7b5291008d6f59cf40ce3aa" title="Enable or disable IO events on this object.">io_enable</a>(stdio_event, <a name="a18"></a><a class="code" href="mainloop-api_8h.html#6769e3c8a68703a81a68d5d72b32d1fa3aff35dad0cd23ae3796b3141fee4dce" title="Output event.">PA_IO_EVENT_OUTPUT</a>); <span class="keywordflow">if</span> (<a name="a19"></a><a class="code" href="stream_8h.html#c2838c449cde56e169224d7fe3d00824" title="Read the next fragment from the buffer (for recording).">pa_stream_peek</a>(s, &data, &length) < 0) { fprintf(stderr, _(<span class="stringliteral">"pa_stream_peek() failed: %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>(context))); quit(1); <span class="keywordflow">return</span>; } assert(data); assert(length > 0); <span class="keywordflow">if</span> (buffer) { buffer = <a name="a20"></a><a class="code" href="xmalloc_8h.html#2d8eb77938ae799182b5372f7c560ea5" title="The combination of pa_xmalloc() and realloc().">pa_xrealloc</a>(buffer, buffer_length + length); memcpy((uint8_t*) buffer + buffer_length, data, length); buffer_length += length; } <span class="keywordflow">else</span> { buffer = <a name="a21"></a><a class="code" href="xmalloc_8h.html#e42cfb0a75434a87cf1d0ded8c7a8eb1" title="Allocate the specified number of bytes, just like malloc() does.">pa_xmalloc</a>(length); memcpy(buffer, data, length); buffer_length = length; buffer_index = 0; } <a name="a22"></a><a class="code" href="stream_8h.html#2e8a3e15fb63a5bb9cbba2d01a6538a5" title="Remove the current fragment on record streams.">pa_stream_drop</a>(s); } <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="a23"></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="a24"></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="a25"></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="a26"></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) { <span class="keyword">const</span> <a name="_a27"></a><a class="code" href="structpa__buffer__attr.html" title="Playback and record buffer metrics.">pa_buffer_attr</a> *a; <span class="keywordtype">char</span> cmt[<a name="a28"></a><a class="code" href="channelmap_8h.html#19fb89628e40ff671f047a83f43899e6" title="The maximum length of strings returned by pa_channel_map_snprint().">PA_CHANNEL_MAP_SNPRINT_MAX</a>], sst[<a name="a29"></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>]; fprintf(stderr, _(<span class="stringliteral">"Stream successfully created.\n"</span>)); <span class="keywordflow">if</span> (!(a = <a name="a30"></a><a class="code" href="stream_8h.html#9a3c3e78eafb28cce3a16cef2b68a385" title="Return the per-stream server-side buffer metrics of the stream.">pa_stream_get_buffer_attr</a>(s))) fprintf(stderr, _(<span class="stringliteral">"pa_stream_get_buffer_attr() failed: %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="a31"></a><a class="code" href="stream_8h.html#d995ede5ff0edefe068b6c7e53940e90" title="Return the context this stream is attached to.">pa_stream_get_context</a>(s)))); <span class="keywordflow">else</span> { <span class="keywordflow">if</span> (mode == PLAYBACK) fprintf(stderr, _(<span class="stringliteral">"Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u\n"</span>), a-><a name="a32"></a><a class="code" href="structpa__buffer__attr.html#bef20d3a6cab53f716846125353e56a4" title="Maximum length of the buffer.">maxlength</a>, a-><a name="a33"></a><a class="code" href="structpa__buffer__attr.html#a7e8f3348cbda863b6f1dd55a9024b7a" title="Playback only: target length of the buffer.">tlength</a>, a-><a name="a34"></a><a class="code" href="structpa__buffer__attr.html#cdbe30979a50075479ee46c56cc724ee" title="Playback only: pre-buffering.">prebuf</a>, a-><a name="a35"></a><a class="code" href="structpa__buffer__attr.html#4571c0c0cd4e1561177172497e886000" title="Playback only: minimum request.">minreq</a>); <span class="keywordflow">else</span> { assert(mode == RECORD); fprintf(stderr, _(<span class="stringliteral">"Buffer metrics: maxlength=%u, fragsize=%u\n"</span>), a-><a class="code" href="structpa__buffer__attr.html#bef20d3a6cab53f716846125353e56a4" title="Maximum length of the buffer.">maxlength</a>, a-><a name="a36"></a><a class="code" href="structpa__buffer__attr.html#2877c9500727299a2d143ef0af13f908" title="Recording only: fragment size.">fragsize</a>); } } fprintf(stderr, _(<span class="stringliteral">"Using sample spec '%s', channel map '%s'.\n"</span>), <a name="a37"></a><a class="code" href="sample_8h.html#3dd4815bbd51d5467b40e28d05ad948d" title="Pretty print a sample type specification to a string.">pa_sample_spec_snprint</a>(sst, <span class="keyword">sizeof</span>(sst), <a name="a38"></a><a class="code" href="stream_8h.html#274d745a41dc54cc6f946bed7bcd8a58" title="Return a pointer to the stream&#39;s sample specification.">pa_stream_get_sample_spec</a>(s)), <a name="a39"></a><a class="code" href="channelmap_8h.html#5baa37ac22ea08485b12fcce63a98abe" title="Make a human readable string from the specified channel map.">pa_channel_map_snprint</a>(cmt, <span class="keyword">sizeof</span>(cmt), <a name="a40"></a><a class="code" href="stream_8h.html#c4c92d45a14a876f187ff7bd8090826a" title="Return a pointer to the stream&#39;s channel map.">pa_stream_get_channel_map</a>(s))); fprintf(stderr, _(<span class="stringliteral">"Connected to device %s (%u, %ssuspended).\n"</span>), <a name="a41"></a><a class="code" href="stream_8h.html#df568b636afbd00ff60e0c100595309e" title="Return the name of the sink or source this stream is connected to in the server.">pa_stream_get_device_name</a>(s), <a name="a42"></a><a class="code" href="stream_8h.html#a84f1dc4657cd2e2f52effffd4583963" title="Return the index of the sink or source this stream is connected to in the server...">pa_stream_get_device_index</a>(s), <a name="a43"></a><a class="code" href="stream_8h.html#aa4234efbfc42b102edfc3f97789d257" title="Return 1 if the sink or source this stream is connected to has been suspended.">pa_stream_is_suspended</a>(s) ? <span class="stringliteral">""</span> : <span class="stringliteral">"not "</span>); } <span class="keywordflow">break</span>; <span class="keywordflow">case</span> <a name="a44"></a><a class="code" href="def_8h.html#71341d6e189549fc0bd25ab669016df917035675606742a577107e86dc14495a" title="An error occurred that made the stream invalid.">PA_STREAM_FAILED</a>: <span class="keywordflow">default</span>: fprintf(stderr, _(<span class="stringliteral">"Stream error: %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 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="keyword">static</span> <span class="keywordtype">void</span> stream_suspended_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">if</span> (verbose) { <span class="keywordflow">if</span> (<a class="code" href="stream_8h.html#aa4234efbfc42b102edfc3f97789d257" title="Return 1 if the sink or source this stream is connected to has been suspended.">pa_stream_is_suspended</a>(s)) fprintf(stderr, _(<span class="stringliteral">"Stream device suspended.%s \n"</span>), CLEAR_LINE); <span class="keywordflow">else</span> fprintf(stderr, _(<span class="stringliteral">"Stream device resumed.%s \n"</span>), CLEAR_LINE); } } <span class="keyword">static</span> <span class="keywordtype">void</span> stream_underflow_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">if</span> (verbose) fprintf(stderr, _(<span class="stringliteral">"Stream underrun.%s \n"</span>), CLEAR_LINE); } <span class="keyword">static</span> <span class="keywordtype">void</span> stream_overflow_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">if</span> (verbose) fprintf(stderr, _(<span class="stringliteral">"Stream overrun.%s \n"</span>), CLEAR_LINE); } <span class="keyword">static</span> <span class="keywordtype">void</span> stream_started_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">if</span> (verbose) fprintf(stderr, _(<span class="stringliteral">"Stream started.%s \n"</span>), CLEAR_LINE); } <span class="keyword">static</span> <span class="keywordtype">void</span> stream_moved_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">if</span> (verbose) fprintf(stderr, _(<span class="stringliteral">"Stream moved to device %s (%u, %ssuspended).%s \n"</span>), <a class="code" href="stream_8h.html#df568b636afbd00ff60e0c100595309e" title="Return the name of the sink or source this stream is connected to in the server.">pa_stream_get_device_name</a>(s), <a class="code" href="stream_8h.html#a84f1dc4657cd2e2f52effffd4583963" title="Return the index of the sink or source this stream is connected to in the server...">pa_stream_get_device_index</a>(s), <a class="code" href="stream_8h.html#aa4234efbfc42b102edfc3f97789d257" title="Return 1 if the sink or source this stream is connected to has been suspended.">pa_stream_is_suspended</a>(s) ? <span class="stringliteral">""</span> : _(<span class="stringliteral">"not "</span>), CLEAR_LINE); } <span class="keyword">static</span> <span class="keywordtype">void</span> stream_buffer_attr_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">if</span> (verbose) fprintf(stderr, _(<span class="stringliteral">"Stream buffer attributes changed.%s \n"</span>), CLEAR_LINE); } <span class="keyword">static</span> <span class="keywordtype">void</span> stream_event_callback(<a class="code" href="stream_8h.html#960d798980692a2ff01e5a70553d4f29" title="An opaque stream for playback or recording.">pa_stream</a> *s, <span class="keyword">const</span> <span class="keywordtype">char</span> *name, <a name="a45"></a><a class="code" href="proplist_8h.html#cdf756a6014b6fae3b358b2c934c3426" title="A property list object.">pa_proplist</a> *pl, <span class="keywordtype">void</span> *userdata) { <span class="keywordtype">char</span> *t; assert(s); assert(name); assert(pl); t = <a name="a46"></a><a class="code" href="proplist_8h.html#f78042ee0665530a50a6f314b348a9a1" title="Format the property list nicely as a human readable string and choose the seperator...">pa_proplist_to_string_sep</a>(pl, <span class="stringliteral">", "</span>); fprintf(stderr, <span class="stringliteral">"Got event '%s', properties '%s'\n"</span>, name, t); <a class="code" href="xmalloc_8h.html#975c3f1d400a40ede0d5e79bb8876008" title="Free allocated memory.">pa_xfree</a>(t); } <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="a47"></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="a48"></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="a49"></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="a50"></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="a51"></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>: { <span class="keywordtype">int</span> r; <a class="code" href="structpa__buffer__attr.html" title="Playback and record buffer metrics.">pa_buffer_attr</a> buffer_attr; assert(c); assert(!stream); <span class="keywordflow">if</span> (verbose) fprintf(stderr, _(<span class="stringliteral">"Connection established.%s \n"</span>), CLEAR_LINE); <span class="keywordflow">if</span> (!(stream = <a name="a52"></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))) { fprintf(stderr, _(<span class="stringliteral">"pa_stream_new() failed: %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))); <span class="keywordflow">goto</span> fail; } <a name="a53"></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="a54"></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="a55"></a><a class="code" href="stream_8h.html#b9949b66e1aca2c1988f864e90f2ae4c" title="Set the callback function that is called when new data is available from the stream...">pa_stream_set_read_callback</a>(stream, stream_read_callback, NULL); <a name="a56"></a><a class="code" href="stream_8h.html#4ddaac3d3a921829c3080e7c8c15a21e" title="Set the callback function that is called whenever the sink/source this stream is...">pa_stream_set_suspended_callback</a>(stream, stream_suspended_callback, NULL); <a name="a57"></a><a class="code" href="stream_8h.html#6def5afeb0b2071f130bb373b3f114b8" title="Set the callback function that is called whenever the stream is moved to a different...">pa_stream_set_moved_callback</a>(stream, stream_moved_callback, NULL); <a name="a58"></a><a class="code" href="stream_8h.html#660b5a7096409f41ef52b8e0b7e96d38" title="Set the callback function that is called when a buffer underflow happens.">pa_stream_set_underflow_callback</a>(stream, stream_underflow_callback, NULL); <a name="a59"></a><a class="code" href="stream_8h.html#f1e07bc89d12aca66d2725a60cfdbdc3" title="Set the callback function that is called when a buffer overflow happens.">pa_stream_set_overflow_callback</a>(stream, stream_overflow_callback, NULL); <a name="a60"></a><a class="code" href="stream_8h.html#aa10d78431d934b07c690bc916f3daa7" title="Set the callback function that is called when a the server starts playback after...">pa_stream_set_started_callback</a>(stream, stream_started_callback, NULL); <a name="a61"></a><a class="code" href="stream_8h.html#5690ed098466233860e632abfa61fe50" title="Set the callback function that is called whenver a meta/policy control event is received...">pa_stream_set_event_callback</a>(stream, stream_event_callback, NULL); <a name="a62"></a><a class="code" href="stream_8h.html#6a3d521e76540896442ef09cd12e3e2b" title="Set the callback function that is called whenver the buffer attributes on the server...">pa_stream_set_buffer_attr_callback</a>(stream, stream_buffer_attr_callback, NULL); <span class="keywordflow">if</span> (latency > 0) { memset(&buffer_attr, 0, <span class="keyword">sizeof</span>(buffer_attr)); buffer_attr.<a class="code" href="structpa__buffer__attr.html#a7e8f3348cbda863b6f1dd55a9024b7a" title="Playback only: target length of the buffer.">tlength</a> = (uint32_t) latency; buffer_attr.<a class="code" href="structpa__buffer__attr.html#4571c0c0cd4e1561177172497e886000" title="Playback only: minimum request.">minreq</a> = (uint32_t) process_time; buffer_attr.<a class="code" href="structpa__buffer__attr.html#bef20d3a6cab53f716846125353e56a4" title="Maximum length of the buffer.">maxlength</a> = (uint32_t) -1; buffer_attr.<a class="code" href="structpa__buffer__attr.html#cdbe30979a50075479ee46c56cc724ee" title="Playback only: pre-buffering.">prebuf</a> = (uint32_t) -1; buffer_attr.<a class="code" href="structpa__buffer__attr.html#2877c9500727299a2d143ef0af13f908" title="Recording only: fragment size.">fragsize</a> = (uint32_t) latency; flags |= <a name="a63"></a><a class="code" href="def_8h.html#6966d809483170bc6d2e6c16188850fcb24aa4c681a4b62af2efc7d53dfd40f0" title="Try to adjust the latency of the sink/source based on the requested buffer metrics...">PA_STREAM_ADJUST_LATENCY</a>; } <span class="keywordflow">if</span> (mode == PLAYBACK) { <a name="_a64"></a><a class="code" href="structpa__cvolume.html" title="A structure encapsulating a per-channel volume.">pa_cvolume</a> cv; <span class="keywordflow">if</span> ((r = <a name="a65"></a><a class="code" href="stream_8h.html#e13072bc6107aa050f2ff4d50dd49640" title="Connect the stream to a sink.">pa_stream_connect_playback</a>(stream, device, latency > 0 ? &buffer_attr : NULL, flags, volume_is_set ? <a name="a66"></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="a67"></a><a class="code" href="structpa__sample__spec.html#625155d20d7e50a3808b889e314d25fa" title="Audio channels.">channels</a>, volume) : NULL, NULL)) < 0) { fprintf(stderr, _(<span class="stringliteral">"pa_stream_connect_playback() failed: %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))); <span class="keywordflow">goto</span> fail; } } <span class="keywordflow">else</span> { <span class="keywordflow">if</span> ((r = <a name="a68"></a><a class="code" href="stream_8h.html#bfd34293aae8f170f572d1093c1bcdf9" title="Connect the stream to a source.">pa_stream_connect_record</a>(stream, device, latency > 0 ? &buffer_attr : NULL, flags)) < 0) { fprintf(stderr, _(<span class="stringliteral">"pa_stream_connect_record() failed: %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))); <span class="keywordflow">goto</span> fail; } } <span class="keywordflow">break</span>; } <span class="keywordflow">case</span> <a name="a69"></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="a70"></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))); <span class="keywordflow">goto</span> fail; } <span class="keywordflow">return</span>; fail: quit(1); } <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="a71"></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) { <span class="keywordflow">if</span> (!success) { fprintf(stderr, _(<span class="stringliteral">"Failed to drain stream: %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>(context))); quit(1); } <span class="keywordflow">if</span> (verbose) fprintf(stderr, _(<span class="stringliteral">"Playback stream drained.\n"</span>)); <a name="a72"></a><a class="code" href="stream_8h.html#a4e0c83264f3935911e6b30e6f8ef2b1" title="Disconnect a stream from a source/sink.">pa_stream_disconnect</a>(stream); <a name="a73"></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> (!<a name="a74"></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> { <span class="keywordflow">if</span> (verbose) fprintf(stderr, _(<span class="stringliteral">"Draining connection to server.\n"</span>)); } } <span class="comment">/* New data on STDIN **/</span> <span class="keyword">static</span> <span class="keywordtype">void</span> stdin_callback(<a class="code" href="structpa__mainloop__api.html" title="An abstract mainloop API vtable.">pa_mainloop_api</a>*a, <a class="code" href="mainloop-api_8h.html#e7acb1df28956a7761ee5488167840a3" title="An opaque IO event source object.">pa_io_event</a> *e, <span class="keywordtype">int</span> fd, <a name="a75"></a><a class="code" href="mainloop-api_8h.html#01d415df4f23e46b20cd218678c4c9a7" title="A bitmask for IO events.">pa_io_event_flags_t</a> f, <span class="keywordtype">void</span> *userdata) { <span class="keywordtype">size_t</span> l, w = 0; ssize_t r; assert(a == mainloop_api); assert(e); assert(stdio_event == e); <span class="keywordflow">if</span> (buffer) { mainloop_api-><a class="code" href="structpa__mainloop__api.html#c8372ccaf7b5291008d6f59cf40ce3aa" title="Enable or disable IO events on this object.">io_enable</a>(stdio_event, <a name="a76"></a><a class="code" href="mainloop-api_8h.html#6769e3c8a68703a81a68d5d72b32d1fa458d976392190c7626b4f789bf11b2ea" title="No event.">PA_IO_EVENT_NULL</a>); <span class="keywordflow">return</span>; } <span class="keywordflow">if</span> (!stream || <a class="code" href="stream_8h.html#b1da38d494d6485e35f0715f40dff0ab" title="Return the current state of the stream.">pa_stream_get_state</a>(stream) != <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> || !(l = w = <a name="a77"></a><a class="code" href="stream_8h.html#b63ccd1908b6deae1b2ca7be6fa759e7" title="Return the number of bytes that may be written using pa_stream_write().">pa_stream_writable_size</a>(stream))) l = 4096; buffer = <a class="code" href="xmalloc_8h.html#e42cfb0a75434a87cf1d0ded8c7a8eb1" title="Allocate the specified number of bytes, just like malloc() does.">pa_xmalloc</a>(l); <span class="keywordflow">if</span> ((r = read(fd, buffer, l)) <= 0) { <span class="keywordflow">if</span> (r == 0) { <span class="keywordflow">if</span> (verbose) fprintf(stderr, _(<span class="stringliteral">"Got EOF.\n"</span>)); <span class="keywordflow">if</span> (stream) { <a name="a78"></a><a class="code" href="operation_8h.html#5614a07f2e7a129e4cb16596ed452a0c" title="An asynchronous operation object.">pa_operation</a> *o; <span class="keywordflow">if</span> (!(o = <a name="a79"></a><a class="code" href="stream_8h.html#8d263f188073f244b3820f3f50db4ba5" title="Drain a playback stream.">pa_stream_drain</a>(stream, stream_drain_complete, NULL))) { fprintf(stderr, _(<span class="stringliteral">"pa_stream_drain(): %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>(context))); quit(1); <span class="keywordflow">return</span>; } <a name="a80"></a><a class="code" href="operation_8h.html#8d2ef9bb2ff961ee31675882bf125227" title="Decrease the reference count by one.">pa_operation_unref</a>(o); } <span class="keywordflow">else</span> quit(0); } <span class="keywordflow">else</span> { fprintf(stderr, _(<span class="stringliteral">"read() failed: %s\n"</span>), strerror(errno)); quit(1); } mainloop_api-><a name="a81"></a><a class="code" href="structpa__mainloop__api.html#3a48c4fa72ef016e5c7b8cfd011a3d7a" title="Free a IO event source object.">io_free</a>(stdio_event); stdio_event = NULL; <span class="keywordflow">return</span>; } buffer_length = (uint32_t) r; buffer_index = 0; <span class="keywordflow">if</span> (w) do_stream_write(w); } <span class="comment">/* Some data may be written to STDOUT */</span> <span class="keyword">static</span> <span class="keywordtype">void</span> stdout_callback(<a class="code" href="structpa__mainloop__api.html" title="An abstract mainloop API vtable.">pa_mainloop_api</a>*a, <a class="code" href="mainloop-api_8h.html#e7acb1df28956a7761ee5488167840a3" title="An opaque IO event source object.">pa_io_event</a> *e, <span class="keywordtype">int</span> fd, <a class="code" href="mainloop-api_8h.html#01d415df4f23e46b20cd218678c4c9a7" title="A bitmask for IO events.">pa_io_event_flags_t</a> f, <span class="keywordtype">void</span> *userdata) { ssize_t r; assert(a == mainloop_api); assert(e); assert(stdio_event == e); <span class="keywordflow">if</span> (!buffer) { mainloop_api-><a class="code" href="structpa__mainloop__api.html#c8372ccaf7b5291008d6f59cf40ce3aa" title="Enable or disable IO events on this object.">io_enable</a>(stdio_event, <a class="code" href="mainloop-api_8h.html#6769e3c8a68703a81a68d5d72b32d1fa458d976392190c7626b4f789bf11b2ea" title="No event.">PA_IO_EVENT_NULL</a>); <span class="keywordflow">return</span>; } assert(buffer_length); <span class="keywordflow">if</span> ((r = write(fd, (uint8_t*) buffer+buffer_index, buffer_length)) <= 0) { fprintf(stderr, _(<span class="stringliteral">"write() failed: %s\n"</span>), strerror(errno)); quit(1); mainloop_api-><a class="code" href="structpa__mainloop__api.html#3a48c4fa72ef016e5c7b8cfd011a3d7a" title="Free a IO event source object.">io_free</a>(stdio_event); stdio_event = NULL; <span class="keywordflow">return</span>; } buffer_length -= (uint32_t) r; buffer_index += (uint32_t) r; <span class="keywordflow">if</span> (!buffer_length) { <a class="code" href="xmalloc_8h.html#975c3f1d400a40ede0d5e79bb8876008" title="Free allocated memory.">pa_xfree</a>(buffer); buffer = NULL; buffer_length = buffer_index = 0; } } <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="a82"></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 signal, exiting.\n"</span>)); quit(0); } <span class="comment">/* Show the current latency */</span> <span class="keyword">static</span> <span class="keywordtype">void</span> stream_update_timing_callback(<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="a83"></a><a class="code" href="sample_8h.html#885df3b973773f0dccbbec6bc6777f89" title="Type for usec specifications (unsigned).">pa_usec_t</a> l, usec; <span class="keywordtype">int</span> negative = 0; assert(s); <span class="keywordflow">if</span> (!success || <a name="a84"></a><a class="code" href="stream_8h.html#9b1caba84c7a5c90efdbcaed31e9dfca" title="Return the current playback/recording time.">pa_stream_get_time</a>(s, &usec) < 0 || <a name="a85"></a><a class="code" href="stream_8h.html#a521efcc16fe2abf0f8461462432ac16" title="Return the total stream latency.">pa_stream_get_latency</a>(s, &l, &negative) < 0) { fprintf(stderr, _(<span class="stringliteral">"Failed to get latency: %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>(context))); quit(1); <span class="keywordflow">return</span>; } fprintf(stderr, _(<span class="stringliteral">"Time: %0.3f sec; Latency: %0.0f usec. \r"</span>), (<span class="keywordtype">float</span>) usec / 1000000, (<span class="keywordtype">float</span>) l * (negative?-1.0f:1.0f)); } <span class="comment">/* Someone requested that the latency is shown */</span> <span class="keyword">static</span> <span class="keywordtype">void</span> sigusr1_signal_callback(<a class="code" href="structpa__mainloop__api.html" title="An abstract mainloop API vtable.">pa_mainloop_api</a>*m, <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> (!stream) <span class="keywordflow">return</span>; <a class="code" href="operation_8h.html#8d2ef9bb2ff961ee31675882bf125227" title="Decrease the reference count by one.">pa_operation_unref</a>(<a name="a86"></a><a class="code" href="stream_8h.html#c8300aa5136a223b14a5384f44564284" title="Request a timing info structure update for a stream.">pa_stream_update_timing_info</a>(stream, stream_update_timing_callback, NULL)); } <span class="keyword">static</span> <span class="keywordtype">void</span> time_event_callback(<a class="code" href="structpa__mainloop__api.html" title="An abstract mainloop API vtable.">pa_mainloop_api</a>*m, <a name="a87"></a><a class="code" href="mainloop-api_8h.html#45b1a5f366caddb669789d5e69338f06" title="An opaque timer event source object.">pa_time_event</a> *e, <span class="keyword">const</span> <span class="keyword">struct</span> timeval *tv, <span class="keywordtype">void</span> *userdata) { <span class="keyword">struct </span>timeval next; <span class="keywordflow">if</span> (stream && <a class="code" href="stream_8h.html#b1da38d494d6485e35f0715f40dff0ab" title="Return the current state of the stream.">pa_stream_get_state</a>(stream) == <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>) { <a class="code" href="operation_8h.html#5614a07f2e7a129e4cb16596ed452a0c" title="An asynchronous operation object.">pa_operation</a> *o; <span class="keywordflow">if</span> (!(o = <a class="code" href="stream_8h.html#c8300aa5136a223b14a5384f44564284" title="Request a timing info structure update for a stream.">pa_stream_update_timing_info</a>(stream, stream_update_timing_callback, NULL))) fprintf(stderr, _(<span class="stringliteral">"pa_stream_update_timing_info() failed: %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>(context))); <span class="keywordflow">else</span> <a class="code" href="operation_8h.html#8d2ef9bb2ff961ee31675882bf125227" title="Decrease the reference count by one.">pa_operation_unref</a>(o); } <a name="a88"></a><a class="code" href="timeval_8h.html#6b172af60031b694582956e8b4ed6785" title="Return the current timestamp, just like UNIX gettimeofday().">pa_gettimeofday</a>(&next); <a name="a89"></a><a class="code" href="timeval_8h.html#43743ff9b5891b03b8b83091b89d0fbe" title="Add the specified time inmicroseconds to the specified timeval structure.">pa_timeval_add</a>(&next, TIME_EVENT_USEC); m-><a name="a90"></a><a class="code" href="structpa__mainloop__api.html#2e03bc11278275c4855c41eb2d54e826" title="Restart a running or expired timer event source with a new Unix time.">time_restart</a>(e, &next); } <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]\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">" -r, --record Create a connection for recording\n"</span> <span class="stringliteral">" -p, --playback Create a connection for playback\n\n"</span> <span class="stringliteral">" -v, --verbose Enable verbose operations\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/source 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">" --rate=SAMPLERATE The sample rate in Hz (defaults to 44100)\n"</span> <span class="stringliteral">" --format=SAMPLEFORMAT The sample type, one of s16le, s16be, u8, float32le,\n"</span> <span class="stringliteral">" float32be, ulaw, alaw, s32le, s32be (defaults to s16ne)\n"</span> <span class="stringliteral">" --channels=CHANNELS The number of channels, 1 for mono, 2 for stereo\n"</span> <span class="stringliteral">" (defaults to 2)\n"</span> <span class="stringliteral">" --channel-map=CHANNELMAP Channel map to use instead of the default\n"</span> <span class="stringliteral">" --fix-format Take the sample format from the sink the stream is\n"</span> <span class="stringliteral">" being connected to.\n"</span> <span class="stringliteral">" --fix-rate Take the sampling rate from the sink the stream is\n"</span> <span class="stringliteral">" being connected to.\n"</span> <span class="stringliteral">" --fix-channels Take the number of channels and the channel map\n"</span> <span class="stringliteral">" from the sink the stream is being connected to.\n"</span> <span class="stringliteral">" --no-remix Don't upmix or downmix channels.\n"</span> <span class="stringliteral">" --no-remap Map channels by index instead of name.\n"</span> <span class="stringliteral">" --latency=BYTES Request the specified latency in bytes.\n"</span> <span class="stringliteral">" --process-time=BYTES Request the specified process time per request in bytes.\n"</span>) , argv0); } <span class="keyword">enum</span> { ARG_VERSION = 256, ARG_STREAM_NAME, ARG_VOLUME, ARG_SAMPLERATE, ARG_SAMPLEFORMAT, ARG_CHANNELS, ARG_CHANNELMAP, ARG_FIX_FORMAT, ARG_FIX_RATE, ARG_FIX_CHANNELS, ARG_NO_REMAP, ARG_NO_REMIX, ARG_LATENCY, ARG_PROCESS_TIME }; <span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[]) { <a name="a91"></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; <a class="code" href="mainloop-api_8h.html#45b1a5f366caddb669789d5e69338f06" title="An opaque timer event source object.">pa_time_event</a> *time_event = NULL; <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">struct </span>option long_options[] = { {<span class="stringliteral">"record"</span>, 0, NULL, <span class="charliteral">'r'</span>}, {<span class="stringliteral">"playback"</span>, 0, NULL, <span class="charliteral">'p'</span>}, {<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">"rate"</span>, 1, NULL, ARG_SAMPLERATE}, {<span class="stringliteral">"format"</span>, 1, NULL, ARG_SAMPLEFORMAT}, {<span class="stringliteral">"channels"</span>, 1, NULL, ARG_CHANNELS}, {<span class="stringliteral">"channel-map"</span>, 1, NULL, ARG_CHANNELMAP}, {<span class="stringliteral">"fix-format"</span>, 0, NULL, ARG_FIX_FORMAT}, {<span class="stringliteral">"fix-rate"</span>, 0, NULL, ARG_FIX_RATE}, {<span class="stringliteral">"fix-channels"</span>, 0, NULL, ARG_FIX_CHANNELS}, {<span class="stringliteral">"no-remap"</span>, 0, NULL, ARG_NO_REMAP}, {<span class="stringliteral">"no-remix"</span>, 0, NULL, ARG_NO_REMIX}, {<span class="stringliteral">"latency"</span>, 1, NULL, ARG_LATENCY}, {<span class="stringliteral">"process-time"</span>, 1, NULL, ARG_PROCESS_TIME}, {NULL, 0, NULL, 0} }; setlocale(LC_ALL, <span class="stringliteral">""</span>); bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR); <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">if</span> (strstr(bn, <span class="stringliteral">"rec"</span>) || strstr(bn, <span class="stringliteral">"mon"</span>)) mode = RECORD; <span class="keywordflow">else</span> <span class="keywordflow">if</span> (strstr(bn, <span class="stringliteral">"cat"</span>) || strstr(bn, <span class="stringliteral">"play"</span>)) mode = PLAYBACK; <span class="keywordflow">while</span> ((c = getopt_long(argc, argv, <span class="stringliteral">"rpd: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">"pacat %s\nCompiled with libpulse %s\nLinked with libpulse %s\n"</span>), PACKAGE_VERSION, <a name="a92"></a><a class="code" href="version_8h.html#ebde117e52b7ee3756e82c457de5fbbf" title="Return the version of the header files.">pa_get_headers_version</a>(), <a name="a93"></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">'r'</span>: mode = RECORD; <span class="keywordflow">break</span>; <span class="keywordflow">case</span> <span class="charliteral">'p'</span>: mode = PLAYBACK; <span class="keywordflow">break</span>; <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="a94"></a><a class="code" href="xmalloc_8h.html#3ba8ba9175ee05503bcd62f7357bbc1d" 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#3ba8ba9175ee05503bcd62f7357bbc1d" 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#3ba8ba9175ee05503bcd62f7357bbc1d" 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#3ba8ba9175ee05503bcd62f7357bbc1d" 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 ? 0U : (<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>) v; volume_is_set = 1; <span class="keywordflow">break</span>; } <span class="keywordflow">case</span> ARG_CHANNELS: sample_spec.<a class="code" href="structpa__sample__spec.html#625155d20d7e50a3808b889e314d25fa" title="Audio channels.">channels</a> = (uint8_t) atoi(optarg); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> ARG_SAMPLEFORMAT: sample_spec.<a name="a95"></a><a class="code" href="structpa__sample__spec.html#6f37954f1b7ac9d9bff4683171a10a99" title="The sample format.">format</a> = <a name="a96"></a><a class="code" href="sample_8h.html#2819db448dd45edb5d777b7568dd3236" title="Parse a sample format text.">pa_parse_sample_format</a>(optarg); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> ARG_SAMPLERATE: sample_spec.<a name="a97"></a><a class="code" href="structpa__sample__spec.html#4fd5a1ef48c1cbea95a94b20a5cc02b0" title="The sample rate.">rate</a> = (uint32_t) atoi(optarg); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> ARG_CHANNELMAP: <span class="keywordflow">if</span> (!<a name="a98"></a><a class="code" href="channelmap_8h.html#66d10dda716c59960d6100c2774e6a36" title="Parse a channel position list or well-known mapping name into a channel map structure...">pa_channel_map_parse</a>(&channel_map, optarg)) { fprintf(stderr, _(<span class="stringliteral">"Invalid channel map '%s'\n"</span>), optarg); <span class="keywordflow">goto</span> quit; } channel_map_set = 1; <span class="keywordflow">break</span>; <span class="keywordflow">case</span> ARG_FIX_CHANNELS: flags |= <a name="a99"></a><a class="code" href="def_8h.html#6966d809483170bc6d2e6c16188850fc13b9fec678fd47a1907413476f7044b7" title="Use the number of channels and the channel map of the sink, and possibly ignore the...">PA_STREAM_FIX_CHANNELS</a>; <span class="keywordflow">break</span>; <span class="keywordflow">case</span> ARG_FIX_RATE: flags |= <a name="a100"></a><a class="code" href="def_8h.html#6966d809483170bc6d2e6c16188850fcb81c3687c121ad24c8c6673eca01c4d3" title="Use the sample rate of the sink, and possibly ignore the rate the sample spec contains...">PA_STREAM_FIX_RATE</a>; <span class="keywordflow">break</span>; <span class="keywordflow">case</span> ARG_FIX_FORMAT: flags |= <a name="a101"></a><a class="code" href="def_8h.html#6966d809483170bc6d2e6c16188850fc8b06af81681e54d33ea334684ab4e37e" title="Use the sample format of the sink/device this stream is being connected to, and possibly...">PA_STREAM_FIX_FORMAT</a>; <span class="keywordflow">break</span>; <span class="keywordflow">case</span> ARG_NO_REMIX: flags |= <a name="a102"></a><a class="code" href="def_8h.html#6966d809483170bc6d2e6c16188850fc58d440b2e196c639cb7c578324b3a5fd" title="When remapping channels by name, don&#39;t upmix or downmix them to related channels...">PA_STREAM_NO_REMIX_CHANNELS</a>; <span class="keywordflow">break</span>; <span class="keywordflow">case</span> ARG_NO_REMAP: flags |= <a name="a103"></a><a class="code" href="def_8h.html#6966d809483170bc6d2e6c16188850fcaf217b8d4ed327de0acaeceff49341c2" title="Don&#39;t remap channels by their name, instead map them simply by their index.">PA_STREAM_NO_REMAP_CHANNELS</a>; <span class="keywordflow">break</span>; <span class="keywordflow">case</span> ARG_LATENCY: <span class="keywordflow">if</span> (((latency = (<span class="keywordtype">size_t</span>) atoi(optarg))) <= 0) { fprintf(stderr, _(<span class="stringliteral">"Invalid latency specification '%s'\n"</span>), optarg); <span class="keywordflow">goto</span> quit; } <span class="keywordflow">break</span>; <span class="keywordflow">case</span> ARG_PROCESS_TIME: <span class="keywordflow">if</span> (((process_time = (<span class="keywordtype">size_t</span>) atoi(optarg))) <= 0) { fprintf(stderr, _(<span class="stringliteral">"Invalid process time specification '%s'\n"</span>), optarg); <span class="keywordflow">goto</span> quit; } <span class="keywordflow">break</span>; <span class="keywordflow">default</span>: <span class="keywordflow">goto</span> quit; } } <span class="keywordflow">if</span> (!<a name="a104"></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)) { fprintf(stderr, _(<span class="stringliteral">"Invalid sample specification\n"</span>)); <span class="keywordflow">goto</span> quit; } <span class="keywordflow">if</span> (channel_map_set && <a name="a105"></a><a class="code" href="channelmap_8h.html#2bfd3d5ff3752b7ef6481cc18f4005fd" title="Return non-zero if the specified channel map is compatible with the specified sample...">pa_channel_map_compatible</a>(&channel_map, &sample_spec)) { fprintf(stderr, _(<span class="stringliteral">"Channel map doesn't match sample specification\n"</span>)); <span class="keywordflow">goto</span> quit; } <span class="keywordflow">if</span> (verbose) { <span class="keywordtype">char</span> t[<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 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">"Opening a %s stream with sample specification '%s'.\n"</span>), mode == RECORD ? _(<span class="stringliteral">"recording"</span>) : _(<span class="stringliteral">"playback"</span>), t); } <span class="keywordflow">if</span> (!(optind >= argc)) { <span class="keywordflow">if</span> (optind+1 == argc) { <span class="keywordtype">int</span> fd; <span class="keywordflow">if</span> ((fd = open(argv[optind], mode == PLAYBACK ? O_RDONLY : O_WRONLY|O_TRUNC|O_CREAT, 0666)) < 0) { fprintf(stderr, _(<span class="stringliteral">"open(): %s\n"</span>), strerror(errno)); <span class="keywordflow">goto</span> quit; } <span class="keywordflow">if</span> (dup2(fd, mode == PLAYBACK ? 0 : 1) < 0) { fprintf(stderr, _(<span class="stringliteral">"dup2(): %s\n"</span>), strerror(errno)); <span class="keywordflow">goto</span> quit; } close(fd); <span class="keywordflow">if</span> (!stream_name) stream_name = <a class="code" href="xmalloc_8h.html#3ba8ba9175ee05503bcd62f7357bbc1d" title="Duplicate the specified string, allocating memory with pa_xmalloc().">pa_xstrdup</a>(argv[optind]); } <span class="keywordflow">else</span> { fprintf(stderr, _(<span class="stringliteral">"Too many arguments.\n"</span>)); <span class="keywordflow">goto</span> quit; } } <span class="keywordflow">if</span> (!client_name) client_name = <a class="code" href="xmalloc_8h.html#3ba8ba9175ee05503bcd62f7357bbc1d" title="Duplicate the specified string, allocating memory with pa_xmalloc().">pa_xstrdup</a>(bn); <span class="keywordflow">if</span> (!stream_name) stream_name = <a class="code" href="xmalloc_8h.html#3ba8ba9175ee05503bcd62f7357bbc1d" title="Duplicate the specified string, allocating memory with pa_xmalloc().">pa_xstrdup</a>(client_name); <span class="comment">/* Set up a new main loop */</span> <span class="keywordflow">if</span> (!(m = <a name="a106"></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="a107"></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="a108"></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="a109"></a><a class="code" href="mainloop-signal_8h.html#c1648b4c7046eea5809e21838b604d12" title="Create a new UNIX signal event source object.">pa_signal_new</a>(SIGINT, exit_signal_callback, NULL); <a class="code" href="mainloop-signal_8h.html#c1648b4c7046eea5809e21838b604d12" title="Create a new UNIX signal event source object.">pa_signal_new</a>(SIGTERM, exit_signal_callback, NULL); <span class="preprocessor">#ifdef SIGUSR1</span> <span class="preprocessor"></span> <a class="code" href="mainloop-signal_8h.html#c1648b4c7046eea5809e21838b604d12" title="Create a new UNIX signal event source object.">pa_signal_new</a>(SIGUSR1, sigusr1_signal_callback, NULL); <span class="preprocessor">#endif</span> <span class="preprocessor"></span><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="keywordflow">if</span> (!(stdio_event = mainloop_api-><a name="a110"></a><a class="code" href="structpa__mainloop__api.html#caf8e4e2a317106ec5cda25dc82c3225" title="Create a new IO event source object.">io_new</a>(mainloop_api, mode == PLAYBACK ? STDIN_FILENO : STDOUT_FILENO, mode == PLAYBACK ? <a class="code" href="mainloop-api_8h.html#6769e3c8a68703a81a68d5d72b32d1faba9fbd1e6cb3031098a2aaa144c78336" title="Input event.">PA_IO_EVENT_INPUT</a> : <a class="code" href="mainloop-api_8h.html#6769e3c8a68703a81a68d5d72b32d1fa3aff35dad0cd23ae3796b3141fee4dce" title="Output event.">PA_IO_EVENT_OUTPUT</a>, mode == PLAYBACK ? stdin_callback : stdout_callback, NULL))) { fprintf(stderr, _(<span class="stringliteral">"io_new() failed.\n"</span>)); <span class="keywordflow">goto</span> quit; } <span class="comment">/* Create a new connection context */</span> <span class="keywordflow">if</span> (!(context = <a name="a111"></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="a112"></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> <span class="keywordflow">if</span> (<a name="a113"></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) < 0) { fprintf(stderr, _(<span class="stringliteral">"pa_context_connect() failed: %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>(context))); <span class="keywordflow">goto</span> quit; } <span class="keywordflow">if</span> (verbose) { <span class="keyword">struct </span>timeval tv; <a class="code" href="timeval_8h.html#6b172af60031b694582956e8b4ed6785" title="Return the current timestamp, just like UNIX gettimeofday().">pa_gettimeofday</a>(&tv); <a class="code" href="timeval_8h.html#43743ff9b5891b03b8b83091b89d0fbe" title="Add the specified time inmicroseconds to the specified timeval structure.">pa_timeval_add</a>(&tv, TIME_EVENT_USEC); <span class="keywordflow">if</span> (!(time_event = mainloop_api-><a name="a114"></a><a class="code" href="structpa__mainloop__api.html#6bb22d8fd9eb1e04c9e47ac65806bbc5" title="Create a new timer event source object for the specified Unix time.">time_new</a>(mainloop_api, &tv, time_event_callback, NULL))) { fprintf(stderr, _(<span class="stringliteral">"time_new() failed.\n"</span>)); <span class="keywordflow">goto</span> quit; } } <span class="comment">/* Run the main loop */</span> <span class="keywordflow">if</span> (<a name="a115"></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="a116"></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> (stdio_event) { assert(mainloop_api); mainloop_api-><a class="code" href="structpa__mainloop__api.html#3a48c4fa72ef016e5c7b8cfd011a3d7a" title="Free a IO event source object.">io_free</a>(stdio_event); } <span class="keywordflow">if</span> (time_event) { assert(mainloop_api); mainloop_api-><a name="a117"></a><a class="code" href="structpa__mainloop__api.html#da2de717320b502a8fce1e30228aa1d5" title="Free a deferred timer event source object.">time_free</a>(time_event); } <span class="keywordflow">if</span> (m) { <a name="a118"></a><a class="code" href="mainloop-signal_8h.html#e75dbfe9876a5482a5c644bac5abf479" title="Cleanup the signal subsystem.">pa_signal_done</a>(); <a name="a119"></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>(buffer); <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">return</span> ret; } </pre></div> </div> <hr size="1"><address style="text-align: right;"><small>Generated on Wed Sep 2 04:18:19 2009 for PulseAudio by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.8 </small></address> </body> </html>