Differenze tra le versioni di "Conoscere con le funzioni esterne di ALSA i dispositivi Midi presenti nel sistema"
(11 versioni intermedie di uno stesso utente non sono mostrate) | |||
Riga 1: | Riga 1: | ||
====Premessa==== | ====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. | 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. | ||
Riga 7: | 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 usando una stringa simile: | + | 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. |
+ | |||
+ | ====Primo esempio==== | ||
+ | Cominciamo con il primo esempio più semplice: | ||
+ | Library "libasound:2.0.0" | ||
+ | |||
+ | Private Const SND_RAWMIDI_STREAM_OUTPUT As Byte = 0 | ||
+ | |||
+ | <FONT color=gray>' ''int snd_card_next (int *card)'' | ||
+ | ' ''Try To determine the Next card.''</font> | ||
+ | Private Extern snd_card_next(card As Pointer) As Integer | ||
+ | |||
+ | <FONT color=gray>' ''int snd_ctl_open (snd_ctl_t **ctl, const char *name, int mode) | ||
+ | ' ''Opens a sound card.''</font> | ||
+ | Private Extern snd_ctl_open(card As Pointer, name As String, mode As Integer) As Integer | ||
+ | |||
+ | <FONT color=gray>' ''int snd_ctl_rawmidi_next_device (snd_ctl_t *ctl, int *device)'' | ||
+ | ' ''Get Next RawMidi device number.''</font> | ||
+ | Private Extern snd_ctl_rawmidi_next_device(ctl As Pointer, device As Pointer) As Integer | ||
+ | |||
+ | <FONT color=gray>' ''int snd_rawmidi_info_malloc (snd_rawmidi_info_t **ptr)'' | ||
+ | ' ''Allocate a new snd_rawmidi_info_t structure.''</font> | ||
+ | Private Extern snd_rawmidi_info_malloc(ptr As Pointer) As Integer | ||
+ | |||
+ | <FONT color=gray>' ''size_t snd_rawmidi_info_sizeof (void)'' | ||
+ | ' ''Get size Of the 'snd_rawmidi_info_t' structure in bytes.''</font> | ||
+ | Private Extern snd_rawmidi_info_sizeof() As Integer | ||
+ | |||
+ | <FONT color=gray>' ''void snd_rawmidi_info_set_device (snd_rawmidi_info_t *obj, unsigned int val)'' | ||
+ | ' ''Set rawmidi device number.''</font> | ||
+ | Private Extern snd_rawmidi_info_set_device(obj As Pointer, ValInt As Integer) | ||
+ | |||
+ | <FONT color=gray>' ''void snd_rawmidi_info_set_stream (snd_rawmidi_info_t *obj, snd_rawmidi_stream_t val)'' | ||
+ | ' ''Set rawmidi stream identifier.''</font> | ||
+ | Private Extern snd_rawmidi_info_set_stream(obj As Pointer, ValInt As Integer) | ||
+ | |||
+ | <FONT color=gray>' ''void snd_rawmidi_info_set_subdevice (snd_rawmidi_info_t *obj, unsigned int val)'' | ||
+ | ' ''Set rawmidi subdevice number.''</font> | ||
+ | Private Extern snd_rawmidi_info_set_subdevice(obj As Pointer, ValInt As Integer) | ||
+ | |||
+ | <FONT color=gray>' ''int snd_ctl_rawmidi_info (snd_ctl_t *ctl, snd_rawmidi_info_t *info)'' | ||
+ | ' ''Get info about a RawMidi device.''</font> | ||
+ | Private Extern snd_ctl_rawmidi_info(ctl As Pointer, info As Pointer) As Integer | ||
+ | |||
+ | <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>' ''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 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 !") | ||
+ | |||
+ | <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> | ||
+ | devNum = -1 | ||
+ | Do | ||
+ | <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.'' | ||
+ | ' ''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> | ||
+ | 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> | ||
+ | snd_rawmidi_info_set_device(rawMidiInfo, devNum) | ||
+ | <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> | ||
+ | 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> | ||
+ | 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 | ||
+ | |||
+ | <FONT color=gray>' ''int snd_card_next (int *card)'' | ||
+ | ' ''Try To determine the Next card.''</font> | ||
+ | Private Extern snd_card_next(card As Pointer) As Integer | ||
+ | |||
+ | <FONT color=gray>' ''int snd_card_get_name (int card, char **name)'' | ||
+ | ' ''Obtain the card name.''</font> | ||
+ | Private Extern snd_card_get_name(card As Integer, name As Pointer) As Integer | ||
+ | |||
+ | <FONT color=gray>' ''int snd_card_get_longname (int card, char **name)'' | ||
+ | ' ''Obtain the card long name.''</font> | ||
+ | Private Extern snd_card_get_longname(card As Integer, name 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_rawmidi_next_device (snd_ctl_t *ctl, int *device)'' | ||
+ | ' ''Get Next RawMidi device number.''</font> | ||
+ | Private Extern snd_ctl_rawmidi_next_device(ctl As Pointer, device As Pointer) As Integer | ||
+ | |||
+ | <FONT color=gray>' ''int snd_rawmidi_info_malloc (snd_rawmidi_info_t **ptr)'' | ||
+ | ' ''Allocate a new snd_rawmidi_info_t structure.''</font> | ||
+ | Private Extern snd_rawmidi_info_malloc(ptr As Pointer) As Integer | ||
+ | |||
+ | <FONT color=gray>' ''void snd_rawmidi_info_set_device (snd_rawmidi_info_t *obj, unsigned int val)'' | ||
+ | ' ''Set rawmidi device number.''</font> | ||
+ | Private Extern snd_rawmidi_info_set_device(obj As Pointer, ValInt As Integer) | ||
+ | |||
+ | <FONT color=gray>' ''void snd_rawmidi_info_set_stream (snd_rawmidi_info_t *obj, snd_rawmidi_stream_t val)'' | ||
+ | ' ''Set rawmidi stream identifier.''</font> | ||
+ | Private Extern snd_rawmidi_info_set_stream(obj As Pointer, ValInt As Integer) | ||
+ | |||
+ | <FONT color=gray>' ''int snd_ctl_rawmidi_info (snd_ctl_t *ctl, snd_rawmidi_info_t *info)'' | ||
+ | ' ''Get info about a RawMidi device.''</font> | ||
+ | Private Extern snd_ctl_rawmidi_info(ctl As Pointer, info As Pointer) As Integer | ||
+ | |||
+ | <FONT color=gray>' ''unsigned int snd_rawmidi_info_get_subdevices_count (const snd_rawmidi_info_t *obj)'' | ||
+ | ' ''Get rawmidi count of subdevices.''</font> | ||
+ | Private Extern snd_rawmidi_info_get_subdevices_count(obj As Pointer) As Integer | ||
+ | |||
+ | <FONT color=gray>' ''const char * snd_rawmidi_info_get_name (const snd_rawmidi_info_t *obj)'' | ||
+ | ' ''Get rawmidi hardware driver name.''</font> | ||
+ | Private Extern snd_rawmidi_info_get_name(obj As Pointer) As String | ||
+ | |||
+ | <FONT color=gray>' ''const char * snd_rawmidi_info_get_subdevice_name (const snd_rawmidi_info_t *obj)'' | ||
+ | ' ''Get rawmidi subdevice name.''</font> | ||
+ | Private Extern snd_rawmidi_info_get_subdevice_name(obj As Pointer) As String | ||
+ | |||
+ | <FONT color=gray>' ''void snd_rawmidi_info_set_subdevice (snd_rawmidi_info_t *obj, unsigned int val)'' | ||
+ | ' ''Set rawmidi subdevice number.''</font> | ||
+ | Private Extern snd_rawmidi_info_set_subdevice(obj As Pointer, ValInt As Integer) | ||
+ | |||
+ | <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>' ''const char * snd_strerror (int errnum)'' | ||
+ | ' ''Returns the message For an Error code.''</font> | ||
+ | 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 | ||
+ | |||
+ | <FONT color=gray>' ''Individua le schede audio disponibili nel sistema ALSA, mostrando il loro numero ed il nome di ciascuna:''</font> | ||
+ | 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 | ||
+ | |||
+ | |||
+ | <FONT color=gray>' '''Individua i dispositivi ed i subdispositivi Midi e le rispettive porte''' | ||
+ | ' '''in grado di leggere e scrivere dati Midi in Entrata ed in Uscita.'''</font> | ||
+ | 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 | ||
+ | |||
+ | |||
+ | <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 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 | ||
+ | |||
+ | |||
+ | <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 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 | ||
+ | <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 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> | ||
+ | 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 | ||
+ | |||
+ | <FONT color=gray>' ''int snd_card_next (int *card)'' | ||
+ | ' ''Try To determine the Next card.''</font> | ||
+ | Private Extern snd_card_next(card 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_rawmidi_next_device (snd_ctl_t *ctl, int *device)'' | ||
+ | ' ''Get Next RawMidi device number.''</font> | ||
+ | Private Extern snd_ctl_rawmidi_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_rawmidi_info_malloc (snd_rawmidi_info_t **ptr)'' | ||
+ | ' ''Allocate a New Snd_rawmidi_info_t structure.''</font> | ||
+ | Private Extern snd_rawmidi_info_malloc(ptr As Pointer) As Integer | ||
+ | |||
+ | <FONT color=gray>' ''size_t snd_rawmidi_info_sizeof (void)'' | ||
+ | ' ''Get size Of the 'snd_rawmidi_info_t' structure in bytes.''</font> | ||
+ | Private Extern snd_rawmidi_info_sizeof() As Integer | ||
+ | |||
+ | <FONT color=gray>' ''void snd_rawmidi_info_set_device (snd_rawmidi_info_t *obj, unsigned int val)'' | ||
+ | ' ''Set rawmidi device number.''</font> | ||
+ | Private Extern snd_rawmidi_info_set_device(obj As Pointer, ValInt As Integer) | ||
+ | |||
+ | <FONT color=gray>' ''void snd_rawmidi_info_set_stream (snd_rawmidi_info_t *obj, snd_rawmidi_stream_t val)'' | ||
+ | ' ''Set rawmidi stream identifier.''</font> | ||
+ | Private Extern snd_rawmidi_info_set_stream(obj As Pointer, ValInt As Integer) | ||
+ | |||
+ | <FONT color=gray>' ''void snd_rawmidi_info_set_subdevice (snd_rawmidi_info_t *obj, unsigned int val)'' | ||
+ | ' ''Set rawmidi subdevice number.''</font> | ||
+ | Private Extern snd_rawmidi_info_set_subdevice(obj As Pointer, ValInt As Integer) | ||
+ | |||
+ | <FONT color=gray>' ''int snd_ctl_rawmidi_info (snd_ctl_t *ctl, snd_rawmidi_info_t *info)'' | ||
+ | ' ''Get info about a RawMidi device.''</font> | ||
+ | Private Extern snd_ctl_rawmidi_info(ctl As Pointer, info As Pointer) As Integer | ||
+ | |||
+ | <FONT color=gray>' ''unsigned int snd_rawmidi_info_get_subdevices_count (const snd_rawmidi_info_t *obj)'' | ||
+ | ' ''Get rawmidi count of subdevices.''</font> | ||
+ | Private Extern snd_rawmidi_info_get_subdevices_count(obj As Pointer) As Integer | ||
+ | |||
+ | <FONT color=gray>' ''unsigned int snd_rawmidi_info_get_subdevices_avail (const snd_rawmidi_info_t *obj)'' | ||
+ | ' ''Get rawmidi available count of subdevices.''</font> | ||
+ | Private Extern snd_rawmidi_info_get_subdevices_avail(obj As Pointer) As Integer | ||
+ | |||
+ | <FONT color=gray>' ''const char * snd_rawmidi_info_get_id (const snd_rawmidi_info_t *obj)'' | ||
+ | ' ''Get rawmidi hardware driver identifier.''</font> | ||
+ | Private Extern snd_rawmidi_info_get_id(obj As Pointer) As String | ||
+ | |||
+ | <FONT color=gray>' ''const char * snd_rawmidi_info_get_name (const snd_rawmidi_info_t *obj)'' | ||
+ | ' ''Get rawmidi hardware driver name.''</font> | ||
+ | Private Extern snd_rawmidi_info_get_name(obj As Pointer) As String | ||
+ | |||
+ | <FONT color=gray>' ''const char * snd_rawmidi_info_get_subdevice_name (const snd_rawmidi_info_t *obj)'' | ||
+ | ' ''Get rawmidi subdevice name.''</font> | ||
+ | Private Extern snd_rawmidi_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 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)) | ||
+ | |||
+ | <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(midiHandle), $Str, 0) | ||
+ | If err < 0 Then Error.Raise("Impossibile aprire la connessione con la scheda audio: " & snd_strerror(err)) | ||
+ | |||
+ | <FONT color=gray>' ''Parte con il primo dispositivo Midi sulla scheda individuata:''</font> | ||
+ | devNum = -1 | ||
+ | |||
+ | While True | ||
+ | |||
+ | <FONT color=gray>' ''Ricava il numero del successivo dispositivo Midi sulla scheda attuale:''</font> | ||
+ | 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)) | ||
+ | |||
+ | <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> | ||
+ | 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(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 | ||
+ | |||
+ | <FONT color=gray>' ''Mostra le informazioni relative ai subdispositivi MIDI Output del corrente dispositivo MIDI:''</font> | ||
+ | lista_subdevice(midiHandle, cardNum, devNum, SND_RAWMIDI_STREAM_OUTPUT) | ||
+ | |||
+ | <FONT color=gray>' ''Mostra le informazioni relative ai subdispositivi MIDI Input del corrente dispositivo MIDI:''</font> | ||
+ | lista_subdevice(midiHandle, cardNum, devNum, SND_RAWMIDI_STREAM_INPUT) | ||
+ | |||
+ | Wend | ||
+ | |||
+ | snd_ctl_close(midiHandle) | ||
+ | |||
+ | Wend | ||
+ | |||
+ | <FONT color=gray>' ''Va in chiusura liberando la memoria precedentemente allocata:''</font> | ||
+ | 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()) | ||
+ | |||
+ | <FONT color=gray>' ''Dice ad ALSA di quale dispositivo Midi si richiedono le informazioni:''</font> | ||
+ | snd_rawmidi_info_set_device(rawMidiInfo, devN) | ||
+ | |||
+ | <FONT color=gray>' ''Si ottengono informazioni sull'uscita Midi o in sezione del corrente dispositivo:''</font> | ||
+ | snd_rawmidi_info_set_stream(rawMidiInfo, tipo) | ||
+ | |||
+ | i = -1 | ||
+ | subDevCount = 1 | ||
+ | |||
+ | Inc i | ||
+ | While i < subDevCount | ||
+ | |||
+ | <FONT color=gray>' ''Dice ad ALSA di riempire 'snd_rawmidi_info_t' con le informazioni sul corrente subdispositivo:''</font> | ||
+ | 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)) | ||
+ | |||
+ | <FONT color=gray>' ''Scrive quanti subdispositivi Midi sono presenti:''</font> | ||
+ | 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 | ||
+ | |||
+ | <FONT color=gray>' ''NOTA: Se è presente un solo subdispositivo, allora il numero del subdispositivo è immateriale, e può essere omesso:''</font> | ||
+ | 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 |
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