Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Using ALSA directly is overly complicated, so I hope a Gstreamer solution is fine to you too. Gstreamer gives a nice abstraction to ALSA/OSS/Pulseaudio/you name it -- and is ubiquitous in the Linux world.</p> <p>I wrote a little library that will open a <code>FILE</code> object where you can fwrite PCM data into: <strong><a href="https://github.com/Kijewski/gstreamer_file" rel="nofollow">Gstreamer file</a></strong>. The actual code is less than 100 lines.</p> <p>Use use it like that:</p> <pre><code>FILE *output = fopen_gst(rate, channels, bit_depth); // open audio output file while (have_more_data) fwrite(data, amount, 1, output); // output audio data fclose(output); // close the output file </code></pre> <p>I added an <a href="https://github.com/Kijewski/gstreamer_file/blob/master/mpg123_example.c" rel="nofollow">mpg123 example</a>, too.</p> <p>Here is the whole file (in case Github get's out of business ;-) ):</p> <pre><code>/** * gstreamer_file.c * Copyright 2012 René Kijewski &lt;rene.SURNAME@fu-berlin.de&gt; * License: LGPL 3.0 (http://www.gnu.org/licenses/lgpl-3.0) */ #include "gstreamer_file.h" #include &lt;stdbool.h&gt; #include &lt;stdlib.h&gt; #include &lt;unistd.h&gt; #include &lt;glib.h&gt; #include &lt;gst/gst.h&gt; #ifndef _GNU_SOURCE # error "You need to add -D_GNU_SOURCE to the GCC parameters!" #endif /** * Cookie passed to the callbacks. */ typedef struct { /** { file descriptor to read from, fd to write to } */ int pipefd[2]; /** Gstreamer pipeline */ GstElement *pipeline; } cookie_t; static ssize_t write_gst(void *cookie_, const char *buf, size_t size) { cookie_t *cookie = cookie_; return write(cookie-&gt;pipefd[1], buf, size); } static int close_gst(void *cookie_) { cookie_t *cookie = cookie_; gst_element_set_state(cookie-&gt;pipeline, GST_STATE_NULL); /* we are finished */ gst_object_unref(GST_OBJECT(cookie-&gt;pipeline)); /* we won't access the pipeline anymore */ close(cookie-&gt;pipefd[0]); /* we won't write anymore */ close(cookie-&gt;pipefd[1]); /* we won't read anymore */ free(cookie); /* dispose the cookie */ return 0; } FILE *fopen_gst(long rate, int channels, int depth) { /* initialize Gstreamer */ if (!gst_is_initialized()) { GError *error; if (!gst_init_check(NULL, NULL, &amp;error)) { g_error_free(error); return NULL; } } /* get a cookie */ cookie_t *cookie = malloc(sizeof(*cookie)); if (!cookie) { return NULL; } /* open a pipe to be used between the caller and the Gstreamer pipeline */ if (pipe(cookie-&gt;pipefd) != 0) { close(cookie-&gt;pipefd[0]); close(cookie-&gt;pipefd[1]); free(cookie); return NULL; } /* set up the pipeline */ char description[256]; snprintf(description, sizeof(description), "fdsrc fd=%d ! " /* read from a file descriptor */ "audio/x-raw-int, rate=%ld, channels=%d, " /* get PCM data */ "endianness=1234, width=%d, depth=%d, signed=true ! " "audioconvert ! audioresample ! " /* convert/resample if needed */ "autoaudiosink", /* output to speakers (using ALSA, OSS, Pulseaudio ...) */ cookie-&gt;pipefd[0], rate, channels, depth, depth); cookie-&gt;pipeline = gst_parse_launch_full(description, NULL, GST_PARSE_FLAG_FATAL_ERRORS, NULL); if (!cookie-&gt;pipeline) { close(cookie-&gt;pipefd[0]); close(cookie-&gt;pipefd[1]); free(cookie); return NULL; } /* open a FILE with specialized write and close functions */ cookie_io_functions_t io_funcs = { NULL, write_gst, NULL, close_gst }; FILE *result = fopencookie(cookie, "w", io_funcs); if (!result) { close_gst(cookie); return NULL; } /* start the pipeline (of cause it will wait for some data first) */ gst_element_set_state(cookie-&gt;pipeline, GST_STATE_PLAYING); return result; } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload