[vlc-devel] Re: Corrected DirectX audio output patch
Sigmund Augdal
sigmunau at stud.ntnu.no
Sun May 22 13:16:34 CEST 2005
On Sun, May 22, 2005 at 09:11:10PM +1000, Matthew Armsby wrote:
> Corrected spacing to 4 space indentation.
>
> ========================
> Patch to select which device to output to for directx audio
>
> File affected:
> vlc-trunk/modules/audio_output/directx.c
> New Command line parameter:
> --directx-device N (0=primary, 1..(Number of devices)=device by number)
> When N is larger than number of devices, use last device in list.
> When N is less than 0, use primary device.
> GUI Preferences:
> 'DirectX audio output' appears in advanced settings
> (audio > Output Modules > DirectX)
> Defaults to primary device, so left editting as advanced setting.
> The 'select device by number' was designed to be similar to use of PortAudio.
Would it be possible to enumerate a list of strings describing the devices?
That would help usability quite a bit. See alsa.c for an example on how to
do that.
Sigmund
> Index: directx.c
> ===================================================================
> --- directx.c (revision 11090)
> +++ directx.c (working copy)
> @@ -143,7 +143,20 @@
>
> } notification_thread_t;
>
> +
> /*****************************************************************************
> + * directSoundDevice: List of available audio devices
> + *****************************************************************************/
> +struct directSoundDevice;
> +typedef struct directSoundDevice
> +{
> + LPGUID p_guid;
> + char *psz_description;
> + char *psz_module;
> + struct directSoundDevice *p_next;
> +} directSoundDevice;
> +
> +/*****************************************************************************
> * aout_sys_t: directx audio output method descriptor
> *****************************************************************************
> * This structure is part of the audio output thread descriptor.
> @@ -161,7 +174,7 @@
> notification_thread_t *p_notif; /* DirectSoundThread id */
>
> int b_playing; /* playing status */
> -
> + int i_device_id; /* User defined device index */
> int i_frame_size; /* Size in bytes of one frame */
>
> vlc_bool_t b_chan_reorder; /* do we need channel reordering */
> @@ -206,6 +219,10 @@
> /*****************************************************************************
> * Module descriptor
> *****************************************************************************/
> +#define FLOAT_TEXT N_("Output device")
> +#define FLOAT_LONGTEXT N_( \
> + "DirectX device number: 0 default device, 1..N device by number" \
> + "(Note that the default device appears as 0 AND another number)." )
> vlc_module_begin();
> set_description( _("DirectX audio output") );
> set_shortname( "DirectX" );
> @@ -213,6 +230,10 @@
> set_category( CAT_AUDIO );
> set_subcategory( SUBCAT_AUDIO_AOUT );
> add_shortcut( "directx" );
> + /* Add variable to VLC directx-device, default value 0, don't callback,
> + name the GUI field, GUI tooltip, display as advanced in preferences */
> + add_integer( "directx-device", 0, NULL, FLOAT_TEXT,
> + FLOAT_LONGTEXT, VLC_TRUE );
> set_callbacks( OpenAudio, CloseAudio );
> vlc_module_end();
>
> @@ -247,6 +268,13 @@
> p_aout->output.pf_play = Play;
> aout_VolumeSoftInit( p_aout );
>
> +
> + /* Retrieve output device id from config */
> + var_Create( p_aout, "directx-device", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT);
> + var_Get( p_aout, "directx-device", &val );
> + p_aout->output.p_sys->i_device_id = val.i_int;
> +
> +
> /* Initialise DirectSound */
> if( InitDirectSound( p_aout ) )
> {
> @@ -594,12 +622,73 @@
> }
>
> /*****************************************************************************
> + * CallBackDirectSoundEnum: callback to enumerate available devices
> + *****************************************************************************/
> +static int CALLBACK CallBackDirectSoundEnum (LPGUID p_guid, LPCSTR psz_desc,
> + LPCSTR psz_mod, LPVOID p_list)
> +{
> + directSoundDevice *p_ad;
> + directSoundDevice *p_otherad = (directSoundDevice *)p_list;
> + p_ad = malloc( sizeof( directSoundDevice ) );
> +
> + /* GUID == NULL is primary (default) device */
> + if (p_guid == NULL)
> + {
> + p_ad->p_guid = NULL;
> + }
> + else
> + {
> + p_ad->p_guid = malloc( sizeof( GUID ) );
> + memcpy( p_ad->p_guid, p_guid, sizeof( GUID ) );
> + }
> +
> + /* Desc & mod not used, kept for next author to use if needed */
> + p_ad->psz_description = malloc( sizeof(char) * (strlen(psz_desc) + 1) );
> + strcpy(p_ad->psz_description, psz_desc);
> + p_ad->psz_module = malloc( sizeof(char) * (strlen(psz_mod) + 1) );
> + strcpy(p_ad->psz_module, psz_mod);
> +
> + /* add to end of list */
> + p_ad->p_next = NULL;
> + while( p_otherad->p_next != NULL )
> + p_otherad = p_otherad->p_next;
> + p_otherad->p_next = p_ad;
> + return 1;
> +}
> +/*****************************************************************************
> + * DirectSoundEnumCleanup: free memory used when enumerating devices
> + *****************************************************************************/
> +static void DirectSoundEnumCleanup(directSoundDevice *p_headDev) {
> + directSoundDevice *p_currDev; /* current device */
> + directSoundDevice *p_delDev; /* pointer for deleting devices */
> + /* clean up: delete the enumerated devices */
> + p_currDev = p_headDev->p_next;
> + while ( p_currDev->p_next != NULL )
> + {
> + p_delDev = p_currDev;
> + p_currDev = p_currDev->p_next;
> + free( p_delDev->p_guid );
> + free( p_delDev );
> + }
> + free( p_currDev->p_guid );
> + free( p_currDev );
> + free( p_headDev );
> +}
> +/*****************************************************************************
> * InitDirectSound: handle all the gory details of DirectSound initialisation
> *****************************************************************************/
> static int InitDirectSound( aout_instance_t *p_aout )
> {
> HRESULT (WINAPI *OurDirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);
> + HRESULT (WINAPI *OurDirectSoundEnumerate)(LPDSENUMCALLBACK, LPVOID);
> + int i_selectedId; /* user defined index of device */
> + directSoundDevice *p_headDev; /* head of device list */
> + directSoundDevice *p_currDev; /* current device */
>
> + i_selectedId = p_aout->output.p_sys->i_device_id; /* get user selected */
> + p_headDev = malloc( sizeof( directSoundDevice ) );
> + p_headDev->p_next = NULL;
> +
> p_aout->output.p_sys->hdsound_dll = LoadLibrary("DSOUND.DLL");
> if( p_aout->output.p_sys->hdsound_dll == NULL )
> {
> @@ -615,15 +704,56 @@
> msg_Warn( p_aout, "GetProcAddress FAILED" );
> goto error;
> }
> -
> - /* Create the direct sound object */
> - if FAILED( OurDirectSoundCreate( NULL, &p_aout->output.p_sys->p_dsobject,
> +
> + /* Get DirectSoundEnumerate
> + (note getting ASCII call, not Unicode DirectSoundEnumerateW) */
> + OurDirectSoundEnumerate = (void *)GetProcAddress(
> + p_aout->output.p_sys->hdsound_dll,
> + "DirectSoundEnumerateA" );
> +
> + if( OurDirectSoundCreate == NULL )
> + {
> + msg_Warn( p_aout, "GetProcAddress DirectSoundEnumerateA FAILED" );
> + goto error;
> + }
> +
> + /* attempt enumeration */
> + if (FAILED ( OurDirectSoundEnumerate( CallBackDirectSoundEnum,
> + p_headDev ) ) )
> + {
> + msg_Warn( p_aout, "Enumeration of DirectSound devices FAILED" );
> + goto error;
> + }
> + else
> + {
> + /* ignore negative device id
> + (unnecessary, will default to first device)
> + ignore id past end of list
> + (default to last device) */
> +
> + /* loop through to the selected device */
> + p_currDev = p_headDev->p_next;
> + while ( p_currDev->p_next != NULL && 0 < i_selectedId )
> + {
> + i_selectedId--;
> + p_currDev = p_currDev->p_next;
> + }
> + }
> +
> + /* Create the direct sound object */
> + if FAILED( OurDirectSoundCreate( p_currDev->p_guid,
> + &p_aout->output.p_sys->p_dsobject,
> NULL ) )
> {
> + /* clean up enumerated devices */
> + DirectSoundEnumCleanup(p_headDev);
> msg_Warn( p_aout, "cannot create a direct sound device" );
> goto error;
> }
>
> + /* clean up enumerated devices */
> + DirectSoundEnumCleanup( p_headDev );
> +
> /* 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
--
Sigmund Augdal
Edgar B. Schieldropsv 29-14
N-7033 Trondheim
Norway
tlf: 91809129
--
This is the vlc-devel mailing-list, see http://www.videolan.org/vlc/
To unsubscribe, please read http://developers.videolan.org/lists.html
More information about the vlc-devel
mailing list