|
|
Riga 1: |
Riga 1: |
| + | ====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 12: |
Riga 14: |
| | | |
| | | |
− | Mostriamo di seguito tre codici, che dovranno essere lanciati dopo aver collegato, ad esempio, uno u più dispositivi Midi esterni hardware (ad esempio una o più tastiere Midi) al proprio computer.
| + | * [[Conoscere con le funzioni esterne del subsistema "seq" i dispositivi Midi presenti nel sistema]] |
− | | |
− | ====Primo esempio====
| |
− | Cominciamo con il primo esempio più semplice:
| |
− | Library "libasound:2"
| |
− |
| |
− | 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 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>' ''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
| |
− |
| |
− |
| |
− | While True
| |
− |
| |
− | 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 Exit
| |
− |
| |
− | $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
| |
− |
| |
− | While True
| |
− |
| |
− | <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 Exit
| |
− |
| |
− | <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
| |
− |
| |
− |
| |
− | Wend
| |
− |
| |
− | snd_ctl_close(cardHandle)
| |
− |
| |
− | Wend
| |
− |
| |
− | snd_config_update_free_global()
| |
− |
| |
− | '''End'''
| |
− | | |
− | | |
− | ====Secondo esempio====
| |
− | Mostriamo il secondo esempio più complesso del precedente.
| |
− | Library "libasound:2"
| |
− |
| |
− | 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))
| |
− |
| |
− | Do
| |
− |
| |
− | 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)
| |
− |
| |
− | Loop 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
| |
− | While True
| |
− |
| |
− | If en Then io = "In "
| |
− | If ex Then io &= "Out"
| |
− | Print io, " hw:"; subSc; ","; subDi; ","; su, subnome
| |
− | Inc su
| |
− | If su >= subs Then Exit
| |
− |
| |
− | 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))
| |
− | Exit
| |
− | 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))
| |
− | Exit
| |
− | Endif
| |
− | Endif
| |
− |
| |
− | subnome = snd_rawmidi_info_get_subdevice_name(mdInfo)
| |
− |
| |
− | Wend
| |
− |
| |
− | 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====
| + | * [[Conoscere con le funzioni esterne del subsistema "rawMidi" i dispositivi Midi presenti nel sistema]] |
− | 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"
| |
− |
| |
− | 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'''
| |
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.
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() usando una stringa simile:
laddove x, y, z sono i tre numeri che rappresentano e specificano una particolare porta MIDI di Entrata o di Uscita, come ad esempio: