1 /*****************************************************************************
2 * amem.c : virtual LibVLC audio output plugin
3 *****************************************************************************
4 * Copyright (C) 2011 RĂ©mi Denis-Courmont
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
25 #include <vlc_common.h>
26 #include <vlc_plugin.h>
30 static int Open (vlc_object_t *);
31 static void Close (vlc_object_t *);
34 set_shortname (N_("Audio memory"))
35 set_description (N_("Audio memory output"))
36 set_capability ("audio output", 0)
37 set_category (CAT_AUDIO)
38 set_subcategory (SUBCAT_AUDIO_AOUT)
39 set_callbacks (Open, Close)
41 add_string ("amem-format", "S16N",
42 N_("Sample format"), N_("Sample format"), false)
44 add_integer ("amem-rate", 44100,
45 N_("Sample rate"), N_("Sample rate"), false)
46 change_integer_range (1, 352800)
48 add_integer ("amem-channels", 2,
49 N_("Channels count"), N_("Channels count"), false)
50 change_integer_range (1, AOUT_CHAN_MAX)
58 int (*setup) (void **, char *, unsigned *, unsigned *);
59 void (*cleanup) (void *opaque);
72 void (*play) (void *opaque, const void *data, unsigned count, int64_t pts);
73 void (*pause) (void *opaque, int64_t pts);
74 void (*resume) (void *opaque, int64_t pts);
75 void (*flush) (void *opaque);
76 void (*drain) (void *opaque);
77 int (*set_volume) (void *opaque, float vol, bool mute);
83 static void Play (audio_output_t *aout, block_t *block)
85 aout_sys_t *sys = aout->sys;
87 sys->play (sys->opaque, block->p_buffer, block->i_nb_samples,
89 block_Release (block);
92 static void Pause (audio_output_t *aout, bool paused, mtime_t date)
94 aout_sys_t *sys = aout->sys;
95 void (*cb) (void *, int64_t) = paused ? sys->pause : sys->resume;
98 cb (sys->opaque, date);
101 static void Flush (audio_output_t *aout, bool wait)
103 aout_sys_t *sys = aout->sys;
104 void (*cb) (void *) = wait ? sys->drain : sys->flush;
110 static int VolumeSet (audio_output_t *aout, float vol)
112 aout_sys_t *sys = aout->sys;
116 return 0; /* sys->opaque is not yet defined... */
117 return sys->set_volume (sys->opaque, vol, sys->mute) ? -1 : 0;
120 static int MuteSet (audio_output_t *aout, bool mute)
122 aout_sys_t *sys = aout->sys;
126 return 0; /* sys->opaque is not yet defined... */
127 return sys->set_volume (sys->opaque, sys->volume, mute) ? -1 : 0;
130 static int SoftVolumeSet (audio_output_t *aout, float vol)
132 aout_sys_t *sys = aout->sys;
134 vol = vol * vol * vol;
135 if (!sys->mute && aout_GainRequest (aout, vol))
141 static int SoftMuteSet (audio_output_t *aout, bool mute)
143 aout_sys_t *sys = aout->sys;
145 if (aout_GainRequest (aout, mute ? 0.f : sys->volume))
151 static void Stop (audio_output_t *aout)
153 aout_sys_t *sys = aout->sys;
155 if (sys->cleanup != NULL)
156 sys->cleanup (sys->opaque);
160 static int Start (audio_output_t *aout, audio_sample_format_t *fmt)
162 aout_sys_t *sys = aout->sys;
163 char format[5] = "S16N";
166 if (sys->setup != NULL)
168 channels = aout_FormatNbChannels(fmt);
170 sys->opaque = sys->setup_opaque;
171 if (sys->setup (&sys->opaque, format, &fmt->i_rate, &channels))
176 fmt->i_rate = sys->rate;
177 channels = sys->channels;
180 /* Initialize volume (in case the UI changed volume before setup) */
182 if (sys->set_volume != NULL)
183 sys->set_volume(sys->opaque, sys->volume, sys->mute);
185 /* Ensure that format is supported */
186 if (fmt->i_rate == 0 || fmt->i_rate > 192000
187 || channels == 0 || channels > AOUT_CHAN_MAX
188 || strcmp(format, "S16N") /* TODO: amem-format */)
190 msg_Err (aout, "format not supported: %s, %u channel(s), %u Hz",
191 format, channels, fmt->i_rate);
196 /* channel mapping */
200 fmt->i_physical_channels = AOUT_CHAN_CENTER;
203 fmt->i_physical_channels = AOUT_CHANS_2_0;
206 fmt->i_physical_channels = AOUT_CHANS_2_1;
209 fmt->i_physical_channels = AOUT_CHANS_4_0;
212 fmt->i_physical_channels = AOUT_CHANS_5_0;
215 fmt->i_physical_channels = AOUT_CHANS_5_1;
218 fmt->i_physical_channels =
219 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
220 AOUT_CHAN_REARCENTER | AOUT_CHAN_MIDDLELEFT |
221 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE;
224 fmt->i_physical_channels = AOUT_CHANS_7_1;
230 fmt->i_format = VLC_CODEC_S16N;
231 fmt->i_original_channels = fmt->i_physical_channels;
235 static int Open (vlc_object_t *obj)
237 audio_output_t *aout = (audio_output_t *)obj;
238 aout_sys_t *sys = malloc (sizeof (*sys));
239 if (unlikely(sys == NULL))
242 void *opaque = var_InheritAddress (obj, "amem-data");
243 sys->setup = var_InheritAddress (obj, "amem-setup");
244 if (sys->setup != NULL)
246 sys->cleanup = var_InheritAddress (obj, "amem-cleanup");
247 sys->setup_opaque = opaque;
252 sys->opaque = opaque;
253 sys->rate = var_InheritInteger (obj, "amem-rate");
254 sys->channels = var_InheritInteger (obj, "amem-channels");
256 sys->play = var_InheritAddress (obj, "amem-play");
257 sys->pause = var_InheritAddress (obj, "amem-pause");
258 sys->resume = var_InheritAddress (obj, "amem-resume");
259 sys->flush = var_InheritAddress (obj, "amem-flush");
260 sys->drain = var_InheritAddress (obj, "amem-drain");
261 sys->set_volume = var_InheritAddress (obj, "amem-set-volume");
265 if (sys->play == NULL)
274 aout->time_get = NULL;
278 if (sys->set_volume != NULL)
280 aout->volume_set = VolumeSet;
281 aout->mute_set = MuteSet;
285 aout->volume_set = SoftVolumeSet;
286 aout->mute_set = SoftMuteSet;
291 static void Close (vlc_object_t *obj)
293 audio_output_t *aout = (audio_output_t *)obj;
294 aout_sys_t *sys = aout->sys;