[vlc-commits] Add virtual audio output plugin

Rémi Denis-Courmont git at videolan.org
Tue May 10 20:06:54 CEST 2011


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Tue May 10 20:54:23 2011 +0300| [283ee7daf8466bc21aa590c5fc3059c31c06d0e0] | committer: Rémi Denis-Courmont

Add virtual audio output plugin

Currently channels cannot be remapped and samples format must be S16N.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=283ee7daf8466bc21aa590c5fc3059c31c06d0e0
---

 modules/LIST                    |    1 +
 modules/audio_output/Modules.am |    9 ++-
 modules/audio_output/amem.c     |  154 +++++++++++++++++++++++++++++++++++++++
 po/POTFILES.in                  |    1 +
 4 files changed, 164 insertions(+), 1 deletions(-)

diff --git a/modules/LIST b/modules/LIST
index 05e8f28..ede35c0 100644
--- a/modules/LIST
+++ b/modules/LIST
@@ -41,6 +41,7 @@ $Id$
  * aiff: AIFF demuxer
  * alphamask: Alpha layer mask video filter
  * alsa: audio output module using the ALSA API
+ * amem: audio memory output
  * aout_directx: audio output module using the DirectX API
  * aout_file: Audio output to write to a file
  * aout_sdl: audio output module using the SDL library
diff --git a/modules/audio_output/Modules.am b/modules/audio_output/Modules.am
index 561f211..804021c 100644
--- a/modules/audio_output/Modules.am
+++ b/modules/audio_output/Modules.am
@@ -7,7 +7,14 @@ SOURCES_auhal = auhal.c
 SOURCES_jack = jack.c
 SOURCES_audioqueue = audioqueue.c
 
-libvlc_LTLIBRARIES += libaout_file_plugin.la
+libamem_plugin_la_SOURCES = amem.c
+libamem_plugin_la_CFLAGS = $(AM_CFLAGS)
+libamem_plugin_la_LIBADD = $(AM_LIBADD)
+libamem_plugin_la_DEPENDENCIES =
+
+libvlc_LTLIBRARIES += \
+	libamem_plugin.la \
+	libaout_file_plugin.la
 
 liboss_plugin_la_SOURCES = oss.c
 liboss_plugin_la_LIBADD = $(AM_LIBADD) $(OSS_LIBS)
