Differenze tra le versioni di "Conoscere con le funzioni esterne di ALSA i dispositivi Midi presenti nel sistema"
(7 versioni intermedie di uno stesso utente non sono mostrate) | |||
Riga 6: | Riga 6: | ||
* un numero che rappresenta il dispositivo; | * un numero che rappresenta il dispositivo; | ||
* un numero che rappresenta il sub-dispositivo. | * un numero che rappresenta il sub-dispositivo. | ||
+ | Questi tre elementi costituiscono una stringa che identifica una scheda audio. <SUP>[[[#Note|nota 1]]]</sup> | ||
− | Gli esempi, che seguono, mostrano come accedere appunto a questi tre numeri rappresentativi. Avendo a disposizione tali numeri, è possibile aprire una porta MIDI di Entrata o di Uscita con la funzione | + | Gli esempi, che seguono, mostrano come accedere appunto a questi tre numeri rappresentativi. Avendo a disposizione tali numeri, è possibile aprire una porta MIDI di Entrata o di Uscita con la funzione "snd_rawmidi_open()" o aprire una scheda audio (un'interfaccia di controllo) con la funzione "snd_ctl_open()", usando una stringa simile: |
hw:x,y,z | hw:x,y,z | ||
− | laddove x, y, z sono i tre numeri che rappresentano e specificano una particolare porta MIDI di Entrata o di Uscita, come ad esempio: | + | laddove x, y, z sono i tre numeri che rappresentano e specificano una particolare porta MIDI di Entrata o di Uscita (l'interfaccia di controllo scheda audio), come ad esempio: |
hw:1,0,0 | hw:1,0,0 | ||
Mostriamo di seguito tre codici, che dovranno essere lanciati dopo aver collegato, ad esempio, uno o più dispositivi Midi esterni hardware (ad esempio una o più tastiere Midi) al proprio computer. | Mostriamo di seguito tre codici, che dovranno essere lanciati dopo aver collegato, ad esempio, uno o più dispositivi Midi esterni hardware (ad esempio una o più tastiere Midi) al proprio computer. | ||
− | |||
====Primo esempio==== | ====Primo esempio==== | ||
Riga 27: | Riga 27: | ||
<FONT color=gray>' ''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 | + | ' ''Opens a sound card.''</font> |
Private Extern snd_ctl_open(card As Pointer, name As String, mode As Integer) As Integer | Private Extern snd_ctl_open(card As Pointer, name As String, mode As Integer) As Integer | ||
Riga 71: | Riga 71: | ||
− | + | Public Sub Main() | |
Dim err, cardNum, devNum, subDevCount, i As Integer | Dim err, cardNum, devNum, subDevCount, i As Integer | ||
Riga 78: | Riga 78: | ||
Dim j, k As Byte | Dim j, k As Byte | ||
− | + | Print "---- DISPOSITIVI HARDWARE MIDI PRESENTI ----\n" | |
− | |||
− | |||
− | + | cardNum = -1 | |
− | |||
− | + | Do | |
− | + | err = snd_card_next(VarPtr(cardNum)) | |
+ | If err < 0 Then Error.Raise("Impossibile ottenere il numero della scheda audio successiva !") | ||
<FONT color=gray>' ''Se non vi sono più schede, Alsa imposta "cardNum" a -1:''</font> | <FONT color=gray>' ''Se non vi sono più schede, Alsa imposta "cardNum" a -1:''</font> | ||
− | + | If cardNum < 0 Then Break | |
− | + | $str = "hw:" & CStr(cardNum) | |
− | + | err = snd_ctl_open(VarPtr(cardHandle), $Str, 0) | |
− | + | If err < 0 Then Error.Raise("Impossibile aprire la connessione con la scheda audio !") | |
− | |||
− | |||
<FONT color=gray>' ''Parte con il primo dispositivo Midi sulla scheda individuata:''</font> | <FONT color=gray>' ''Parte con il primo dispositivo Midi sulla scheda individuata:''</font> | ||
− | + | devNum = -1 | |
− | + | Do | |
− | |||
− | |||
<FONT color=gray>' ''Ricava il numero del successivo dispositivo Midi sulla scheda attuale:''</font> | <FONT color=gray>' ''Ricava il numero del successivo dispositivo Midi sulla scheda attuale:''</font> | ||
− | + | err = snd_ctl_rawmidi_next_device(cardHandle, VarPtr(devNum)) | |
− | + | If err < 0 Then Error.Raise("Impossibile ottenere il numero del successivo dispositivo Midi !") | |
− | |||
<FONT color=gray>' ''Se non ci sono altri dispositivi Midi sulla scheda audio, Alsa imposta "devNum" a -1.'' | <FONT color=gray>' ''Se non ci sono altri dispositivi Midi 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 Midi:''</font> | ' ''NOTA: E' possibile che la scheda audio (ad esempio una scheda audio digitale) possa non avere dispositivi Midi:''</font> | ||
− | + | If devNum < 0 Then Break | |
− | + | <FONT color=gray>' ''Per ottenere informazioni sui sub-dispositivi del presente dispositivo Midi (sulla scheda), bisogna chiamare la funzione "snd_rawmidi_info_t", previa allocazione di memoria sullo stack:''</font> | |
− | <FONT color=gray>' ''Per ottenere informazioni sui sub-dispositivi del presente dispositivo Midi (sulla scheda), | + | snd_rawmidi_info_malloc(VarPtr(rawMidiInfo)) |
− | + | memset(rawMidiInfo, 0, snd_rawmidi_info_sizeof()) | |
− | |||
− | |||
− | |||
<FONT color=gray>' ''Si dice ad Alsa di quale numero di dispositivo vogliamo ottenere informazioni:''</font> | <FONT color=gray>' ''Si dice ad Alsa di quale numero di dispositivo vogliamo ottenere informazioni:''</font> | ||
− | + | snd_rawmidi_info_set_device(rawMidiInfo, devNum) | |
− | |||
<FONT color=gray>' ''Si ottengono le informazioni Midi del dispositivo:''</font> | <FONT color=gray>' ''Si ottengono le informazioni Midi del dispositivo:''</font> | ||
− | + | snd_rawmidi_info_set_stream(rawMidiInfo, SND_RAWMIDI_STREAM_OUTPUT) | |
− | + | i = -1 | |
− | + | subDevCount = 1 | |
− | + | While (i < subDevCount - 1) | |
− | + | Inc i | |
− | |||
− | |||
− | |||
<FONT color=gray>' ''Si dice ad Alsa di riempire la funzione "our snd_rawmidi_info_t" con le informazioni sul presente sub-dispositivo:''</font> | <FONT color=gray>' ''Si dice ad Alsa di riempire la funzione "our snd_rawmidi_info_t" con le informazioni sul presente sub-dispositivo:''</font> | ||
− | + | snd_rawmidi_info_set_subdevice(rawMidiInfo, i) | |
− | + | err = snd_ctl_rawmidi_info(cardHandle, rawMidiInfo) | |
− | + | If err < 0 Then Error.Raise("Impossibile ottenere informazioni dal subdispositivo Midi output !") | |
− | + | <FONT color=gray>' ''NOTA: Se v'è un solo subdevice, allora il numero del subdispositivo è virtuale, e può essere omesso quando viene specificato il nome dell'hardware Midi:''</font> | |
− | <FONT color=gray>' ''NOTA: Se v'è un solo subdevice, allora il numero del subdispositivo è virtuale, | + | If subDevCount > 1 Then |
− | + | Print "hw:"; cardNum; ","; devNum; ","; i; Chr(10) | |
− | + | Else | |
− | + | Print"hw:"; cardNum; ","; devNum; Chr(10) | |
− | + | Endif | |
− | |||
− | |||
− | |||
− | |||
− | |||
Wend | Wend | ||
+ | Loop | ||
+ | snd_ctl_close(cardHandle) | ||
+ | Loop | ||
− | + | snd_config_update_free_global() | |
− | |||
− | |||
− | + | End | |
− | |||
− | |||
− | |||
====Secondo esempio==== | ====Secondo esempio==== | ||
Riga 223: | Riga 202: | ||
− | + | Public Sub Main() | |
− | + | Dim err, scheda As Integer | |
− | + | Dim nomecorto, nomeesteso As Pointer | |
Print "---- DISPOSITIVI HARDWARE MIDI PRESENTI ----\n" | Print "---- DISPOSITIVI HARDWARE MIDI PRESENTI ----\n" | ||
Riga 279: | Riga 258: | ||
− | + | End | |
− | <FONT color=gray>' '''Ottiene informazioni circa i dispositivi hardware Midi | + | <FONT color=gray>' '''Ottiene informazioni circa i dispositivi hardware Midi in grado di gestire i dati Midi in Entrata ed in Uscita.'''</font> |
− | |||
− | + | Private Procedure lista_dispositivi_midi(dispSc As Integer) | |
Dim nome As String | Dim nome As String | ||
Dim err, disp As Integer | Dim err, disp As Integer | ||
Dim ctl As Pointer | Dim ctl As Pointer | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | disp = -1 | |
+ | |||
+ | nome = "hw:" & CStr(dispSc) | ||
+ | err = snd_ctl_open(VarPtr(ctl), nome, 0) | ||
+ | If err < 0 Then Error.Raise("Impossibile aprire un controllo della scheda audio " & CStr(dispSc) & ": " & snd_strerror(err)) | ||
+ | |||
+ | Repeat | ||
+ | err = snd_ctl_rawmidi_next_device(ctl, VarPtr(disp)) | ||
+ | If err < 0 Then Error.Raise("Impossibile ottenere il numero del dispositivo: " & snd_strerror(err)) | ||
+ | If disp >= 0 Then lista_subdispositivi_midi(ctl, dispSc, disp) | ||
+ | Until disp < 0 | ||
− | + | snd_ctl_close(ctl) | |
− | |||
− | |||
− | + | End | |
− | <FONT color=gray>' '''Ottiene informazioni circa i subdispositivi hardware Midi | + | <FONT color=gray>' '''Ottiene informazioni circa i subdispositivi hardware Midi in grado di gestire i dati Midi in Entrata ed in Uscita.'''</font> |
− | |||
− | + | Private Procedure lista_subdispositivi_midi(subCtl As Pointer, subSc As Integer, subDi As Integer) | |
Dim mdInfo As Pointer | Dim mdInfo As Pointer | ||
Riga 321: | Riga 294: | ||
Dim nome, subnome, io As String | Dim nome, subnome, io As String | ||
− | + | snd_rawmidi_info_malloc(VarPtr(mdInfo)) | |
− | + | snd_rawmidi_info_set_device(mdInfo, subDi) | |
− | + | snd_rawmidi_info_set_stream(mdInfo, SND_RAWMIDI_STREAM_INPUT) | |
− | + | snd_ctl_rawmidi_info(subCtl, mdInfo) | |
− | + | subIn = snd_rawmidi_info_get_subdevices_count(mdInfo) | |
− | + | snd_rawmidi_info_set_stream(mdInfo, SND_RAWMIDI_STREAM_OUTPUT) | |
− | + | snd_ctl_rawmidi_info(subCtl, mdInfo) | |
− | + | subEx = snd_rawmidi_info_get_subdevices_count(mdInfo) | |
− | + | If subIn > subEx Then | |
− | + | subs = subIn | |
− | + | Else | |
− | + | subs = subEx | |
− | + | Endif | |
+ | |||
+ | err = emissio(subCtl, subDi, su) | ||
+ | If err < 0 Then | ||
+ | Error.Raise("Impossibile ottenere informazioni 'rawmidi': " & CStr(subSc) & ":" & subDi & ": " & snd_strerror(err)) | ||
+ | Else If err Then | ||
+ | ex = 1 | ||
+ | Endif | ||
+ | |||
+ | err = immissio(subCtl, subDi, su) | ||
+ | If err < 0 Then | ||
+ | Error.Raise("Impossibile ottenere informazioni 'rawmidi': " & CStr(subSc) & ":" & subDi & ": " & snd_strerror(err)) | ||
+ | Else If err Then | ||
+ | en = 1 | ||
+ | Endif | ||
+ | |||
+ | If err = 0 Then Return | ||
− | + | nome = snd_rawmidi_info_get_name(mdInfo) | |
− | + | subnome = snd_rawmidi_info_get_subdevice_name(mdInfo) | |
− | + | ||
− | + | If Left(subnome, 1) = Chr(0) Then | |
− | + | If subs = 1 Then | |
− | + | If en Then io = "In " | |
+ | If ex Then io &= "Out" | ||
+ | Print io, " hw:"; subSc; ","; subDi, nome | ||
+ | Else | ||
+ | If en Then io = "In " | ||
+ | If ex Then io &= "Out" | ||
+ | Print io, " hw:"; subSc; ","; subDi, nome; " ("; subs; "subdispositivi)" | ||
+ | Endif | ||
+ | Else | ||
+ | su = 0 | ||
+ | Do | ||
+ | If en Then io = "In " | ||
+ | If ex Then io &= "Out" | ||
+ | Print io, " hw:"; subSc; ","; subDi; ","; su, subnome | ||
+ | Inc su | ||
+ | If su >= subs Then Break | ||
+ | en = immissio(subCtl, subDi, su) | ||
+ | ex = emissio(subCtl, subDi, su) | ||
+ | snd_rawmidi_info_set_subdevice(mdInfo, su) | ||
+ | If ex Then | ||
+ | snd_rawmidi_info_set_stream(mdInfo, SND_RAWMIDI_STREAM_OUTPUT) | ||
+ | err = snd_ctl_rawmidi_info(subCtl, mdInfo) | ||
+ | If err < 0 Then | ||
+ | Error.Raise("Impossibile ottenere informazioni 'rawmidi': " & CStr(subSc) & ":" & subDi & ":" & su & ": " & snd_strerror(err)) | ||
+ | Break | ||
+ | Endif | ||
+ | Else | ||
+ | snd_rawmidi_info_set_stream(mdInfo, SND_RAWMIDI_STREAM_INPUT) | ||
+ | err = snd_ctl_rawmidi_info(subCtl, mdInfo) | ||
+ | If err < 0 Then | ||
+ | Error.Raise("Impossibile ottenere informazioni 'rawmidi': " & CStr(subSc) & ":" & subDi & ":" & su & ": " & snd_strerror(err)) | ||
+ | Break | ||
+ | Endif | ||
+ | Endif | ||
+ | subnome = snd_rawmidi_info_get_subdevice_name(mdInfo) | ||
+ | Loop | ||
+ | Endif | ||
− | + | End | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | Private Function emissio(subCtl As Pointer, subDi As Integer, su As Integer) As Integer | |
− | |||
Dim eInfo As Pointer | Dim eInfo As Pointer | ||
Dim err As Integer | Dim err As Integer | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | snd_rawmidi_info_malloc(VarPtr(eInfo)) | |
+ | snd_rawmidi_info_set_device(eInfo, subDi) | ||
+ | snd_rawmidi_info_set_subdevice(eInfo, su) | ||
+ | snd_rawmidi_info_set_stream(eInfo, SND_RAWMIDI_STREAM_OUTPUT) | ||
+ | |||
+ | err = snd_ctl_rawmidi_info(subCtl, eInfo) | ||
− | + | If (err < 0) And (err <> - ENXIO) Then | |
− | + | Return err | |
− | + | Else If err = 0 Then | |
<FONT color=gray>' ''Ritorna "1", se gli specificati scheda/device/subdevice hanno la capacità di inviare dati MIDI in uscita:''</font> | <FONT color=gray>' ''Ritorna "1", se gli specificati scheda/device/subdevice hanno la capacità di inviare dati MIDI in uscita:''</font> | ||
− | + | Return 1 | |
− | + | Endif | |
− | + | ||
− | + | End | |
− | + | Private Function immissio(subCtl As Pointer, subDi As Integer, su As Integer) As Integer | |
Dim iInfo As Pointer | Dim iInfo As Pointer | ||
Dim err As Integer | Dim err As Integer | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | snd_rawmidi_info_malloc(VarPtr(iInfo)) | |
− | + | snd_rawmidi_info_set_device(iInfo, subDi) | |
− | + | snd_rawmidi_info_set_subdevice(iInfo, su) | |
− | + | snd_rawmidi_info_set_stream(iInfo, SND_RAWMIDI_STREAM_INPUT) | |
+ | |||
+ | err = snd_ctl_rawmidi_info(subCtl, iInfo) | ||
+ | If (err < 0) And (err <> - ENXIO) Then | ||
+ | Return err | ||
+ | Else If err = 0 Then | ||
<FONT color=gray>' ''Ritorna "1", se gli specificati scheda/device/subdevice hanno la capacità di inviare dati MIDI in entrata:''</font> | <FONT color=gray>' ''Ritorna "1", se gli specificati scheda/device/subdevice hanno la capacità di inviare dati MIDI in entrata:''</font> | ||
− | + | Return 1 | |
− | + | Endif | |
− | + | ||
− | + | End | |
Riga 559: | Riga 526: | ||
− | + | Public Sub Main() | |
− | + | Dim err, cardNum, devNum, unaVolta As Integer | |
− | + | Dim midiHandle, cardInfo As Pointer | |
− | + | Dim $str As String | |
Print "---- DISPOSITIVI HARDWARE MIDI PRESENTI ----" | Print "---- DISPOSITIVI HARDWARE MIDI PRESENTI ----" | ||
Riga 569: | Riga 536: | ||
cardNum = -1 | cardNum = -1 | ||
− | |||
While True | While True | ||
Riga 635: | Riga 601: | ||
snd_config_update_free_global() | snd_config_update_free_global() | ||
− | + | End | |
+ | Private Procedure lista_subdevice(midiH As Pointer, cardN As Integer, devN As Integer, tipo As Integer) | ||
+ | |||
+ | Dim rawMidiInfo As Pointer | ||
+ | Dim subDevCount, i, err As Integer | ||
+ | Dim stringa As String | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
If tipo = SND_RAWMIDI_STREAM_OUTPUT Then | If tipo = SND_RAWMIDI_STREAM_OUTPUT Then | ||
stringa = "Output" | stringa = "Output" | ||
Riga 694: | Riga 658: | ||
Wend | Wend | ||
− | + | End | |
+ | |||
+ | |||
+ | |||
+ | =Note= | ||
+ | [1] Vedere la seguente pagina: https://www.alsa-project.org/alsa-doc/alsa-lib/control.html#control_cards_id |
Versione attuale delle 11:02, 19 giu 2024
Premessa
Alcune funzioni esterne del API di Alsa consentono di conoscere i dispositivi Midi dell'hardware audio presenti nel proprio sistema, con i quali poter ricevere ed inviare dati Midi grezzi.
L'accesso ad una porta MIDI richiede tre Interi:
- un numero che rappresenta la scheda audio;
- un numero che rappresenta il dispositivo;
- un numero che rappresenta il sub-dispositivo.
Questi tre elementi costituiscono una stringa che identifica una scheda audio. [nota 1]
Gli esempi, che seguono, mostrano come accedere appunto a questi tre numeri rappresentativi. Avendo a disposizione tali numeri, è possibile aprire una porta MIDI di Entrata o di Uscita con la funzione "snd_rawmidi_open()" o aprire una scheda audio (un'interfaccia di controllo) con la funzione "snd_ctl_open()", usando una stringa simile:
hw:x,y,z
laddove x, y, z sono i tre numeri che rappresentano e specificano una particolare porta MIDI di Entrata o di Uscita (l'interfaccia di controllo scheda audio), come ad esempio:
hw:1,0,0
Mostriamo di seguito tre codici, che dovranno essere lanciati dopo aver collegato, ad esempio, uno o più dispositivi Midi esterni hardware (ad esempio una o più tastiere Midi) al proprio computer.
Primo esempio
Cominciamo con il primo esempio più semplice:
Library "libasound:2.0.0" Private Const SND_RAWMIDI_STREAM_OUTPUT As Byte = 0 ' int snd_card_next (int *card) ' Try To determine the Next card. Private Extern snd_card_next(card As Pointer) As Integer ' int snd_ctl_open (snd_ctl_t **ctl, const char *name, int mode) ' Opens a sound card. Private Extern snd_ctl_open(card As Pointer, name As String, mode As Integer) As Integer ' int snd_ctl_rawmidi_next_device (snd_ctl_t *ctl, int *device) ' Get Next RawMidi device number. Private Extern snd_ctl_rawmidi_next_device(ctl As Pointer, device As Pointer) As Integer ' int snd_rawmidi_info_malloc (snd_rawmidi_info_t **ptr) ' Allocate a new snd_rawmidi_info_t structure. Private Extern snd_rawmidi_info_malloc(ptr As Pointer) As Integer ' size_t snd_rawmidi_info_sizeof (void) ' Get size Of the 'snd_rawmidi_info_t' structure in bytes. Private Extern snd_rawmidi_info_sizeof() As Integer ' void snd_rawmidi_info_set_device (snd_rawmidi_info_t *obj, unsigned int val) ' Set rawmidi device number. Private Extern snd_rawmidi_info_set_device(obj As Pointer, ValInt As Integer) ' void snd_rawmidi_info_set_stream (snd_rawmidi_info_t *obj, snd_rawmidi_stream_t val) ' Set rawmidi stream identifier. Private Extern snd_rawmidi_info_set_stream(obj As Pointer, ValInt As Integer) ' void snd_rawmidi_info_set_subdevice (snd_rawmidi_info_t *obj, unsigned int val) ' Set rawmidi subdevice number. Private Extern snd_rawmidi_info_set_subdevice(obj As Pointer, ValInt As Integer) ' int snd_ctl_rawmidi_info (snd_ctl_t *ctl, snd_rawmidi_info_t *info) ' Get info about a RawMidi device. Private Extern snd_ctl_rawmidi_info(ctl As Pointer, info As Pointer) As Integer ' 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 ' 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 Main() Dim err, cardNum, devNum, subDevCount, i As Integer Dim cardHandle, rawMidiInfo As Pointer Dim $str As String Dim j, k As Byte Print "---- DISPOSITIVI HARDWARE MIDI PRESENTI ----\n" cardNum = -1 Do err = snd_card_next(VarPtr(cardNum)) If err < 0 Then Error.Raise("Impossibile ottenere il numero della scheda audio successiva !") ' Se non vi sono più schede, Alsa imposta "cardNum" a -1: If cardNum < 0 Then Break $str = "hw:" & CStr(cardNum) err = snd_ctl_open(VarPtr(cardHandle), $Str, 0) If err < 0 Then Error.Raise("Impossibile aprire la connessione con la scheda audio !") ' Parte con il primo dispositivo Midi sulla scheda individuata: devNum = -1 Do ' Ricava il numero del successivo dispositivo Midi sulla scheda attuale: err = snd_ctl_rawmidi_next_device(cardHandle, VarPtr(devNum)) If err < 0 Then Error.Raise("Impossibile ottenere il numero del successivo dispositivo Midi !") ' Se non ci sono altri dispositivi Midi 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 Midi: If devNum < 0 Then Break ' Per ottenere informazioni sui sub-dispositivi del presente dispositivo Midi (sulla scheda), bisogna chiamare la funzione "snd_rawmidi_info_t", previa allocazione di memoria sullo stack: snd_rawmidi_info_malloc(VarPtr(rawMidiInfo)) memset(rawMidiInfo, 0, snd_rawmidi_info_sizeof()) ' Si dice ad Alsa di quale numero di dispositivo vogliamo ottenere informazioni: snd_rawmidi_info_set_device(rawMidiInfo, devNum) ' Si ottengono le informazioni Midi del dispositivo: snd_rawmidi_info_set_stream(rawMidiInfo, SND_RAWMIDI_STREAM_OUTPUT) i = -1 subDevCount = 1 While (i < subDevCount - 1) Inc i ' Si dice ad Alsa di riempire la funzione "our snd_rawmidi_info_t" con le informazioni sul presente sub-dispositivo: snd_rawmidi_info_set_subdevice(rawMidiInfo, i) err = snd_ctl_rawmidi_info(cardHandle, rawMidiInfo) If err < 0 Then Error.Raise("Impossibile ottenere informazioni dal subdispositivo Midi output !") ' NOTA: Se v'è un solo subdevice, allora il numero del subdispositivo è virtuale, e può essere omesso quando viene specificato il nome dell'hardware Midi: If subDevCount > 1 Then Print "hw:"; cardNum; ","; devNum; ","; i; Chr(10) Else Print"hw:"; cardNum; ","; devNum; Chr(10) Endif Wend Loop snd_ctl_close(cardHandle) Loop snd_config_update_free_global() End
Secondo esempio
Mostriamo il secondo esempio più complesso del precedente.
Private Const ENXIO As Integer = 6 Library "libasound:2.0.0" Private Const SND_RAWMIDI_STREAM_OUTPUT As Integer = 0 Private Const SND_RAWMIDI_STREAM_INPUT As Integer = 1 ' int snd_card_next (int *card) ' Try To determine the Next card. Private Extern snd_card_next(card As Pointer) As Integer ' int snd_card_get_name (int card, char **name) ' Obtain the card name. Private Extern snd_card_get_name(card As Integer, name As Pointer) As Integer ' int snd_card_get_longname (int card, char **name) ' Obtain the card long name. Private Extern snd_card_get_longname(card As Integer, name 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_rawmidi_next_device (snd_ctl_t *ctl, int *device) ' Get Next RawMidi device number. Private Extern snd_ctl_rawmidi_next_device(ctl As Pointer, device As Pointer) As Integer ' int snd_rawmidi_info_malloc (snd_rawmidi_info_t **ptr) ' Allocate a new snd_rawmidi_info_t structure. Private Extern snd_rawmidi_info_malloc(ptr As Pointer) As Integer ' void snd_rawmidi_info_set_device (snd_rawmidi_info_t *obj, unsigned int val) ' Set rawmidi device number. Private Extern snd_rawmidi_info_set_device(obj As Pointer, ValInt As Integer) ' void snd_rawmidi_info_set_stream (snd_rawmidi_info_t *obj, snd_rawmidi_stream_t val) ' Set rawmidi stream identifier. Private Extern snd_rawmidi_info_set_stream(obj As Pointer, ValInt As Integer) ' int snd_ctl_rawmidi_info (snd_ctl_t *ctl, snd_rawmidi_info_t *info) ' Get info about a RawMidi device. Private Extern snd_ctl_rawmidi_info(ctl As Pointer, info As Pointer) As Integer ' unsigned int snd_rawmidi_info_get_subdevices_count (const snd_rawmidi_info_t *obj) ' Get rawmidi count of subdevices. Private Extern snd_rawmidi_info_get_subdevices_count(obj As Pointer) As Integer ' const char * snd_rawmidi_info_get_name (const snd_rawmidi_info_t *obj) ' Get rawmidi hardware driver name. Private Extern snd_rawmidi_info_get_name(obj As Pointer) As String ' const char * snd_rawmidi_info_get_subdevice_name (const snd_rawmidi_info_t *obj) ' Get rawmidi subdevice name. Private Extern snd_rawmidi_info_get_subdevice_name(obj As Pointer) As String ' void snd_rawmidi_info_set_subdevice (snd_rawmidi_info_t *obj, unsigned int val) ' Set rawmidi subdevice number. Private Extern snd_rawmidi_info_set_subdevice(obj As Pointer, ValInt As Integer) ' int snd_ctl_close (snd_ctl_t *ctl) ' Closes CTL handle. Private Extern snd_ctl_close(ctl As Pointer) As Integer ' const char * snd_strerror (int errnum) ' Returns the message For an Error code. Private Extern snd_strerror(errore As Integer) As String Public Sub Main() Dim err, scheda As Integer Dim nomecorto, nomeesteso As Pointer Print "---- DISPOSITIVI HARDWARE MIDI PRESENTI ----\n" scheda = -1 ' Individua le schede audio disponibili nel sistema ALSA, mostrando il loro numero ed il nome di ciascuna: err = snd_card_next(VarPtr(scheda)) If err < 0 Then Error.Raise("Impossibile ottenere il numero della scheda audio: " & snd_strerror(err)) If scheda < 0 Then Print "Nessuna scheda audio trovata nel sistema !" Quit Endif While scheda >= 0 Print "Scheda: "; scheda err = snd_card_get_name(scheda, VarPtr(nomecorto)) If err < 0 Then Error.Raise("Impossibile ottenere il nome breve della scheda audio !") err = snd_card_get_longname(scheda, VarPtr(nomeesteso)) If err < 0 Then Error.Raise("Impossibile ottenere il nome esteso della scheda audio !") Print " NOME INTERO: "; String@(nomeesteso) Print " NOME ABBREV.: "; String@(nomecorto) err = snd_card_next(VarPtr(scheda)) If err < 0 Then Error.Raise("Impossibile ottenere il numero della scheda audio: " & snd_strerror(err)) Wend ' Individua i dispositivi ed i subdispositivi Midi e le rispettive porte ' in grado di leggere e scrivere dati Midi in Entrata ed in Uscita. err = snd_card_next(VarPtr(scheda)) If err < 0 Then Error.Raise("Impossibile ottenere il numero della scheda audio: " & snd_strerror(err)) If scheda < 0 Then Print "Nessuna scheda audio trovata nel sistema !" Quit Endif Print "\nDir Dispositivo Nome" Print "====================================\n" While scheda >= 0 lista_dispositivi_midi(scheda) err = snd_card_next(VarPtr(scheda)) If err < 0 Then Error.Raise("Impossibile ottenere il numero della scheda audio: " & snd_strerror(err)) Wend End ' Ottiene informazioni circa i dispositivi hardware Midi in grado di gestire i dati Midi in Entrata ed in Uscita. Private Procedure lista_dispositivi_midi(dispSc As Integer) Dim nome As String Dim err, disp As Integer Dim ctl As Pointer disp = -1 nome = "hw:" & CStr(dispSc) err = snd_ctl_open(VarPtr(ctl), nome, 0) If err < 0 Then Error.Raise("Impossibile aprire un controllo della scheda audio " & CStr(dispSc) & ": " & snd_strerror(err)) Repeat err = snd_ctl_rawmidi_next_device(ctl, VarPtr(disp)) If err < 0 Then Error.Raise("Impossibile ottenere il numero del dispositivo: " & snd_strerror(err)) If disp >= 0 Then lista_subdispositivi_midi(ctl, dispSc, disp) Until disp < 0 snd_ctl_close(ctl) End ' Ottiene informazioni circa i subdispositivi hardware Midi in grado di gestire i dati Midi in Entrata ed in Uscita. Private Procedure lista_subdispositivi_midi(subCtl As Pointer, subSc As Integer, subDi As Integer) Dim mdInfo As Pointer Dim subIn, subEx, subs, su, en, ex, err As Integer Dim nome, subnome, io As String snd_rawmidi_info_malloc(VarPtr(mdInfo)) snd_rawmidi_info_set_device(mdInfo, subDi) snd_rawmidi_info_set_stream(mdInfo, SND_RAWMIDI_STREAM_INPUT) snd_ctl_rawmidi_info(subCtl, mdInfo) subIn = snd_rawmidi_info_get_subdevices_count(mdInfo) snd_rawmidi_info_set_stream(mdInfo, SND_RAWMIDI_STREAM_OUTPUT) snd_ctl_rawmidi_info(subCtl, mdInfo) subEx = snd_rawmidi_info_get_subdevices_count(mdInfo) If subIn > subEx Then subs = subIn Else subs = subEx Endif err = emissio(subCtl, subDi, su) If err < 0 Then Error.Raise("Impossibile ottenere informazioni 'rawmidi': " & CStr(subSc) & ":" & subDi & ": " & snd_strerror(err)) Else If err Then ex = 1 Endif err = immissio(subCtl, subDi, su) If err < 0 Then Error.Raise("Impossibile ottenere informazioni 'rawmidi': " & CStr(subSc) & ":" & subDi & ": " & snd_strerror(err)) Else If err Then en = 1 Endif If err = 0 Then Return nome = snd_rawmidi_info_get_name(mdInfo) subnome = snd_rawmidi_info_get_subdevice_name(mdInfo) If Left(subnome, 1) = Chr(0) Then If subs = 1 Then If en Then io = "In " If ex Then io &= "Out" Print io, " hw:"; subSc; ","; subDi, nome Else If en Then io = "In " If ex Then io &= "Out" Print io, " hw:"; subSc; ","; subDi, nome; " ("; subs; "subdispositivi)" Endif Else su = 0 Do If en Then io = "In " If ex Then io &= "Out" Print io, " hw:"; subSc; ","; subDi; ","; su, subnome Inc su If su >= subs Then Break en = immissio(subCtl, subDi, su) ex = emissio(subCtl, subDi, su) snd_rawmidi_info_set_subdevice(mdInfo, su) If ex Then snd_rawmidi_info_set_stream(mdInfo, SND_RAWMIDI_STREAM_OUTPUT) err = snd_ctl_rawmidi_info(subCtl, mdInfo) If err < 0 Then Error.Raise("Impossibile ottenere informazioni 'rawmidi': " & CStr(subSc) & ":" & subDi & ":" & su & ": " & snd_strerror(err)) Break Endif Else snd_rawmidi_info_set_stream(mdInfo, SND_RAWMIDI_STREAM_INPUT) err = snd_ctl_rawmidi_info(subCtl, mdInfo) If err < 0 Then Error.Raise("Impossibile ottenere informazioni 'rawmidi': " & CStr(subSc) & ":" & subDi & ":" & su & ": " & snd_strerror(err)) Break Endif Endif subnome = snd_rawmidi_info_get_subdevice_name(mdInfo) Loop Endif End Private Function emissio(subCtl As Pointer, subDi As Integer, su As Integer) As Integer Dim eInfo As Pointer Dim err As Integer snd_rawmidi_info_malloc(VarPtr(eInfo)) snd_rawmidi_info_set_device(eInfo, subDi) snd_rawmidi_info_set_subdevice(eInfo, su) snd_rawmidi_info_set_stream(eInfo, SND_RAWMIDI_STREAM_OUTPUT) err = snd_ctl_rawmidi_info(subCtl, eInfo) If (err < 0) And (err <> - ENXIO) Then Return err Else If err = 0 Then ' Ritorna "1", se gli specificati scheda/device/subdevice hanno la capacità di inviare dati MIDI in uscita: Return 1 Endif End Private Function immissio(subCtl As Pointer, subDi As Integer, su As Integer) As Integer Dim iInfo As Pointer Dim err As Integer snd_rawmidi_info_malloc(VarPtr(iInfo)) snd_rawmidi_info_set_device(iInfo, subDi) snd_rawmidi_info_set_subdevice(iInfo, su) snd_rawmidi_info_set_stream(iInfo, SND_RAWMIDI_STREAM_INPUT) err = snd_ctl_rawmidi_info(subCtl, iInfo) If (err < 0) And (err <> - ENXIO) Then Return err Else If err = 0 Then ' Ritorna "1", se gli specificati scheda/device/subdevice hanno la capacità di inviare dati MIDI in entrata: Return 1 Endif End
Terzo esempio
Mostriamo infine il terzo esempio, che consentirà di ottenere maggiori e più dettagliate informazioni relativamente all'hardware Midi, al dispositivo ed all'eventuale subdispositivo:
Library "libasound:2.0.0" Private Const SND_RAWMIDI_STREAM_OUTPUT As Integer = 0 Private Const SND_RAWMIDI_STREAM_INPUT As Integer = 1 ' int snd_card_next (int *card) ' Try To determine the Next card. Private Extern snd_card_next(card 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_rawmidi_next_device (snd_ctl_t *ctl, int *device) ' Get Next RawMidi device number. Private Extern snd_ctl_rawmidi_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_rawmidi_info_malloc (snd_rawmidi_info_t **ptr) ' Allocate a New Snd_rawmidi_info_t structure. Private Extern snd_rawmidi_info_malloc(ptr As Pointer) As Integer ' size_t snd_rawmidi_info_sizeof (void) ' Get size Of the 'snd_rawmidi_info_t' structure in bytes. Private Extern snd_rawmidi_info_sizeof() As Integer ' void snd_rawmidi_info_set_device (snd_rawmidi_info_t *obj, unsigned int val) ' Set rawmidi device number. Private Extern snd_rawmidi_info_set_device(obj As Pointer, ValInt As Integer) ' void snd_rawmidi_info_set_stream (snd_rawmidi_info_t *obj, snd_rawmidi_stream_t val) ' Set rawmidi stream identifier. Private Extern snd_rawmidi_info_set_stream(obj As Pointer, ValInt As Integer) ' void snd_rawmidi_info_set_subdevice (snd_rawmidi_info_t *obj, unsigned int val) ' Set rawmidi subdevice number. Private Extern snd_rawmidi_info_set_subdevice(obj As Pointer, ValInt As Integer) ' int snd_ctl_rawmidi_info (snd_ctl_t *ctl, snd_rawmidi_info_t *info) ' Get info about a RawMidi device. Private Extern snd_ctl_rawmidi_info(ctl As Pointer, info As Pointer) As Integer ' unsigned int snd_rawmidi_info_get_subdevices_count (const snd_rawmidi_info_t *obj) ' Get rawmidi count of subdevices. Private Extern snd_rawmidi_info_get_subdevices_count(obj As Pointer) As Integer ' unsigned int snd_rawmidi_info_get_subdevices_avail (const snd_rawmidi_info_t *obj) ' Get rawmidi available count of subdevices. Private Extern snd_rawmidi_info_get_subdevices_avail(obj As Pointer) As Integer ' const char * snd_rawmidi_info_get_id (const snd_rawmidi_info_t *obj) ' Get rawmidi hardware driver identifier. Private Extern snd_rawmidi_info_get_id(obj As Pointer) As String ' const char * snd_rawmidi_info_get_name (const snd_rawmidi_info_t *obj) ' Get rawmidi hardware driver name. Private Extern snd_rawmidi_info_get_name(obj As Pointer) As String ' const char * snd_rawmidi_info_get_subdevice_name (const snd_rawmidi_info_t *obj) ' Get rawmidi subdevice name. Private Extern snd_rawmidi_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 Main() Dim err, cardNum, devNum, unaVolta As Integer Dim midiHandle, cardInfo As Pointer Dim $str As String Print "---- DISPOSITIVI HARDWARE MIDI 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(midiHandle), $Str, 0) If err < 0 Then Error.Raise("Impossibile aprire la connessione con la scheda audio: " & snd_strerror(err)) ' Parte con il primo dispositivo Midi sulla scheda individuata: devNum = -1 While True ' Ricava il numero del successivo dispositivo Midi sulla scheda attuale: err = snd_ctl_rawmidi_next_device(midiHandle, VarPtr(devNum)) If err < 0 Then Error.Raise("Impossibile ottenere il numero del successivo dispositivo Midi: " & snd_strerror(err)) ' Se non ci sono altri dispositivi Midi 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 Midi: 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(midiHandle, cardInfo) If err < 0 Then Error.Raise("Impossibile ottenere informazioni sulla scheda audio: " & snd_strerror(err)) Else Print "\n\n=================================================================================" Print snd_ctl_card_info_get_longname(cardInfo) Print "=================================================================================\n" Print "id = "; snd_ctl_card_info_get_id(cardInfo) Print "\nnome = "; snd_ctl_card_info_get_name(cardInfo) Print "\ndriver = "; snd_ctl_card_info_get_driver(cardInfo) Print "\nmixername = "; snd_ctl_card_info_get_mixername(cardInfo) Print "\ncomponenti = "; snd_ctl_card_info_get_components(cardInfo) Endif Endif ' Mostra le informazioni relative ai subdispositivi MIDI Output del corrente dispositivo MIDI: lista_subdevice(midiHandle, cardNum, devNum, SND_RAWMIDI_STREAM_OUTPUT) ' Mostra le informazioni relative ai subdispositivi MIDI Input del corrente dispositivo MIDI: lista_subdevice(midiHandle, cardNum, devNum, SND_RAWMIDI_STREAM_INPUT) Wend snd_ctl_close(midiHandle) Wend ' Va in chiusura liberando la memoria precedentemente allocata: snd_config_update_free_global() End Private Procedure lista_subdevice(midiH As Pointer, cardN As Integer, devN As Integer, tipo As Integer) Dim rawMidiInfo As Pointer Dim subDevCount, i, err As Integer Dim stringa As String If tipo = SND_RAWMIDI_STREAM_OUTPUT Then stringa = "Output" Else stringa = "Input" Endif snd_rawmidi_info_malloc(VarPtr(rawMidiInfo)) memset(rawMidiInfo, 0, snd_rawmidi_info_sizeof()) ' Dice ad ALSA di quale dispositivo Midi si richiedono le informazioni: snd_rawmidi_info_set_device(rawMidiInfo, devN) ' Si ottengono informazioni sull'uscita Midi o in sezione del corrente dispositivo: snd_rawmidi_info_set_stream(rawMidiInfo, tipo) i = -1 subDevCount = 1 Inc i While i < subDevCount ' Dice ad ALSA di riempire 'snd_rawmidi_info_t' con le informazioni sul corrente subdispositivo: snd_rawmidi_info_set_subdevice(rawMidiInfo, i) err = snd_ctl_rawmidi_info(midiH, rawMidiInfo) If err < 0 Then Error.Raise("Impossibile ottenere informazioni sul subdevice " & stringa & " Midi 'hw:" & CStr(cardN) & "," & CStr(devN) & "," & CStr(i) & " : " & snd_strerror(err)) ' Scrive quanti subdispositivi Midi sono presenti: If Not i Then subDevCount = snd_rawmidi_info_get_subdevices_count(rawMidiInfo) Print "\n ------ "; subDevCount; " "; stringa; " subdevice ("; snd_rawmidi_info_get_subdevices_avail(rawMidiInfo); " disponibili)" Print "id = "; snd_rawmidi_info_get_id(rawMidiInfo) Print "nome = "; snd_rawmidi_info_get_name(rawMidiInfo) Endif ' NOTA: Se è presente un solo subdispositivo, allora il numero del subdispositivo è immateriale, e può essere omesso: If subDevCount > 1 Then Print " MIDI "; stringa; " 'hw:"; cardN; ","; devN; ","; i; "'" Else Print " MIDI "; stringa; " 'hw:"; cardN; ","; devN; "'" Endif Print " sottonome = '"; snd_rawmidi_info_get_subdevice_name(rawMidiInfo); "'" Inc i Wend End
Note
[1] Vedere la seguente pagina: https://www.alsa-project.org/alsa-doc/alsa-lib/control.html#control_cards_id