Differenze tra le versioni di "Conoscere con le funzioni esterne di ALSA i dispositivi audio presenti nel sistema"

Da Gambas-it.org - Wikipedia.
(Creata pagina con 'Alcune funzioni esterne del API di ALSA consentono di conoscere quali sono le porte di entrata e di uscita dell'audio digitale delle schede audio presenti nel proprio sistema....')
 
 
(11 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
Alcune funzioni esterne del API di ALSA consentono di conoscere quali sono le porte di entrata e di uscita dell'audio digitale delle schede audio presenti nel proprio sistema.
+
Alcune funzioni esterne del API di ALSA consentono di conoscere quali sono i dispositivi audio delle schede audio presenti nel proprio sistema.
  
 +
Mostriamo due esempi, nei quali sul ''Form'' dell'applicativo porremo una ''ListBox''.
  
Mostriamo di segtuito qualche esempio:
+
Di seguito il primo possibile codice:
Private Const SND_PCM_STREAM_PLAYBACK As Byte = 0      ' Playback stream
 
 
  Private Const ENOENT As Byte = 2
 
  Private Const ENOENT As Byte = 2
Private handlCtl As Pointer
+
 
 
   
 
   
 +
Library "libasound:2.0.0"
 
   
 
   
  Library "libasound:2"
+
  Private Const SND_PCM_STREAM_PLAYBACK As Byte = 0  <FONT color=gray>' ''Playback stream''</font>
 
   
 
   
  ' int snd_card_next(int *card)
+
  <FONT color=gray>' ''int snd_card_next(int *card)''
  ' Try to determine the next card.  
+
  ' ''Try to determine the next card.''</font>
 
  Private Extern snd_card_next(cardI As Pointer) As Integer
 
  Private Extern snd_card_next(cardI As Pointer) As Integer
 
   
 
   
  ' const char* snd_pcm_stream_name(snd_pcm_stream_t stream)
+
  <FONT color=gray>' ''const char* snd_pcm_stream_name(snd_pcm_stream_t stream)''
  ' Get name of PCM stream type  
+
  ' ''Get name of PCM stream type''</font>
 
  Private Extern snd_pcm_stream_name(streamI As Byte) As String
 
  Private Extern snd_pcm_stream_name(streamI As Byte) As String
 
   
 
   
  ' int snd_ctl_open(snd_ctl_t **ctl, const char *name, int mode)
+
  <FONT color=gray>' ''int snd_ctl_open(snd_ctl_t **ctl, const char *name, int mode)''
  ' Opens a CTL.  
+
  ' ''Opens a CTL.''</font>
 
  Private Extern snd_ctl_open(ctlP As Pointer, name As String, mode As Integer) As Integer
 
  Private Extern snd_ctl_open(ctlP As Pointer, name As String, mode As Integer) As Integer
 
   
 
   
  ' snd_ctl_card_info_malloc(ptr)
+
  <FONT color=gray>' ''snd_ctl_card_info_malloc(ptr)''
  ' Allocate an invalid snd_ctl_card_info_t using standard malloc
+
  ' ''Allocate an invalid snd_ctl_card_info_t using standard malloc''</font>
 
  Private Extern snd_ctl_card_info_malloc(ptr As Pointer)
 
  Private Extern snd_ctl_card_info_malloc(ptr As Pointer)
 
   
 
   
  ' int snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info)
+
  <FONT color=gray>' ''int snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info)
  ' Get card related information.  
+
  ' ''Get card related information.''</font>
 
  Private Extern snd_ctl_card_info(ctlP As Pointer, infoP As Pointer) As Integer
 
  Private Extern snd_ctl_card_info(ctlP As Pointer, infoP As Pointer) As Integer
 
   
 
   
  ' void snd_ctl_close(snd_ctl_t *ctl)
+
  <FONT color=gray>' ''void snd_ctl_close(snd_ctl_t *ctl)
  ' chiude il ctl
+
  ' ''Closes a ctl.''</font>
 
  Private Extern snd_ctl_close(ctlP As Pointer)
 
  Private Extern snd_ctl_close(ctlP As Pointer)
 
   
 
   
  ' int snd_ctl_pcm_next_device(snd_ctl_t *ctl, int *device)
+
  <FONT color=gray>' ''int snd_ctl_pcm_next_device(snd_ctl_t *ctl, int *device)
  ' Get Next PCM device number.  
+
  ' ''Get Next PCM device number.''</font>
 
  Private Extern snd_ctl_pcm_next_device(ctlP As Pointer, device As Pointer) As Integer
 
  Private Extern snd_ctl_pcm_next_device(ctlP As Pointer, device As Pointer) As Integer
 
   
 
   
  ' int snd_pcm_info_malloc(snd_pcm_info_t ** ptr)
+
  <FONT color=gray>' ''int snd_pcm_info_malloc(snd_pcm_info_t ** ptr)
  ' Allocate an invalid snd_pcm_info_t using standard malloc
+
  ' ''Allocate an invalid snd_pcm_info_t using standard malloc.''</font>
 
  Private Extern snd_pcm_info_malloc(ptr As Pointer) As Integer
 
  Private Extern snd_pcm_info_malloc(ptr As Pointer) As Integer
 
   
 
   
  ' void snd_pcm_info_set_device (snd_pcm_info_t *obj, unsigned int val)
+
  <FONT color=gray>' ''void snd_pcm_info_set_device (snd_pcm_info_t *obj, unsigned int val)
  ' Set wanted device inside a PCM info container  
+
  ' ''Set wanted device inside a PCM info container.''</font>
 
  Private Extern snd_pcm_info_set_device(pcminfoP As Pointer, ValI As Integer)
 
  Private Extern snd_pcm_info_set_device(pcminfoP As Pointer, ValI As Integer)
 
   
 
   
  ' void snd_pcm_info_set_subdevice(snd_pcm_info_t *obj, unsigned int val)
+
  <FONT color=gray>' ''void snd_pcm_info_set_subdevice(snd_pcm_info_t *obj, unsigned int val)
  ' Set wanted subdevice inside a PCM info container
+
  ' ''Set wanted subdevice inside a PCM info container.''</font>
 
  Private Extern snd_pcm_info_set_subdevice(pcminfoP As Pointer, ValI As Integer)
 
  Private Extern snd_pcm_info_set_subdevice(pcminfoP As Pointer, ValI As Integer)
 
   
 
   
  ' void snd_pcm_info_set_stream(snd_pcm_info_t *obj, snd_pcm_stream_t val)
+
  <FONT color=gray>' ''void snd_pcm_info_set_stream(snd_pcm_info_t *obj, snd_pcm_stream_t val)
  ' Set wanted stream inside a PCM info container
+
  ' ''Set wanted stream inside a PCM info container.''</font>
 
  Private Extern snd_pcm_info_set_stream(pcminfoP As Pointer, valInt As Integer)
 
  Private Extern snd_pcm_info_set_stream(pcminfoP As Pointer, valInt As Integer)
 
   
 
   
  ' int snd_ctl_pcm_info (snd_ctl_t *ctl, snd_pcm_info_t *info)
+
  <FONT color=gray>' ''int snd_ctl_pcm_info (snd_ctl_t *ctl, snd_pcm_info_t *info)
  ' Get info about a PCM device.  
+
  ' ''Get info about a PCM device.''</font>
 
  Private Extern snd_ctl_pcm_info(ctlP As Pointer, pcminfoP As Pointer) As Integer
 
  Private Extern snd_ctl_pcm_info(ctlP As Pointer, pcminfoP As Pointer) As Integer
 
   
 
   
  ' const char * snd_ctl_card_info_get_id (const snd_ctl_card_info_t *obj)
+
  <FONT color=gray>' ''const char * snd_ctl_card_info_get_id (const snd_ctl_card_info_t *obj)
  ' Get card identifier From a CTL card info.
+
  ' ''Get card identifier From a CTL card info.''</font>
 
  Private Extern snd_ctl_card_info_get_id(infoP As Pointer) As String
 
  Private Extern snd_ctl_card_info_get_id(infoP As Pointer) As String
 
   
 
   
  ' const char * snd_ctl_card_info_get_name (const snd_ctl_card_info_t *obj)
+
  <FONT color=gray>' ''const char * snd_ctl_card_info_get_name (const snd_ctl_card_info_t *obj)
  ' Get card name From a CTL card info.
+
  ' ''Get card name From a CTL card info.''</font>
 
  Private Extern snd_ctl_card_info_get_name(infoP As Pointer) As String
 
  Private Extern snd_ctl_card_info_get_name(infoP As Pointer) As String
 
   
 
   
  ' const char* snd_pcm_info_get_id(const snd_pcm_info_t * obj)
+
  <FONT color=gray>' ''const char* snd_pcm_info_get_id(const snd_pcm_info_t * obj)
  ' Get id from a PCM info container.
+
  ' ''Get id from a PCM info container.''</font>
 
  Private Extern snd_pcm_info_get_id(pcminfoP As Pointer) As String
 
  Private Extern snd_pcm_info_get_id(pcminfoP As Pointer) As String
 
   
 
   
  ' const char* snd_pcm_info_get_name (const snd_pcm_info_t * obj)
+
  <FONT color=gray>' ''const char* snd_pcm_info_get_name (const snd_pcm_info_t * obj)
  ' Get name From a PCM info container.  
+
  ' ''Get name From a PCM info container.''</font>
 
  Private Extern snd_pcm_info_get_name(pcminfoP As Pointer) As String
 
  Private Extern snd_pcm_info_get_name(pcminfoP As Pointer) As String
 
   
 
   
  ' unsigned int  snd_pcm_info_get_subdevices_count (const snd_pcm_info_t *obj)
+
  <FONT color=gray>' ''unsigned int  snd_pcm_info_get_subdevices_count (const snd_pcm_info_t *obj)
  ' Get subdevices count From a PCM info container.  
+
  ' ''Get subdevices count From a PCM info container.''</font>
 
  Private Extern snd_pcm_info_get_subdevices_count(pcminfoP As Pointer) As Integer
 
  Private Extern snd_pcm_info_get_subdevices_count(pcminfoP As Pointer) As Integer
 
   
 
   
  ' unsigned int snd_pcm_info_get_subdevices_avail (const snd_pcm_info_t *obj)
+
  <FONT color=gray>' ''unsigned int snd_pcm_info_get_subdevices_avail (const snd_pcm_info_t *obj)
  ' Get available subdevices count From a PCM info container.
+
  ' ''Get available subdevices count From a PCM info container.''</font>
 
  Private Extern snd_pcm_info_get_subdevices_avail(pcminfoP As Pointer) As Integer
 
  Private Extern snd_pcm_info_get_subdevices_avail(pcminfoP As Pointer) As Integer
 
   
 
   
  ' const char * snd_pcm_info_get_subdevice_name (const snd_pcm_info_t *obj)
+
  <FONT color=gray>' ''const char * snd_pcm_info_get_subdevice_name (const snd_pcm_info_t *obj)
  ' Get subdevice name From a PCM info container.  
+
  ' ''Get subdevice name From a PCM info container.''</font>
 
  Private Extern snd_pcm_info_get_subdevice_name(pcminfoP As Pointer) As String
 
  Private Extern snd_pcm_info_get_subdevice_name(pcminfoP As Pointer) As String
 
   
 
   
  ' const char * snd_strerror (int errnum)
+
  <FONT color=gray>' ''const char * snd_strerror (int errnum)
  ' Returns the message For an Error code.  
+
  ' ''Returns the message For an Error code.''</font>
 
  Private Extern snd_strerror(errore As Integer) As String
 
  Private Extern snd_strerror(errore As Integer) As String
 +
 
 
   
 
   
 +
Public Sub Form_Open()
 
   
 
   
'''Public''' Sub Form_Open()
+
  Me.show
 
  Me.show
 
 
    
 
    
  Do
+
  Do
    Wait 0.1
+
    Wait 0.1
  Loop Until Me.Id <> 0
+
  Loop Until Me.Id <> 0
 
   
 
   
  device_list()
+
  Lista_Dispositivi()
 
   
 
   
  '''End'''
+
  End
 
   
 
   
 
   
 
   
  '''Public''' Sub device_list()
+
  Private Procedure Lista_Dispositivi()
 
   
 
   
   Dim info, pcminfo As Pointer
+
   Dim handlCtl, info, pcminfo As Pointer
 
   Dim card, dev, count, avail, idx, err As Integer
 
   Dim card, dev, count, avail, idx, err As Integer
 
   Dim name, card_id, card_name, pcm_id, pcm_name, subdevice_name As String
 
   Dim name, card_id, card_name, pcm_id, pcm_name, subdevice_name As String
Riga 116: Riga 117:
 
   card = -1
 
   card = -1
 
   
 
   
   If (snd_card_next(VarPtr(card)) < 0) Or (card < 0) Then Error.Raise("Nessuna scheda audio trovata !")
+
   If (snd_card_next(VarPtr(card)) < 0) Or (card < 0) Then
      
+
    Error("Nessuna scheda audio trovata !")
   With ListBox1
+
     Return
    .Add("******* LISTA DEI DISPOSITIVI HARDWARE DI RIPRODUZIONE AUDIO *******")
+
  Endif
  End With
+
 +
   ListBox1.Add("******* LISTA DEI DISPOSITIVI HARDWARE DI RIPRODUZIONE AUDIO *******")
 
      
 
      
 
   snd_pcm_stream_name(SND_PCM_STREAM_PLAYBACK)
 
   snd_pcm_stream_name(SND_PCM_STREAM_PLAYBACK)
 
   
 
   
   
 
 
   While card >= 0
 
   While card >= 0
 
   
 
   
Riga 131: Riga 132:
 
     err = snd_ctl_open(VarPtr(handlCtl), name, 0)
 
     err = snd_ctl_open(VarPtr(handlCtl), name, 0)
 
     If err < 0 Then
 
     If err < 0 Then
       Error("Errore nell'apertura del Controllo: " & card & ":" & snd_strerror(err))
+
       Error("Apertura del Controllo: " & card & ":" & snd_strerror(err))
 
       Goto next_card
 
       Goto next_card
 
     Endif
 
     Endif
     
+
   
 
     err = snd_ctl_card_info(handlCtl, info)
 
     err = snd_ctl_card_info(handlCtl, info)
 
     If err < 0 Then
 
     If err < 0 Then
Riga 146: Riga 147:
 
     While True
 
     While True
 
   
 
   
       If snd_ctl_pcm_next_device(handlCtl, VarPtr(dev)) < 0 Then Error.Raise("Errore alla funzione 'snd_ctl_pcm_next_device' !")
+
       If snd_ctl_pcm_next_device(handlCtl, VarPtr(dev)) < 0 Then Error("Errore alla funzione 'snd_ctl_pcm_next_device' !")
 
   
 
   
 
       If dev < 0 Then Break
 
       If dev < 0 Then Break
       
+
     
 
       snd_pcm_info_set_device(pcminfo, dev)
 
       snd_pcm_info_set_device(pcminfo, dev)
 
          
 
          
Riga 156: Riga 157:
 
       snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK)
 
       snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK)
 
   
 
   
     
 
 
       err = snd_ctl_pcm_info(handlCtl, pcminfo)
 
       err = snd_ctl_pcm_info(handlCtl, pcminfo)
 
   
 
   
