Interconectar un programa Gambas a otro a través ALSA para enviar datos MIDI - Versión para impresión +- Comunidad Gambas-es (https://gambas-es.org) +-- Foro: Gambas (https://gambas-es.org/forum-3.html) +--- Foro: Aplicaciones/Fragmentos de Código (https://gambas-es.org/forum-8.html) +--- Tema: Interconectar un programa Gambas a otro a través ALSA para enviar datos MIDI (/thread-98.html) |
Interconectar un programa Gambas a otro a través ALSA para enviar datos MIDI - vuott - 11-09-2020 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" 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. 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. RE: Interconectar un programa Gambas a otro a través ALSA para enviar datos MIDI - jguardon - 12-09-2020 Espectacular RE: Interconectar un programa Gambas a otro a través ALSA para enviar datos MIDI - vuott - 14-09-2020 OBTENER DATOS MIDI BRUTOS DE UN DISPOSITIVO EXTERNO Y ENVIARLOS A UN CLIENT-SOFTSYNTH A TRAVÉS ALSA Bueno, ahora veamos cómo obtener datos Midi brutos de un dispositivo externo (por ejemplo, un teclado Midi) y enviarlos a través de ALSA a un Client-Softsynth para que proporcione los sonidos necesarios para escuchar las notas. Podríamos utilizar los recursos del API del ALSA para recibir los datos brutos del dispositivo Midi externo, pero no será absolutamente necesario: en efecto è posible tambien recibir esos datos Midi crudos leyendo desde el file-device que se crea al conectar el teclado Midi al ordenador. ALSA no acepta simples datos Midi brutos (como son enviados por los teclados Midi). ALSA acepta los datos Midi rigurosamente en forma de sus "Eventos Midi ", según las especificaciones de ALSA. Así, cada "Mensaje", previsto por el protocolo Midi, debe ser organizado en una porción de memoria asignada, introduciendo varios valores, y luego enviado a ALSA. La primera parte (16 byte) de esta memoria será ocupada por valores comunes a todos los "Eventos Midi" de ALSA; la parte restante y última será ocupada por los valores de los "Mensajes" específicos del protocolo Midi. Para organizar un "Evento Midi " de ALSA podemos utilizar el Objeto Estructura de Gambas como sigue: Public Struct Snd_seq_event_t type As Byte flags As Byte tag As Byte queue As Byte Datos comunes tick_time As Integer a todos real_time As Integer los Eventos Midi ALSA source_client As Byte source_port As Byte dest_client As Byte dest_port As Byte channel As Byte note As Byte Datos pertenecientes velocity As Byte a los especificos "Mensajes" off_velocity As Byte del protocolo Midi param As Integer value As Integer End Struct A continuación mostramos un simple ejemplo, en un entorno gráfico, para recibir los datos Midi brutos, enviados desde el dispositivo Midi a través de su archivo-device del sistema, y para enviarlos enseguida a través de ALSA al Client-softsynth. Por lo tanto al pulsar una tecla del teclado Midi externo, oiremos el sonido de su nota con el timbre del instrumento musical elegido en el Combobox. Como se puede ver, utilizamos un código especial para la gestión de recursos de ALSA, en el que no se creará arbitrariamente un Puerto de nuestro cliente mediante la especifica función externa de ALSA. Al mismo tiempo, sin embargo, deberemos asignar al miembro "queue" de la Estructura de los "Eventos Midi" de ALSA el valor de la Constante "SND_SEQ_QUEUE_DIRECT" que es igual a 253. Funcionamiento: 1) conectar un teclado Midi al ordenador; 2) lanzar el softhsynth (p.e. Qsynth); 3) luego lanzar el código ejemplo subyacente; 4) elegir un instrumento musical de la lista "General Midi" contenida por el ComboBox; 5) ...tocar el teclado Midi externo. Código: Private fl As File RE: Interconectar un programa Gambas a otro a través ALSA para enviar datos MIDI - tincho - 14-09-2020 Esto se esta poniendo cada vez mas interesante, lastima que no dispongo de un teclado midi, que si no ahora mismo me ponía con esto. Vuott, gracias por compartir estas cosas. Saludos. RE: Interconectar un programa Gambas a otro a través ALSA para enviar datos MIDI - vuott - 05-10-2020 ENVIAR EVENTOS MIDI DE ALSA DESDE NUESTRO PROGRAMA A UN SOFTSYNTH En este otro ejemplo, los datos Midi serán enviados por el propio programa y no por un dispositivo externo. En particular, vamos a ejecutar 8 notas de la escala musical de Do mayor. Desde el punto de vista del Midi, por lo tanto, tendremos que enviar Mensajes Midi de "Note On", para activar la ejecución de una nota musical Midi, y Mensajes Midi de "Note Off" para hacer cesar la ejecución de la nota. También enviaremos previamente un mensaje Midi de "Program Change" para establecer el sonido del instrumento seleccionado según el estándar General Midi. En el código anterior nos dimos cuenta de que ALSA sólo acepta eventos Midi si se envían en el modo rígido representado por la Estructura "snd_seq_event_t ". Por lo tanto, los eventos Midi de ALSA, que corresponden a los Mensajes Midi, deberán ser rígidamente y correctamente configurados y enviados a ALSA a través de esta Estructura. En el código estableceremos algunos miembros de esa Estructura de forma genérica y válida para los tres Mensajes Midi que deberemos enviar. Antes de lanzar el programa, hace falta lanzar el Softsyhth "Qsynth" para permitir escuchar el sonido. El código detectará automáticamente el programa "Qsynth" (que es otro "Client" de ALSA) y se conectará a él. Rutinas especiales se encargarán de los datos relativos al específico Mensaje Midi, que se enviarán al sub-sistema "Seq" de ALSA. Código: Private sndseq As Pointer RE: Interconectar un programa Gambas a otro a través ALSA para enviar datos MIDI - kokodrilo - 05-10-2020 hola vuott, excelente, sin dudas eres un gurú de la programación, ya que veo tu pontencial, te doy una gran idea que manejo hace mucho pero no he hecho nada porque soy un batata programando. Esta idea es muy importante para la privacidad de la gente, y seria necesario en cientos de programas, ningún programa implementa esto, por eso para mi es una gran idea y muy necesaria pero yo por ahora no tengo la capacidad para llevarlo al código pero tu si. La idea es la siguiente espero poder explicarla bien sino me dicen, trataría de un programa que actuara entre un micrófono y alsa o el encargado de sonido, el cual captura el sonido del micrófono, varia sus frecuencias ( para camuflar la voz aquí la gran idea) y lo pasa a alza, entonces, cualquier programa que use un micrófono obtendrá una voz encriptada por decir de alguna manera. bueno esa es la idea vuott, seguramente vos tendrás otras ideas u otro planteo para resolver esta cuestión, yo te tiro la idea por si a ti te gusta y le hechas mano y dejas el código publico para que los programadores la puedan usar en sus aplicaciones. saludos RE: Interconectar un programa Gambas a otro a través ALSA para enviar datos MIDI - vuott - 06-10-2020 (05-10-2020, 16:34)kokodrilo escribió: trataría de un programa que actuara entre un micrófono y alsa o el encargado de sonido, el cual captura el sonido del micrófono, varia sus frecuencias Con respecto a este tu problema, por favor, abre un nuevo tema separado. gracias. |