Creación del conjunto de eventos

Ubicación

Las funciones que generan los eventos están ubicadas en el archivo eventos.h

Descripción

Cada evento es representado por una estructura EVENTO que tiene información de cada uno de sus parámetros. Se desprende facilmente que la obra es un conjunto de éstos eventos, y por lo tanto definiremos una función que devolverá estos eventos en forma de un arreglo creado dinámicamente.

La creación dinámica es debida a que la forma de generación de la obra no permite saber de antemano la cantidad de eventos. La función debe devolver también información de la cantidad de eventos generados ya que será usada por otras partes de la aplicación.

Creación de cada parámetro

El usuario ingresa para cada parámetro un valor mínimo y máximo. Cada parámetro se crea entre éstos valores. En la versión actual de textura, la generación para cada parámetro es la misma, entonces es bueno usar una sóla función para dicha generación, o más bien diríamos dos.

La generación es aleatoria y vamos a crear una función auxiliar que utiliza la función rand() de c. Devuelve un valor aleatorio decimal entre dos valores pasados como argumento. No se necesita mucha explicación:

double Aleat(double min, double max)
{
  return (double)(max - min) * (1.0 * rand() / RAND_MAX) + min;
}

El casting a double se debe a que rand() devuelve un valor entero entre 0 y RAND_MAX que es una macro definida en una librería de c. (Si dividimos a rand() entre RAND_MAX, siempre nos devolvería 0, por eso la multiplicación por 1.0.)

Función GenParametros

Usamos una función genérica para crear cada parámetro. Los argumentos son los valores mínimos y máximos que puede tener cada parámetro y la cantidad de eventos. Creamos una tabla dinámicamente en el cuerpo de la función cuyo tamaño es la cantidad de eventos. Asignamos a cada elemento de la tabla un valor aleatorio entre mínimo y máximo. Devolvemos la tabla.

Diagrama de flujo

diagrama de flujo GenParametros

Código

double *GenParametro(RANGO par, int cant)
{
  double *pars;
  int i;
  pars = (double *)calloc(cant, sizeof(double));
  for(i = 0; i < cant; i++)
    pars[i] = Aleat(par.min, par.max);
  return pars;
}

Función GenComienzos

Antes de crear el conjunto de eventos, debemos conocer su cantidad. Esto depende de los comienzos de los eventos y de la duración total de la obra. Por lo tanto lo primero que debemos generar son los comienzos, y para eso usamos una función especial que devolverá un arreglo con los comienzos y la cantidad de eventos. Esta información será usada para la generación de los demás parámetros.

El arreglo de comienzos se crea dinámicamente en el cuerpo de la función, pero aún no sabemos de que tamaño debe ser. Una solución es dividir la duración total de la obra entre el valor mínimo de comienzo, es seguro que no se generarán más eventos que este valor. Luego actualizaremos éste valor ántes de devolverlo.

Diagrama de flujo

diagrama de flujo GenComienzos

Código

double *GenComienzos(double durTotal, RANGO com, int *cant)
{
  double *coms = NULL;
  double *temp = NULL;
  int i = 0;

  *cant = (int)(durTotal / com.min);
  temp = (double *)calloc(*cant, sizeof(double));
  temp[0] = 0.0;
  while(temp[i] < durTotal && i < *cant)
    {
    i++;
    temp[i] = Aleat(temp[i-1] + com.min, temp[i-1] + com.max);
    }
  *cant = i;
  coms = (double *)calloc(*cant, sizeof(double));
  for(i = 0; i < *cant; i++)
    coms[i] = temp[i];
  free(temp);
  return coms;
}

Crear los eventos

Una vez creadas las funciones anteriores, ConstruirObra simplemente las llama, y el proceso se hace más lineal. Antes asigna memoria para arreglos de cada parámetro de los eventos. Llama a la función GenComienzos, y luego a GenParametro por cada parámetro restante. Todos éstos datos se copian al arreglo de estructuras EVENTO, y se devuelve para ser usado por otras funciones.

Diagrama de flujo

diagrama de flujo ConstruirObra

Código

EVENTO *ConstruirObra(PARAMETROS *parms, int *cant)
{
  EVENTO *evs;
  double *coms, *durs, *amps, *frecs, *pans;    
  int i;

  coms = GenComienzos(parms->durTotal, parms->evCom, cant);

  durs = GenParametro(parms->evDur, *cant);
  amps = GenParametro(parms->evAmp, *cant);
  frecs = GenParametro(parms->evFrec, *cant);
  pans = GenParametro(parms->evPan, *cant);

  evs = (EVENTO *)calloc(*cant, sizeof(EVENTO));
  for(i = 0; i < *cant; i++)
    {
    evs[i].comienzo = coms[i];
    evs[i].duracion = durs[i];
    evs[i].amplitud = amps[i];
    evs[i].frecuencia = frecs[i];
    evs[i].paneo = pans[i];
    }

  free(coms);
  free(durs);
  free(amps);
  free(frecs);
  free(pans);
  return evs;
}

Anterior  Inicio  Siguiente
E/S Audio   Sintetizar