Portal    Foro    Buscar    FAQ    Registrarse    Conectarse


Publicar nuevo tema  Responder al tema 
Página 1 de 1
 
 
Client Alsa Midi Demostrativo Mínimo
Autor Mensaje
Responder citando   Descargar mensaje  
Mensaje Client Alsa Midi Demostrativo Mínimo 
 
Hola amigosss,

os dejo el código de un Client Alsa Midi demostrativo mínimo, que muestra come crear un simple Client del sistema audio Alsa, capaz de recibir algunos mensajes Midi (se seleccionaron más comunes y importantes) desde un otro Client de Alsa.

Como funciona por ejemplo con un teclado Midi:
- conectar el teclado Midi a el ordenador;
- iniciar el programa;
- abrir el Terminal y detectar el numero del ID Client del programa y aquello del teclado;
- conectar el teclado a el programa Midi con el comando: aconnect
(por ejemplo, si el Id del teclado Midi es 24 y el ID del progama es 128:  aconnect 24:0 128:0 )

Public Struct snd_seq_event_t
  type As Byte              ' |- byte n° 0
  flag As Byte              ' |
  tag As Byte               ' |
  queue As Byte             ' |
  timestamp1 As Integer     ' |
  timestamp2 As Integer     ' |  datos comunes a totos los mensajes Midi  
  source_id As Byte         ' |
  source_porta As Byte      ' |
  dest_id As Byte           ' |
  dest_porta As Byte        ' |_ byte n° 15
   channel As Byte              ' byte n° 16 -|
   note As Byte                 ' byte n° 17  |
   velocity As Short            ' byte n° 18  |< datos pertenecientes a los mensajes MIDI específicos
     primoValore As Integer      ' byte n° 20 |
     secondoValore As Integer    ' byte n° 24_|
End Struct


Private seq As Pointer


Library "libasound:2.0.0"

Private Const SND_SEQ_OPEN_INPUT As Integer = 2
Private Const SND_SEQ_PORT_CAP_WRITE As Integer = 2
Private Const SND_SEQ_PORT_CAP_SUBS_WRITE As Integer = 64
Private Const SND_SEQ_PORT_TYPE_APPLICATION As Integer = 1048576
Private Const SND_SEQ_EVENT_NOTEON As Byte = 6
Private Const SND_SEQ_EVENT_NOTEOFF As Byte = 7
Private Const SND_SEQ_EVENT_CONTROLLER As Byte = 10
Private Const SND_SEQ_EVENT_PGMCHANGE As Byte = 11


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

' int snd_seq_open (snd_seq_t **handle, const char *name, int streams, int mode)
' Open the ALSA sequencer.
Private Extern snd_seq_open(handle As Pointer, name As String, streams As Integer, mode As Integer) As Integer

' int snd_seq_set_client_name(snd_seq_t* seq, const char* name)
' Set client name.
Private Extern snd_seq_set_client_name(handle As Pointer, name As String) As Integer

' int snd_seq_create_simple_port(snd_seq_t *seq, const char *name, unsigned int caps, unsigned int type)
' Create a port - simple version.
Private Extern snd_seq_create_simple_port(handle As Pointer, name As String, caps As Integer, type As Integer) As Integer

' int snd_seq_event_input(snd_seq_t *handle, snd_seq_event_t **ev)
' Retrieve an event from sequencer
Private Extern snd_seq_event_input(handle As Pointer, ev As Snd_seq_event_t) As Integer


Public Sub Main()

  Dim idporta, err As Integer
    

    err = snd_seq_open(VarPtr(seq), "default", SND_SEQ_OPEN_INPUT, 0)
    If err < 0 Then Error.Raise("Imposible inizialiciar el subsistema 'seq' de ALSA: " & snd_strerror(err))
    
    err = snd_seq_set_client_name(seq, "Client demostrativo de ALSA")
    If err < 0 Then Error.Raise("Imposible asignar un nombre a el Client aplicativo de ALSA: " & snd_strerror(err))
    
    idporta = snd_seq_create_simple_port(seq, "Puerta del Client demostrativo de ALSA", SND_SEQ_PORT_CAP_WRITE Or SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_APPLICATION)
    If idporta < 0 Then Error.Raise("Imposible crear una puerta del Client aplicativo de ALSA: " & snd_strerror(err))

    intercettaMessaggiMidi()

