00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <errno.h>
00029 #include <fcntl.h>
00030 #include <string.h>
00031 #include <unistd.h>
00032 #include <stdlib.h>
00033
00034 #include <vlc/vlc.h>
00035 #include <vlc/aout.h>
00036
00037 #include "aout_internal.h"
00038
00039 #include <artsc.h>
00040
00041
00042
00043
00044
00045
00046
00047 struct aout_sys_t
00048 {
00049 arts_stream_t stream;
00050
00051 mtime_t latency;
00052 int i_size;
00053 };
00054
00055
00056
00057
00058 static int Open ( vlc_object_t * );
00059 static void Close ( vlc_object_t * );
00060 static void Play ( aout_instance_t * );
00061
00062
00063
00064
00065 vlc_module_begin();
00066 set_shortname( "aRts" );
00067 set_description( _("aRts audio output") );
00068 set_capability( "audio output", 50 );
00069 set_category( CAT_AUDIO );
00070 set_subcategory( SUBCAT_AUDIO_AOUT );
00071 set_callbacks( Open, Close );
00072 vlc_module_end();
00073
00074
00075
00076
00077 static int Open( vlc_object_t *p_this )
00078 {
00079 aout_instance_t *p_aout = (aout_instance_t *)p_this;
00080 struct aout_sys_t * p_sys;
00081 int i_err;
00082 int i_nb_channels;
00083
00084
00085 p_sys = malloc( sizeof( aout_sys_t ) );
00086 if( p_sys == NULL )
00087 {
00088 msg_Err( p_aout, "out of memory" );
00089 return VLC_ENOMEM;
00090 }
00091 p_aout->output.p_sys = p_sys;
00092
00093 i_err = arts_init();
00094
00095 if( i_err < 0 )
00096 {
00097 msg_Err( p_aout, "arts_init failed (%s)", arts_error_text(i_err) );
00098 free( p_sys );
00099 return VLC_EGENERIC;
00100 }
00101
00102 p_aout->output.pf_play = Play;
00103 aout_VolumeSoftInit( p_aout );
00104
00105 p_aout->output.output.i_format = AOUT_FMT_S16_NE;
00106 i_nb_channels = aout_FormatNbChannels( &p_aout->output.output );
00107 if ( i_nb_channels > 2 )
00108 {
00109
00110 i_nb_channels = 2;
00111 p_aout->output.output.i_physical_channels =
00112 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
00113 }
00114
00115
00116 p_sys->stream = arts_play_stream( p_aout->output.output.i_rate, 16,
00117 i_nb_channels, "vlc" );
00118 if( p_sys->stream == NULL )
00119 {
00120 msg_Err( p_aout, "cannot open aRts socket" );
00121 free( p_sys );
00122 return VLC_EGENERIC;
00123 }
00124
00125
00126 arts_stream_set( p_sys->stream, ARTS_P_BUFFER_TIME, 50 );
00127
00128
00129 p_sys->latency = (mtime_t)1000
00130 * (mtime_t)arts_stream_get( p_sys->stream, ARTS_P_SERVER_LATENCY );
00131 p_sys->i_size = arts_stream_get( p_sys->stream, ARTS_P_PACKET_SIZE );
00132
00133 msg_Dbg( p_aout, "aRts initialized, latency %i000, %i packets of size %i",
00134 arts_stream_get( p_sys->stream, ARTS_P_SERVER_LATENCY ),
00135 arts_stream_get( p_sys->stream, ARTS_P_PACKET_COUNT ),
00136 arts_stream_get( p_sys->stream, ARTS_P_PACKET_SIZE ) );
00137
00138 p_aout->output.i_nb_samples = p_sys->i_size / sizeof(uint16_t)
00139 / i_nb_channels;
00140
00141 return VLC_SUCCESS;
00142 }
00143
00144
00145
00146
00147 static void Play( aout_instance_t *p_aout )
00148 {
00149 struct aout_sys_t * p_sys = p_aout->output.p_sys;
00150 aout_buffer_t * p_buffer;
00151 int i_tmp;
00152
00153 #if 0
00154 while( arts_stream_get( p_sys->stream, ARTS_P_BUFFER_SPACE ) < 16384*3/2 )
00155 {
00156 msleep( 10000 );
00157 }
00158 #endif
00159
00160 p_buffer = aout_FifoPop( p_aout, &p_aout->output.fifo );
00161
00162 if( p_buffer != NULL )
00163 {
00164 i_tmp = arts_write( p_sys->stream, p_buffer->p_buffer,
00165 p_buffer->i_nb_bytes );
00166
00167 if( i_tmp < 0 )
00168 {
00169 msg_Err( p_aout, "write failed (%s)", arts_error_text(i_tmp) );
00170 }
00171
00172 aout_BufferFree( p_buffer );
00173 }
00174 }
00175
00176
00177
00178
00179 static void Close( vlc_object_t *p_this )
00180 {
00181 aout_instance_t *p_aout = (aout_instance_t *)p_this;
00182 struct aout_sys_t * p_sys = p_aout->output.p_sys;
00183
00184 arts_close_stream( p_sys->stream );
00185 arts_free();
00186 free( p_sys );
00187 }
00188