1 /*****************************************************************************
2 * intf.c : audio output API towards the interface modules
3 *****************************************************************************
4 * Copyright (C) 2002-2007 VLC authors and VideoLAN
7 * Authors: Christophe Massiot <massiot@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_aout_intf.h>
36 #include <stdlib.h> /* calloc(), malloc(), free() */
41 #include "aout_internal.h"
43 #include <vlc_playlist.h>
45 static audio_output_t *findAout (vlc_object_t *obj)
47 input_thread_t *(*pf_find_input) (vlc_object_t *);
49 pf_find_input = var_GetAddress (obj, "find-input-callback");
50 if (unlikely(pf_find_input == NULL))
53 input_thread_t *p_input = pf_find_input (obj);
57 audio_output_t *p_aout = input_GetAout (p_input);
58 vlc_object_release (p_input);
61 #define findAout(o) findAout(VLC_OBJECT(o))
63 /** Start a volume change transaction. */
64 static void prepareVolume (vlc_object_t *obj, audio_output_t **aoutp,
65 float *vol, bool *mute)
67 audio_output_t *aout = findAout (obj);
69 /* FIXME: we need interlocking even if aout does not exist! */
73 obj = VLC_OBJECT(aout); /* use aout volume if aout exists */
74 aout_lock_volume (aout);
77 *vol = var_InheritInteger (obj, "volume") / (float)AOUT_VOLUME_DEFAULT;
79 *mute = var_InheritBool (obj, "mute");
82 /** Commit a volume change transaction. */
83 static int commitVolume (vlc_object_t *obj, audio_output_t *aout,
86 long volume = lroundf (vol * AOUT_VOLUME_DEFAULT);
91 /* apply volume to the pipeline */
93 if (aout->mute_set != NULL)
94 ret = aout->mute_set (aout, mute);
97 if (ret == 0 && aout->volume_set != NULL)
98 ret = aout->volume_set (aout, vol);
102 { /* update aout volume if it maintains its own */
103 var_SetInteger (aout, "volume", volume);
104 var_SetBool (aout, "mute", mute);
106 aout_unlock_volume (aout);
108 vlc_object_release (aout);
111 { /* update caller (input manager) volume */
112 var_SetInteger (obj, "volume", volume);
113 var_SetBool (obj, "mute", mute);
114 if (var_InheritBool (obj, "volume-save"))
115 config_PutInt (obj, "volume", volume);
120 /** Cancel a volume change transaction. */
121 static void cancelVolume (vlc_object_t *obj, audio_output_t *aout)
126 aout_unlock_volume (aout);
127 vlc_object_release (aout);
131 #undef aout_VolumeGet
133 * Gets the volume of the output device (independent of mute).
134 * \return Current audio volume (0 = silent, 1 = nominal),
135 * or a strictly negative value if undefined.
137 float aout_VolumeGet (vlc_object_t *obj)
139 audio_output_t *aout;
142 prepareVolume (obj, &aout, &vol, NULL);
143 cancelVolume (obj, aout);
147 #undef aout_VolumeSet
149 * Sets the volume of the output device.
150 * The mute status is not changed.
152 int aout_VolumeSet (vlc_object_t *obj, float vol)
154 audio_output_t *aout;
157 prepareVolume (obj, &aout, NULL, &mute);
158 return commitVolume (obj, aout, vol, mute);
164 * \param value how much to increase (> 0) or decrease (< 0) the volume
165 * \param volp if non-NULL, will contain contain the resulting volume
167 int aout_VolumeUp (vlc_object_t *obj, int value, float *volp)
169 audio_output_t *aout;
174 value *= var_InheritInteger (obj, "volume-step");
176 prepareVolume (obj, &aout, &vol, &mute);
177 vol += value / (float)AOUT_VOLUME_DEFAULT;
180 if (vol > (AOUT_VOLUME_MAX / AOUT_VOLUME_DEFAULT))
181 vol = AOUT_VOLUME_MAX / AOUT_VOLUME_DEFAULT;
182 ret = commitVolume (obj, aout, vol, mute);
188 #undef aout_MuteToggle
190 * Toggles the mute state.
192 int aout_MuteToggle (vlc_object_t *obj)
194 audio_output_t *aout;
198 prepareVolume (obj, &aout, &vol, &mute);
200 return commitVolume (obj, aout, vol, mute);
205 * Gets the output mute status.
206 * \return 0 if not muted, 1 if muted, -1 if undefined.
208 int aout_MuteGet (vlc_object_t *obj)
210 audio_output_t *aout;
213 prepareVolume (obj, &aout, NULL, &mute);
214 cancelVolume (obj, aout);
222 int aout_MuteSet (vlc_object_t *obj, bool mute)
224 audio_output_t *aout;
227 prepareVolume (obj, &aout, &vol, NULL);
228 return commitVolume (obj, aout, vol, mute);
233 * Pipelines management
236 /*****************************************************************************
237 * aout_ChannelsRestart : change the audio device or channels and restart
238 *****************************************************************************/
239 int aout_ChannelsRestart( vlc_object_t * p_this, const char * psz_variable,
240 vlc_value_t oldval, vlc_value_t newval,
243 audio_output_t * p_aout = (audio_output_t *)p_this;
244 (void)oldval; (void)newval; (void)p_data;
246 if ( !strcmp( psz_variable, "audio-device" ) )
248 /* This is supposed to be a significant change and supposes
249 * rebuilding the channel choices. */
250 var_Destroy( p_aout, "audio-channels" );
252 aout_RequestRestart (p_aout);
256 #undef aout_EnableFilter
257 /** Enable or disable an audio filter
258 * \param p_this a vlc object
259 * \param psz_name name of the filter
260 * \param b_add are we adding or removing the filter ?
262 void aout_EnableFilter( vlc_object_t *p_this, const char *psz_name,
265 audio_output_t *p_aout = findAout( p_this );
267 if( aout_ChangeFilterString( p_this, VLC_OBJECT(p_aout), "audio-filter", psz_name, b_add ) )
270 aout_InputRequestRestart( p_aout );
274 vlc_object_release( p_aout );