vuott 11-09-2020, 01:36
INTERCONECTAR UN PROGRAMA GAMBAS A OTRA APLICACION A TRAVÉS ALSA PARA ENVIAR DATOS MIDI

Quid est A.L.S.A. ?

ALSA (Advanced Linux Sound Architecture) es un componente del kernel que sustituye al original Open Sound System (OSS) utilizado para proporcionar driver de dispositivo para tarjetas de audio.
Además de los driver de audio, ALSA también ofrece una libreria en espacio-usuario para desarrolladores de aplicaciones que deseen utilizar las funciones de los driver a través de una API en lugar de una interacción directa con los driver del kernel.


Es posible enviar datos Midi desde una aplicación a otra aplicación a través ALSA. De misma manera una aplicación puede rebir datos Midi de otros aplicaciones.
Para ello, las aplicaciones que deseen intercambiar datos Midi deben conectarse al ALSA, y en particolar al sub-sistema de ALSA que gestiona el Midi: la "Interfaz Sequencer".
Las aplicaciones, por lo tanto, se convierten en "Client" de ALSA, que representa su "Server".

 APLICACIÓN-Client_A ---> A L S A <--- APLICACIÓN-Client_B

Así, si se pretende realizar una aplicación Midi que debe relacionarse con ALSA, será necesario que se conciba en primer lugar como "Client" Midi de ALSA.
ALSA sólo se ocupa de programar eventos Midi y enviarlos al destino en el momento adecuado. Todo el procesamiento de eventos MIDI tiene que hacerse dentro de los Clientes.
En efecto la interfaz de ALSA está diseñada para ofrecer eventos MIDI entre los Clientes/Puertos.


USAR EN GAMBAS LOS RECURSOS DE ALSA

Gambas, por ahora, no tiene un su Componente para gestionar directamente los recursos del sistema de sonido ALSA.
Es posible, pero, usar las funciones externas del API de ALSA, invocando su libreria:
 Library "libasound:2"

A continuación, cada una de las funciones externas de ALSA se declarará con EXTERN, para que puedan utilizarse en las rutinas.


CREAR UN CLIENT DE ALSA

Para crear una aplicación, que se relaciona con el ALSA como su "Client", se necesitan varias fases de desarrollo.

El API de ALSA proporciona una función específica para crear un ''Client'' Midi de ALSA:
 int snd_seq_open (snd_seq_t ** seqp, const char * name, int streams, int mode)

Esta función será declarada en Gambas:
 Private Extern snd_seq_open(seqp As Pointer, name As String, streams As Integer, mode As Integer) As Integer

Donde:
- "seqp" es un handle al sub-sistema "Sequencer" de ALSA;
- "name" es en nombre del dispositivo de sonido;
- "streams" establece la gestión de datos Midis del sub-sistema "Sequencer" de ALSA;
- "mode" que hará que las operaciones de lectura/escritura bloqueen o no bloqueen.


DAR UN NOMBRE AL "CLIENT"

Si lo desea, es posible asignar un nombre al "Client" que estamos creando.

El API de ALSA proporciona una función específica para eso:
 int snd_seq_set_client_name(snd_seq_t *seq, const char *name)

Esta función será declarada en Gambas:
 Private Extern snd_seq_set_client_name(seq As Pointer, name As String) As Integer


OBTENER EL NUMERO DE IDENTIFICACION DEL "CLIENT"

Para obtener el número de identificación del nuestro "Client", ALSA proporciona esta función:
 int snd_seq_client_id(snd_seq_t *seq)

que será declarada en Gambas:
 Private Extern snd_seq_client_id(seq As Pointer) As Integer


CREACION DEL PUERTO DEL "CLIENT" Y SU CAPACIDAD

