]> git.sesse.net Git - vlc/blob - lib/audio.c
aout: remove aout_MuteToggle()
[vlc] / lib / audio.c
1 /*****************************************************************************
2  * libvlc_audio.c: New libvlc audio control API
3  *****************************************************************************
4  * Copyright (C) 2006 VLC authors and VideoLAN
5  * $Id$
6  *
7  * Authors: Filippo Carone <filippo@carone.org>
8  *          Jean-Paul Saman <jpsaman _at_ m2x _dot_ nl>
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation; either version 2.1 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program; if not, write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <assert.h>
30 #include <math.h>
31
32 #include <vlc/libvlc.h>
33 #include <vlc/libvlc_media.h>
34 #include <vlc/libvlc_media_player.h>
35
36 #include <vlc_common.h>
37 #include <vlc_input.h>
38 #include <vlc_aout_intf.h>
39 #include <vlc_aout.h>
40 #include <vlc_modules.h>
41
42 #include "libvlc_internal.h"
43 #include "media_player_internal.h"
44
45 /*
46  * Remember to release the returned audio_output_t since it is locked at
47  * the end of this function.
48  */
49 static audio_output_t *GetAOut( libvlc_media_player_t *mp )
50 {
51     assert( mp != NULL );
52
53     audio_output_t *p_aout = input_resource_HoldAout( mp->input.p_resource );
54     if( p_aout == NULL )
55         libvlc_printerr( "No active audio output" );
56     return p_aout;
57 }
58
59 /*****************************************
60  * Get the list of available audio outputs
61  *****************************************/
62 libvlc_audio_output_t *
63         libvlc_audio_output_list_get( libvlc_instance_t *p_instance )
64 {
65     size_t count;
66     module_t **module_list = module_list_get( &count );
67     libvlc_audio_output_t *list = NULL;
68
69     for (size_t i = 0; i < count; i++)
70     {
71         module_t *module = module_list[i];
72
73         if( !module_provides( module, "audio output" ) )
74             continue;
75
76         libvlc_audio_output_t *item = malloc( sizeof( *item ) );
77         if( unlikely(item == NULL) )
78         {
79     error:
80             libvlc_printerr( "Not enough memory" );
81             libvlc_audio_output_list_release( list );
82             list = NULL;
83             break;
84         }
85
86         item->psz_name = strdup( module_get_object( module ) );
87         item->psz_description = strdup( module_get_name( module, true ) );
88         if( unlikely(item->psz_name == NULL || item->psz_description == NULL) )
89         {
90             free( item );
91             goto error;
92         }
93         item->p_next = list;
94         list = item;
95     }
96     module_list_free( module_list );
97
98     VLC_UNUSED( p_instance );
99     return list;
100 }
101
102 /********************************************
103  * Free the list of available audio outputs
104  ***********************************************/
105 void libvlc_audio_output_list_release( libvlc_audio_output_t *list )
106 {
107     while( list != NULL )
108     {
109         libvlc_audio_output_t *next = list->p_next;
110
111         free( list->psz_name );
112         free( list->psz_description );
113         free( list );
114         list = next;
115     }
116 }
117
118
119 /***********************
120  * Set the audio output.
121  ***********************/
122 int libvlc_audio_output_set( libvlc_media_player_t *mp, const char *psz_name )
123 {
124     char *value;
125
126     if( !module_exists( psz_name )
127      || asprintf( &value, "%s,none", psz_name ) == -1 )
128         return -1;
129     var_SetString( mp, "aout", value );
130     free( value );
131     return 0;
132 }
133
134 libvlc_audio_output_device_t *
135 libvlc_audio_output_device_list_get( libvlc_instance_t *p_instance,
136                                      const char *aout )
137 {
138     char varname[32];
139     if( (size_t)snprintf( varname, sizeof(varname), "%s-output-device", aout )
140                                                            >= sizeof(varname) )
141         return NULL;
142
143     libvlc_audio_output_device_t *list = NULL, **pp = &list;
144     char **values, **texts;
145     ssize_t count = config_GetPszChoices( VLC_OBJECT(p_instance->p_libvlc_int),
146                                           varname, &values, &texts );
147     for( ssize_t i = 0; i < count; i++ )
148     {
149         libvlc_audio_output_device_t *item = malloc( sizeof(*item) );
150         if( unlikely(item == NULL) )
151             break;
152
153         *pp = item;
154         pp = &item->p_next;
155         item->psz_device = values[i];
156         item->psz_description = texts[i];
157     }
158
159     *pp = NULL;
160     free( texts );
161     free( values );
162     (void) p_instance;
163     return list;
164 }
165
166 void libvlc_audio_output_device_list_release( libvlc_audio_output_device_t *l )
167 {
168     while( l != NULL )
169     {
170         libvlc_audio_output_device_t *next = l->p_next;
171
172         free( l->psz_description );
173         free( l->psz_device );
174         free( l );
175         l = next;
176     }
177 }
178
179 int libvlc_audio_output_device_count( libvlc_instance_t *p_instance,
180                                       const char *psz_audio_output )
181 {
182     (void) p_instance; (void) psz_audio_output;
183     return 0;
184 }
185
186 char *libvlc_audio_output_device_longname( libvlc_instance_t *p_instance,
187                                            const char *psz_audio_output,
188                                            int i_device )
189 {
190     (void) p_instance; (void) psz_audio_output; (void) i_device;
191     return NULL;
192 }
193
194 char *libvlc_audio_output_device_id( libvlc_instance_t *p_instance,
195                                      const char *psz_audio_output,
196                                      int i_device )
197 {
198     (void) p_instance; (void) psz_audio_output; (void) i_device;
199     return NULL;
200 }
201
202 /*****************************
203  * Set device for using
204  *****************************/
205 void libvlc_audio_output_device_set( libvlc_media_player_t *mp,
206                                      const char *psz_audio_output,
207                                      const char *psz_device_id )
208 {
209     char *psz_config_name;
210     if( !psz_audio_output || !psz_device_id )
211         return;
212     if( asprintf( &psz_config_name, "%s-audio-device", psz_audio_output ) == -1 )
213         return;
214     if( !var_Type( mp, psz_config_name ) )
215         /* Don't recreate the same variable over and over and over... */
216         var_Create( mp, psz_config_name, VLC_VAR_STRING );
217     var_SetString( mp, psz_config_name, psz_device_id );
218     free( psz_config_name );
219 }
220
221 /*****************************************************************************
222  * libvlc_audio_output_get_device_type : Get the current audio device type
223  *****************************************************************************/
224 int libvlc_audio_output_get_device_type( libvlc_media_player_t *mp )
225 {
226     audio_output_t *p_aout = GetAOut( mp );
227     if( p_aout )
228     {
229         int i_device_type = var_GetInteger( p_aout, "audio-device" );
230         vlc_object_release( p_aout );
231         return i_device_type;
232     }
233     return libvlc_AudioOutputDevice_Error;
234 }
235
236 /*****************************************************************************
237  * libvlc_audio_output_set_device_type : Set the audio device type
238  *****************************************************************************/
239 void libvlc_audio_output_set_device_type( libvlc_media_player_t *mp,
240                                           int device_type )
241 {
242     audio_output_t *p_aout = GetAOut( mp );
243     if( !p_aout )
244         return;
245     if( var_SetInteger( p_aout, "audio-device", device_type ) < 0 )
246         libvlc_printerr( "Error setting audio device" );
247     vlc_object_release( p_aout );
248 }
249
250 void libvlc_audio_toggle_mute( libvlc_media_player_t *mp )
251 {
252     int mute = libvlc_audio_get_mute( mp );
253     if( mute != -1 )
254         libvlc_audio_set_mute( mp, !mute );
255 }
256
257 int libvlc_audio_get_mute( libvlc_media_player_t *mp )
258 {
259     return aout_MuteGet( mp );
260 }
261
262 void libvlc_audio_set_mute( libvlc_media_player_t *mp, int mute )
263 {
264     aout_MuteSet( VLC_OBJECT(mp), mute != 0 );
265 }
266
267 int libvlc_audio_get_volume( libvlc_media_player_t *mp )
268 {
269     float vol = aout_VolumeGet( mp );
270     return ( vol >= 0.f ) ? lroundf( vol * 100.f ) : -1;
271 }
272
273 int libvlc_audio_set_volume( libvlc_media_player_t *mp, int volume )
274 {
275     float vol = volume / 100.f;
276     if (vol < 0.f)
277     {
278         libvlc_printerr( "Volume out of range" );
279         return -1;
280     }
281     aout_VolumeSet (mp, vol);
282     return 0;
283 }
284
285 /*****************************************************************************
286  * libvlc_audio_get_track_count : Get the number of available audio tracks
287  *****************************************************************************/
288 int libvlc_audio_get_track_count( libvlc_media_player_t *p_mi )
289 {
290     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
291     int i_track_count;
292
293     if( !p_input_thread )
294         return -1;
295
296     i_track_count = var_CountChoices( p_input_thread, "audio-es" );
297
298     vlc_object_release( p_input_thread );
299     return i_track_count;
300 }
301
302 /*****************************************************************************
303  * libvlc_audio_get_track_description : Get the description of available audio tracks
304  *****************************************************************************/
305 libvlc_track_description_t *
306         libvlc_audio_get_track_description( libvlc_media_player_t *p_mi )
307 {
308     return libvlc_get_track_description( p_mi, "audio-es" );
309 }
310
311 /*****************************************************************************
312  * libvlc_audio_get_track : Get the current audio track
313  *****************************************************************************/
314 int libvlc_audio_get_track( libvlc_media_player_t *p_mi )
315 {
316     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
317     vlc_value_t val_list;
318     vlc_value_t val;
319     int i_track = -1;
320     int i;
321
322     if( !p_input_thread )
323         return -1;
324
325     if( var_Get( p_input_thread, "audio-es", &val ) < 0 )
326     {
327         vlc_object_release( p_input_thread );
328         libvlc_printerr( "Audio track information not found" );
329         return -1;
330     }
331
332     var_Change( p_input_thread, "audio-es", VLC_VAR_GETCHOICES, &val_list, NULL );
333     for( i = 0; i < val_list.p_list->i_count; i++ )
334     {
335         if( val_list.p_list->p_values[i].i_int == val.i_int )
336         {
337             i_track = i;
338             break;
339         }
340     }
341     var_FreeList( &val_list, NULL );
342     vlc_object_release( p_input_thread );
343     return i_track;
344 }
345
346 /*****************************************************************************
347  * libvlc_audio_set_track : Set the current audio track
348  *****************************************************************************/
349 int libvlc_audio_set_track( libvlc_media_player_t *p_mi, int i_track )
350 {
351     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
352     vlc_value_t val_list;
353     vlc_value_t newval;
354     int i_ret;
355
356     if( !p_input_thread )
357         return -1;
358
359     var_Change( p_input_thread, "audio-es", VLC_VAR_GETCHOICES, &val_list, NULL );
360     if( (i_track < 0) || (i_track > val_list.p_list->i_count) )
361     {
362         libvlc_printerr( "Audio track out of range" );
363         i_ret = -1;
364         goto end;
365     }
366
367     newval = val_list.p_list->p_values[i_track];
368     i_ret = var_Set( p_input_thread, "audio-es", newval );
369     if( i_ret < 0 )
370     {
371         libvlc_printerr( "Audio track out of range" ); /* Race... */
372         i_ret = -1;
373         goto end;
374     }
375     i_ret = 0;
376
377 end:
378     var_FreeList( &val_list, NULL );
379     vlc_object_release( p_input_thread );
380     return i_ret;
381 }
382
383 /*****************************************************************************
384  * libvlc_audio_get_channel : Get the current audio channel
385  *****************************************************************************/
386 int libvlc_audio_get_channel( libvlc_media_player_t *mp )
387 {
388     audio_output_t *p_aout = GetAOut( mp );
389     if( !p_aout )
390         return 0;
391
392     int val = var_GetInteger( p_aout, "stereo-mode" );
393     vlc_object_release( p_aout );
394     return val;
395 }
396
397 /*****************************************************************************
398  * libvlc_audio_set_channel : Set the current audio channel
399  *****************************************************************************/
400 int libvlc_audio_set_channel( libvlc_media_player_t *mp, int channel )
401 {
402     audio_output_t *p_aout = GetAOut( mp );
403     int ret = 0;
404
405     if( !p_aout )
406         return -1;
407
408     if( var_SetInteger( p_aout, "stereo-mode", channel ) < 0 )
409     {
410         libvlc_printerr( "Audio channel out of range" );
411         ret = -1;
412     }
413     vlc_object_release( p_aout );
414     return ret;
415 }
416
417 /*****************************************************************************
418  * libvlc_audio_get_delay : Get the current audio delay
419  *****************************************************************************/
420 int64_t libvlc_audio_get_delay( libvlc_media_player_t *p_mi )
421 {
422     input_thread_t *p_input_thread = libvlc_get_input_thread ( p_mi );
423     int64_t val = 0;
424     if( p_input_thread != NULL )
425     {
426       val = var_GetTime( p_input_thread, "audio-delay" );
427       vlc_object_release( p_input_thread );
428     }
429     return val;
430 }
431
432 /*****************************************************************************
433  * libvlc_audio_set_delay : Set the current audio delay
434  *****************************************************************************/
435 int libvlc_audio_set_delay( libvlc_media_player_t *p_mi, int64_t i_delay )
436 {
437     input_thread_t *p_input_thread = libvlc_get_input_thread ( p_mi );
438     int ret = 0;
439     if( p_input_thread != NULL )
440     {
441       var_SetTime( p_input_thread, "audio-delay", i_delay );
442       vlc_object_release( p_input_thread );
443     }
444     else
445     {
446       ret = -1;
447     }
448     return ret;
449 }