Riga 164: Riga 164:
 
       Endif
 
       Endif
 
          
 
          
'''''''''''''
 
 
       card_id = snd_ctl_card_info_get_id(info)
 
       card_id = snd_ctl_card_info_get_id(info)
 
          
 
          
Riga 180: Riga 179:
 
       End With
 
       End With
 
   
 
   
       
 
 
       count = snd_pcm_info_get_subdevices_count(pcminfo)
 
       count = snd_pcm_info_get_subdevices_count(pcminfo)
 
          
 
          
Riga 189: Riga 187:
 
         .Add(" ")
 
         .Add(" ")
 
       End With
 
       End With
+
       
 
       For idx = 0 To count - 1
 
       For idx = 0 To count - 1
 
         snd_pcm_info_set_subdevice(pcminfo, idx)
 
         snd_pcm_info_set_subdevice(pcminfo, idx)
 
         err = snd_ctl_pcm_info(handlCtl, pcminfo)
 
         err = snd_ctl_pcm_info(handlCtl, pcminfo)
 
         If err < 0 Then
 
         If err < 0 Then
           Error.Raise("Informazione sulla Riproduzione audio digitale del controllo: " & card & " " & snd_strerror(err))
+
           Error("Informazione sulla Riproduzione audio digitale del controllo: " & card & " " & snd_strerror(err))
 
         Else
 
         Else
 
           subdevice_name = snd_pcm_info_get_subdevice_name(pcminfo)
 
           subdevice_name = snd_pcm_info_get_subdevice_name(pcminfo)
           With ListBox1
