Index: libao2/ao_dart.c =================================================================== --- libao2/ao_dart.c (revision 0) +++ libao2/ao_dart.c (revision 0) @@ -0,0 +1,335 @@ +/* + * OS/2 DART audio output driver + * + * Copyright (c) 2007-2009 by KO Myung-Hun (komh@chollian.net) + * + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#define INCL_DOS +#define INCL_DOSERRORS +#include + +#include +#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" + +static ao_info_t info = { + "DART audio output", + "dart", + "KO Myung-Hun ", + "" +}; + +LIBAO_EXTERN(dart) + +#define OUTBURST_SAMPLES 512 +#define DEFAULT_DART_SAMPLES (OUTBURST_SAMPLES << 2) + +#define CHUNK_SIZE ao_data.outburst + +static uint8_t *m_audioBuf = NULL; + +static int m_nBufSize = 0; + +static volatile int m_fQuit = FALSE; +// may only be modified by DART's playback thread or while it is stopped +static volatile int m_iBufReadPos = 0; +// may only be modified by MPlayer's thread +static volatile int m_iBufWritePos = 0; + +// may only be called by MPlayer's thread +// return value may change between immediately following two calls, +// and the real number of free bytes might be larger! +static int buf_free(void) +{ + int nFree = m_iBufReadPos - m_iBufWritePos - CHUNK_SIZE; + + if (nFree < 0) + nFree += m_nBufSize; + + return nFree; +} + +// may only be called by DART's playback thread +// return value may change between immediately following two calls, +// and the real number of buffered bytes might be larger! +static int buf_used(void) +{ + int nUsed = m_iBufWritePos - m_iBufReadPos; + + if (nUsed < 0) + nUsed += m_nBufSize; + + return nUsed; +} + +static int write_buffer(unsigned char *data, int len) +{ + int nFirstLen = m_nBufSize - m_iBufWritePos; + int nFree = buf_free(); + + if (len > nFree) + len = nFree; + + if (nFirstLen > len) + nFirstLen = len; + + // till end of buffer + fast_memcpy(m_audioBuf + m_iBufWritePos, data, nFirstLen); + if (len > nFirstLen) { // we have to wrap around + // remaining part from beginning of buffer + fast_memcpy(m_audioBuf, data + nFirstLen, len - nFirstLen); + } + + m_iBufWritePos = (m_iBufWritePos + len) % m_nBufSize; + + return len; +} + +static int read_buffer(unsigned char *data, int len) +{ + int nFirstLen = m_nBufSize - m_iBufReadPos; + int nBuffered = buf_used(); + + if (len > nBuffered) + len = nBuffered; + + if (nFirstLen > len) + nFirstLen = len; + + // till end of buffer + fast_memcpy(data, m_audioBuf + m_iBufReadPos, nFirstLen); + if (len > nFirstLen) { // we have to wrap around + // remaining part from beginning of buffer + fast_memcpy(data + nFirstLen, m_audioBuf, len - nFirstLen); + } + + m_iBufReadPos = (m_iBufReadPos + len) % m_nBufSize; + + return len; +} + +// end ring buffer stuff + +static ULONG APIENTRY dart_audio_callback(PVOID pCBData, PVOID pBuffer, + ULONG ulSize) +{ + int nReadLen; + + nReadLen = read_buffer(pBuffer, ulSize); + if (nReadLen < ulSize && !m_fQuit) { + memset((uint8_t *)pBuffer + nReadLen, DART.bSilence, ulSize - nReadLen); + nReadLen = ulSize; + } + + return nReadLen; +} + +// 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 = arg; + + vol->left = vol->right = LOUSHORT(dartGetVolume()); + + return CONTROL_OK; + } + + case AOCONTROL_SET_VOLUME: + { + int mid; + ao_control_vol_t *vol = 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 dart:noshare\n" + " open DART in exclusive mode\n" + "\nOptions:\n" + " (no)share\n" + " Open DART in shareable or exclusive mode\n" + " bufsize=\n" + " Set buffer size to in samples(default: 2048)\n"); +} + +// open & set up audio device +// return: 1=success 0=fail +static int init(int rate, int channels, int format, int flags) +{ + int fShare = 1; + int nDartSamples = DEFAULT_DART_SAMPLES; + int nBytesPerSample; + + opt_t subopts[] = { + {"share", OPT_ARG_BOOL, &fShare, NULL}, + {"bufsize", OPT_ARG_INT, &nDartSamples, (opt_test_f)int_non_neg}, + {NULL} + }; + + if (subopt_parse(ao_subdevice, subopts) != 0) { + print_help(); + return 0; + } + + if (!nDartSamples) + nDartSamples = DEFAULT_DART_SAMPLES; + + mp_msg(MSGT_AO, MSGL_V, "DART: opened in %s mode, buffer size = %d sample(s)\n", + fShare ? "shareable" : "exclusive", nDartSamples); + + 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; + } + + nBytesPerSample = (af_fmt2bits(format) >> 3) * channels; + + if (dartInit(0, af_fmt2bits(format), rate, MCI_WAVE_FORMAT_PCM, channels, + 2, nBytesPerSample * nDartSamples, fShare, + dart_audio_callback, NULL)) + return 0; + + mp_msg(MSGT_AO, MSGL_V, "DART: obtained buffer size = %lu bytes\n", + DART.ulBufferSize); + + m_fQuit = FALSE; + + ao_data.channels = channels; + ao_data.samplerate = rate; + ao_data.format = format; + ao_data.bps = nBytesPerSample * rate; + ao_data.outburst = nBytesPerSample * OUTBURST_SAMPLES; + ao_data.buffersize = DART.ulBufferSize; + + // multiple of CHUNK_SIZE + m_nBufSize = ((DART.ulBufferSize << 2) / CHUNK_SIZE) * CHUNK_SIZE; + // and one more chunk plus round up + m_nBufSize += 2 * CHUNK_SIZE; + + m_audioBuf = malloc(m_nBufSize); + + m_iBufReadPos = 0; + m_iBufWritePos = 0; + + dartPlay(); + + // might cause PM DLLs to be loaded which incorrectly enable SIG_FPE, + // which AAC decoding might trigger. + // so, mask off all floating-point exceptions. + _control87(MCW_EM, MCW_EM); + + return 1; +} + +// close audio device +static void uninit(int immed) +{ + m_fQuit = TRUE; + + if (!immed) { + while (DART.fPlaying) + DosSleep(1); + } + + dartClose(); + + free(m_audioBuf); +} + +// stop playing and empty buffers (for seeking/pause) +static void reset(void) +{ + dartPause(); + + // Reset ring-buffer state + m_iBufReadPos = 0; + m_iBufWritePos = 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 buf_free(); +} + +// 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) +{ + + if (!(flags & AOPLAY_FINAL_CHUNK)) + len = (len / ao_data.outburst) * ao_data.outburst; + + return write_buffer(data, len); +} + +// return: delay in seconds between first and last sample in buffer +static float get_delay(void) +{ + int nBuffered = m_nBufSize - CHUNK_SIZE - buf_free(); // could be less + + return (float)nBuffered / (float)ao_data.bps; +} + + Index: libao2/audio_out.c =================================================================== --- libao2/audio_out.c (revision 28593) +++ libao2/audio_out.c (working copy) @@ -47,6 +47,7 @@ extern ao_functions_t audio_out_sgi; extern ao_functions_t audio_out_win32; extern ao_functions_t audio_out_dsound; +extern ao_functions_t audio_out_dart; extern ao_functions_t audio_out_dxr2; extern ao_functions_t audio_out_ivtv; extern ao_functions_t audio_out_v4l2; @@ -63,6 +64,9 @@ #ifdef CONFIG_WIN32WAVEOUT &audio_out_win32, #endif +#ifdef CONFIG_DART + &audio_out_dart, +#endif #ifdef CONFIG_COREAUDIO &audio_out_macosx, #endif Index: Makefile =================================================================== --- Makefile (revision 28593) +++ Makefile (working copy) @@ -545,6 +545,7 @@ SRCS_MPLAYER-$(CACA) += libvo/vo_caca.c SRCS_MPLAYER-$(COREAUDIO) += libao2/ao_macosx.c SRCS_MPLAYER-$(COREVIDEO) += libvo/vo_macosx.m +SRCS_MPLAYER-$(DART) += libao2/ao_dart.c SRCS_MPLAYER-$(DFBMGA) += libvo/vo_dfbmga.c SRCS_MPLAYER-$(DGA) += libvo/vo_dga.c SRCS_MPLAYER-$(DIRECT3D) += libvo/vo_direct3d.c libvo/w32_common.c Index: configure =================================================================== --- configure (revision 28593) +++ configure (working copy) @@ -414,6 +415,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] @@ -586,6 +589,7 @@ _esd=auto _pulse=auto _jack=auto +_dart=auto _openal=auto _libcdio=auto _liblzo=auto @@ -952,6 +958,8 @@ --disable-jack) _jack=no ;; --enable-openal) _openal=yes ;; --disable-openal) _openal=no ;; + --enable-dart) _dart=yes ;; + --disable-dart) _dart=no ;; --enable-mad) _mad=yes ;; --disable-mad) _mad=no ;; --enable-mp3lame) _mp3lame=yes ;; @@ -5611,6 +5643,30 @@ fi #if irix +if os2 ; then +echocheck "DART" +if test "$_dart" = auto; then + cat > $TMPC << EOF +#include +#include +int main( void ) { return 0; } +EOF + _dart=no; + cc_check -ldart && _dart=yes +fi +if test "$_dart" = yes ; then + def_dart='#define CONFIG_DART 1' + _libs_mplayer="$_libs_mplayer -ldart" + _aosrc="$_aosrc ao_dart.c" + _aomodules="dart $_aomodules" +else + def_dart='#undef CONFIG_DART' + _noaomodules="dart $_noaomodules" +fi +echores "$_dart" +fi #if os2 + + # set default CD/DVD devices if win32 || os2 ; then default_cdrom_device="D:" @@ -8045,6 +8101,7 @@ CDDB = $_cddb COREAUDIO = $_coreaudio COREVIDEO = $_corevideo +DART = $_dart DFBMGA = $_dfbmga DGA = $_dga DIRECT3D = $_direct3d @@ -8485,6 +8543,7 @@ $def_alsa9 $def_arts $def_coreaudio +$def_dart $def_esd $def_esd_latency $def_jack Index: Changelog =================================================================== --- Changelog (revision 28593) +++ Changelog (working copy) @@ -98,6 +98,7 @@ * factorize code in vo_wii * removed unnecessary code from vo x11, xv, xvmc * automatic detection of hw acceleration (vo gl:yuv=x) for vo_gl + * add OS/2 DART audio driver (-ao dart) MEncoder: * check for system-wide configuration file in MEncoder Index: DOCS/man/en/mplayer.1 =================================================================== --- DOCS/man/en/mplayer.1 (revision 28593) +++ DOCS/man/en/mplayer.1 (working copy) @@ -2836,6 +2836,18 @@ .PD 1 . .TP +.B dart (OS/2 only) +OS/2 DART audio output driver +.PD 0 +.RSs +.IPs (no)share +Open DART in shareable or exclusive mode. +.IPs bufsize= +Set buffer size to in samples (default: 2048). +.RE +.PD 1 +. +.TP .B dxr2 (also see \-dxr2) (DXR2 only) Creative DXR2 specific output driver .