Differenze tra le versioni di "Conoscere con le funzioni esterne di ALSA i dispositivi audio presenti nel sistema"
Da Gambas-it.org - Wikipedia.
Riga 1: | Riga 1: | ||
Alcune funzioni esterne del API di ALSA consentono di conoscere quali sono i dispositivi audio 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 due esempi, nei quali sul ''Form'' dell'applicativo porremo una ''ListBox''. | ||
Riga 8: | Riga 7: | ||
− | Library "libasound:2" | + | Library "libasound:2.0.0" |
Private Const SND_PCM_STREAM_PLAYBACK As Byte = 0 <FONT color=gray>' ''Playback stream''</font> | Private Const SND_PCM_STREAM_PLAYBACK As Byte = 0 <FONT color=gray>' ''Playback stream''</font> | ||
Riga 212: | Riga 211: | ||
'''End''' | '''End''' | ||
− | |||
Di seguito invece il secondo possibile codice: | Di seguito invece il secondo possibile codice: | ||
− | Library "libasound:2" | + | Library "libasound:2.0.0" |
Private Const SND_PCM_STREAM_PLAYBACK As Integer = 0 | Private Const SND_PCM_STREAM_PLAYBACK As Integer = 0 |
Versione delle 17:06, 22 ott 2021
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 While True 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 While True ' 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) Wend snd_ctl_close(audioHandle) Wend ' 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)) Exit 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