Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Taller de Msica Electrnica Sergi Jord, 2005 E.S.U.P., Universitat Pompeu Fabra Barcelona
ndice
Programa MIDI: introduccin Polling, interrupciones, sincrona Relojes, eventos, callbacks y multithreads Introduccin: MIDI en Windows Introduccin a PortMusic (instalacin, funciones) Relojes, callbacks y procesos Sincrona en multithreading Eventos MIDI Control de tiempo: tempo, ticks Standard MIDI Files Artculos y bibliografa Apndice A: Ejemplos de bucles de control Apndice B: Callbacks & punteros a funciones Apndice C: Ciclos interactivos Escalas temporales Apndice D: Standard MIDI Files
Un programa MIDI
Es un buen ejemplo de programa que funciona a t.real Recibe inputs Los procesa Ejecuta outputs
Adems es mucho ms estricto que otros tipos de programas en cuanto al control del tiempo. En qu? & porqu? Frecuencia del ciclo Estabilidad del ciclo
Un programa MIDI
Es un buen ejemplo de programa que funciona a t.real Recibe inputs Los procesa Ejecuta outputs
Adems es mucho ms estricto que otros tipos de programas en cuanto al control del tiempo. En qu? & porqu? Frecuencia del ciclo Estabilidad del ciclo
Sncronos asncronos
A veces se toma sncrono como sinnimo de en tiempo real, con lo que se implica que los sistemas en tiempo real NO pueden ser asncronos. Esto no tiene porque ser as, ya que todos ellos (sncrono, asncrono, t.real) son conceptos un tanto relativos En un sistema de t.real sncrono, el sistema responde instantneamente a los eventos externos Instantaneamente : en un tiempo notablemente inferior al del lapso entre eventos En un sistema de t.real asncrono, se presupone que la densidad de los eventos puede llegar a ser muy alta (o su granularidad temporal muy pequea) por lo que el sistema tan slo debe dar un compromiso tipo tiempo mximo de espera En la mayora de APIs MIDI (y de audio), lo que se realiza es una combinacin de ambos mecanismos
Polling Es el caso ms sencillo el sistema mira entradas externas peridicamente Adecuado para un input de tipo continuo (analgico), pero no para uno con eventos (ya que podran perderse) Interrupciones Los eventos externos provocan un servicio de interrupcin, que ejecuta un programa breve (que debera terminar antes de que deban comenzar otras tareas) En el ms breve de los casos, este programa o proceso simplemente pone el evento en una cola de entrada Una vez terminado este proceso el programa principal retoma el punto en el que estaba
Un sistema basado en interrupciones, suele asociar un proceso a un evento: evento: la entrada de un dato proceso: llamada a funcin El caso del reloj es similar ya que el reloj produce peridicamente un evento de reloj
Un sistema basado en interrupciones, suele asociar un proceso a un evento: evento: la entrada de un dato proceso: llamada a funcin El caso del reloj es similar ya que el reloj produce peridicamente un evento de reloj La asociacin de estos eventos (e.g. entradas, relos, etc.) a una funcin se suele realizar mediante funciones callback
Funciones Callback
Una funcin callback es una funcin que se llama desde un proceso que nosotros no controlamos (normalmente desde una API) Esta llamada puede ser peridica (eg. llenar un frame de audio) o motivada por determinados eventos (e.g. recibir mensaje MIDI, procesar frame video) En realidad estn siempre generadas por eventos (en el primer caso, un evento de RELOJ) Se suelen implementar mediante punteros a funciones (cfg. Apndice B) En una funcin callback, no es conveniente realizar gestin de memoria, acceso a ficheros, refresco de pantalla y ningn tipo de acceso a los recursos del sistema que pueda suponer un retardo para el resto de los procesos
Relojes
Los timers son fundamentales para que las aplicaciones realicen operaciones peridicas en varios procesos y con mxima precisin temporal En windows (por ej.) existe un Timer multimedia con una resolucin de hasta 1 ms, y el standard, que tiene una resolucin de ~ 40-50 ms Un Timer se suele poner en marcha mediante una llamada a una funcin a la que se suele pasar los siguientes parmetros: Periodicidad Callback function Tolerancia [opc] (Periodicidad +- Tolerancia) Puntero [opc] (para intercambio de informacin entre procesos)
// ejemplo de PortMIDI Pt_Start(1, &process_midi, (void*)&iData); // start a timer with millisecond accuracy
Multithreading
Si usamos este tipo de arquitecturas (relojes con callbacks o interrupciones en lugar de polling) tendremos al menos dos procesos (el principal y el llamado de vez en cuando por las interrupciones) multithreading NOTA: la diferencia entre threads y procesos es que los primeros comparten el mismo espacio de memoria, variables, etc Sin embargo, en bastantes casos, el programador no gestiona directamente estos threads, cuyo uso puede venir facilitado por las libreras que se utilicen Ejemplos: Salida de audio a la tarjeta: una librera (e.g. DirectX) se encarga de esto a partir de unos frames de tamao predefinido (y rellenados por nuestro programa) Entrada de datos MIDI o serie: las libreras suele invocar un thread que coloca los datos en una cola Procesado de imagen a t.real: las libreras suele llamar a una funcin a la que le pasan el frame (imagen) recin capturado. En estos casos, nuestro programa NO controla el bucle principal Si utilizamos alguna librera de audio de ms alto nivel que DirectX (e.g. CLAM, PortAudio) la librera puede comportarse de forma similar al caso de vdeo. En lugar de responsabilizarnos del bucle principal, debemos escribir la funcin que se ejecuta peridicamente y que se encarga de rellenar un frame de audio (calcular todas sus muestras). La llamada a esta funcin (callback) queda como responsabilidad del scheduler de la librera
La librera PortMusic
MIDI en Windows
(drivers virtuales: e.g. MidiYoke) Entre la aplicacin y el driver existe una capa intermedia (winmm.dll) con centenares de funciones para Audio (Wave), MIDI, Timers, Video, Joystick En cualquiera de estos casos, deberemos incluir mmsystem.h y linkar con winmm.lib
Winmm
En el caso de MIDI, las funciones bsicas nos permiten Preguntar por puertos disponibles (I & O) y sus propiedades Abrirlos / cerrarlos Recibir mensajes de los puertos de entrada Mandar mensajes a los puertos de salida Adems tambin habr que utilizar las de relojes Winmm es suficiente para aplicaciones sencillas (slo MIDI OUT) (cfg. Anaya cap. 17), pero demasiado laborioso para aplicaciones ms complejas... Por ello es recomendable utilizar alguna API adicional
Instalacin
Download (slo 85Kb) y la documentacin (slo un .h, que contiene una descripcin de cada una de las funciones) Hay que compilar los proyectos para obtener las libreras (portmidi.lib, porttime.lib y pm_dll.dll) Se incluyen los proyectos que generan estas libreras, junto con ejemplos sencillos Entrada y salida Envo sistema exclusivo Aplicin multithreaded
Funciones PortMusic
Listar y abrir puertos MIDI (IN & OUT) Recibir mensajes del IN y enviar mensajes al OUT Crear timers con callbacks para procesar las entradas Gestionar colas de mensajes para comunicar callbacks y otros procesos
Evento MIDI: mensaje + timestamp El timestamp no se mide en ms sino en ticks (ULONG) typedef long PmMessage; typedef struct { PmMessage message; PmTimestamp timestamp; } PmEvent;
Entradas y salidas
Entrada y salida (varias opciones)
1. 2.
El puerto de entrada ejecuta un thread independiente que se activa (otra callback) cuando recibe mensajes El puerto de entrada deja mensajes en una cola. La callback de salida mira si hay mensajes en la cola (poll) y los procesa (an as tenemos como mnimo 2 threads de que preocuparnos: principal + timer-callback)
Esta funcin podra estar mirando en un array (o lista o array, etc.) de eventos (con timestamp) para ver si debe mandar algo a la salida (los ticks los debe controlar la funcin) Esta funcin no debera ejecutar ninguna llamada tipo leer/escribir en fichero, consola se podra retrasar
Sincrona en Multithreading
Por definicin, si dos threads son independientes es imposible garantizar la sincrona entre ellos, con una precisin mxima Esto es generalizable al uso de cualquier dato compartido por 2 o ms threads Orden de actualizacin? Problema ms grave: que el thread A que escribe los datos, se interrumpa durante la escritura para dar paso al thread B que los leer (parcialmente actualizados) 2 procesos leyendo y escribiendo simultneamente de las mismas posiciones de memoria Soluciones: Semforos: mecanismos de bloqueo de acceso Ms simple: intercambio de datos entre threads mediante colas de mensajes Slo uno de los threads debe tener acceso de escritura Si 2 threads deben intercambiar datos mutuamente (ambos con posibilidad I/O) 2 colas PortMusic implementa estas colas de comunicacin (ej. midithread.c)
Tempo y ticks
Tempo = negras/minuto Resolucin del secuenciador = ticks/negra Duracin de un tick = ms/tick Cmo calcular la duracin de un tick en funcin del tempo y la resolucin? 60.000 [ms] 1 [min] ----------------- x ---------------------------------1 [min] Tempo*Resolucin [tick] Problemas?
Tempo y ticks
Tempo = negras/minuto Resolucin del secuenciador = ticks/negra Duracin de un tick = ms/tick Cmo calcular la duracin de un tick en funcin del tempo y la resolucin? 60.000 [ms] 1 [min] ----------------- x ---------------------------------1 [min] Tempo*Resolucin [tick] Problemas?
En la prctica, no todos los tempos son posibles, ya que la duracin de 1 tick es int Soluciones: Cuantizar los tempos (si el usuario introduce un tempo imposible, se le avisa del redondeo poco prof!) Acumular errores y corregir (e.g. si la duracin terica de 1 tick es 1,5 ms, cada 2 ticks de 1 ms se aade 1 tick fantasma que no se cuenta - ~aos bisiestos) Adems, El timestamp puede ser absoluto o relativo (en SMF es relativo, en PortMusic es abierto) Si es relativo, al insertar un evento hay que corregir el TimeStamp del siguiente
http://www.sonicspot.com/guide/midifiles.html
Un SMF se almacena como varias pistas, cada una de ellas con TimeStamps relativos (a los eventos de esta pista) Para reproducir el fichero 1. Se convierte cada pista a t absolutos 2. Se combinan todas las pistas en una sola en memoria 3. Opcionalmente (si nuestro reloj funciona con relativos), se vuelven a relativizar Si no trabajamos con SMF, y lo hacemos con t absolutos, no es necesario todo esto:
Podemos tener un array 2D (un array de secuencias donde cada secuencia es un array de eventos) Y un array de ndices (cada ndice indica el prximo evento de la secuencia) A cada tick, miramos para cada secuencia si el timestamp del prximo evento coincide con el tick actual. Si s, lo mandamos a la salida e incrementamos el ndice. Si adems de un secuenciador, quisiramos un editor, los arrays no son suficientes (hay que insertar/borrar). Habra que trabajar con listas enlazadas.
Varios artculos sobre diseo de lenguajes y sistemas para interactividad en tiempo real (especialmente en audio)
Dannenberg, ``Software Design for Interactive Multimedia Performance,'' Interface - Journal of New Music Research, 22(3) (August 1993), pp. 213-228. Brandt and Dannenberg, ``Low-Latency Music Software Using OffThe-Shelf Operating Systems,'' in Proceedings of the International Computer Music Conference, San Francisco: International Computer Music Association, (1998), pp.137-141. Brandt and Dannenberg, ``Time in Distributed Real-Time Systems,'' in Proceedings of the 1999 International Computer Music Conference, San Francisco: International Computer Music Association, (1999), pp. 523-526. Bencina and Burk, PortAudio an Open Source Cross Platform Audio API, in Proceedings of the 2001 International Computer Music Conference, San Francisco: International Computer Music Association, (2001). What is latency and how to tune it?
NB: Se incluyen a ttulo informativo ya que la mayora de APIs (incl. PortMusic) ya se encargan de la gestin de estos bucles
Suposiciones: Queremos hacer algo peridicamente, cada h El sistema es multithreated: que un proceso espere un rato determinado, no significa que el sistema se quede sin hacer nada
Punteros a funciones (y 2)
Los punteros a funciones se utilizan mucho par ordenaciones. En las ordenaciones se realizan dos acciones bsicas: la de comparacin y la de cambio de lugar. La comparacin no es algo trivial. No es vlido el smbolo < para comparar cadenas, o muchos otros tipos de datos. A una funcin de ordenacin le podremos determinar cmo se compara para que sea genrica. El prototipo de una funcin de este estilo podra ser: int ordenar (void *array_a_ordenar, unsigned int n_elem, unsigned int tam_elem, int (*pfcomparacion)(const void *, const void *)) El const se utiliza para evitar que la funcin de comparacin pueda modificar los elementos a comparar El puntero a elementos a ordenar es de tipo void para poder ordenar cualquier cosa Por esta misma razn, es necesario indicar el tamao de cada elemento
En ANSI C existe la funcin qsort, que utiliza el algoritmo quick sort. Lo nico que deberemos escribir para que funcione es la funcin que compara. Otra aplicacin de los punteros a funciones es la de crear mens u opciones diferentes: int f1(void); int f2(void); int f3(void); inf (*pf[3])( ); // esto es un array de punteros a cada una de estas tres funciones Para llamar a una de estas funciones podramos hacer: while ((i=opcion( ) ) > 0 && i < 3) (*pf[i] )( );
Antes hemos hablado de ciclos que deben ser estables pero que frecuencia deben tener? cuanto deben valer este tiempo justo?
A partir de ~10 Hz percibimos un continuo de movimiento Cine ? TV ? Generada por ordenador ? Una cosa es la continuidad de movimiento (evitar saltos) y otra es la continuidad de brillo (evitar flickering), que mejora conforme aumenta la frecuencia Por ello, estos sistemas muestran cada imagen 2 veces (cine=48 Hz, PAL=50 Hz, NTSC=60 Hz) Como se ve entonces una pelcula en TV? En Europa (PAL) + rpido (en un factor 24/25 = 0,96). Una pelcula de 90 minutos dura 86,4 en TV En USA (NTSC) cada par de frames se repite x2 y x3 resp (48+72=60+60)
A partir de ~10 Hz percibimos un continuo de movimiento Cine : inicios: 12-16 fps actual: 24 fps dibuj.anim.: 12-30 fps TV : PAL: 25 fps NTSC: 30 fps Generada por ordenador : ~12-30 fps (flexible) Una cosa es la continuidad de movimiento (evitar saltos) y otra es la continuidad de brillo (evitar flickering), que mejora conforme aumenta la frecuencia Por ello, estos sistemas muestran cada imagen 2 veces (cine=48 Hz, PAL=50 Hz, NTSC=60 Hz) Como se ve entonces una pelcula en TV? En Europa (PAL) + rpido (en un factor 24/25 = 0,96). Una pelcula de 90 minutos dura 86,4 en TV En USA (NTSC) cada par de frames se repite x2 y x3 resp (48+72=60+60)
Sonido: la freq. de muestreo est relacionada con la mxima freq. audible (T.Nyquist dice que debe ser como mnimo el doble) Comprensin perfecta voz hablada : a partir de ~3 4.000 Hz Calidad CD : 44.100 Hz Sistemas grabacin profesionales : 96.000 Hz Significa esto que un sistema interactivo sonoro debe funcionar varios miles de veces + rpido que un sistema interactivo visual? No se debe confundir el ciclo o la frecuencia de reproduccin de medios, con el ciclo o la frecuencia de interaccin
Sonido: la freq. de muestreo est relacionada con la mxima freq. audible (T.Nyquist dice que debe ser como mnimo el doble) Comprensin perfecta voz hablada : a partir de ~3 4.000 Hz Calidad CD : 44.100 Hz Sistemas grabacin profesionales : 96.000 Hz Significa esto que un sistema interactivo sonoro debe funcionar varios miles de veces + rpido que un sistema interactivo visual? No se debe confundir el ciclo o la frecuencia de reproduccin de medios, con el ciclo o la frecuencia de interaccin
Duracin de un ciclo?
Necesidades de la interaccin (depende del tipo de aplicacin, de centsimas a centenares de Hz) Limitaciones velocidad hard+soft (todos los procesos de un ciclo deberan completarse antes del inicio del nuevo ciclo) Algunos ejemplos
Windows GUI (timer...) Termostato aire acondicionado vs. Termostato reactor nuclear
Sistemas blandos vs. duros (donde pasar del ciclo puede ser catastrfico) Para asegurar la estabilidad, de acuerdo con el T.Nyquist, en principio la duracin de un ciclo debera ser como mnimo, igual a la mitad del tiempo de cambio de cualquier parmetro externo
Aplicacin interactiva procesado de vdeo t.real Reconocimiento de gestos Teclado + Secuenciador MIDI
La frecuencia del ciclo de entrada no siempre tiene que coincidir con la del de salida (e.g. reconocimiento de gestos) Excepto casos como el teclado MIDI, el ciclo de entrada en HCI suele estar entre 20-100 Hz (10-50 ms)
Duracin de un ciclo?
Necesidades de la interaccin (depende del tipo de aplicacin, de centsimas a centenares de Hz) Limitaciones velocidad hard+soft (todos los procesos de un ciclo deberan completarse antes del inicio del nuevo ciclo) Algunos ejemplos
Windows GUI (timer...) ~20 Hz Termostato aire acondicionado vs. Termostato reactor nuclear
Sistemas blandos vs. duros (donde pasar del ciclo puede ser catastrfico) Para asegurar la estabilidad, de acuerdo con el T.Nyquist, en principio la duracin de un ciclo debera ser como mnimo, igual a la mitad del tiempo de cambio de cualquier parmetro externo Aplicacin interactiva procesado de vdeo t.real: al frame rate, a no ser que
Reconocimiento de gestos: frecuencia min. doble de la del gesto Teclado + Secuenciador MIDI: en algunos programas hasta 1000 Hz!
La frecuencia del ciclo de entrada no siempre tiene que coincidir con la del de salida (e.g. reconocimiento de gestos) Excepto casos como el teclado MIDI, el ciclo de entrada en HCI suele estar entre 20-100 Hz (10-50 ms)
Escalas de tiempos
The Dictionary of Computer Science (Van Nostrand Reinhold, 1993) defines a simple table of average response times, and processing methods and models: Computer Processing Modes and Times Card Oriented Batch Keyboard Oriented Batch Interactive Computing Online Inquiry and Transactions Message Switching Data Acquisition and Control 100-10000s 1-100s 1-10s 1-10s 0.1-10s 0.01-10s
Which of these are real-time? (extrado de Real-Time Computing for Human Computer Interfacing,
Perry Cook)