#include "/musr/cmix/H/ugens.h"
#include "/musr/cmix/H/sfheader.h"
funpan(p,n_args)
float p[];
int n_args;
{
int i,nsamps;
float in[1],out[2];
/*
p[0] = cantidad a saltar en el archivo de entrada
p[1] = cantidad a saltar en el archivo de salida (en segundos)
p[2] = duracion
p[3] = valor de la panoramica (0 - todo en canal 0; 1 - todo en canal 1
*/
setnote(p[0],p[2],0);
nsamps = setnote(p[1],p[2],1);
for (i = 0; i < nsamps; i++) {
GETIN(in,0);
out[0] = in[0] * (1.0 - p[3]);
out[1] = in[0] * p[3];
ADDOUT(out,1);
}
endnote(1);
}
Este instrumento es relativamente facil de entender, incluso para los no muy familiarizados con la programacion en C. Las primeras
lineas:
#include "/musr/cmix/H/ugens.h"
#include "/musr/cmix/H/sfheader.h"
simplemente dan instrucciones al compilador C para incluir esos archivos con el resto del codigo.
Esos dos archivos contienenlas declaraciones de funciones y variables que Cmix necesita para funcionar correctamente.
En este ejemplo, se asume que el paquete de Cmix fue instalado en el directorio */musr/cmix*. Estos archivos son tambien una buena
fuente, ellos contienen una lista completa de todas las funciones y macros disponibles en las librerias Cmix.
Las lineas siguientes de codigo:
funpan(p,n_args)
float p[];
int n_args;
{
comienzan con la definicion del usuario del instrumento *funpan*. Cmix pasa dos argumentos a todas las funciones escritas-por-el-usuario
despues que la partitura ha sido procesada por Minc. El primer argumento es una cadena de valores, llamados *p-fields*. Esta
cadena contiene los datos especificados en la partitura necesarios al instrumento *funpan*. Los datos en la partitura pueden ser
accedidos referiendose a los elementos de esta cadena (vector). Por ejemplo, si la partitura para el instrumento *funpan* contiene
la linea siguiente:
Entonces p[0] puede ser definido como 0.0, p[1] buede ser 3.4, p[2] sera 7.0, y p[3] sera 0.3. Los parametros particulares de
procesamiento de señal o de sintesis, representados por los elementos de ese vector "p" son enteramente arbitrarios. Su
funcion esta definida por el uso de cada elemento en el instrumento. Ppor convencion, muchos instrumentos de sintesis de Cmix
usan p[0] como el tiempo inicial y p[1] como la duracion, y muchos instrumentos de procesamiento de señales usan p[0] como
la cantidad de tiempo para saltar cuando se lee el archivo de entrada, p[1] como la cantidad de tiempo para saltar antes de escribir
en el archivo de salida, y p[2] como la duracion. Nada es completamente 'hard-wired' (fijo), de todas maneras.
Notese que los valores en el vector "p" son del tipo decimal (floating point). Minc promueve todo al tipo decimal (o doble) antes
de pasar los datos al instrumento. El numero maximo de elementos en el vector "p" es determinado como 500, pero esto puede ser
cambiado muy facilmente modificando el valor de
in the file *defs.h* (en el directorio *cmix/Minc*).
El segundo argumento ("n_args") es solo el numero de elementos cargados en el vector "p". Esto puede ser usado para testear por
datos opcionales para el instrumento. Cmix asigna el valor 0.0 a todos los elementos que no se usan en el vector "p".
Siguiendo
Siguiendo a la definicion de funcion:
int i,nsamps;
float in[1],out[2];
declara las variables que seran usadas en la funcion del instrumento en si mismo> "i" y "nsamps" son enteros, seran usados para
contar el numero de muestras. Los vectores "in" y "out" son de numeros decimales, ellos contendran los valores de las muestras
que seran leidos y escritos en el disco. El vector "in" tiene un solo elemento. Esto es porque el archivo de entrada es considerado
siempre mono (solo un canal) en este instrumento particular. El archivo de salida sera estereo, por eso la declaracion de los dos
elementos en el vector "out" de salida.
Por convencion, casi todos los instrumentos de Cmix tienen un comentario cerca de la parte superior del archivo que describe
como deber ser usados los diferentes p-fields:
/*
p[0] = tiempo de salto en el archivo de entrada
p[1] = tiempo de salto en el archivo de salida en segundos
p[2] = duracion
p[3] = valor panoramico (0 - todo en canal 0; 1 - todo en canal 1 */
Muchas veces esto es la unica documentacion que existe para un instrumento!
Las proximas dos lineas:
setnote(p[0],p[2],0);
nsamps = setnote(p[1],p[2],1);
define los archivos de entrada y de salida, respectivamente. *setnote* es una funcion de Cmix que tiene tres argumentos:
tiempo de salto en el archivo (en segundos); duracion de lectura del archivo (tambien en segundos); y el *numer* *descriptor*
del archivo de *Cmix*> Los primeros dos argumentos pueden ser tambien especificados como un numero absoluto de muestras si son
dados como un numero negativo. El ultimo argumento necesita alguna explicacion. Cmix necesita algun modo para "recordar" los
diferentes archivos de sonidos. Esto es hecho con el uso de los descriptores de Cmix -- otras funciones que tambien 'tienen que
ver' con i/o de archivos de audio (entrada/salida) tambien los usan. Por default, la sentencia *input* en las partituras de Minc
asigna el valor 0 al archivo de sonidos. La sentencia *output* asigna un valor 1 como default. Estos descriptores de archivos
son usados por Cmix y no deben ser confundidos con los descriptores estandard de Unix (incluso si ellos sirven a mas o menos
a lo mismo).
La primera llamada a *setnote* en el ejemplo abre el archivo 0 de Cmix y posiciona el puntero interno (read/write - lectura/escritura)
en la muestra correspondiente a segundos p[0] (notese que p[0] fue decidido para ser la cantidad de tiempo para saltar en el
archivo de entrada).
La segunda llamada a *setnote* pone el puntero read/write en el segundo p[1] del archivo de salida. *setnote* tambien devuelve
un entero que representa el numero de muestras para la duracion dada en el segundo argumento (en este caso p[2]) a la frecuencia
de muestreo de ese archivo. (Nota: la frecuencia de muestreo es almacenada en el encabezamiento del archivo. Cmix lee el valor
desde el encabezamiento en una variable interna "SR". Esta variable puede ser usada en la definicion de un instrumento) "nsamps"
es calculado por la funcion *setnote*, y puede ser usado entonces para determinar cuantas muestras deben ser procesadas para la
duracion de p[2] segundos:
for (i = 0; i < nsamps; i++) {
This statement starts the sample-processing loop. The following statements will be executed once for every sound sample computed:
GETIN(in,0);
out[0] = in[0] * (1.0 - p[3]);
out[1] = in[0] * p[3];
ADDOUT(out,1);
}
*GETIN* es una macro de Cmix para leer muestras hacia un vector de entrada. en este caso, *GETIN* carga una muestra simple en el
array "in", declarado para contener al menos un elemento. Si "in" fue declarado como vector de 2 o mas elementos (float in[2]), y
el archivo de entrada fue stereo, *GETIN* leera dos muestras, una en in[0] y otra en in[1] -- canal 0 y canal 1. *GETIN* determina
cuantos canales tiene analizando el encabezamiento del archivo. Como hace para saber que archivo leer? El segundo argumento en
*GETIN* es el numero descriptor del archivo. En este caso es 0, referiendose al archivo de entrada.
Similarmente, *ADDOUT* es una macro de CMIX que hace lo inverso que *GETIN*. Adiciona una muestra a un existente archivo de
sonidos (si el archivo es nuevo, *ADDOUT* crea los nuevos datos de audio automaticamente). CMIX tambien provee una macro
destructiva, *WIPEOUT*. Los argumentos son los mismos que para *WIPEOUT* y que para *ADDOUT* (como para *GETIN*): el nombre
del vector de salida, y el mismo descriptor de archivo de Cmix. Como *GETIN*, *ADDOUT* tambien escribe una muestra en el
vector de un archivo mono, y dos muestras en uno estereo.
Las dos sentencias de comando entre *GETIN* y *ADDOUT* toman una sola muestra desde el vector "in" y la dividen entre los dos
canales del vector "out" salida. p[3] es usado para determinar la amplitud de la muestra que va hacie cada elemento del vector
"out".
finalmente, despues del bucle de muestras la sentencia:
termina la definicion del instrumento. Esta funcion de Cmix pone al dia el encabezamiento del archivo de sonido de salida,
almacenando nueva informacion acerca del pico de amplitud del archivo, etc. Tambien genera un resumen en la terminal del
instrumento del usuario, describiendo cuanto tiempo escribio muestras en el archivo de salida, cuanto tiempo tomo el
computador para generar las muestras y otra informacion util (ver el articulo en el Array para mas informacion).
Proxima seccion: Un instrumento un poco mas complejo de Cmix
Que es Cmix? -Index-