[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