Hemos dicho que una aplicación-Client de ALSA envia o recibe datos Midi desde otras aplicaciones-Client a través ALSA (más precisamente a través un sub-sistema de ALSA adecuado para el tipo de datos enviados).
Un "Client" envia o recibe datos mediante una o más sus Puertos.
Cada Puerto del "Client" tiene su particular "Capacidad"; es decir que puede solo ser "Leído" (READ) o solo ser "Escrito" (WRITE), o ambas (DUPLEX).
ATENCIÓN: la definición de la "Capacidad " ("READ", "WRITE" o "DUPLEX") del Puerto de un Client debe considerarse siempre "desde el punto de vista del otro Client " de ALSA, al que el nuestro Client desea conectarse.
Por lo tanto, si configuramos - por ejemplo - la "Capacidad" del puerto del nuestro Client a READ (en lectura), significa que el otro Client, al que el nuestro Cliente se conecta, podrá "leer" los datos desde el Puerto de nuestro Client. En este caso el nuestro Client sólo puede escribir (enviar) datos a su propio puerto.
Es decir, en este caso, si la Capacidad del Puerto del nuestro Client es "READ", el nuestro Client puede escibir (es decir "enviar") datos Midi a su Puerto y un otro Client (al que el nuestro està conectado) puede LEER (es decir "recibir") aquellos datos Midi desde el Puerto de nuestro Client.

Para establecer la capacidad de un puerto del Client, que estamos creando, utilizamos las siguientes Constantes de ALSA:
 SND_SEQ_PORT_CAP_READ
 SND_SEQ_PORT_CAP_WRITE
 SND_SEQ_PORT_CAP_DUPLEX

Para crear un Puerto del Client, se usa esta función:
 int snd_seq_create_simple_port(snd_seq_t *seq, const char *name, unsigned int caps, unsigned int type)

que será declarada en Gambas:
 Private Extern snd_seq_create_simple_port(seq As Pointer, name As String, caps As Integer, type As Integer) As Integer


EJEMPLO PRACTICO

Vamos a crear ahora una muy simple aplicación-Client con su Puerto con capacidad "READ":
Código:
Library "libasound:2"

Private Const SND_SEQ_OPEN_OUTPUT As Integer = 1
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_MIDI_GENERIC As Integer = 2
Private Const SND_SEQ_PORT_TYPE_APPLICATION As Integer = 1048576

' 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(seq As Pointer, name As String) As Integer

' int snd_seq_client_id (snd_seq_t *handle)
' 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(seq As Pointer, name As String, caps As Integer, type As Integer) As Integer

' 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_close (snd_seq_t *handle)
' Close the sequencer.
Private Extern snd_seq_close(handle As Pointer) As Integer


Public Sub Main()

 Dim handle As Pointer
 Dim rit, id, porta As Integer
 
' Crea un Client de ALSA:
 rit = snd_seq_open(VarPtr(handle), "default", SND_SEQ_OPEN_OUTPUT, 0)
 If rit < 0 Then Error.Raise("Imposible abrir el subsistema 'seq' de ALSA: " & snd_strerror(rit))
   
' Da un nombre al Client:
 snd_seq_set_client_name(handle, "Mi primer Client de ALSA")
   
' Obtiene el número de identificación del Client:
 id = snd_seq_client_id(handle)
 If id < 0 Then
  snd_seq_close(handle)
  Error.Raise("Imposible obtener el número de identificación del Client: " & snd_strerror(id))
 Endif
 Print "Número de identificación del Client: "; id
 
' Crea un Puerto del Client; le asigna la capacidad de "ser leído" (READ) por otros Clientes y realiza la suscripción.
' Obtiene tambien el número de identificación del Puerto del Client.
 porta = snd_seq_create_simple_port(handle, "Puerto", SND_SEQ_PORT_CAP_READ Or SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_MIDI_GENERIC Or SND_SEQ_PORT_TYPE_APPLICATION)
 If porta < 0 Then
   snd_seq_close(handle)
   Error.Raise("Imposible crear el Puerto del Client: " & snd_strerror(porta))
 Endif
 Print "Número del Puerto del Client: "; porta
 
' Mantiene vivo a este Client solo por 20 segundos:
 Wait 20
 
 ' Cerra el subsistema 'seq' de ALSA y destruye el Client:
 snd_seq_close(handle)
 
End