diff --git a/modules/audio_output/amem.c b/modules/audio_output/amem.c
new file mode 100644
index 0000000..7e5122c
--- /dev/null
+++ b/modules/audio_output/amem.c
@@ -0,0 +1,154 @@
+/*****************************************************************************
+ * amem.c : virtual LibVLC audio output plugin
+ *****************************************************************************
+ * Copyright (C) 2011 Rémi Denis-Courmont
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_aout.h>
+
+static int Open (vlc_object_t *);
+static void Close (vlc_object_t *);
+
+vlc_module_begin ()
+    set_shortname (N_("Audio memory"))
+    set_description (N_("Audio memory output"))
+    set_capability ("audio output", 0)
+    set_category (CAT_AUDIO)
+    set_subcategory (SUBCAT_AUDIO_AOUT)
+    set_callbacks (Open, Close)
+
+    add_string ("amem-format", "S16N",
+                N_("Sample format"), N_("Sample format"), false)
+        change_private()
+    add_integer ("amem-rate", 44100,
+                 N_("Sample rate"), N_("Sample rate"), false)
+        change_integer_range (1, 192000)
+        change_private()
+    add_integer ("amem-channels", 2,
+                 N_("Channels count"), N_("Channels count"), false)
+        change_integer_range (1, AOUT_CHAN_MAX)
+        change_private()
+
+vlc_module_end ()
+
+struct aout_sys_t
+{
+    void *opaque;
+    void (*play) (void *opaque, const void *data, size_t count, int64_t pts);
+    int (*set_volume) (void *opaque, float vol, bool mute);
+    void (*cleanup) (void *opaque);
+};
+
+static void Play (aout_instance_t *aout)
+{
+    aout_sys_t *sys = aout->output.p_sys;
+    block_t *block;
+
+    while ((block = aout_FifoPop(aout, &aout->output.fifo)) != NULL)
+    {
+        sys->play (sys->opaque, block->p_buffer, block->i_nb_samples,
+                   block->i_pts);
+        block_Release (block);
+    }
+}
+
+static int VolumeSet (aout_instance_t *aout, audio_volume_t ivol, bool mute)
+{
+    aout_sys_t *sys = aout->output.p_sys;
+    float fvol = ivol / (float)AOUT_VOLUME_DEFAULT;
+
+    return sys->set_volume (sys->opaque, fvol, mute) ? -1 : 0;
+}
+
+typedef int (*vlc_audio_format_cb) (void **, char *, unsigned *, unsigned *);
+
+static int Open (vlc_object_t *obj)
+{
+    aout_instance_t *aout = (aout_instance_t *)obj;
+    aout_sys_t *sys = malloc (sizeof (*sys));
+    if (unlikely(sys == NULL))
+        return VLC_ENOMEM;
+
+    aout->output.p_sys = sys;
+    sys->opaque = var_InheritAddress (obj, "amem-data");
+    sys->play = var_InheritAddress (obj, "amem-play");
+    sys->set_volume = var_InheritAddress (obj, "amem-set-volume");
+    sys->cleanup = NULL; /* defer */
+    if (sys->play == NULL)
+        goto error;
+
+    vlc_audio_format_cb setup = var_InheritAddress (obj, "amem-setup");
+    char format[5] = "S16N";
+    unsigned rate, channels;
+
+    if (setup != NULL)
+    {
+        rate = aout->output.output.i_rate;
+        channels = aout_FormatNbChannels(&aout->output.output);
+
+        if (setup (&sys->opaque, format, &rate, &channels))
+            goto error;
+        /* Only call this callback if setup succeeded */ 
+        sys->cleanup = var_InheritAddress (obj, "amem-cleanup");
+    }
+    else
+    {
+        rate = var_InheritInteger (obj, "amem-rate");
+        channels = var_InheritInteger (obj, "amem-channels");
+    }
+
+    if (rate == 0 || rate > 192000
+     || channels == 0 || channels > AOUT_CHAN_MAX)
+        goto error;
+
+    /* TODO: amem-format */
+    /* FIXME/TODO channel mapping */
+    if (strcmp(format, "S16N") || aout->output.output.i_channels != channels)
+    {
+        msg_Err (aout, "format not supported");
+        goto error;
+    }
+    aout->output.output.i_format = VLC_CODEC_S16N;
+    aout->output.output.i_rate = rate;
+
+    aout->output.pf_play = Play;
+    if (sys->set_volume != NULL)
+        aout->output.pf_volume_set = VolumeSet;
+    else
+        aout_VolumeSoftInit (aout);
+    return VLC_SUCCESS;
+
+error:
+    Close (obj);
+    return VLC_EGENERIC;
+}
+
+static void Close (vlc_object_t *obj)
+{
+    aout_instance_t *aout = (aout_instance_t *)obj;
+    aout_sys_t *sys = aout->output.p_sys;
+
+    if (sys->cleanup != NULL)
+        sys->cleanup (sys->opaque);
+    free (sys);
+}
diff --git a/po/POTFILES.in b/po/POTFILES.in
index e35d810..cd1a7e1 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -316,6 +316,7 @@ modules/audio_mixer/float32.c
 modules/audio_mixer/spdif.c
 modules/audio_mixer/trivial.c
 modules/audio_output/alsa.c
+modules/audio_output/amem.c
 modules/audio_output/audioqueue.c
 modules/audio_output/auhal.c
 modules/audio_output/directx.c



More information about the vlc-commits mailing list