+
           ListBox1.Add("Subdevice: #" & idx & ":  " & subdevice_name)
            .Add("Subdevice: #" & idx & ":  " & subdevice_name)
 
          End With
 
 
         Endif
 
         Endif
 
       Next
 
       Next
       
 
 
          
 
          
 
     Wend
 
     Wend
      snd_ctl_close(handlCtl)
+
      next_card:
+
    snd_ctl_close(handlCtl)
      If snd_card_next(VarPtr(card)) < 0 Then
+
    next_card:
        Error("Errore in 'next_card' !")
+
    If snd_card_next(VarPtr(card)) < 0 Then
        Break
+
      Error("Errore in 'next_card' !")
      Endif
+
      Break
 +
    Endif
 +
 
 
   Wend
 
   Wend
 
   
 
   
  '''End'''
+
  End
 
  
  
 
+
Di seguito invece il secondo possibile codice:
 
+
Library "libasound:2.0.0"
<FONT color=red size=4><B>Pagina in costruzione !
+
 +
Private Const SND_PCM_STREAM_PLAYBACK As Integer = 0
 +
Private Const SND_PCM_STREAM_CAPTURE As Integer = 1
 +
 +
<FONT color=gray>' ''int snd_card_next(int *card)''
 +
' ''Try to determine the next card.''</font>
 +
Private Extern snd_card_next(cardI As Pointer) As Integer
 +
 +
<FONT color=gray>' ''int snd_ctl_open (snd_ctl_t **ctl, const char *name, int mode)''
 +
' ''Opens a CTL.''</font>
 +
Private Extern snd_ctl_open(card As Pointer, name As String, mode As Integer) As Integer
 +
 +
<FONT color=gray>' ''int snd_ctl_pcm_next_device (snd_ctl_t *ctl, int *device)''
 +
' ''Get Next pcm device number.''</font>
 +
Private Extern snd_ctl_pcm_next_device(ctl As Pointer, device As Pointer) As Integer
 +
 +
<FONT color=gray>' ''int snd_ctl_card_info_malloc (snd_ctl_card_info_t **ptr)''
 +
' ''Allocate an invalid snd_ctl_card_info_t using standard malloc.''</font>
 +
Private Extern snd_ctl_card_info_malloc(ptr As Pointer) As Integer
 +
 +
<FONT color=gray>' ''int snd_ctl_card_info (snd_ctl_t *ctl, snd_ctl_card_info_t *info)''
 +
' ''Get card related information.''</font>
 +
Private Extern snd_ctl_card_info(ctl As Pointer, snd_ctl_card_info_t As Pointer) As Integer
 +
 +
<FONT color=gray>' ''const char * snd_ctl_card_info_get_longname (const snd_ctl_card_info_t *obj)''
 +
' ''Get card long name from a CTL card info.''</font>
 +