Podemos ver el efecto practico de este codigo, abriendo el archivo de sistema: /proc/asound/seq/clients .
En este archivo de texto encontraremos la referencia a nuestro Client creado. Rolleyes
En particular, si no hay otro Client de ALSA activo, nosotros veremos esta referencia:
...........................................................................
Client 128 : "Mi primer Client de ALSA" [User]
  Port   0 : "Puerto" (R-e-)

...........................................................................
Donde las palabras:
"Client " = ...el nuestro programa es un Client de ALSA;
"128 " = el número de identificación del nuestro Client;
"Mi primer Client de ALSA " = el nombre que le dimos al nuestro Client;
"[User] " = especifica que este Client ha sido creado por un usuario;
"Port " = se refiere a el Puerto del nuestro Client;
"0 " = el número de identificación del Puerto del nuestro Client;
"Puerto " = el nombre que le dimos al Puerto (2° argumento de la función "snd_seq_create_simple_port( ) " )
"R " = el Puerto del Client tiene su Capacidad a READ.
FLAVIO35 10-09-2020, 20:37
Hola,
Mi nombre es Flavio y estoy comenzando con Gambas. He programado mucho en VB6 pero Tanto Gambas como Linux son nuevos para mi.
Desde ya pido disculpas si mi pregunta llega a ser un poco básica pero hay que comenzar de algún modo.
Mi intención es recibir una constante en el programa principal al ejecutar un script.
Doy un ejemplo:

user@PC:~$ recibiendo.gambas 4

En este ejemplo la idea sería que desde el script se lance "recibiendo.gambas" (se trata de un formulario con entorno gráfico, audio,etc) y que de algún modo llegue el dato (en este caso el número 4) para que lo pueda procesar dentro del programa. No sé si esto es posible ni tampoco cómo sería la sintaxis del script.
Gracias desde ya por lo que se pueda aportar.
tincho 08-09-2020, 23:17
Hola a todos.
En la lista internacional se dio una charla sobre como cambiar el texto de varias Labels en tiempo de ejecución.
les trasmito un procedimiento que se me ocurrió para editar el texto de algunos controles.
Dejo también el proyecto con el que hice el experimento por si a alguien le interesa.
Código:
Public Sub Button1_Click()

  Dim i As Integer

  For i = 1 To 3
    ControlStamp(["Label", "Label" & CStr(i), "Bingo!!"])
    Wait 0.5
  Next

End

Public Sub ControlStamp(stx As String[])

  Dim ct As Object
  Dim i As Integer
  Dim colex As New Collection

  If stx.Count = 3 Then
    Select stx[0]
      Case "TextBox", "ComboBox", "Label" 'To be continued....
        For Each ct In Me.Controls
          If Object.Type(ct) = stx[0] Then
            colex.Add(ct, ct.Name)
          Endif
        Next
        If colex.Exist(stx[1]) Then
          colex[stx[1]].Text = stx[2]
        Endif
    End Select
  Endif
End
Saludos.
Archivos adjuntos
.gz
ejemplo-label-array-0.0.1.tar.gz (Tamaño: 11.81 KB Descargas: 1)
Páginas (520):    1 489 490 491 492 493 520   
Bienvenido, Invitado
Tienes que registrarte para poder participar en nuestro foro.
Recordarme?
Miembros: 265
Último miembro: Morfeo68
Temas del foro: 1,596
Mensajes del foro: 8,338
Últimos temas
Antiguo foro. ¿ Viable ?
Foro: Sobre gambas-es.org
Último mensaje por: jguardon, Ayer, 20:51
Respuestas: 2 - Vistas: 35
Ver los repositorios del ...
Foro: Mundo Linux
Último mensaje por: guizans, Ayer, 20:10
Respuestas: 4 - Vistas: 54
¿Cómo crear servidor FTP ...
Foro: General
Último mensaje por: Shordi, 22-01-2025, 12:19
Respuestas: 2 - Vistas: 65
TextEditor. Formateado. E...
Foro: General
Último mensaje por: Shell, 21-01-2025, 14:33
Respuestas: 2 - Vistas: 46
Gambas 3.20
Foro: Instalación
Último mensaje por: Shell, 21-01-2025, 14:32
Respuestas: 11 - Vistas: 321
Powered By MyBB, © 2002-2025 MyBB Group.
Made with by Curves UI.