17 changed files with 2303 additions and 242 deletions
File diff suppressed because it is too large
@ -0,0 +1,31 @@ |
|||
###############################################################################
|
|||
# vlc (VideoLAN Client) DirectX module Makefile
|
|||
# (c)2001 VideoLAN
|
|||
###############################################################################
|
|||
|
|||
#
|
|||
# Objects
|
|||
#
|
|||
|
|||
PLUGIN_C = directx.o vout_directx.o aout_directx.o |
|||
BUILTIN_C = $(PLUGIN_C:%.o=BUILTIN_%.o) |
|||
|
|||
ALL_OBJ = $(PLUGIN_C) $(BUILTIN_C) |
|||
|
|||
#
|
|||
# Virtual targets
|
|||
#
|
|||
|
|||
include ../../Makefile.modules |
|||
|
|||
#
|
|||
# Real targets
|
|||
#
|
|||
|
|||
../../lib/directx.so: $(PLUGIN_C) |
|||
$(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS) $(LIB_DIRECTX) |
|||
|
|||
../../lib/directx.a: $(BUILTIN_C) |
|||
ar r $@ $^ |
|||
$(RANLIB) $@ |
|||
|
|||
@ -0,0 +1,553 @@ |
|||
/*****************************************************************************
|
|||
* aout_directx.c: Windows DirectX audio output method |
|||
***************************************************************************** |
|||
* Copyright (C) 1999, 2000 VideoLAN |
|||
* $Id: aout_directx.c,v 1.1 2001/06/02 01:09:03 sam Exp $ |
|||
* |
|||
* Authors: Gildas Bazin <gbazin@netcourrier.com> |
|||
* |
|||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA. |
|||
*****************************************************************************/ |
|||
|
|||
#define MODULE_NAME directx |
|||
#include "modules_inner.h" |
|||
|
|||
/* The most important this to do for now is to fix the audio bug we've got
|
|||
* on startup: the audio will start later than the video (sometimes) and |
|||
* is trying to catching up with it. |
|||
* At first sight it seems to be a scheduling problem |
|||
*/ |
|||
|
|||
|
|||
/*****************************************************************************
|
|||
* Preamble |
|||
*****************************************************************************/ |
|||
#include "defs.h" |
|||
|
|||
#include <errno.h> /* ENOMEM */ |
|||
#include <fcntl.h> /* open(), O_WRONLY */ |
|||
#include <string.h> /* strerror() */ |
|||
#include <unistd.h> /* write(), close() */ |
|||
#include <stdio.h> /* "intf_msg.h" */ |
|||
#include <stdlib.h> /* calloc(), malloc(), free() */ |
|||
|
|||
#include "config.h" |
|||
#include "common.h" /* boolean_t, byte_t */ |
|||
#include "threads.h" |
|||
#include "mtime.h" |
|||
#include "tests.h" |
|||
|
|||
#include "directx.h" |
|||
|
|||
#include "audio_output.h" /* aout_thread_t */ |
|||
|
|||
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ |
|||
#include "main.h" |
|||
|
|||
#include "modules.h" |
|||
|
|||
/*****************************************************************************
|
|||
* aout_sys_t: directx audio output method descriptor |
|||
***************************************************************************** |
|||
* This structure is part of the audio output thread descriptor. |
|||
* It describes the direct sound specific properties of an audio device. |
|||
*****************************************************************************/ |
|||
|
|||
typedef struct aout_sys_s |
|||
{ |
|||
LPDIRECTSOUND p_dsobject; /* main Direct Sound object */ |
|||
|
|||
LPDIRECTSOUNDBUFFER p_dsbuffer_primary; /* the actual sound card buffer
|
|||
(not used directly) */ |
|||
|
|||
LPDIRECTSOUNDBUFFER p_dsbuffer; /* the sound buffer we use (direct sound
|
|||
* takes care of mixing all the |
|||
* secondary buffers into the primary) */ |
|||
|
|||
long l_buffer_size; /* secondary sound buffer size */ |
|||
long l_write_position; /* next write position for the buffer */ |
|||
|
|||
boolean_t b_active; |
|||
|
|||
} aout_sys_t; |
|||
|
|||
/*****************************************************************************
|
|||
* Local prototypes. |
|||
*****************************************************************************/ |
|||
static int aout_Probe ( probedata_t *p_data ); |
|||
static int aout_Open ( aout_thread_t *p_aout ); |
|||
static int aout_SetFormat ( aout_thread_t *p_aout ); |
|||
static long aout_GetBufInfo ( aout_thread_t *p_aout, long l_buffer_info ); |
|||
static void aout_Play ( aout_thread_t *p_aout, |
|||
byte_t *buffer, int i_size ); |
|||
static void aout_Close ( aout_thread_t *p_aout ); |
|||
|
|||
/* local function */ |
|||
static int windx_CreateSecondaryBuffer( aout_thread_t *p_aout ); |
|||
|
|||
/*****************************************************************************
|
|||
* Functions exported as capabilities. They are declared as static so that |
|||
* we don't pollute the namespace too much. |
|||
*****************************************************************************/ |
|||
void _M( aout_getfunctions )( function_list_t * p_function_list ) |
|||
{ |
|||
p_function_list->pf_probe = aout_Probe; |
|||
p_function_list->functions.aout.pf_open = aout_Open; |
|||
p_function_list->functions.aout.pf_setformat = aout_SetFormat; |
|||
p_function_list->functions.aout.pf_getbufinfo = aout_GetBufInfo; |
|||
p_function_list->functions.aout.pf_play = aout_Play; |
|||
p_function_list->functions.aout.pf_close = aout_Close; |
|||
} |
|||
|
|||
/*****************************************************************************
|
|||
* aout_Probe: probe the audio device and return a score |
|||
***************************************************************************** |
|||
* This function tries to probe for a Direct Sound device and returns a |
|||
* score to the plugin manager so that it can select the best plugin. |
|||
*****************************************************************************/ |
|||
static int aout_Probe( probedata_t *p_data ) |
|||
{ |
|||
/* For now just assume the computer has a sound device */ |
|||
if( TestMethod( AOUT_METHOD_VAR, "directx" ) ) |
|||
{ |
|||
return( 999 ); |
|||
} |
|||
return( 400 ); |
|||
} |
|||
|
|||
/*****************************************************************************
|
|||
* aout_Open: open the audio device |
|||
***************************************************************************** |
|||
* This function opens and setups Direct Sound. |
|||
*****************************************************************************/ |
|||
static int aout_Open( aout_thread_t *p_aout ) |
|||
{ |
|||
#if 0 |
|||
HRESULT dsresult; |
|||
DSBUFFERDESC dsbuffer_desc; |
|||
WAVEFORMATEX waveformat; |
|||
#endif |
|||
|
|||
/* Allocate structure */ |
|||
p_aout->p_sys = malloc( sizeof( aout_sys_t ) ); |
|||
|
|||
if( p_aout->p_sys == NULL ) |
|||
{ |
|||
intf_ErrMsg( "aout error: %s", strerror(ENOMEM) ); |
|||
return( 1 ); |
|||
} |
|||
|
|||
/* Initialize some variables */ |
|||
p_aout->p_sys->p_dsobject = NULL; |
|||
p_aout->p_sys->p_dsbuffer_primary = NULL; |
|||
p_aout->p_sys->p_dsbuffer = NULL; |
|||
|
|||
p_aout->psz_device = 0; |
|||
p_aout->i_format = AOUT_FORMAT_DEFAULT; |
|||
p_aout->i_channels = 1 + main_GetIntVariable( AOUT_STEREO_VAR, |
|||
AOUT_STEREO_DEFAULT ); |
|||
p_aout->l_rate = main_GetIntVariable( AOUT_RATE_VAR, |
|||
AOUT_RATE_DEFAULT ); |
|||
|
|||
/* Create the direct sound object */ |
|||
if( DirectSoundCreate(NULL, &p_aout->p_sys->p_dsobject, NULL) != DS_OK ) |
|||
{ |
|||
intf_WarnMsg( 3, "aout: can't create a direct sound device "); |
|||
p_aout->p_sys->p_dsobject = NULL; |
|||
return( 1 ); |
|||
} |
|||
|
|||
/* Set DirectSound Cooperative level, ie what control we want over Windows
|
|||
* sound device. In our case, DSSCL_EXCLUSIVE means that we can modify the |
|||
* settings of the primary buffer, but also that only the sound of our |
|||
* application will be hearable when it will have the focus. |
|||
* !!! (this is not really working as intended yet because to set the |
|||
* cooperative level you need the window handle of your application, and |
|||
* I don't know of any easy way to get it. Especially since we might play |
|||
* sound without any video, and so what window handle should we use ??? |
|||
* The hack for now is to use the Desktop window handle - it seems to be |
|||
* working */ |
|||
if( IDirectSound_SetCooperativeLevel(p_aout->p_sys->p_dsobject, |
|||
GetDesktopWindow(), |
|||
DSSCL_EXCLUSIVE) ) |
|||
{ |
|||
intf_WarnMsg( 3, "aout: can't set direct sound cooperative level "); |
|||
} |
|||
|
|||
#if 0 |
|||
/* Obtain (not create) Direct Sound primary buffer */ |
|||
memset( &dsbuffer_desc, 0, sizeof(DSBUFFERDESC) ); |
|||
dsbuffer_desc.dwSize = sizeof(DSBUFFERDESC); |
|||
dsbuffer_desc.dwFlags = DSBCAPS_PRIMARYBUFFER; |
|||
intf_WarnMsg( 3, "aout: Create direct sound primary buffer "); |
|||
dsresult = IDirectSound_CreateSoundBuffer(p_aout->p_sys->p_dsobject, |
|||
&dsbuffer_desc, |
|||
&p_aout->p_sys->p_dsbuffer_primary, |
|||
NULL); |
|||
if( dsresult != DS_OK ) |
|||
{ |
|||
intf_WarnMsg( 3, "aout: can't create direct sound primary buffer "); |
|||
IDirectSound_Release( p_aout->p_sys->p_dsobject ); |
|||
p_aout->p_sys->p_dsobject = NULL; |
|||
p_aout->p_sys->p_dsbuffer_primary = NULL; |
|||
return( 1 ); |
|||
} |
|||
|
|||
/* Set Direct Sound primary buffer format because the default value set by
|
|||
* Windows is usually not the high quality value */ |
|||
memset(&waveformat, 0, sizeof(WAVEFORMATEX)); |
|||
waveformat.wFormatTag = WAVE_FORMAT_PCM; |
|||
waveformat.nChannels = 2; |
|||
waveformat.nSamplesPerSec = 44100; |
|||
waveformat.wBitsPerSample = 16; |
|||
waveformat.nBlockAlign = waveformat.wBitsPerSample / 8 * |
|||
waveformat.nChannels; |
|||
waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec * |
|||
waveformat.nBlockAlign; |
|||
|
|||
dsresult = IDirectSoundBuffer_SetFormat(p_aout->p_sys->p_dsbuffer_primary, |
|||
&waveformat); |
|||
if( dsresult != DS_OK ) |
|||
{ |
|||
intf_WarnMsg( 3, "aout: can't set primary buffer format"); |
|||
} |
|||
|
|||
/* ensure the primary buffer is playing. We won't actually hear anything
|
|||
* until the secondary buffer is playing */ |
|||
dsresult = IDirectSoundBuffer_Play( p_aout->p_sys->p_dsbuffer_primary, |
|||
0, |
|||
0, |
|||
DSBPLAY_LOOPING); |
|||
if( dsresult != DS_OK ) |
|||
{ |
|||
intf_WarnMsg( 3, "aout: can't play direct sound primary buffer "); |
|||
IDirectSound_Release( p_aout->p_sys->p_dsbuffer_primary ); |
|||
IDirectSound_Release( p_aout->p_sys->p_dsobject ); |
|||
p_aout->p_sys->p_dsobject = NULL; |
|||
p_aout->p_sys->p_dsbuffer_primary = NULL; |
|||
return( 1 ); |
|||
} |
|||
#endif |
|||
|
|||
/* Now create the buffer that we'll actually use: the secondary buffer */ |
|||
if( windx_CreateSecondaryBuffer( p_aout ) ) |
|||
{ |
|||
intf_WarnMsg( 3, "aout: can't create direct sound secondary buffer "); |
|||
#if 0 |
|||
IDirectSound_Release( p_aout->p_sys->p_dsbuffer_primary ); |
|||
#endif |
|||
IDirectSound_Release( p_aout->p_sys->p_dsobject ); |
|||
p_aout->p_sys->p_dsobject = NULL; |
|||
p_aout->p_sys->p_dsbuffer_primary = NULL; |
|||
p_aout->p_sys->p_dsbuffer = NULL; |
|||
return( 1 ); |
|||
} |
|||
|
|||
return( 0 ); |
|||
} |
|||
|
|||
/*****************************************************************************
|
|||
* aout_SetFormat: reset the audio device and sets its format |
|||
***************************************************************************** |
|||
* This functions set a new audio format. |
|||
* For this we need to close the current secondary buffer and create another |
|||
* one with the desired format. |
|||
*****************************************************************************/ |
|||
static int aout_SetFormat( aout_thread_t *p_aout ) |
|||
{ |
|||
HRESULT dsresult; |
|||
|
|||
/* first release the current secondary buffer */ |
|||
if( p_aout->p_sys->p_dsbuffer != NULL ) |
|||
{ |
|||
IDirectSoundBuffer_Release( p_aout->p_sys->p_dsbuffer ); |
|||
p_aout->p_sys->p_dsbuffer = NULL; |
|||
} |
|||
|
|||
/* then create a new secondary buffer */ |
|||
dsresult = windx_CreateSecondaryBuffer( p_aout ); |
|||
if( dsresult != DS_OK ) |
|||
{ |
|||
intf_WarnMsg( 3, "aout: WinDX aout_SetFormat cannot create buffer"); |
|||
return( 1 ); |
|||
} |
|||
|
|||
return( 0 ); |
|||
} |
|||
|
|||
/*****************************************************************************
|
|||
* aout_GetBufInfo: buffer status query |
|||
***************************************************************************** |
|||
* returns the number of bytes in the audio buffer compared to the size of |
|||
* l_buffer_limit... |
|||
*****************************************************************************/ |
|||
static long aout_GetBufInfo( aout_thread_t *p_aout, long l_buffer_limit ) |
|||
{ |
|||
long l_play_position, l_notused, l_result; |
|||
HRESULT dsresult; |
|||
|
|||
dsresult = IDirectSoundBuffer_GetCurrentPosition(p_aout->p_sys->p_dsbuffer, |
|||
&l_play_position, &l_notused); |
|||
if( dsresult == DSERR_BUFFERLOST ) |
|||
{ |
|||
IDirectSoundBuffer_Restore( p_aout->p_sys->p_dsbuffer ); |
|||
dsresult = IDirectSoundBuffer_GetCurrentPosition( |
|||
p_aout->p_sys->p_dsbuffer, |
|||
&l_play_position, &l_notused |
|||
); |
|||
} |
|||
if( dsresult != DS_OK ) |
|||
{ |
|||
intf_WarnMsg( 3, "aout: WinDX aout_GetBufInfo cannot get current pos"); |
|||
return( l_buffer_limit ); |
|||
} |
|||
|
|||
l_result = ((p_aout->p_sys->l_write_position >= l_play_position) ? |
|||
(p_aout->p_sys->l_write_position - l_play_position)/2 |
|||
: (p_aout->p_sys->l_buffer_size - l_play_position |
|||
+ p_aout->p_sys->l_write_position)/2 ); |
|||
|
|||
intf_WarnMsg( 5, "aout: WinDX aout_GetBufInfo: %li", l_result); |
|||
return l_result; |
|||
} |
|||
|
|||
/*****************************************************************************
|
|||
* aout_Play: play a sound buffer |
|||
***************************************************************************** |
|||
* This function writes a buffer of i_length bytes |
|||
*****************************************************************************/ |
|||
static void aout_Play( aout_thread_t *p_aout, byte_t *buffer, int i_size ) |
|||
{ |
|||
VOID *p_write_position, *p_start_buffer; |
|||
long l_bytes1, l_bytes2; |
|||
long l_play_position, l_notused, l_buffer_free_length; |
|||
HRESULT dsresult; |
|||
|
|||
/* We want to copy data to the circular sound buffer, so first we need to
|
|||
* find out were in the buffer we can write our data */ |
|||
dsresult = IDirectSoundBuffer_GetCurrentPosition(p_aout->p_sys->p_dsbuffer, |
|||
&l_play_position, |
|||
&l_notused); |
|||
if( dsresult == DSERR_BUFFERLOST ) |
|||
{ |
|||
IDirectSoundBuffer_Restore( p_aout->p_sys->p_dsbuffer ); |
|||
dsresult = IDirectSoundBuffer_GetCurrentPosition( |
|||
p_aout->p_sys->p_dsbuffer, |
|||
&l_play_position, &l_notused |
|||
); |
|||
} |
|||
if( dsresult != DS_OK ) |
|||
{ |
|||
intf_WarnMsg( 3, "aout: WinDX aout_Play can'get buffer position"); |
|||
} |
|||
|
|||
/* check that we are not overflowing the circular buffer (everything should
|
|||
* be alright but just in case) */ |
|||
l_buffer_free_length = l_play_position - p_aout->p_sys->l_write_position; |
|||
if( l_buffer_free_length <= 0 ) |
|||
l_buffer_free_length += p_aout->p_sys->l_buffer_size ; |
|||
|
|||
if( i_size > l_buffer_free_length ) |
|||
{ |
|||
intf_WarnMsg( 3, "aout: WinDX aout_Play buffer overflow: size %i, free %i !!!", i_size, l_buffer_free_length); |
|||
intf_WarnMsg( 3, "aout: WinDX aout_Play buffer overflow: writepos %i, readpos %i !!!", l_play_position, p_aout->p_sys->l_write_position); |
|||
/*i_size = l_buffer_free_length;*/ |
|||
} |
|||
|
|||
/* Before copying anything, we have to lock the buffer */ |
|||
dsresult = IDirectSoundBuffer_Lock( p_aout->p_sys->p_dsbuffer, |
|||
p_aout->p_sys->l_write_position, /* Offset of lock start */ |
|||
i_size, /* Number of bytes to lock */ |
|||
&p_write_position, /* Address of lock start */ |
|||
&l_bytes1, /* Count of bytes locked before wrap around */ |
|||
&p_start_buffer, /* Buffer adress (if wrap around) */ |
|||
&l_bytes2, /* Count of bytes after wrap around */ |
|||
0); /* Flags */ |
|||
if( dsresult == DSERR_BUFFERLOST ) |
|||
{ |
|||
IDirectSoundBuffer_Restore( p_aout->p_sys->p_dsbuffer ); |
|||
dsresult = IDirectSoundBuffer_Lock( p_aout->p_sys->p_dsbuffer, |
|||
p_aout->p_sys->l_write_position, |
|||
i_size, |
|||
&p_write_position, |
|||
&l_bytes1, |
|||
&p_start_buffer, |
|||
&l_bytes2, |
|||
0); |
|||
|
|||
} |
|||
if( dsresult != DS_OK ) |
|||
{ |
|||
intf_WarnMsg( 3, "aout: WinDX aout_Play can't lock buffer"); |
|||
return; |
|||
} |
|||
|
|||
/* Now do the actual memcopy (two memcpy because the buffer is circular) */ |
|||
memcpy( p_write_position, buffer, l_bytes1 ); |
|||
if( p_start_buffer != NULL ) |
|||
memcpy( p_start_buffer, buffer + l_bytes1, l_bytes2 ); |
|||
|
|||
/* Now the data has been copied, unlock the buffer */ |
|||
IDirectSoundBuffer_Unlock( p_aout->p_sys->p_dsbuffer, |
|||
p_write_position, l_bytes1, p_start_buffer, l_bytes2 ); |
|||
|
|||
/* Update the write position index of the buffer*/ |
|||
p_aout->p_sys->l_write_position += i_size; |
|||
p_aout->p_sys->l_write_position %= p_aout->p_sys->l_buffer_size; |
|||
|
|||
/* The play function has no effect if the buffer is already playing */ |
|||
dsresult = IDirectSoundBuffer_Play( p_aout->p_sys->p_dsbuffer, |
|||
0, /* Unused */ |
|||
0, /* Unused */ |
|||
DSBPLAY_LOOPING ); /* Flags */ |
|||
if( dsresult == DSERR_BUFFERLOST ) |
|||
{ |
|||
IDirectSoundBuffer_Restore( p_aout->p_sys->p_dsbuffer ); |
|||
dsresult = IDirectSoundBuffer_Play( p_aout->p_sys->p_dsbuffer, |
|||
0, /* Unused */ |
|||
0, /* Unused */ |
|||
DSBPLAY_LOOPING ); /* Flags */ |
|||
} |
|||
if( dsresult != DS_OK ) |
|||
{ |
|||
intf_WarnMsg( 3, "aout: WinDX aout_Play can't play buffer"); |
|||
return; |
|||
} |
|||
|
|||
} |
|||
|
|||
/*****************************************************************************
|
|||
* aout_Close: close the audio device |
|||
*****************************************************************************/ |
|||
static void aout_Close( aout_thread_t *p_aout ) |
|||
{ |
|||
/* make sure the buffer isn't playing */ |
|||
if( p_aout->p_sys->p_dsbuffer != NULL ) |
|||
{ |
|||
IDirectSoundBuffer_Stop( p_aout->p_sys->p_dsbuffer ); |
|||
} |
|||
|
|||
/* first release the secondary buffer */ |
|||
if( p_aout->p_sys->p_dsbuffer != NULL ) |
|||
{ |
|||
IDirectSoundBuffer_Release( p_aout->p_sys->p_dsbuffer ); |
|||
p_aout->p_sys->p_dsbuffer = NULL; |
|||
} |
|||
|
|||
/* then release the primary buffer */ |
|||
if( p_aout->p_sys->p_dsbuffer_primary != NULL ) |
|||
{ |
|||
IDirectSoundBuffer_Release( p_aout->p_sys->p_dsbuffer_primary ); |
|||
p_aout->p_sys->p_dsbuffer_primary = NULL; |
|||
} |
|||
|
|||
/* finally release the DirectSound object */ |
|||
if( p_aout->p_sys->p_dsobject != NULL ) |
|||
{ |
|||
IDirectSound_Release( p_aout->p_sys->p_dsobject ); |
|||
p_aout->p_sys->p_dsobject = NULL; |
|||
} |
|||
|
|||
/* Close the Output. */ |
|||
if ( p_aout->p_sys != NULL ) |
|||
{ |
|||
free( p_aout->p_sys ); |
|||
p_aout->p_sys = NULL; |
|||
} |
|||
} |
|||
|
|||
/*****************************************************************************
|
|||
* windx_CreateSecondaryBuffer |
|||
***************************************************************************** |
|||
* This function creates the buffer we'll use to play audio. |
|||
* In DirectSound there are two kinds of buffers: |
|||
* - the primary buffer: which is the actual buffer that the soundcard plays |
|||
* - the secondary buffer(s): these buffers are the one actually used by |
|||
* applications and DirectSound takes care of mixing them into the primary. |
|||
* |
|||
* Once you create a secondary buffer, you cannot change its format anymore so |
|||
* you have to release the current and create another one. |
|||
*****************************************************************************/ |
|||
static int windx_CreateSecondaryBuffer( aout_thread_t *p_aout ) |
|||
{ |
|||
WAVEFORMATEX waveformat; |
|||
DSBUFFERDESC dsbdesc; |
|||
DSBCAPS dsbcaps; |
|||
HRESULT dsresult; |
|||
|
|||
/* First set the buffer format */ |
|||
memset(&waveformat, 0, sizeof(WAVEFORMATEX)); |
|||
waveformat.wFormatTag = WAVE_FORMAT_PCM; |
|||
waveformat.nChannels = p_aout->i_channels; |
|||
waveformat.nSamplesPerSec = p_aout->l_rate; |
|||
waveformat.wBitsPerSample = 16; |
|||
waveformat.nBlockAlign = waveformat.wBitsPerSample / 8 * |
|||
waveformat.nChannels; |
|||
waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec * |
|||
waveformat.nBlockAlign; |
|||
|
|||
/* Then fill in the descriptor */ |
|||
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); |
|||
dsbdesc.dwSize = sizeof(DSBUFFERDESC); |
|||
dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2/* Better position accuracy */ |
|||
| DSBCAPS_GLOBALFOCUS; /* Allows background playing */ |
|||
/* | DSBCAPS_CTRLPAN
|
|||
| DSBCAPS_CTRLVOLUME |
|||
| DSBCAPS_CTRLFREQUENCY; |
|||
*/ |
|||
dsbdesc.dwBufferBytes = waveformat.nAvgBytesPerSec * 4; /* 4 sec buffer */ |
|||
dsbdesc.lpwfxFormat = &waveformat; |
|||
|
|||
if( IDirectSound_CreateSoundBuffer( p_aout->p_sys->p_dsobject, |
|||
&dsbdesc, |
|||
&p_aout->p_sys->p_dsbuffer, |
|||
NULL) != DS_OK ) |
|||
{ |
|||
intf_WarnMsg( 3, "aout: can't create direct sound secondary buffer "); |
|||
p_aout->p_sys->p_dsbuffer = NULL; |
|||
return( 1 ); |
|||
} |
|||
|
|||
/* backup the size of the secondary sound buffer */ |
|||
memset(&dsbcaps, 0, sizeof(DSBCAPS)); |
|||
dsbcaps.dwSize = sizeof(DSBCAPS); |
|||
IDirectSoundBuffer_GetCaps( p_aout->p_sys->p_dsbuffer, &dsbcaps ); |
|||
p_aout->p_sys->l_buffer_size = dsbcaps.dwBufferBytes; |
|||
p_aout->p_sys->l_write_position = 0; |
|||
intf_WarnMsg( 3, "aout: WinDX WinDX_CreateSecondaryBuffer: %li", |
|||
p_aout->p_sys->l_buffer_size); |
|||
|
|||
/* make sure the buffer isn't playing */ |
|||
IDirectSoundBuffer_Stop( p_aout->p_sys->p_dsbuffer ); |
|||
|
|||
/* reset play position, just to be sure (and after some tests it seems
|
|||
* indeed necessary */ |
|||
dsresult = IDirectSoundBuffer_SetCurrentPosition(p_aout->p_sys->p_dsbuffer, |
|||
0 ); |
|||
if( dsresult == DSERR_BUFFERLOST ) |
|||
{ |
|||
IDirectSoundBuffer_Restore( p_aout->p_sys->p_dsbuffer ); |
|||
dsresult = IDirectSoundBuffer_SetCurrentPosition( |
|||
p_aout->p_sys->p_dsbuffer, |
|||
0 ); |
|||
} |
|||
if( dsresult != DS_OK ) |
|||
{ |
|||
intf_WarnMsg( 3, "aout: WinDX CreateSecondary cannot wet current pos"); |
|||
} |
|||
|
|||
return( 0 ); |
|||
} |
|||
|
|||
@ -0,0 +1,75 @@ |
|||
/*****************************************************************************
|
|||
* directx.c : Windows DirectX plugin for vlc |
|||
***************************************************************************** |
|||
* Copyright (C) 2000, 2001 VideoLAN |
|||
* $Id: directx.c,v 1.1 2001/06/02 01:09:03 sam Exp $ |
|||
* |
|||
* Authors: Gildas Bazin <gbazin@netcourrier.com> |
|||
* |
|||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA. |
|||
*****************************************************************************/ |
|||
|
|||
#define MODULE_NAME directx |
|||
#include "modules_inner.h" |
|||
|
|||
/*****************************************************************************
|
|||
* Preamble |
|||
*****************************************************************************/ |
|||
#include "defs.h" |
|||
|
|||
#include <stdlib.h> /* malloc(), free() */ |
|||
|
|||
#include "config.h" |
|||
#include "common.h" /* boolean_t, byte_t */ |
|||
#include "threads.h" |
|||
#include "mtime.h" |
|||
|
|||
#include "audio_output.h" |
|||
|
|||
#include "video.h" |
|||
#include "video_output.h" |
|||
|
|||
#include "modules.h" |
|||
#include "modules_export.h" |
|||
|
|||
/*****************************************************************************
|
|||
* Capabilities defined in the other files. |
|||
*****************************************************************************/ |
|||
void _M( aout_getfunctions )( function_list_t * p_function_list ); |
|||
void _M( vout_getfunctions )( function_list_t * p_function_list ); |
|||
|
|||
/*****************************************************************************
|
|||
* Building configuration tree |
|||
*****************************************************************************/ |
|||
MODULE_CONFIG_START |
|||
ADD_WINDOW( "Configuration for Windows DirectX module" ) |
|||
ADD_COMMENT( "For now, the Windows DirectX module cannot be configured" ) |
|||
MODULE_CONFIG_STOP |
|||
|
|||
MODULE_INIT_START |
|||
p_module->i_capabilities = MODULE_CAPABILITY_NULL |
|||
| MODULE_CAPABILITY_VOUT |
|||
| MODULE_CAPABILITY_AOUT; |
|||
p_module->psz_longname = "DirectX module"; |
|||
MODULE_INIT_STOP |
|||
|
|||
MODULE_ACTIVATE_START |
|||
_M( aout_getfunctions )( &p_module->p_functions->aout ); |
|||
_M( vout_getfunctions )( &p_module->p_functions->vout ); |
|||
MODULE_ACTIVATE_STOP |
|||
|
|||
MODULE_DEACTIVATE_START |
|||
MODULE_DEACTIVATE_STOP |
|||
|
|||
File diff suppressed because it is too large
Loading…
Reference in new issue