diff --git a/modules/LIST b/modules/LIST index 05e8f28fc0b7328bb3be62b1929f3f87e8a40fc6..ede35c0a34b0cf0a48c6cd00a25f29f2bb448d29 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 561f211a0a293e63b9f220c135f81e761b9aeec5..804021cc449298d8ead5dc6c935b28307afab661 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 0000000000000000000000000000000000000000..7e5122c1f3f1ad3543a18f2b14cc58ffb04214aa --- /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 e35d8108ae99536c4d0692b990abc6f7ec2610cd..cd1a7e1db9fc5ffea620a46c2f02f3707c34d4ce 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