Index: libao2/ao_dart.c =================================================================== --- libao2/ao_dart.c (revision 0) +++ libao2/ao_dart.c (revision 0) @@ -0,0 +1,267 @@ +/* + * ao_dart.c - libao2 DART Audio Output Driver for MPlayer + * + * Copyright (c) 2007 by KO Myung-Hun (komh@chollian.net) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Changes : + * KO Myung-Hun 2007/07/08 + * - Call fast_memcpy instead of memcpy() + */ + +#define INCL_DOS +#include + +#include +#include +#include + +#include "config.h" +#include "libaf/af_format.h" +#include "audio_out.h" +#include "audio_out_internal.h" +#include "mp_msg.h" +#include "libvo/fastmemcpy.h" +#include "subopt-helper.h" + +#include "dart.h" + +static ao_info_t info = +{ + "DART audio output", + "dart", + "KO Myung-Hun ", + "" +}; + +LIBAO_EXTERN( dart ) + +#define OUTBURST_SAMPLES 512 +#define DART_SAMPLES ( OUTBURST_SAMPLES << 2 ) +#define MPLAYER_SAMPLES ( OUTBURST_SAMPLES << 4 ) + +static uint8_t *m_audioBuf = NULL; +static volatile int m_nBufSize = 0; +static volatile int m_nBufLen = 0; +static volatile int m_iBufPos = 0; + +static ULONG APIENTRY dart_audio_callback( PVOID pBuffer, ULONG ulSize ) +{ + int nCopySize; + + nCopySize = ulSize < m_nBufLen ? ulSize : m_nBufLen; + + if( m_iBufPos + nCopySize > m_nBufSize ) + { + int len = m_nBufSize - m_iBufPos; + + fast_memcpy( pBuffer, m_audioBuf + m_iBufPos, len ); + fast_memcpy(( uint8_t * )pBuffer + len, m_audioBuf, nCopySize - len ); + } + else + fast_memcpy( pBuffer, m_audioBuf + m_iBufPos, nCopySize ); + + m_iBufPos = ( m_iBufPos + nCopySize ) % m_nBufSize; + m_nBufLen -= nCopySize; + + memset(( uint8_t * )pBuffer + nCopySize, DART.bSilence, ulSize - nCopySize ); + + return ulSize; +} + +// to set/get/query special features/parameters +static int control( int cmd, void *arg ) +{ + switch (cmd) + { + case AOCONTROL_GET_VOLUME : + { + ao_control_vol_t *vol = ( ao_control_vol_t * )arg; + + vol->left = vol->right = LOUSHORT( dartGetVolume()); + + return CONTROL_OK; + } + + case AOCONTROL_SET_VOLUME: + { + int mid; + ao_control_vol_t *vol = ( ao_control_vol_t * )arg; + + mid = ( vol->left + vol->right ) / 2; + dartSetVolume( MCI_SET_AUDIO_ALL, mid ); + + return CONTROL_OK; + } + } + + return CONTROL_UNKNOWN; +} + +static void print_help( void ) +{ + mp_msg( MSGT_AO, MSGL_FATAL, + "\n-ao dart commandline help:\n" + "Example: mplayer -ao kva:noshare\n" + " open DART as exclusive mode\n" + "\nOptions:\n" + " noshare\n" + " Open DART as exclusive mode\n"); +} + +// open & setup audio device +// return: 1=success 0=fail +static int init( int rate, int channels, int format, int flags ) +{ + BOOL fNoShare = FALSE; + int n; + + opt_t subopts[] = { + {"noshare", OPT_ARG_BOOL, &fNoShare, NULL }, + { NULL } + }; + + if( subopt_parse( ao_subdevice, subopts ) != 0 ) + { + print_help(); + return 0; + } + + mp_msg( MSGT_AO, MSGL_V, "DART : opened as %s mode\n", fNoShare ? "exclusive" : "shareable"); + + switch( format ) + { + case AF_FORMAT_S16_LE: + case AF_FORMAT_S8: + break; + + default : + format = AF_FORMAT_S16_LE; + mp_msg( MSGT_AO, MSGL_V, "DART: format %s not supported defaulting to Signed 16-bit Little-Endian\n", af_fmt2str_short( format )); + break; + } + + n = ( af_fmt2bits( format ) >> 3 ) * channels; + + m_nBufSize = n * MPLAYER_SAMPLES; + + if( dartInit( 0, af_fmt2bits( format ), rate, MCI_WAVE_FORMAT_PCM, channels, + 2, n * DART_SAMPLES, !fNoShare, dart_audio_callback )) + return 0; + + ao_data.channels = channels; + ao_data.samplerate = rate; + ao_data.format = format; + ao_data.bps = channels * rate * ( af_fmt2bits( format ) >> 3 ); + ao_data.outburst = n * OUTBURST_SAMPLES; + ao_data.buffersize = m_nBufSize; + + m_audioBuf = malloc( m_nBufSize ); + + m_nBufLen = 0; + m_iBufPos = 0; + + dartPlay(); + + return 1; +} + +// close audio device +static void uninit( int immed ) +{ + if( !immed ) + { + while( m_nBufLen ) + DosSleep( 1 ); + } + + dartClose(); + + free( m_audioBuf ); +} + +// stop playing and empty buffers (for seeking/pause) +static void reset( void ) +{ + dartPause(); + + // empty buffers + m_nBufLen = 0; + + dartResume(); +} + +// stop playing, keep buffers (for pause) +static void audio_pause( void ) +{ + dartPause(); +} + +// resume playing, after audio_pause() +static void audio_resume( void ) +{ + dartResume(); +} + +// return: how many bytes can be played without blocking +static int get_space( void ) +{ + return ( m_nBufSize - m_nBufLen ); +} + +// plays 'len' bytes of 'data' +// it should round it down to outburst*n +// return: number of bytes played +static int play( void *data, int len, int flags) +{ + int start_pos, end_pos; + + if( !( flags & AOPLAY_FINAL_CHUNK )) + len = ( len / ao_data.outburst ) * ao_data.outburst; + + if( len == 0 ) + return 0; + + start_pos = ( m_iBufPos + m_nBufLen ) % m_nBufSize; + + end_pos = ( start_pos + len ) % m_nBufSize; + if( end_pos <= start_pos ) + { + int len1 = m_nBufSize - start_pos; + + if( end_pos > m_iBufPos ) + end_pos = m_iBufPos; + + fast_memcpy( m_audioBuf + start_pos, data, len1 ); + fast_memcpy( m_audioBuf, ( uint8_t * )data + len1, end_pos ); + + len = len1 + end_pos; + } + else + fast_memcpy( m_audioBuf + start_pos, data, len ); + + m_nBufLen += len; + + return len; +} + +// return: delay in seconds between first and last sample in buffer +static float get_delay( void ) +{ + return ( float )m_nBufLen / ( float )ao_data.bps; +} + + Index: libao2/audio_out.c =================================================================== --- libao2/audio_out.c (revision 24089) +++ libao2/audio_out.c (working copy) @@ -62,6 +62,9 @@ #ifdef HAVE_DIRECTX extern ao_functions_t audio_out_dsound; #endif +#ifdef HAVE_DART +extern ao_functions_t audio_out_dart; +#endif #ifdef HAVE_DXR2 extern ao_functions_t audio_out_dxr2; #endif @@ -84,6 +87,9 @@ #ifdef HAVE_WIN32WAVEOUT &audio_out_win32, #endif +#ifdef HAVE_DART + &audio_out_dart, +#endif #ifdef MACOSX &audio_out_macosx, #endif Index: configure =================================================================== --- configure (revision 24089) +++ configure (working copy) @@ -395,6 +397,7 @@ --disable-nas disable NAS audio output [autodetect] --disable-sgiaudio disable SGI audio output [autodetect] --disable-sunaudio disable Sun audio output [autodetect] + --disable-dart disable DART audio output [autodetect] --disable-win32waveout disable Windows waveout audio output [autodetect] --disable-select disable using select() on the audio device [enable] @@ -524,6 +528,7 @@ _xv=auto _xvmc=no #auto when complete _sdl=auto +_dart=auto _directx=auto _win32waveout=auto _nas=auto @@ -819,6 +825,8 @@ --disable-xvmc) _xvmc=no ;; --enable-sdl) _sdl=yes ;; --disable-sdl) _sdl=no ;; + --enable-dart) _dart=yes ;; + --disable-dart) _dart=no ;; --enable-directx) _directx=yes ;; --disable-directx) _directx=no ;; --enable-win32waveout) _win32waveout=yes ;; @@ -4782,6 +4821,28 @@ echores "$_sdl" +echocheck "DART" +if test "$_dart" = auto; then + cat > $TMPC << EOF +#include +#include +int main( void ) { return 0; } +EOF + _dart=no; + cc_check -ldart -lmmpm2 && _dart=yes +fi +if test "$_dart" = yes ; then + _def_dart='#define HAVE_DART 1' + _libs_mplayer="$_libs_mplayer -ldart" + _aosrc="$_aosrc ao_dart.c" + _aomodules="dart $_aomodules" +else + _def_dart='#undef HAVE_DART' + _noaomodules="dart $_noaomodules" +fi +echores "$_dart" + + if win32; then echocheck "Windows waveout" @@ -8385,6 +8474,7 @@ $_def_sdl /* defined for SDLlib with keyrepeat bugs (before 1.2.1) */ $_def_sdlbuggy +$_def_dart $_def_directx $_def_ggi $_def_ggiwmh