arts.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:6k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * arts.c : aRts module
  3.  *****************************************************************************
  4.  * Copyright (C) 2001-2002 VideoLAN
  5.  * $Id: arts.c 6961 2004-03-05 17:34:23Z sam $
  6.  *
  7.  * Authors: Emmanuel Blindauer <manu@agat.net>
  8.  *          Samuel Hocevar <sam@zoy.org>
  9.  *
  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.
  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 General Public License for more details.
  19.  *
  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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  23.  *****************************************************************************/
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #include <errno.h>                                                 /* ENOMEM */
  28. #include <fcntl.h>                                       /* open(), O_WRONLY */
  29. #include <string.h>                                            /* strerror() */
  30. #include <unistd.h>                                      /* write(), close() */
  31. #include <stdlib.h>                            /* calloc(), malloc(), free() */
  32. #include <vlc/vlc.h>
  33. #include <vlc/aout.h>
  34. #include "aout_internal.h"
  35. #include <artsc.h>
  36. /*****************************************************************************
  37.  * aout_sys_t: arts audio output method descriptor
  38.  *****************************************************************************
  39.  * This structure is part of the audio output thread descriptor.
  40.  * It describes some arts specific variables.
  41.  *****************************************************************************/
  42. struct aout_sys_t
  43. {
  44.     arts_stream_t stream;
  45.     mtime_t       latency;
  46.     int           i_size;
  47. };
  48. /*****************************************************************************
  49.  * Local prototypes
  50.  *****************************************************************************/
  51. static int  Open         ( vlc_object_t * );
  52. static void Close        ( vlc_object_t * );
  53. static void Play         ( aout_instance_t * );
  54. /*****************************************************************************
  55.  * Module descriptor
  56.  *****************************************************************************/
  57. vlc_module_begin();
  58.    set_description( _("aRts audio output") );
  59.    set_capability( "audio output", 50 );
  60.    set_callbacks( Open, Close );
  61. vlc_module_end();
  62. /*****************************************************************************
  63.  * Open: open an aRts socket
  64.  *****************************************************************************/
  65. static int Open( vlc_object_t *p_this )
  66. {
  67.     aout_instance_t *p_aout = (aout_instance_t *)p_this;
  68.     struct aout_sys_t * p_sys;
  69.     int i_err;
  70.     int i_nb_channels;
  71.     /* Allocate structure */
  72.     p_sys = malloc( sizeof( aout_sys_t ) );
  73.     if( p_sys == NULL )
  74.     {
  75.         msg_Err( p_aout, "out of memory" );
  76.         return VLC_ENOMEM;
  77.     }
  78.     p_aout->output.p_sys = p_sys;
  79.     i_err = arts_init();
  80.     if( i_err < 0 )
  81.     {
  82.         msg_Err( p_aout, "arts_init failed (%s)", arts_error_text(i_err) );
  83.         free( p_sys );
  84.         return VLC_EGENERIC;
  85.     }
  86.     p_aout->output.pf_play = Play;
  87.     aout_VolumeSoftInit( p_aout );
  88.     p_aout->output.output.i_format = AOUT_FMT_S16_NE;
  89.     i_nb_channels = aout_FormatNbChannels( &p_aout->output.output );
  90.     if ( i_nb_channels > 2 )
  91.     {
  92.         /* aRts doesn't support more than two channels. */
  93.         i_nb_channels = 2;
  94.         p_aout->output.output.i_physical_channels =
  95.             AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
  96.     }
  97.     /* Open a socket for playing a stream, set format to 16 bits */
  98.     p_sys->stream = arts_play_stream( p_aout->output.output.i_rate, 16,
  99.                                       i_nb_channels, "vlc" );
  100.     if( p_sys->stream == NULL )
  101.     {
  102.         msg_Err( p_aout, "cannot open aRts socket" );
  103.         free( p_sys );
  104.         return VLC_EGENERIC;
  105.     }
  106.     /* Try not to bufferize more than 200 ms */
  107.     arts_stream_set( p_sys->stream, ARTS_P_BUFFER_TIME, 50 );
  108.     /* Estimate latency with a half full buffer */
  109.     p_sys->latency = (mtime_t)1000
  110.        * (mtime_t)arts_stream_get( p_sys->stream, ARTS_P_SERVER_LATENCY );
  111.     p_sys->i_size = arts_stream_get( p_sys->stream, ARTS_P_PACKET_SIZE );
  112.     msg_Dbg( p_aout, "aRts initialized, latency %i000, %i packets of size %i",
  113.                      arts_stream_get( p_sys->stream, ARTS_P_SERVER_LATENCY ),
  114.                      arts_stream_get( p_sys->stream, ARTS_P_PACKET_COUNT ),
  115.                      arts_stream_get( p_sys->stream, ARTS_P_PACKET_SIZE ) );
  116.     p_aout->output.i_nb_samples = p_sys->i_size / sizeof(uint16_t)
  117.                                                 / i_nb_channels;
  118.     return VLC_SUCCESS;
  119. }
  120. /*****************************************************************************
  121.  * Play: nothing to do
  122.  *****************************************************************************/
  123. static void Play( aout_instance_t *p_aout )
  124. {
  125.     struct aout_sys_t * p_sys = p_aout->output.p_sys;
  126.     aout_buffer_t * p_buffer;
  127.     int i_tmp;
  128. #if 0
  129.     while( arts_stream_get( p_sys->stream, ARTS_P_BUFFER_SPACE ) < 16384*3/2 )
  130.     {
  131.         msleep( 10000 );
  132.     }
  133. #endif
  134.     p_buffer = aout_FifoPop( p_aout, &p_aout->output.fifo );
  135.     if( p_buffer != NULL )
  136.     {
  137.         i_tmp = arts_write( p_sys->stream, p_buffer->p_buffer,
  138.                                            p_buffer->i_nb_bytes );
  139.         if( i_tmp < 0 )
  140.         {
  141.             msg_Err( p_aout, "write failed (%s)", arts_error_text(i_tmp) );
  142.         }
  143.         aout_BufferFree( p_buffer );
  144.     }
  145. }
  146. /*****************************************************************************
  147.  * Close: close the aRts socket
  148.  *****************************************************************************/
  149. static void Close( vlc_object_t *p_this )
  150. {
  151.     aout_instance_t *p_aout = (aout_instance_t *)p_this;
  152.     struct aout_sys_t * p_sys = p_aout->output.p_sys;
  153.     arts_close_stream( p_sys->stream );
  154.     arts_free();
  155.     free( p_sys );
  156. }