1 /*****************************************************************************
2 * jack.c : JACK audio output module
3 *****************************************************************************
4 * Copyright (C) 2006 VLC authors and VideoLAN
7 * Authors: Cyril Deguet <asmax _at_ 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 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.
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.
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 *****************************************************************************/
25 * \file modules/audio_output/jack.c
26 * \brief JACK audio output functions
28 /*****************************************************************************
30 *****************************************************************************/
36 #include <vlc_common.h>
37 #include <vlc_plugin.h>
40 #include <jack/jack.h>
41 #include <jack/ringbuffer.h>
44 #include <unistd.h> /* write(), close() */
46 typedef jack_default_audio_sample_t jack_sample_t
;
48 /*****************************************************************************
49 * aout_sys_t: JACK audio output method descriptor
50 *****************************************************************************
51 * This structure is part of the audio output thread descriptor.
52 * It describes some JACK specific variables.
53 *****************************************************************************/
56 jack_ringbuffer_t
*p_jack_ringbuffer
;
57 jack_client_t
*p_jack_client
;
58 jack_port_t
**p_jack_ports
;
59 jack_sample_t
**p_jack_buffers
;
60 unsigned int i_channels
;
62 jack_nframes_t latency
;
65 mtime_t paused
; /**< Time when (last) paused */
68 /*****************************************************************************
70 *****************************************************************************/
71 static int Open ( vlc_object_t
* );
72 static void Close ( vlc_object_t
* );
73 static void Play ( audio_output_t
* p_aout
, block_t
* p_block
);
74 static void Pause ( audio_output_t
*aout
, bool paused
, mtime_t date
);
75 static void Flush ( audio_output_t
*p_aout
, bool wait
);
76 static int TimeGet ( audio_output_t
*, mtime_t
* );
77 static int Process ( jack_nframes_t i_frames
, void *p_arg
);
78 static int GraphChange ( void *p_arg
);
80 #include "audio_output/volume.h"
82 #define AUTO_CONNECT_OPTION "jack-auto-connect"
83 #define AUTO_CONNECT_TEXT N_("Automatically connect to writable clients")
84 #define AUTO_CONNECT_LONGTEXT N_( \
85 "If enabled, this option will automatically connect sound output to the " \
86 "first writable JACK clients found." )
88 #define CONNECT_REGEX_OPTION "jack-connect-regex"
89 #define CONNECT_REGEX_TEXT N_("Connect to clients matching")
90 #define CONNECT_REGEX_LONGTEXT N_( \
91 "If automatic connection is enabled, only JACK clients whose names " \
92 "match this regular expression will be considered for connection." )
94 #define JACK_NAME_TEXT N_( "JACK client name" )
96 /*****************************************************************************
98 *****************************************************************************/
100 set_shortname( "JACK" )
101 set_description( N_("JACK audio output") )
102 set_capability( "audio output", 100 )
103 set_category( CAT_AUDIO
)
104 set_subcategory( SUBCAT_AUDIO_AOUT
)
105 add_bool( AUTO_CONNECT_OPTION
, true, AUTO_CONNECT_TEXT
,
106 AUTO_CONNECT_LONGTEXT
, false )
107 add_string( CONNECT_REGEX_OPTION
, "system", CONNECT_REGEX_TEXT
,
108 CONNECT_REGEX_LONGTEXT
, false )
109 add_string( "jack-name", "", JACK_NAME_TEXT
, JACK_NAME_TEXT
, false)
112 set_callbacks( Open
, Close
)
116 static int Start( audio_output_t
*p_aout
, audio_sample_format_t
*restrict fmt
)
119 struct aout_sys_t
*p_sys
= p_aout
->sys
;
120 int status
= VLC_SUCCESS
;
124 if( aout_FormatNbChannels( fmt
) == 0 )
128 p_sys
->paused
= VLC_TS_INVALID
;
130 /* Connect to the JACK server */
131 psz_name
= var_InheritString( p_aout
, "jack-name" );
132 if( !psz_name
|| !*psz_name
)
135 if( asprintf( &psz_name
, "vlc_%d", getpid()) == -1 )
139 p_sys
->p_jack_client
= jack_client_open( psz_name
,
140 JackNullOption
| JackNoStartServer
,
142 if( p_sys
->p_jack_client
== NULL
)
144 msg_Err( p_aout
, "failed to connect to JACK server" );
145 status
= VLC_EGENERIC
;
149 /* Set the process callback */
150 jack_set_process_callback( p_sys
->p_jack_client
, Process
, p_aout
);
151 jack_set_graph_order_callback ( p_sys
->p_jack_client
, GraphChange
, p_aout
);
153 /* JACK only supports fl32 format */
154 fmt
->i_format
= VLC_CODEC_FL32
;
155 // TODO add buffer size callback
156 p_sys
->i_rate
= fmt
->i_rate
= jack_get_sample_rate( p_sys
->p_jack_client
);
159 p_aout
->pause
= Pause
;
160 p_aout
->flush
= Flush
;
161 p_aout
->time_get
= TimeGet
;
162 aout_SoftVolumeStart( p_aout
);
164 p_sys
->i_channels
= aout_FormatNbChannels( fmt
);
165 aout_FormatPrepare(fmt
);
167 p_sys
->p_jack_ports
= malloc( p_sys
->i_channels
*
168 sizeof(jack_port_t
*) );
169 if( p_sys
->p_jack_ports
== NULL
)
175 p_sys
->p_jack_buffers
= malloc( p_sys
->i_channels
*
176 sizeof(jack_sample_t
*) );
177 if( p_sys
->p_jack_buffers
== NULL
)
183 const size_t buf_sz
= AOUT_MAX_ADVANCE_TIME
* fmt
->i_rate
*
184 fmt
->i_bytes_per_frame
/ CLOCK_FREQ
;
185 p_sys
->p_jack_ringbuffer
= jack_ringbuffer_create( buf_sz
);
187 if( p_sys
->p_jack_ringbuffer
== NULL
)
193 if( jack_ringbuffer_mlock( p_sys
->p_jack_ringbuffer
))
195 msg_Warn( p_aout
, "failed to lock JACK ringbuffer in memory" );
198 /* Create the output ports */
199 for( i
= 0; i
< p_sys
->i_channels
; i
++ )
201 char *psz_name_output
;
202 if( asprintf( &psz_name_output
, "%s_out_%d", psz_name
, i
+ 1) != -1 )
204 p_sys
->p_jack_ports
[i
] = jack_port_register( p_sys
->p_jack_client
,
205 psz_name_output
, JACK_DEFAULT_AUDIO_TYPE
, JackPortIsOutput
, 0 );
206 free( psz_name_output
);
209 if( p_sys
->p_jack_ports
[i
] == NULL
)
211 msg_Err( p_aout
, "failed to register a JACK port" );
212 status
= VLC_EGENERIC
;
217 /* Tell the JACK server we are ready */
218 i_error
= jack_activate( p_sys
->p_jack_client
);
221 msg_Err( p_aout
, "failed to activate JACK client (error %d)", i_error
);
222 status
= VLC_EGENERIC
;
226 /* Auto connect ports if we were asked to */
227 if( var_InheritBool( p_aout
, AUTO_CONNECT_OPTION
) )
229 unsigned int i_in_ports
;
230 char *psz_regex
= var_InheritString( p_aout
, CONNECT_REGEX_OPTION
);
231 const char **pp_in_ports
= jack_get_ports( p_sys
->p_jack_client
,
235 /* Count the number of returned ports */
237 while( pp_in_ports
&& pp_in_ports
[i_in_ports
] )
242 /* Tie the output ports to JACK input ports */
243 for( i
= 0; i_in_ports
> 0 && i
< p_sys
->i_channels
; i
++ )
245 const char* psz_in
= pp_in_ports
[i
% i_in_ports
];
246 const char* psz_out
= jack_port_name( p_sys
->p_jack_ports
[i
] );
248 i_error
= jack_connect( p_sys
->p_jack_client
, psz_out
, psz_in
);
251 msg_Err( p_aout
, "failed to connect port %s to port %s (error %d)",
252 psz_out
, psz_in
, i_error
);
256 msg_Dbg( p_aout
, "connecting port %s to port %s",
263 msg_Dbg( p_aout
, "JACK audio output initialized (%d channels, rate=%d)",
264 p_sys
->i_channels
, fmt
->i_rate
);
265 fmt
->channel_type
= AUDIO_CHANNEL_TYPE_BITMAP
;
268 /* Clean up, if an error occurred */
269 if( status
!= VLC_SUCCESS
)
271 if( p_sys
->p_jack_client
)
273 jack_deactivate( p_sys
->p_jack_client
);
274 jack_client_close( p_sys
->p_jack_client
);
276 if( p_sys
->p_jack_ringbuffer
)
277 jack_ringbuffer_free( p_sys
->p_jack_ringbuffer
);
279 free( p_sys
->p_jack_ports
);
280 free( p_sys
->p_jack_buffers
);
286 static void Play (audio_output_t
* p_aout
, block_t
* p_block
)
288 struct aout_sys_t
*p_sys
= p_aout
->sys
;
289 jack_ringbuffer_t
*rb
= p_sys
->p_jack_ringbuffer
;
290 const size_t bytes_per_frame
= p_sys
->i_channels
* sizeof(jack_sample_t
);
292 while (p_block
->i_buffer
> 0) {
294 /* move data to buffer */
295 const size_t write_space
= jack_ringbuffer_write_space(rb
);
296 const size_t bytes
= p_block
->i_buffer
< write_space
?
297 p_block
->i_buffer
: write_space
;
299 /* If our audio thread is not reading fast enough */
300 if( unlikely( bytes
== 0 ) ) {
301 msg_Warn( p_aout
, "%"PRIuPTR
" frames of audio dropped",
302 p_block
->i_buffer
/ bytes_per_frame
);
306 jack_ringbuffer_write( rb
, (const char *) p_block
->p_buffer
, bytes
);
308 p_block
->p_buffer
+= bytes
;
309 p_block
->i_buffer
-= bytes
;
312 block_Release(p_block
);
316 * Pause or unpause playback
318 static void Pause(audio_output_t
*aout
, bool paused
, mtime_t date
)
320 aout_sys_t
*sys
= aout
->sys
;
326 msg_Dbg(aout
, "resuming after %"PRId64
" us", date
);
327 sys
->paused
= VLC_TS_INVALID
;
331 static void Flush(audio_output_t
*p_aout
, bool wait
)
333 struct aout_sys_t
* p_sys
= p_aout
->sys
;
334 jack_ringbuffer_t
*rb
= p_sys
->p_jack_ringbuffer
;
336 /* Sleep if wait was requested */
340 if (!TimeGet(p_aout
, &delay
))
344 /* reset ringbuffer read and write pointers */
345 jack_ringbuffer_reset(rb
);
348 static int TimeGet(audio_output_t
*p_aout
, mtime_t
*delay
)
350 struct aout_sys_t
* p_sys
= p_aout
->sys
;
351 jack_ringbuffer_t
*rb
= p_sys
->p_jack_ringbuffer
;
352 const size_t bytes_per_frame
= p_sys
->i_channels
* sizeof(jack_sample_t
);
354 *delay
= (p_sys
->latency
+
355 (jack_ringbuffer_read_space(rb
) / bytes_per_frame
)) *
356 CLOCK_FREQ
/ p_sys
->i_rate
;
361 /*****************************************************************************
362 * Process: callback for JACK
363 *****************************************************************************/
364 int Process( jack_nframes_t i_frames
, void *p_arg
)
366 unsigned int i
, j
, frames_from_rb
= 0;
367 size_t bytes_read
= 0;
369 audio_output_t
*p_aout
= (audio_output_t
*) p_arg
;
370 struct aout_sys_t
*p_sys
= p_aout
->sys
;
372 /* Get the next audio data buffer unless paused */
374 if( p_sys
->paused
== VLC_TS_INVALID
)
375 frames_from_rb
= i_frames
;
377 /* Get the JACK buffers to write to */
378 for( i
= 0; i
< p_sys
->i_channels
; i
++ )
380 p_sys
->p_jack_buffers
[i
] = jack_port_get_buffer( p_sys
->p_jack_ports
[i
],
384 /* Copy in the audio data */
385 for( j
= 0; j
< frames_from_rb
; j
++ )
387 for( i
= 0; i
< p_sys
->i_channels
; i
++ )
389 jack_sample_t
*p_dst
= p_sys
->p_jack_buffers
[i
] + j
;
390 bytes_read
+= jack_ringbuffer_read( p_sys
->p_jack_ringbuffer
,
391 (char *) p_dst
, sizeof(jack_sample_t
) );
395 /* Fill any remaining buffer with silence */
396 frames_read
= (bytes_read
/ sizeof(jack_sample_t
)) / p_sys
->i_channels
;
397 if( frames_read
< i_frames
)
399 for( i
= 0; i
< p_sys
->i_channels
; i
++ )
401 memset( p_sys
->p_jack_buffers
[i
] + frames_read
, 0,
402 sizeof( jack_sample_t
) * (i_frames
- frames_read
) );
409 /*****************************************************************************
410 * GraphChange: callback when JACK reorders it's process graph.
411 We update latency information.
412 *****************************************************************************/
414 static int GraphChange( void *p_arg
)
416 audio_output_t
*p_aout
= (audio_output_t
*) p_arg
;
417 struct aout_sys_t
*p_sys
= p_aout
->sys
;
419 jack_latency_range_t port_latency
;
423 for( i
= 0; i
< p_sys
->i_channels
; ++i
)
425 jack_port_get_latency_range( p_sys
->p_jack_ports
[i
], JackPlaybackLatency
,
427 p_sys
->latency
= __MAX( p_sys
->latency
, port_latency
.max
);
430 msg_Dbg(p_aout
, "JACK graph reordered. Our maximum latency=%d.",
436 /*****************************************************************************
437 * Close: close the JACK client
438 *****************************************************************************/
439 static void Stop( audio_output_t
*p_aout
)
442 struct aout_sys_t
*p_sys
= p_aout
->sys
;
444 i_error
= jack_deactivate( p_sys
->p_jack_client
);
447 msg_Err( p_aout
, "jack_deactivate failed (error %d)", i_error
);
450 i_error
= jack_client_close( p_sys
->p_jack_client
);
453 msg_Err( p_aout
, "jack_client_close failed (error %d)", i_error
);
455 free( p_sys
->p_jack_ports
);
456 free( p_sys
->p_jack_buffers
);
457 jack_ringbuffer_free( p_sys
->p_jack_ringbuffer
);
460 static int Open(vlc_object_t
*obj
)
462 audio_output_t
*aout
= (audio_output_t
*)obj
;
463 aout_sys_t
*sys
= calloc(1, sizeof (*sys
));
465 if( unlikely( sys
== NULL
) )
470 aout_SoftVolumeInit(aout
);
474 static void Close(vlc_object_t
*obj
)
476 audio_output_t
*aout
= (audio_output_t
*)obj
;
477 aout_sys_t
*sys
= aout
->sys
;