Sophie

Sophie

distrib > Mandriva > 2009.1 > x86_64 > media > main-testing > by-pkgid > 187676b5433787923dfa2cdd6900c6cd > files > 135

lib64pulseaudio-devel-0.9.15-2.0.7mdv2009.1.x86_64.rpm

<!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&nbsp;Page</span></a></li>
      <li><a href="pages.html"><span>Related&nbsp;Pages</span></a></li>
      <li><a href="annotated.html"><span>Data&nbsp;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 &lt;ossman@cendio.se&gt; 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 &lt;config.h&gt;</span>
<span class="preprocessor">#endif</span>
<span class="preprocessor"></span>
<span class="preprocessor">#include &lt;signal.h&gt;</span>
<span class="preprocessor">#include &lt;string.h&gt;</span>
<span class="preprocessor">#include &lt;errno.h&gt;</span>
<span class="preprocessor">#include &lt;unistd.h&gt;</span>
<span class="preprocessor">#include &lt;assert.h&gt;</span>
<span class="preprocessor">#include &lt;stdio.h&gt;</span>
<span class="preprocessor">#include &lt;stdlib.h&gt;</span>
<span class="preprocessor">#include &lt;getopt.h&gt;</span>
<span class="preprocessor">#include &lt;fcntl.h&gt;</span>
<span class="preprocessor">#include &lt;locale.h&gt;</span>

<span class="preprocessor">#include &lt;pulse/i18n.h&gt;</span>
<span class="preprocessor">#include &lt;<a class="code" href="pulseaudio_8h.html" title="Include all libpulse header files at once.">pulse/pulseaudio.h</a>&gt;</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; &amp;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-&gt;<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 &gt; 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>) &lt; 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 &gt; 0);

    <span class="keywordflow">if</span> (stdio_event)
        mainloop_api-&gt;<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 &gt; 0);

    <span class="keywordflow">if</span> (stdio_event)
        mainloop_api-&gt;<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, &amp;data, &amp;length) &lt; 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 &gt; 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-&gt;<a name="a32"></a><a class="code" href="structpa__buffer__attr.html#bef20d3a6cab53f716846125353e56a4" title="Maximum length of the buffer.">maxlength</a>, a-&gt;<a name="a33"></a><a class="code" href="structpa__buffer__attr.html#a7e8f3348cbda863b6f1dd55a9024b7a" title="Playback only: target length of the buffer.">tlength</a>, a-&gt;<a name="a34"></a><a class="code" href="structpa__buffer__attr.html#cdbe30979a50075479ee46c56cc724ee" title="Playback only: pre-buffering.">prebuf</a>, a-&gt;<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-&gt;<a class="code" href="structpa__buffer__attr.html#bef20d3a6cab53f716846125353e56a4" title="Maximum length of the buffer.">maxlength</a>, a-&gt;<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&amp;#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&amp;#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, &amp;sample_spec, channel_map_set ? &amp;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 &gt; 0) {
                memset(&amp;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 &gt; 0 ? &amp;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>(&amp;cv, sample_spec.<a name="a67"></a><a class="code" href="structpa__sample__spec.html#625155d20d7e50a3808b889e314d25fa" title="Audio channels.">channels</a>, volume) : NULL, NULL)) &lt; 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 &gt; 0 ? &amp;buffer_attr : NULL, flags)) &lt; 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-&gt;<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)) &lt;= 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-&gt;<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-&gt;<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)) &lt;= 0) {
        fprintf(stderr, _(<span class="stringliteral">"write() failed: %s\n"</span>), strerror(errno));
        quit(1);

        mainloop_api-&gt;<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, &amp;usec) &lt; 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, &amp;l, &amp;negative) &lt; 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 &amp;&amp; <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>(&amp;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>(&amp;next, TIME_EVENT_USEC);

    m-&gt;<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, &amp;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 &lt; 0 ? 0U : (<a class="code" href="volume_8h.html#6d671c65284ff2e94d3773c7368a0352" title="Volume specification: PA_VOLUME_MUTED: silence; &amp;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>(&amp;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&amp;#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&amp;#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))) &lt;= 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))) &lt;= 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>(&amp;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 &amp;&amp; <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>(&amp;channel_map, &amp;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), &amp;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 &gt;= 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)) &lt; 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) &lt; 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-&gt;<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) &lt; 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>(&amp;tv);
        <a class="code" href="timeval_8h.html#43743ff9b5891b03b8b83091b89d0fbe" title="Add the specified time inmicroseconds to the specified timeval structure.">pa_timeval_add</a>(&amp;tv, TIME_EVENT_USEC);

        <span class="keywordflow">if</span> (!(time_event = mainloop_api-&gt;<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, &amp;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&amp;#39;s quit()...">pa_mainloop_run</a>(m, &amp;ret) &lt; 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-&gt;<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-&gt;<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&nbsp;
<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>