Private Extern snd_ctl_card_info_get_longname(obj As Pointer) As String
 +
 +
<FONT color=gray>' ''const char * snd_ctl_card_info_get_id (const snd_ctl_card_info_t *obj)''
 +
' ''Get card identifier from a CTL card info.''</font>
 +
Private Extern snd_ctl_card_info_get_id(obj As Pointer) As String
 +
 +
<FONT color=gray>' ''const char * snd_ctl_card_info_get_name (const snd_ctl_card_info_t *obj)''
 +
' ''Get card name from a CTL card info.''</font>
 +
Private Extern snd_ctl_card_info_get_name(obj As Pointer) As String
 +
 +
<FONT color=gray>' ''const char * snd_ctl_card_info_get_driver (const snd_ctl_card_info_t *obj)''
 +
' ''Get card driver name from a CTL card info.''</font>
 +
Private Extern snd_ctl_card_info_get_driver(obj As Pointer) As String
 +
 +
<FONT color=gray>' ''const char * snd_ctl_card_info_get_mixername (const snd_ctl_card_info_t *obj)''
 +
' ''Get card mixer name from a CTL card info.''</font>
 +
Private Extern snd_ctl_card_info_get_mixername(obj As Pointer) As String
 +
 +
<FONT color=gray>' ''const char * snd_ctl_card_info_get_components (const snd_ctl_card_info_t *obj)''
 +
' ''Get card component list from a CTL card info.''</font>
 +
Private Extern snd_ctl_card_info_get_components(obj As Pointer) As String
 +
 +
<FONT color=gray>' ''int snd_pcm_info_malloc (snd_pcm_info_t **ptr)''
 +
' ''Allocate a New Snd_pcm_info_t structure.''</font>
 +
Private Extern snd_pcm_info_malloc(ptr As Pointer) As Integer
 +
 +
<FONT color=gray>' ''size_t snd_pcm_info_sizeof (void)''
 +
' ''Get size Of the 'snd_pcm_info_t' structure in bytes.''</font>
 +
Private Extern snd_pcm_info_sizeof() As Integer
 +
 +
<FONT color=gray>' ''void snd_pcm_info_set_device (snd_pcm_info_t *obj, unsigned int val)''
 +
' ''Set pcm device number.''</font>
 +
Private Extern snd_pcm_info_set_device(obj As Pointer, ValInt As Integer)
 +
 +
<FONT color=gray>' ''void snd_pcm_info_set_stream (snd_pcm_info_t *obj, snd_pcm_stream_t val)''
 +
' ''Set pcm stream identifier.''</font>
 +
Private Extern snd_pcm_info_set_stream(obj As Pointer, ValInt As Integer)
 +
 +
<FONT color=gray>' ''void snd_pcm_info_set_subdevice (snd_pcm_info_t *obj, unsigned int val)''
 +
' ''Set pcm subdevice number.''</font>
 +
Private Extern snd_pcm_info_set_subdevice(obj As Pointer, ValInt As Integer)
 +
 +
<FONT color=gray>' ''int snd_ctl_pcm_info (snd_ctl_t *ctl, snd_pcm_info_t *info)''
 +
' ''Get info about a pcm device.''</font>
 +
Private Extern snd_ctl_pcm_info(ctl As Pointer, info As Pointer) As Integer
 +
 +
<FONT color=gray>' ''unsigned int snd_pcm_info_get_subdevices_count (const snd_pcm_info_t *obj)''
 +
' ''Get pcm count of subdevices.''</font>
 +
Private Extern snd_pcm_info_get_subdevices_count(obj As Pointer) As Integer
 +
 +
<FONT color=gray>' ''unsigned int snd_pcm_info_get_subdevices_avail (const snd_pcm_info_t *obj)''
 +
' ''Get pcm available count of subdevices.''</font>
 +
Private Extern snd_pcm_info_get_subdevices_avail(obj As Pointer) As Integer
 +
 +
<FONT color=gray>' ''const char * snd_pcm_info_get_id (const snd_pcm_info_t *obj)''
 +
' ''Get pcm hardware driver identifier.''</font>
 +
Private Extern snd_pcm_info_get_id(obj As Pointer) As String
 +
 +
<FONT color=gray>' ''const char * snd_pcm_info_get_name (const snd_pcm_info_t *obj)''
 +
' ''Get pcm hardware driver name.''</font>
 +
Private Extern snd_pcm_info_get_name(obj As Pointer) As String
 +
 +
<FONT color=gray>' ''const char * snd_pcm_info_get_subdevice_name (const snd_pcm_info_t *obj)''
 +
' ''Get pcm subdevice name.''</font>
 +
Private Extern snd_pcm_info_get_subdevice_name(obj As Pointer) As String
 +
 +
<FONT color=gray>' ''int snd_ctl_close (snd_ctl_t *ctl)''
 +
' ''Closes CTL handle.''</font>
 +
Private Extern snd_ctl_close(ctl As Pointer) As Integer
 +
 +
<FONT color=gray>' ''int snd_config_update_free_global (void)''
 +
' ''Frees the global configuration tree In snd_config.''</font>
 +
Private Extern snd_config_update_free_global() As Integer
 +
 +
<FONT color=gray>' ''const char * snd_strerror (int errnum)''
 +
' ''Returns the message For an Error code.''</font>
 +
Private Extern snd_strerror(errore As Integer) As String
 +
 +
<FONT color=gray>' ''void *memset(void *str, int c, size_t n)''
 +
' ''Copies the character c (an unsigned char) to the first n characters of the string pointed to by the argument str.''</font>
 +
Private Extern memset(StrP As Pointer, c As Integer, n As Integer) As Pointer In "libc:6"
 +
 +
 +
Public Sub Form_Open()
 +
 +
  Me.show
 +
 +
  Do
 +
    Wait 0.1
 +
  Loop Until Me.Id <> 0
 +
 +
  Lista_Dispositivi()
 +
 +
End
 +
 +
 +
Public Sub Lista_Dispositivi()
 +
 +
  Dim err, cardNum, devNum, unaVolta As Integer
 +
  Dim audioHandle, cardInfo As Pointer
 +
  Dim $str As String
 +
 +
  ListBox1.Add("---- DISPOSITIVI HARDWARE AUDIO PRESENTI ----")
 +
 +
  cardNum = -1
 +
 
 +
  Do
 +
 +
    err = snd_card_next(VarPtr(cardNum))
 +
    If err < 0 Then Error.Raise("Impossibile ottenere il numero della scheda audio successiva: " & snd_strerror(err))
 +
 
 +
