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 (aout_FormatNbChannels(fmt
) == 0)
169 if (sys
->setup
!= NULL
)
171 channels
= aout_FormatNbChannels(fmt
);
173 sys
->opaque
= sys
->setup_opaque
;
174 if (sys
->setup (&sys
->opaque
, format
, &fmt
->i_rate
, &channels
))
179 fmt
->i_rate
= sys
->rate
;
180 channels
= sys
->channels
;
183 /* Initialize volume (in case the UI changed volume before setup) */
185 if (sys
->set_volume
!= NULL
)
186 sys
->set_volume(sys
->opaque
, sys
->volume
, sys
->mute
);
188 /* Ensure that format is supported */
189 if (fmt
->i_rate
== 0 || fmt
->i_rate
> 192000
190 || channels
== 0 || channels
> AOUT_CHAN_MAX
191 || strcmp(format
, "S16N") /* TODO: amem-format */)
193 msg_Err (aout
, "format not supported: %s, %u channel(s), %u Hz",
194 format
, channels
, fmt
->i_rate
);
199 /* channel mapping */
203 fmt
->i_physical_channels
= AOUT_CHAN_CENTER
;
206 fmt
->i_physical_channels
= AOUT_CHANS_2_0
;
209 fmt
->i_physical_channels
= AOUT_CHANS_2_1
;
212 fmt
->i_physical_channels
= AOUT_CHANS_4_0
;
215 fmt
->i_physical_channels
= AOUT_CHANS_5_0
;
218 fmt
->i_physical_channels
= AOUT_CHANS_5_1
;
221 fmt
->i_physical_channels
=
222 AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
|
223 AOUT_CHAN_REARCENTER
| AOUT_CHAN_MIDDLELEFT
|
224 AOUT_CHAN_MIDDLERIGHT
| AOUT_CHAN_LFE
;
227 fmt
->i_physical_channels
= AOUT_CHANS_7_1
;
230 vlc_assert_unreachable();
233 fmt
->i_format
= VLC_CODEC_S16N
;
234 fmt
->channel_type
= AUDIO_CHANNEL_TYPE_BITMAP
;
238 static int Open (vlc_object_t
*obj
)
240 audio_output_t
*aout
= (audio_output_t
*)obj
;
241 aout_sys_t
*sys
= malloc (sizeof (*sys
));
242 if (unlikely(sys
== NULL
))
245 void *opaque
= var_InheritAddress (obj
, "amem-data");
246 sys
->setup
= var_InheritAddress (obj
, "amem-setup");
247 if (sys
->setup
!= NULL
)
249 sys
->cleanup
= var_InheritAddress (obj
, "amem-cleanup");
250 sys
->setup_opaque
= opaque
;
255 sys
->opaque
= opaque
;
256 sys
->rate
= var_InheritInteger (obj
, "amem-rate");
257 sys
->channels
= var_InheritInteger (obj
, "amem-channels");
259 sys
->play
= var_InheritAddress (obj
, "amem-play");
260 sys
->pause
= var_InheritAddress (obj
, "amem-pause");
261 sys
->resume
= var_InheritAddress (obj
, "amem-resume");
262 sys
->flush
= var_InheritAddress (obj
, "amem-flush");
263 sys
->drain
= var_InheritAddress (obj
, "amem-drain");
264 sys
->set_volume
= var_InheritAddress (obj
, "amem-set-volume");
268 if (sys
->play
== NULL
)
277 aout
->time_get
= NULL
;
281 if (sys
->set_volume
!= NULL
)
283 aout
->volume_set
= VolumeSet
;
284 aout
->mute_set
= MuteSet
;
288 aout
->volume_set
= SoftVolumeSet
;
289 aout
->mute_set
= SoftMuteSet
;
294 static void Close (vlc_object_t
*obj
)
296 audio_output_t
*aout
= (audio_output_t
*)obj
;
297 aout_sys_t
*sys
= aout
->sys
;