End


Public Procedure intercettaMessaggiMidi()
  
  Dim ev As Pointer
  Dim midi@ As Snd_seq_event_t
  
    While True

        snd_seq_event_input(seq, VarPtr(ev))
        midi@ = ev

        Select Case midi@.type
          Case SND_SEQ_EVENT_CONTROLLER
            Print "Evento 'Control'  al canal: "; midi@.channel, midi@.primoValore, midi@.secondoValore
          Case SND_SEQ_EVENT_PGMCHANGE
            Print "Evento 'Program Change' al canal: "; midi@.channel, midi@.secondoValore
          Case SND_SEQ_EVENT_NOTEON
            Print "Evento 'NoteOn' al canal: "; midi@.channel, midi@.note, midi@.velocity
          Case SND_SEQ_EVENT_NOTEOFF
            Print "Evento 'NoteOff' al canal: "; midi@.channel, midi@.note, midi@.velocity
        End Select

    Wend
  
    Free(pfd)
  
End

 



 
última edición por vuott el Miercoles, 18 Junio 2014, 23:40; editado 20 veces 
vuott - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Client Alsa Midi Demostrativo Mínimo 
 
Hooola amigos,
de nuevo la MIDI-mania    con una otra aplicación simple simple.
Desarrollando el código anterior, creamos una aplicación que recibe datos MIDI desde un dispositivo externo Midi (por ejemplo, un teclado MIDI), y de inmediato los envía a un softsynth para escuchar el sonido.
Public Struct snd_seq_event_t
  type As Byte              
  flag As Byte
  tag As Byte
  queue As Byte
  timestamp1 As Integer
  timestamp2 As Integer
  source_id As Byte
  source_porta As Byte
  dest_id As Byte
  dest_porta As Byte  
   channel As Byte      
   note As Byte            
   velocity As Byte      
   off_velocity As Byte
     parametro As Integer
     value As Integer    
End Struct

Library "libasound:2.0.0"

Private Const SND_SEQ_OPEN_DUPLEX As Integer = 3
Private Const SND_SEQ_PORT_CAP_WRITE As Integer = 2
Private Const SND_SEQ_PORT_CAP_SUBS_WRviaITE As Integer = 64
Private Const SND_SEQ_PORT_CAP_READ As Integer = 1
Private Const SND_SEQ_PORT_CAP_SUBS_READ As Integer = 32
Private Const SND_SEQ_PORT_TYPE_APPLICATION As Integer = 1048576
Private Const SND_SEQ_ADDRESS_UNKNOWN As Byte = 253
Private Const SND_SEQ_ADDRESS_SUBSCRIBERS As Byte = 254
Private Const SND_SEQ_EVENT_NOTEON As Byte = 6
Private Const SND_SEQ_EVENT_NOTEOFF As Byte = 7
Private Const SND_SEQ_EVENT_CONTROLLER As Byte = 10
Private Const SND_SEQ_EVENT_PGMCHANGE As Byte = 11


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

' int snd_seq_open (snd_seq_t **handle, const char *name, int streams, int mode)
' Open the ALSA sequencer.
Private Extern snd_seq_open(handle As Pointer, name As String, streams As Integer, mode As Integer) As Integer

' int snd_seq_set_client_name(snd_seq_t* seq, const char* name)
' Set client name.
Private Extern snd_seq_set_client_name(handle As Pointer, name As String) As Integer

' int snd_seq_client_id (snd_seq_t *seq)
' Get the client id.
Private Extern snd_seq_client_id(handle As Pointer) As Integer

' int snd_seq_create_simple_port(snd_seq_t *seq, const char *name, unsigned int caps, unsigned int type)
' Create a port - simple version.
Private Extern snd_seq_create_simple_port(handle As Pointer, name As String, caps As Integer, type As Integer) As Integer

' int snd_seq_event_input(snd_seq_t *handle, snd_seq_event_t **ev)
' Retrieve an event from sequencer
Private Extern snd_seq_event_input(handle As Pointer, ev As Snd_seq_event_t) As Integer