<FONT color=gray>' ''Se non vi sono più schede, Alsa imposta "cardNum" a -1:''</font>
 +
    If cardNum < 0 Then Exit
 +
    $str = "hw:" & CStr(cardNum)
 +
    err = snd_ctl_open(VarPtr(audioHandle), $Str, 0)
 +
    If err < 0 Then Error.Raise("Impossibile aprire la connessione con la scheda audio: " & snd_strerror(err))
 +
    unaVolta = 0
 +
     
 +
<FONT color=gray>' ''Parte con il primo dispositivo audio sulla scheda individuata:''</font>
 +
    devNum = -1
 +
      Do
 +
<FONT color=gray>' ''Ricava il numero del successivo dispositivo Midi sulla scheda attuale:''</font>
 +
        err = snd_ctl_pcm_next_device(audioHandle, VarPtr(devNum))
 +
        If err < 0 Then Error.Raise("Impossibile ottenere il numero del successivo dispositivo audio: " & snd_strerror(err))
 +
<FONT color=gray>' ''Se non ci sono altri dispositivi audio sulla scheda audio, Alsa imposta "devNum" a -1.
 +
' ''NOTA: E' possibile che la scheda audio (ad esempio una scheda audio digitale) possa non avere dispositivi audio:''</font>
 +
        If devNum < 0 Then Exit
 +
        If Not unaVolta Then
 +
<FONT color=gray>' ''Esegue il codice qui sotto una sola volta:''</font>
 +
          unaVolta = 1
 +
          snd_ctl_card_info_malloc(VarPtr(cardInfo))
 +
<FONT color=gray>' ''Dice ad ALSA di riempire 'snd_ctl_card_info_t' con informazioni sulla corrente scheda:''</font>
 +
          err = snd_ctl_card_info(audioHandle, cardInfo)
 +
          If err < 0 Then
 +
            Error.Raise("Impossibile ottenere informazioni sulla scheda audio: " & snd_strerror(err))
 +
          Else
 +
            With ListBox1
 +
              .Add(" ")
 +
              .Add(" ")
 +
              .Add("=================================================================================")
 +
              .Add(snd_ctl_card_info_get_longname(cardInfo))
 +
              .Add("=================================================================================")
 +
              .Add("id = " & snd_ctl_card_info_get_id(cardInfo))
 +
              .Add("nome = " & snd_ctl_card_info_get_name(cardInfo))
 +
              .Add("driver = " & snd_ctl_card_info_get_driver(cardInfo))
 +
              .Add("mixername = " & snd_ctl_card_info_get_mixername(cardInfo))
 +
              .Add("componenti = " & snd_ctl_card_info_get_components(cardInfo))
 +
            End With
 +
          Endif
 +
        Endif
 +
<FONT color=gray>' ''Mostra le informazioni relative ai subdispositivi audio Output del corrente dispositivo audio:''</font>
 +
        lista_subdevice(audioHandle, cardNum, devNum, SND_PCM_STREAM_PLAYBACK)
 +
<FONT color=gray>' ''Mostra le informazioni relative ai subdispositivi audio Input del corrente dispositivo audio:''</font>
 +
        lista_subdevice(audioHandle, cardNum, devNum, SND_PCM_STREAM_CAPTURE)
 +
      Loop
 +
 +
    snd_ctl_close(audioHandle)
 +
 
 +
  Loop
 +
 +
<FONT color=gray>' ''Va in chiusura liberando la memoria precedentemente allocata:''</font>
 +
  snd_config_update_free_global()
 +
 +
End
 +
 +
 +
Private Procedure lista_subdevice(audioH As Pointer, cardN As Integer, devN As Integer, tipo As Integer)
 +
 
 +
  Dim pcmInfo As Pointer
 +
  Dim subDevCount, i, err As Integer
 +
  Dim stringa As String
 +
 +
  If tipo = SND_PCM_STREAM_PLAYBACK Then
 +
    stringa = "Output"
 +
  Else
 +
    stringa = "Input"
 +
  Endif
 +
 
 +
  snd_pcm_info_malloc(VarPtr(pcmInfo))
 +
  memset(pcmInfo, 0, snd_pcm_info_sizeof())
 +
 +
<FONT color=gray>' ''Dice ad ALSA di quale dispositivo Audio si richiedono le informazioni:''</font>
 +
  snd_pcm_info_set_device(pcmInfo, devN)
 +
   
 +
<FONT color=gray>' ''Si ottengono informazioni sull'uscita Audio o in sezione del corrente dispositivo:''</font>
 +
  snd_pcm_info_set_stream(pcmInfo, tipo)
 +
   
 +
  i = -1
 +
  subDevCount = 1
 +
 
 +
  Inc i
 +
  While i < subDevCount
 +
<FONT color=gray>' ''Dice ad ALSA di riempire 'snd_pcm_info_t' con le informazioni sul corrente subdispositivo:''</font>
 +
    snd_pcm_info_set_subdevice(pcmInfo, i)
 +
    err = snd_ctl_pcm_info(audioH, pcmInfo)
 +
    If err < 0 Then
 +
      ListBox1.Add("Impossibile ottenere informazioni sul subdevice " & stringa & " Audio 'hw:" & CStr(cardN) & "," & CStr(devN) & "," & CStr(i) & " : " & snd_strerror(err))
 +
      Break
 +
    Endif
 +
<FONT color=gray>' ''Scrive quanti subdispositivi audio sono presenti:''</font>
 +
    If Not i Then
 +
      subDevCount = snd_pcm_info_get_subdevices_count(pcmInfo)
 +
      With ListBox1
 +
        .Add(" ")
 +
        .Add("------ " & subDevCount & " " & stringa & " subdevice (" & snd_pcm_info_get_subdevices_avail(pcmInfo) & " disponibili)")
 +
        .Add("id = " & snd_pcm_info_get_id(pcmInfo))
 +
        .Add("nome = " & snd_pcm_info_get_name(pcmInfo))
 +
      End With
 +
    Endif
 +
<FONT color=gray>' ''NOTA: Se è presente un solo subdispositivo, allora il numero del subdispositivo è immateriale, e può essere omesso:''</font>
 +
    If subDevCount > 1 Then
 +
      ListBox1.Add(" ")
 +
      ListBox1.Add("  AUDIO " & stringa & " 'hw:" & cardN & "," & devN & "," & i & "'")
 +
    Else
 +
      ListBox1.Add(" ")
 +
      ListBox1.Add("  AUDIO " & stringa & " 'hw:" & cardN & "," & devN & "'")
 +
    Endif
 +
    ListBox1.Add("  subnome = '" & snd_pcm_info_get_subdevice_name(pcmInfo) & "'")
 +
    Inc i
 +
  Wend
 +
 +
End

Versione attuale delle 12:13, 13 gen 2024

Alcune funzioni esterne del API di ALSA consentono di conoscere quali sono i dispositivi audio delle schede audio presenti nel proprio sistema.

Mostriamo due esempi, nei quali sul Form dell'applicativo porremo una ListBox.

Di seguito il primo possibile codice:

Private Const ENOENT As Byte = 2
 

Library "libasound:2.0.0"

Private Const SND_PCM_STREAM_PLAYBACK As Byte = 0   ' Playback stream

' int snd_card_next(int *card)
' Try to determine the next card.
Private Extern snd_card_next(cardI As Pointer) As Integer

' const char* snd_pcm_stream_name(snd_pcm_stream_t stream)
' Get name of PCM stream type
Private Extern snd_pcm_stream_name(streamI As Byte) As String

' int snd_ctl_open(snd_ctl_t **ctl, const char *name, int mode)
' Opens a CTL.
Private Extern snd_ctl_open(ctlP As Pointer, name As String, mode As Integer) As Integer

' snd_ctl_card_info_malloc(ptr)
' Allocate an invalid snd_ctl_card_info_t using standard malloc
Private Extern snd_ctl_card_info_malloc(ptr As Pointer)

' int snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info)
' Get card related information.
Private Extern snd_ctl_card_info(ctlP As Pointer, infoP As Pointer) As Integer

' void snd_ctl_close(snd_ctl_t *ctl)
' Closes a ctl.
Private Extern snd_ctl_close(ctlP As Pointer)

' int snd_ctl_pcm_next_device(snd_ctl_t *ctl, int *device)
' Get Next PCM device number.
Private Extern snd_ctl_pcm_next_device(ctlP As Pointer, device As Pointer) As Integer

' int snd_pcm_info_malloc(snd_pcm_info_t ** ptr)
' Allocate an invalid snd_pcm_info_t using standard malloc.
Private Extern snd_pcm_info_malloc(ptr As Pointer) As Integer

' void snd_pcm_info_set_device (snd_pcm_info_t *obj, unsigned int val)
' Set wanted device inside a PCM info container.
Private Extern snd_pcm_info_set_device(pcminfoP As Pointer, ValI As Integer)

' void snd_pcm_info_set_subdevice(snd_pcm_info_t *obj, unsigned int val)
' Set wanted subdevice inside a PCM info container.
Private Extern snd_pcm_info_set_subdevice(pcminfoP As Pointer, ValI As Integer)

' void snd_pcm_info_set_stream(snd_pcm_info_t *obj, snd_pcm_stream_t val)
' Set wanted stream inside a PCM info container.
Private Extern snd_pcm_info_set_stream(pcminfoP As Pointer, valInt As Integer)

' int snd_ctl_pcm_info (snd_ctl_t *ctl, snd_pcm_info_t *info)
' Get info about a PCM device.
Private Extern snd_ctl_pcm_info(ctlP As Pointer, pcminfoP As Pointer) As Integer

' const char * snd_ctl_card_info_get_id (const snd_ctl_card_info_t *obj)
' Get card identifier From a CTL card info.
Private Extern snd_ctl_card_info_get_id(infoP As Pointer) As String

' const char * snd_ctl_card_info_get_name (const snd_ctl_card_info_t *obj)
' Get card name From a CTL card info.
Private Extern snd_ctl_card_info_get_name(infoP As Pointer) As String

' const char* snd_pcm_info_get_id(const snd_pcm_info_t * obj)
' Get id from a PCM info container.
Private Extern snd_pcm_info_get_id(pcminfoP As Pointer) As String

' const char* snd_pcm_info_get_name (const snd_pcm_info_t * obj)
' Get name From a PCM info container.
Private Extern snd_pcm_info_get_name(pcminfoP As Pointer) As String

' unsigned int  snd_pcm_info_get_subdevices_count (const snd_pcm_info_t *obj)
' Get subdevices count From a PCM info container.
Private Extern snd_pcm_info_get_subdevices_count(pcminfoP As Pointer) As Integer

' unsigned int snd_pcm_info_get_subdevices_avail (const snd_pcm_info_t *obj)
' Get available subdevices count From a PCM info container.
Private Extern snd_pcm_info_get_subdevices_avail(pcminfoP As Pointer) As Integer

' const char * snd_pcm_info_get_subdevice_name (const snd_pcm_info_t *obj)
' Get subdevice name From a PCM info container.
Private Extern snd_pcm_info_get_subdevice_name(pcminfoP As Pointer) As String

' const char * snd_strerror (int errnum)
' Returns the message For an Error code.
Private Extern snd_strerror(errore As Integer) As String
 

Public Sub Form_Open()

 Me.show
 
 Do
   Wait 0.1
 Loop Until Me.Id <> 0

 Lista_Dispositivi()

End


Private Procedure Lista_Dispositivi()

 Dim handlCtl, info, pcminfo As Pointer
 Dim card, dev, count, avail, idx, err As Integer
 Dim name, card_id, card_name, pcm_id, pcm_name, subdevice_name As String

 
  snd_ctl_card_info_malloc(VarPtr(info))
  snd_pcm_info_malloc(VarPtr(pcminfo))
   
  card = -1

  If (snd_card_next(VarPtr(card)) < 0) Or (card < 0) Then
    Error("Nessuna scheda audio trovata !")
    Return
  Endif

  ListBox1.Add("******* LISTA DEI DISPOSITIVI HARDWARE DI RIPRODUZIONE AUDIO *******")
   
  snd_pcm_stream_name(SND_PCM_STREAM_PLAYBACK)

  While card >= 0

    name = "hw:" & card

    err = snd_ctl_open(VarPtr(handlCtl), name, 0)
    If err < 0 Then
      Error("Apertura del Controllo: " & card & ":" & snd_strerror(err))
      Goto next_card
    Endif
    
    err = snd_ctl_card_info(handlCtl, info)
    If err < 0 Then
      Error("Informazione sull'hardware del controllo: " & card & ":" & snd_strerror(err))
      snd_ctl_close(handlCtl)
      Goto next_card
    Endif
     
    dev = -1
     
    While True

      If snd_ctl_pcm_next_device(handlCtl, VarPtr(dev)) < 0 Then Error("Errore alla funzione 'snd_ctl_pcm_next_device' !")

      If dev < 0 Then Break
      
      snd_pcm_info_set_device(pcminfo, dev)
       
      snd_pcm_info_set_subdevice(pcminfo, 0)
       
      snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK)

      err = snd_ctl_pcm_info(handlCtl, pcminfo)

      If err < 0 Then
        If err <> - ENOENT Then Error.Raise("Informazione sull'audio digitale del controllo: " & card & " " & snd_strerror(err))
        Continue
      Endif
       
      card_id = snd_ctl_card_info_get_id(info)
       
      card_name = snd_ctl_card_info_get_name(info)
       
      pcm_id = snd_pcm_info_get_id(pcminfo)
       
      pcm_name = snd_pcm_info_get_name(pcminfo)
       
      With ListBox1
        .Add("_______________________________________________________________________________________")
        .Add(" ")
        .Add("DISPOSITIVO AUDIO: " & name & "  " & card_id & " [" & card_name & "]    Device: " & dev & "  " & pcm_id & " [" & pcm_name & "]")
        .Add(" ")
      End With

      count = snd_pcm_info_get_subdevices_count(pcminfo)
       
      avail = snd_pcm_info_get_subdevices_avail(pcminfo)
       
      With ListBox1
        .Add("Subdevices: " & avail & "/" & count)
        .Add(" ")
      End With
       
      For idx = 0 To count - 1
        snd_pcm_info_set_subdevice(pcminfo, idx)
        err = snd_ctl_pcm_info(handlCtl, pcminfo)
        If err < 0 Then
          Error("Informazione sulla Riproduzione audio digitale del controllo: " & card & " " & snd_strerror(err))
        Else
          subdevice_name = snd_pcm_info_get_subdevice_name(pcminfo)
          ListBox1.Add("Subdevice: #" & idx & ":  " & subdevice_name)
        Endif
      Next
        
    Wend

    snd_ctl_close(handlCtl)
    next_card:
    If snd_card_next(VarPtr(card)) < 0 Then
      Error("Errore in 'next_card' !")
      Break
    Endif
 
  Wend

End


Di seguito invece il secondo possibile codice:

Library "libasound:2.0.0"

Private Const SND_PCM_STREAM_PLAYBACK As Integer = 0
Private Const SND_PCM_STREAM_CAPTURE As Integer = 1

' int snd_card_next(int *card)
' Try to determine the next card.
Private Extern snd_card_next(cardI As Pointer) As Integer

' int snd_ctl_open (snd_ctl_t **ctl, const char *name, int mode)
' Opens a CTL.
Private Extern snd_ctl_open(card As Pointer, name As String, mode As Integer) As Integer

' int snd_ctl_pcm_next_device (snd_ctl_t *ctl, int *device)
' Get Next pcm device number.
Private Extern snd_ctl_pcm_next_device(ctl As Pointer, device As Pointer) As Integer

' int snd_ctl_card_info_malloc (snd_ctl_card_info_t **ptr)
' Allocate an invalid snd_ctl_card_info_t using standard malloc.
Private Extern snd_ctl_card_info_malloc(ptr As Pointer) As Integer

' int snd_ctl_card_info (snd_ctl_t *ctl, snd_ctl_card_info_t *info)
' Get card related information.
Private Extern snd_ctl_card_info(ctl As Pointer, snd_ctl_card_info_t As Pointer) As Integer

' const char * snd_ctl_card_info_get_longname (const snd_ctl_card_info_t *obj)
' Get card long name from a CTL card info.
Private Extern snd_ctl_card_info_get_longname(obj As Pointer) As String

' const char * snd_ctl_card_info_get_id (const snd_ctl_card_info_t *obj)
' Get card identifier from a CTL card info.
Private Extern snd_ctl_card_info_get_id(obj As Pointer) As String

' const char * snd_ctl_card_info_get_name (const snd_ctl_card_info_t *obj)
' Get card name from a CTL card info.
Private Extern snd_ctl_card_info_get_name(obj As Pointer) As String

' const char * snd_ctl_card_info_get_driver (const snd_ctl_card_info_t *obj)
' Get card driver name from a CTL card info.
Private Extern snd_ctl_card_info_get_driver(obj As Pointer) As String

' const char * snd_ctl_card_info_get_mixername (const snd_ctl_card_info_t *obj)
' Get card mixer name from a CTL card info.
Private Extern snd_ctl_card_info_get_mixername(obj As Pointer) As String

' const char * snd_ctl_card_info_get_components (const snd_ctl_card_info_t *obj)
' Get card component list from a CTL card info.
Private Extern snd_ctl_card_info_get_components(obj As Pointer) As String

' int snd_pcm_info_malloc (snd_pcm_info_t **ptr)
' Allocate a New Snd_pcm_info_t structure.
Private Extern snd_pcm_info_malloc(ptr As Pointer) As Integer

' size_t snd_pcm_info_sizeof (void)
' Get size Of the 'snd_pcm_info_t' structure in bytes.
Private Extern snd_pcm_info_sizeof() As Integer

' void snd_pcm_info_set_device (snd_pcm_info_t *obj, unsigned int val)
' Set pcm device number.
Private Extern snd_pcm_info_set_device(obj As Pointer, ValInt As Integer)

' void snd_pcm_info_set_stream (snd_pcm_info_t *obj, snd_pcm_stream_t val)
' Set pcm stream identifier.
Private Extern snd_pcm_info_set_stream(obj As Pointer, ValInt As Integer)

' void snd_pcm_info_set_subdevice (snd_pcm_info_t *obj, unsigned int val)
' Set pcm subdevice number.
Private Extern snd_pcm_info_set_subdevice(obj As Pointer, ValInt As Integer)

' int snd_ctl_pcm_info (snd_ctl_t *ctl, snd_pcm_info_t *info)
' Get info about a pcm device.
Private Extern snd_ctl_pcm_info(ctl As Pointer, info As Pointer) As Integer

' unsigned int snd_pcm_info_get_subdevices_count (const snd_pcm_info_t *obj)
' Get pcm count of subdevices.
Private Extern snd_pcm_info_get_subdevices_count(obj As Pointer) As Integer

' unsigned int snd_pcm_info_get_subdevices_avail (const snd_pcm_info_t *obj)
' Get pcm available count of subdevices.
Private Extern snd_pcm_info_get_subdevices_avail(obj As Pointer) As Integer

' const char * snd_pcm_info_get_id (const snd_pcm_info_t *obj)
' Get pcm hardware driver identifier.
Private Extern snd_pcm_info_get_id(obj As Pointer) As String

' const char * snd_pcm_info_get_name (const snd_pcm_info_t *obj)
' Get pcm hardware driver name.
Private Extern snd_pcm_info_get_name(obj As Pointer) As String

' const char * snd_pcm_info_get_subdevice_name (const snd_pcm_info_t *obj)
' Get pcm subdevice name.
Private Extern snd_pcm_info_get_subdevice_name(obj As Pointer) As String

