1 /*****************************************************************************
2 * jack : JACK audio output module
3 *****************************************************************************
4 * Copyright (C) 2006 the VideoLAN team
7 * Authors: Cyril Deguet <asmax@videolan.org>
8 * Jon Griffiths <jon_p_griffiths _At_ yahoo _DOT_ com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
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 General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 * \file modules/audio_output/jack.c
26 * \brief JACK audio output functions
28 /*****************************************************************************
30 *****************************************************************************/
31 #include <string.h> /* strerror() */
32 #include <unistd.h> /* write(), close() */
33 #include <stdlib.h> /* calloc(), malloc(), free() */
38 #include <jack/jack.h>
40 /*****************************************************************************
41 * aout_sys_t: JACK audio output method descriptor
42 *****************************************************************************
43 * This structure is part of the audio output thread descriptor.
44 * It describes some JACK specific variables.
45 *****************************************************************************/
48 jack_client_t *p_jack_client;
49 jack_port_t **p_jack_ports;
50 unsigned int i_channels;
53 /*****************************************************************************
55 *****************************************************************************/
56 static int Open ( vlc_object_t * );
57 static void Close ( vlc_object_t * );
58 static void Play ( aout_instance_t * );
59 static int Process ( jack_nframes_t i_frames, void *p_arg );
61 #define AUTO_CONNECT_OPTION "jack-auto-connect"
62 #define AUTO_CONNECT_TEXT N_("Automatically connect to input devices")
63 #define AUTO_CONNECT_LONGTEXT N_( \
64 "If enabled, this option will automatically connect output to the " \
65 "first JACK inputs found." )
67 #define CONNECT_MATCH_OPTION "jack-connect-match"
68 #define CONNECT_MATCH_TEXT N_("Connect to outputs beginning with")
69 #define CONNECT_MATCH_LONGTEXT N_( \
70 "If automatic connection is enabled, only JACK inputs whose names " \
71 "begin with this prefix will be considered for connection." )
73 /*****************************************************************************
75 *****************************************************************************/
77 set_shortname( "JACK" );
78 set_description( _("JACK audio output") );
79 set_capability( "audio output", 100 );
80 set_category( CAT_AUDIO );
81 set_subcategory( SUBCAT_AUDIO_AOUT );
82 add_bool( AUTO_CONNECT_OPTION, 0, NULL, AUTO_CONNECT_TEXT,
83 AUTO_CONNECT_LONGTEXT, VLC_TRUE );
84 add_string( CONNECT_MATCH_OPTION, NULL, NULL, CONNECT_MATCH_TEXT,
85 CONNECT_MATCH_LONGTEXT, VLC_TRUE );
86 set_callbacks( Open, Close );
89 /*****************************************************************************
90 * Open: create a JACK client
91 *****************************************************************************/
92 static int Open( vlc_object_t *p_this )
94 aout_instance_t *p_aout = (aout_instance_t *)p_this;
95 struct aout_sys_t *p_sys = NULL;
96 char **pp_match_ports = NULL;
97 char *psz_prefix = NULL;
98 int status = VLC_SUCCESS;
101 /* Allocate structure */
102 p_sys = malloc( sizeof( aout_sys_t ) );
105 msg_Err( p_aout, "out of memory" );
109 p_aout->output.p_sys = p_sys;
111 /* Connect to the JACK server */
112 p_sys->p_jack_client = jack_client_new( "vlc" );
113 if( p_sys->p_jack_client == NULL )
115 msg_Err( p_aout, "failed to connect to JACK server" );
116 status = VLC_EGENERIC;
120 /* Set the process callback */
121 jack_set_process_callback( p_sys->p_jack_client, Process, p_aout );
123 p_aout->output.pf_play = Play;
124 aout_VolumeSoftInit( p_aout );
126 /* JACK only supports fl32 format */
127 p_aout->output.output.i_format = VLC_FOURCC('f','l','3','2');
128 // TODO add buffer size callback
129 p_aout->output.i_nb_samples = jack_get_buffer_size( p_sys->p_jack_client );
130 p_aout->output.output.i_rate = jack_get_sample_rate( p_sys->p_jack_client );
132 p_sys->i_channels = aout_FormatNbChannels( &p_aout->output.output );
134 p_sys->p_jack_ports = malloc( p_sys->i_channels * sizeof(jack_port_t *) );
135 if( p_sys->p_jack_ports == NULL )
137 msg_Err( p_aout, "out of memory" );
142 /* Create the output ports */
143 for( i = 0; i < p_sys->i_channels; i++ )
146 snprintf( p_name, 32, "out_%d", i + 1);
147 p_sys->p_jack_ports[i] = jack_port_register( p_sys->p_jack_client,
148 p_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 );
150 if( p_sys->p_jack_ports[i] == NULL )
152 msg_Err( p_aout, "failed to register a JACK port" );
153 status = VLC_EGENERIC;
158 /* Tell the JACK server we are ready */
159 if( jack_activate( p_sys->p_jack_client ) )
161 msg_Err( p_aout, "failed to activate JACK client" );
162 jack_client_close( p_sys->p_jack_client );
163 status = VLC_EGENERIC;
167 /* Auto connect ports if we were asked to */
168 if( config_GetInt( p_aout, AUTO_CONNECT_OPTION ) )
170 unsigned int i_in_ports, i_prefix_len;
171 const char **pp_in_ports;
173 pp_in_ports = jack_get_ports( p_sys->p_jack_client, NULL, NULL,
175 psz_prefix = config_GetPsz( p_aout, CONNECT_MATCH_OPTION );
176 i_prefix_len = psz_prefix ? strlen(psz_prefix) : 0;
178 /* Find JACK input ports to connect to */
181 while( pp_in_ports && pp_in_ports[i] )
184 !strncmp(psz_prefix, pp_in_ports[i], i_prefix_len) )
186 i_in_ports++; /* Found one */
191 /* Connect the output ports to input ports */
194 pp_match_ports = malloc( i_in_ports * sizeof(char*) );
195 if( pp_match_ports == NULL )
197 msg_Err( p_aout, "out of memory" );
202 /* populate list of matching ports */
205 while( pp_in_ports[i] )
208 !strncmp(psz_prefix, pp_in_ports[i], i_prefix_len) )
210 pp_match_ports[i_in_ports] = pp_in_ports[i];
211 i_in_ports++; /* Found one */
216 /* Tie the output ports to JACK input ports */
217 for( i = 0; i < p_sys->i_channels; i++ )
219 const char* psz_in = pp_match_ports[i % i_in_ports];
220 const char* psz_out = jack_port_name( p_sys->p_jack_ports[i] );
222 if( jack_connect( p_sys->p_jack_client, psz_out, psz_in) )
224 msg_Err( p_aout, "failed to connect port %s to port %s",
229 msg_Dbg( p_aout, "connecting port %s to port %s",
236 msg_Dbg( p_aout, "JACK audio output initialized (%d channels, buffer "
237 "size=%d, rate=%d)", p_sys->i_channels,
238 p_aout->output.i_nb_samples, p_aout->output.output.i_rate );
246 free( pp_match_ports );
248 if( status != VLC_SUCCESS && p_sys != NULL)
250 if( p_sys->p_jack_ports )
251 free( p_sys->p_jack_ports );
252 if( p_sys->p_jack_client )
253 jack_client_close( p_sys->p_jack_client );
260 /*****************************************************************************
261 * Process: callback for JACK
262 *****************************************************************************/
263 int Process( jack_nframes_t i_frames, void *p_arg )
265 aout_buffer_t *p_buffer;
266 jack_default_audio_sample_t *p_jack_buffer;
267 unsigned int i, j, i_nb_samples = 0;
268 aout_instance_t *p_aout = (aout_instance_t*) p_arg;
269 unsigned int i_nb_channels = p_aout->output.p_sys->i_channels;
271 /* Get the next audio data buffer */
272 p_buffer = aout_FifoPop( p_aout, &p_aout->output.fifo );
276 i_nb_samples = p_buffer->i_nb_samples;
279 for( i = 0; i < i_nb_channels; i++ )
281 /* Get an output buffer from JACK */
282 p_jack_buffer = jack_port_get_buffer(
283 p_aout->output.p_sys->p_jack_ports[i], i_frames );
285 /* Fill the buffer with audio data */
286 for( j = 0; j < i_nb_samples; j++ )
288 p_jack_buffer[j] = ((float*)p_buffer->p_buffer)[i_nb_channels*j+i];
290 if( i_nb_samples < i_frames )
292 memset( p_jack_buffer + i_nb_samples, 0,
293 sizeof( jack_default_audio_sample_t ) *
294 (i_frames - i_nb_samples) );
300 aout_BufferFree( p_buffer );
307 /*****************************************************************************
308 * Play: nothing to do
309 *****************************************************************************/
310 static void Play( aout_instance_t *p_aout )
312 aout_FifoFirstDate( p_aout, &p_aout->output.fifo );
315 /*****************************************************************************
316 * Close: close the JACK client
317 *****************************************************************************/
318 static void Close( vlc_object_t *p_this )
320 aout_instance_t *p_aout = (aout_instance_t *)p_this;
321 struct aout_sys_t *p_sys = p_aout->output.p_sys;
323 free( p_sys->p_jack_ports );
324 jack_client_close( p_sys->p_jack_client );