Enviar datos MIDI a un softsynth vía ALSA - 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: Enviar datos MIDI a un softsynth vía ALSA (/thread-1563.html) |
Enviar datos MIDI a un softsynth vía ALSA - vuott - 06-12-2023 Notas breves sobre cómo enviar "Mensajes MIDI" a un softsynth vía A.L.S.A., de la manera más sencilla posible. Como es sabido, un flujo de datos MIDI no contiene - como es el caso del audio - la información que describe las características de la onda sonora, sino información que será utilizada por otros programas para ejecutar un sonido localizado entre una colección. Esta colección estandarizada de sonidos de varios instrumentos musicales, en su mayoría de formato WAV, está contenida en un archivo especial, llamado banco de fuentes de sonido. El programa que debe utilizar los sonidos, contenidos en los archivos del banco de fuentes sonoras (soundfont bank), para que una nota MIDI pueda ser escuchada, se llama softsynth. El protocolo MIDI a través de un "Mensaje MIDI" informa al softsynth de que debe usar una fuente de sonido WAV (que en la práctica corresponde a un instrumento musical) para cambiar a una cierta frecuencia de sonido durante un período de tiempo determinado. Por lo tanto, un programa, que produce "Mensajes MIDI", debe entregar los datos necesarios al softsynth. Solo así el "Mensaje MIDI" podrá proporcionar la producción del sonido requerido. Actualmente, la comunicación entre un programa que envía datos MIDI y el softsynth suministrado se realiza a través del sistema de sonido A.L.S.A. que se encarga de gestionar el protocolo de transmisión, recepción y eventual temporización de los datos MIDI, así como la relación con el sistema operativo y el hardware de audio suministrado. ALSA actúa como un "Servidor" central que proporciona funciones y servicios a los programas que deben tratar con él para la reproducción de audio. Dichos programas, por lo tanto, se convierten en "Clientes" de ALSA, y se relacionan con dicho sistema central de sonido para poder comunicarse con otros "Clientes" y con el sistema operativo. Los "Clientes" del "Servidor" de ALSA son visibles en el archivo "/proc/asound/seq/clients". Por lo tanto, si queremos en Gambas realizar cualquier programa que envíe "Mensajes MIDI" al softsynth en punto para su gestión sonora, deberá relacionarse con ALSA. El sistema ALSA se compone de algunos subsistemas. El sub-sistema que gestiona los datos MIDI se llama "secuenciador" de ALSA e identificado con la abreviatura "seq". Por lo tanto, será necesario abrir ese sub-sistema para poder, por un lado, transformar nuestro programa en un "cliente" de ALSA y, por otro, aprovechar los recursos que ese sub-sistema proporciona. Para operar directamente con ALSA y sus recursos, nuestro programa Gambas deberá utilizar las funciones externas de ALSA mediante la instrucción "Extern", después de haber declarado la biblioteca compartida de ALSA, que contiene las funciones externas que servirán para el envío de "Mensajes de Midi". La biblioteca compartida externa de ALSA se declarará como sigue: Cita: Library "libasound:2.0.0"La función externa de ALSA que permite hacer de nuestro programa Gambas un "Cliente" de ALSA es: snd_seq_open() De los cuatro parámetros formales aquí se encuentra en particular el primero, que es un puntero de puntero, y que en Gambas se debe reproducir: VarPtr(Pointer); así como el tercero: el argumento pasado será una Constante para la configuración del "secuenciador" de ALSA para los datos en "Salida". Esta función externa figurará en nuestro programa como sigue: Cita: Private Extern snd_seq_open(handle As Pointer, name As String, streams As Integer, mode As Integer) As IntegerUna vez terminado, el sub-sistema "seq" debe cerrarse para liberar la memoria utilizada para la gestión de los recursos proporcionados por ALSA. El cierre se efectuará con la función externa de ALSA declarada en Gambas: Cita:Private Extern snd_seq_close(handle As Pointer) As IntegerLa gestión de los posibles errores con las funciones externas de ALSA se realizará con la función externa específica declarada en Gambas: Cita:Private Extern snd_strerror(err As Integer) As StringPor lo tanto, al disponer la apertura del sub-sistema "seq" de ALSA mediante un 'ToggleButton', tendremos hasta ahora el siguiente código: Código: Private midi As Pointer Nuestro programa MIDI ya está listo para enviar datos MIDI al softsynth a través de ALSA. ALSA es muy estricto y requiere que el "Mensaje MIDI" esté compuesto por varios datos específicos que se deben tener en un área de memoria reservada, formada por 28 bytes. Cada "Mensaje MIDI" está representado en el protocolo de ALSA con un "Evento MIDI" que consiste en la zona de memoria asignada de 28 bytes, para la cual el protocolo de ALSA prevé el uso de una Estructura. Gambas nos ofrece más de una opción para crear ese área de memoria reservada. Dado que nuestro ejemplo se limitará solo a "Mensajes MIDI" de encendido y apagado de una nota MIDI, podremos utilizar con tranquilidad un vector de tipo Byte[]. Al hacer clic en un 'Botón', de los 28 bytes, solo valoraremos algunos: Al elemento de índice cero asignaremos un entero que represente de vez en cuando el "Mensaje MIDI" de Note-ON (encendido de la nota MID) o de Note-OFF (apagado de la nota MIDI que se está ejecutando). Al elemento de índice 3 asignaremos el valor 253 para indicar que el envío del "Evento MIDI" de ALSA es directo. Al elemento del índice 14 le asignaremos el número de identificación del softsynth, al que enviar el "Evento MIDI" de ALSA, y que suele ser 128, como se puede comprobar en el archivo "/proc/asound/seq/clients". Al elemento de índice 17 le asignaremos un número de nota MIDI, que se ejecutará o silenciará. Al elemento del índice 18 asignaremos el valor 100 de "velocidad del tacto". El elemento de índice 16 representa el canal MIDI, que permanecerá - en nuestro caso - preestablecido en cero (canal MIDI 1). Si lo ponemos a 9 (canal MIDI 10), escucharemos un instrumento de percusión. Constituido el "Evento MIDI" de ALSA en el vector de tipo Byte[], es necesario enviarlo al softsynth a través de ALSA. Esto se hace en nuestro caso esencial a través de una función externa específica, como se indica en nuestro programa: Cita:Private Extern snd_seq_event_output_direct(handle As Pointer, ev As Byte[]) Todo está en orden. A continuación, el código completo de nuestro sencillo y esencial programa Gambas: Código: Private midi As Pointer Si ha instalado softsynth Fluidsynth en el sistema, entonces el programa, descrito anteriormente, debería conectarse automáticamente a ese softsynth. En caso contrario, proceder como sigue: 1) desde Terminal lanzar esta línea: ~$ fluidsynth reload 0 ; 2) sin cerrar el terminal, comprobar en la utilidad "Monitor de sistema" que Fluidsynth está presente entre los procesos activos; 3) si Fluidsynth está presente entre los procesos, verificar también que esté presente en el num. 128 en el fichero /proc/asound/seq/clients; 4) en caso afirmativo - sin cerrar el Terminal - lanzar el código, mostrado arriba. Si utiliza el softsynth de Fluidsynth, debe tener instalado en su sistema el paquete Fluid (R3) General MIDI SoundFont (GM): fluid-soundfont-gm RE: Enviar datos MIDI a un softsynth vía ALSA - Shell - 06-12-2023 Bonus labor. Tengo que leerlo con más tranquilidad, es un tema interesante. No sabía lo que era un softsynth, pero si lo he usado con los bancos de instrumentos. Cuando las tarjetas de música eran más grandes de lo habitual. Más allá de una Sound Blaster 2.0. Hoy reproducir con bancos de sonidos es más fácil. Cualquier "tarjetita" de sonido incorporadas en el pc puede hacerlo. Sobretodo lo uso en emulación "DosBox" con juegos de msdos. Puedo afirmar que se nota. Era el tiempo de msdos y cuando se escuchaba aquello era algo totalmente distinto a lo habitual. La rom de la propia tarjeta de sonido incorporaba un banco de instrumentos. Ya existían dos tipos de bancos de sonidos, dos extensiones. Hoy puedes bajarte de Internet aquellos bancos de sonidos que incorporaban las tarjetas de sonido. Los juegos usaban esos bancos de sonidos "concretos", si le pones otro, puede sonar muy diferente y no gustar. Y esto es midi, no hablamos de los mod,s3m, tiempo de Amiga ( SoundTrackers, había muchas aplicaciones de sonido terminadas en "Tracker", eran como pistas, era varias pistas que cada una, era un instrumento). En el cual los instrumentos era un archivo añadido al archivo de la canción (Tenías que ir cambiando disquetes, según la aplicación te iba pidiendo archivos de sonido o samples. Y a veces según el tipo de extensión iba todo en el mismo archivo mod. Instrumentos y la canción. Era otro mundo. Saludos RE: Enviar datos MIDI a un softsynth vía ALSA - jguardon - 06-12-2023 Fantástica masterclass, voutt. Me quito el sombrero! Me gustaría incluirlo en nuestro viejo y oxidado blog para futuras referencias y como punto de partida para más artículos como éste dedicados al audio en Gambas, por supuesto con su atribución a vos, su autor. ¿Da usted su permiso, cónsul? Saludos RE: Enviar datos MIDI a un softsynth vía ALSA - vuott - 06-12-2023 (06-12-2023, 16:38)jguardon escribió: ¿Da usted su permiso, cónsul?Claro que sì. De todos modos, a todos los que quieran profundizar en este tema, sugiero la lectura de mi "magnum opus " sobre Gambas, MIDI y ALSA en la wiki del foro italiano: https://www.gambas-it.org/wiki/index.php/Gestione_del_MIDI_con_ALSA RE: Enviar datos MIDI a un softsynth vía ALSA - vuott - 07-12-2023 Otro código similar, pero más complejo, usando una Estructura para crear el Evento Midi de ALSA: Código: Private cb As ComboBox |