]> git.sesse.net Git - vlc/commitdiff
Add virtual audio output plugin
authorRémi Denis-Courmont <remi@remlab.net>
Tue, 10 May 2011 17:54:23 +0000 (20:54 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Tue, 10 May 2011 18:06:36 +0000 (21:06 +0300)
Currently channels cannot be remapped and samples format must be S16N.

modules/LIST
modules/audio_output/Modules.am
modules/audio_output/amem.c [new file with mode: 0644]
po/POTFILES.in

index 05e8f28fc0b7328bb3be62b1929f3f87e8a40fc6..ede35c0a34b0cf0a48c6cd00a25f29f2bb448d29 100644 (file)
@@ -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
index 561f211a0a293e63b9f220c135f81e761b9aeec5..804021cc449298d8ead5dc6c935b28307afab661 100644 (file)
@@ -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 (file)
index 0000000..7e5122c
--- /dev/null
@@ -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);
+}
index e35d8108ae99536c4d0692b990abc6f7ec2610cd..cd1a7e1db9fc5ffea620a46c2f02f3707c34d4ce 100644 (file)
@@ -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