' int snd_ctl_close (snd_ctl_t *ctl)
' Closes CTL handle.
Private Extern snd_ctl_close(ctl As Pointer) As Integer

' int snd_config_update_free_global (void)
' Frees the global configuration tree In snd_config.
Private Extern snd_config_update_free_global() As Integer

' const char * snd_strerror (int errnum)
' Returns the message For an Error code.
Private Extern snd_strerror(errore As Integer) As String

' void *memset(void *str, int c, size_t n)
' Copies the character c (an unsigned char) to the first n characters of the string pointed to by the argument str.
Private Extern memset(StrP As Pointer, c As Integer, n As Integer) As Pointer In "libc:6"


Public Sub Form_Open()

 Me.show

 Do
   Wait 0.1
 Loop Until Me.Id <> 0

 Lista_Dispositivi()

End


Public Sub Lista_Dispositivi()

 Dim err, cardNum, devNum, unaVolta As Integer
 Dim audioHandle, cardInfo As Pointer
 Dim $str As String

 ListBox1.Add("---- DISPOSITIVI HARDWARE AUDIO PRESENTI ----")

 cardNum = -1
 
 Do

   err = snd_card_next(VarPtr(cardNum))
   If err < 0 Then Error.Raise("Impossibile ottenere il numero della scheda audio successiva: " & snd_strerror(err))
 
' Se non vi sono più schede, Alsa imposta "cardNum" a -1:
   If cardNum < 0 Then Exit
   $str = "hw:" & CStr(cardNum)
   err = snd_ctl_open(VarPtr(audioHandle), $Str, 0)
   If err < 0 Then Error.Raise("Impossibile aprire la connessione con la scheda audio: " & snd_strerror(err))
   unaVolta = 0
     
' Parte con il primo dispositivo audio sulla scheda individuata:
   devNum = -1
     Do
' Ricava il numero del successivo dispositivo Midi sulla scheda attuale:
       err = snd_ctl_pcm_next_device(audioHandle, VarPtr(devNum))
       If err < 0 Then Error.Raise("Impossibile ottenere il numero del successivo dispositivo audio: " & snd_strerror(err))
' Se non ci sono altri dispositivi audio sulla scheda audio, Alsa imposta "devNum" a -1.
' NOTA: E' possibile che la scheda audio (ad esempio una scheda audio digitale) possa non avere dispositivi audio:
       If devNum < 0 Then Exit
       If Not unaVolta Then
' Esegue il codice qui sotto una sola volta:
         unaVolta = 1
         snd_ctl_card_info_malloc(VarPtr(cardInfo))
' Dice ad ALSA di riempire 'snd_ctl_card_info_t' con informazioni sulla corrente scheda:
         err = snd_ctl_card_info(audioHandle, cardInfo)
         If err < 0 Then
           Error.Raise("Impossibile ottenere informazioni sulla scheda audio: " & snd_strerror(err))
         Else
           With ListBox1
             .Add(" ")
             .Add(" ")
             .Add("=================================================================================")
             .Add(snd_ctl_card_info_get_longname(cardInfo))
             .Add("=================================================================================")
             .Add("id = " & snd_ctl_card_info_get_id(cardInfo))
             .Add("nome = " & snd_ctl_card_info_get_name(cardInfo))
             .Add("driver = " & snd_ctl_card_info_get_driver(cardInfo))
             .Add("mixername = " & snd_ctl_card_info_get_mixername(cardInfo))
             .Add("componenti = " & snd_ctl_card_info_get_components(cardInfo))
           End With
         Endif
       Endif
' Mostra le informazioni relative ai subdispositivi audio Output del corrente dispositivo audio:
       lista_subdevice(audioHandle, cardNum, devNum, SND_PCM_STREAM_PLAYBACK)
' Mostra le informazioni relative ai subdispositivi audio Input del corrente dispositivo audio:
       lista_subdevice(audioHandle, cardNum, devNum, SND_PCM_STREAM_CAPTURE)
     Loop

   snd_ctl_close(audioHandle)
 
 Loop

' Va in chiusura liberando la memoria precedentemente allocata:
 snd_config_update_free_global()

End


Private Procedure lista_subdevice(audioH As Pointer, cardN As Integer, devN As Integer, tipo As Integer)
 
 Dim pcmInfo As Pointer
 Dim subDevCount, i, err As Integer
 Dim stringa As String

 If tipo = SND_PCM_STREAM_PLAYBACK Then
   stringa = "Output"
 Else
   stringa = "Input"
 Endif
 
 snd_pcm_info_malloc(VarPtr(pcmInfo))
 memset(pcmInfo, 0, snd_pcm_info_sizeof())

' Dice ad ALSA di quale dispositivo Audio si richiedono le informazioni:
 snd_pcm_info_set_device(pcmInfo, devN)
   
' Si ottengono informazioni sull'uscita Audio o in sezione del corrente dispositivo:
 snd_pcm_info_set_stream(pcmInfo, tipo)
    
 i = -1
 subDevCount = 1
  
 Inc i
 While i < subDevCount
' Dice ad ALSA di riempire 'snd_pcm_info_t' con le informazioni sul corrente subdispositivo:
   snd_pcm_info_set_subdevice(pcmInfo, i)
   err = snd_ctl_pcm_info(audioH, pcmInfo)
   If err < 0 Then
     ListBox1.Add("Impossibile ottenere informazioni sul subdevice " & stringa & " Audio 'hw:" & CStr(cardN) & "," & CStr(devN) & "," & CStr(i) & " : " & snd_strerror(err))
     Break
   Endif
' Scrive quanti subdispositivi audio sono presenti:
   If Not i Then
     subDevCount = snd_pcm_info_get_subdevices_count(pcmInfo)
     With ListBox1
       .Add(" ")
       .Add("------ " & subDevCount & " " & stringa & " subdevice (" & snd_pcm_info_get_subdevices_avail(pcmInfo) & " disponibili)")
       .Add("id = " & snd_pcm_info_get_id(pcmInfo))
       .Add("nome = " & snd_pcm_info_get_name(pcmInfo))
     End With
   Endif
' NOTA: Se è presente un solo subdispositivo, allora il numero del subdispositivo è immateriale, e può essere omesso:
   If subDevCount > 1 Then
     ListBox1.Add(" ")
     ListBox1.Add("   AUDIO " & stringa & " 'hw:" & cardN & "," & devN & "," & i & "'")
   Else
     ListBox1.Add(" ")
     ListBox1.Add("   AUDIO " & stringa & " 'hw:" & cardN & "," & devN & "'")
   Endif
   ListBox1.Add("   subnome = '" & snd_pcm_info_get_subdevice_name(pcmInfo) & "'")
   Inc i
 Wend

End