' int snd_seq_event_output_direct (snd_seq_t *handle, snd_seq_event_t *ev)
' Output an event directly to the sequencer NOT through output buffer.
Private Extern snd_seq_event_output_direct(handle As Pointer, ev As Snd_seq_event_t) As Integer


Public Sub Main()

  Dim seq As Pointer
  Dim idportaE, idportaU, err, id As Integer
    

    err = snd_seq_open(VarPtr(seq), "default", SND_SEQ_OPEN_DUPLEX, 0)
    If err < 0 Then Error.Raise("Impossible inicializar el subsistema 'seq' de ALSA: " & snd_strerror(err))
    
    err = snd_seq_set_client_name(seq, "Sequencer demostrativo de ALSA")
    If err < 0 Then Error.Raise("Impossible asignar un nombre a el Client aplicativo de ALSA: " & snd_strerror(err))
    
    id = snd_seq_client_id(seq)
    Print "Numero identificativo del sequencer demostrativo:  "; id

    idportaE = snd_seq_create_simple_port(seq, "Puerta de Entrada del sequencer demostrativo de ALSA", SND_SEQ_PORT_CAP_WRITE Or SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_APPLICATION)
    If idportaE < 0 Then Error.Raise("Impossible crear una puerta de Entrada del Client aplicativo de ALSA: " & snd_strerror(err))
    Print "Numero identificativo de la puerta de Entrada:  "; idportaE

    idportaU = snd_seq_create_simple_port(seq, "Puerta de Salida del sequencer demostrativo de ALSA", SND_SEQ_PORT_CAP_READ Or SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_APPLICATION)
    If idportaU < 0 Then Error.Raise("Impossible crear una puerta de Salida del Client aplicativo de ALSA: " & snd_strerror(err))
    Print "Numero identificativo de la puerta di Salida:  "; idportaU

    intercettaMessaggiMidi(seq, id, idportaU)

End


Public Procedure intercettaMessaggiMidi(seqiM As Pointer, idC As Integer, portEx As Integer)
  
  Dim ev As Pointer
  Dim midi@ As Snd_seq_event_t
    
    While True

        snd_seq_event_input(seqiM, VarPtr(ev))
        midi@ = ev

' Vamos a ver el evento:
      With midi@
        Select Case .type
          Case SND_SEQ_EVENT_CONTROLLER
            Print "Evento 'Control'  al canal: "; .channel, .parametro, .value
          Case SND_SEQ_EVENT_PGMCHANGE
            Print "Evento 'Program Change' al canal: "; .channel, .value
          Case SND_SEQ_EVENT_NOTEON
            Print "Evento 'NoteOn' al canal: "; .channel, .note, .velocity
          Case SND_SEQ_EVENT_NOTEOFF
            Print "Evento 'NoteOff' al canal: "; .channel, .note, .velocity
        End Select
        
' Si pulsamos la tecla de la nota 42 o 44 o 46 cambia el instrumento musical ("Program Change"):
Select Case .note
Case 42
  .type = 11
  .note = 0
  .velocity = 0
  .value = 0
Case 44
    .type = 11
  .note = 0
  .velocity = 0
  .value = 11
Case 46
    .type = 11
  .note = 0
  .velocity = 0
  .value = 88
End Select
' ...para enviar los datos Midi Alsa:
        .source_id = idC
        .source_porta = portEx
        .dest_id = SND_SEQ_ADDRESS_SUBSCRIBERS
        .dest_porta = SND_SEQ_ADDRESS_UNKNOWN
      End With

' Enviamos los datos Midi a el softsynth por Alsa:
      snd_seq_event_output_direct(seqiM, midi@)

    Wend
  
End

 



 
última edición por vuott el Miercoles, 18 Junio 2014, 23:40; editado 4 veces 
vuott - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Mostrar mensajes anteriores:    
 

Publicar nuevo tema  Responder al tema  Página 1 de 1
 

Usuarios navegando en este tema: 0 registrados, 0 ocultos y 1 invitado
Usuarios registrados conectados: Ninguno


 
Lista de permisos
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas
No puede adjuntar archivos
Puede descargar archivos
No puede publicar eventos en el calendario



  

 

cron