[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