Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

arts.c

00001 /*****************************************************************************
00002  * arts.c : aRts module
00003  *****************************************************************************
00004  * Copyright (C) 2001-2002 the VideoLAN team
00005  * $Id: arts.c 12186 2005-08-14 12:43:30Z sam $
00006  *
00007  * Authors: Emmanuel Blindauer <[email protected]>
00008  *          Samuel Hocevar <[email protected]>
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00023  *****************************************************************************/
00024 
00025 /*****************************************************************************
00026  * Preamble
00027  *****************************************************************************/
00028 #include <errno.h>                                                 /* ENOMEM */
00029 #include <fcntl.h>                                       /* open(), O_WRONLY */
00030 #include <string.h>                                            /* strerror() */
00031 #include <unistd.h>                                      /* write(), close() */
00032 #include <stdlib.h>                            /* calloc(), malloc(), free() */
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  * aout_sys_t: arts audio output method descriptor
00043  *****************************************************************************
00044  * This structure is part of the audio output thread descriptor.
00045  * It describes some arts specific variables.
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  * Local prototypes
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  * Module descriptor
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  * Open: open an aRts socket
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     /* Allocate structure */
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         /* aRts doesn't support more than two channels. */
00110         i_nb_channels = 2;
00111         p_aout->output.output.i_physical_channels =
00112             AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
00113     }
00114 
00115     /* Open a socket for playing a stream, set format to 16 bits */
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     /* Try not to bufferize more than 200 ms */
00126     arts_stream_set( p_sys->stream, ARTS_P_BUFFER_TIME, 50 );
00127 
00128     /* Estimate latency with a half full buffer */
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  * Play: nothing to do
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  * Close: close the aRts socket
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 

Generated on Tue Dec 20 10:14:27 2005 for vlc-0.8.4a by  doxygen 1.4.2