#ifndef cab_util_h
 /* Contiene todo lo necesario para Temporizacion y la lectura de archivos
    de sonido en formato RAW 8 bits unsigned byte
    Autor: Jaime Jose Gavin Sierra
    Alias: JJ
    Correo: jaimejj@mixmail.com
    WEB: http://www.lanzadera.com/ensamblador */

 #define cab_util_h
 #define tope_elementos 10

 #ifdef ALLEGRO_WINDOWS
  int diita,mesito,anito,horita,minutitos,segunditos;
 #endif
 struct TArrayBuffer{
  unsigned char num;
  unsigned char *buffer;
 };
 
 enum TEstado {comienzo,fin};
 enum TRepe {iniGraba,grabando,finGraba,nada};
 volatile int segundos= 0;   //Variable de temporizacion en segundos
 int radioSample, estereoSample, numBytes, tamBuffer,tamAnterior,i,j;
 int bitsSample= 8;
 int vozRepe;
 unsigned char *bufferSonido=NULL;   //Para 8 bits
 unsigned int * bufferSonido16= NULL; //Para 16 bits
// unsigned char *bufferPrueba=NULL;
 int fichero,tamanio,media,valor,segAntes,segDespues,segTX;
 FILE *ficheroLog=NULL;
 enum TEstado estado;
 enum TRepe estadoRepe= nada; //Para el estado del Repetidor
 int segTope = 10;           //Maximos segundos de TX
 boolean sancionTope= FALSE; //Para saber si se ha pasado de tope en TX
 boolean finTX= FALSE;       //Para saber que se acabo el TX
 int umbral= 10;             //Umbral de media para detectar audio de 0 a 127
 int segSancion= 5;          //Segundos de espera despues de una TX muy larga
 int segSilencio= 2;         //Maximos segundos de silencio para parar TX
 int segFinTX= 1;            //Segundos de espera despues de una TX normal
 int numeroIncidencias= 0;   //El n§ d veces k se entra en el gateway o repe

 int tipoPantalla=GFX_AUTODETECT_FULLSCREEN;
 boolean parametroPortada=TRUE;
 boolean parametroSetup=FALSE;
 int parametroUmbralRX= 10;
 int parametroTxTope= 10;
 int parametroSancionTxTope=10;
 int parametroKhz= 11025;
 int parametroTxOff=1;
 int parametroGrabar=SOUND_INPUT_LINE;
 int parametroTXRX=1;
 boolean parametroLogTX= FALSE;  //Para log archivo TEXTO
 boolean parametroLogRAW= FALSE; //Para log archivo sonido
 boolean parametroRepe= FALSE;   //Para el repetidor
 boolean grabarFicheroSonido= FALSE; //PAra grabar solo los datos de TX
 int contBufferRepe=0;
 SAMPLE *sonidoRepe= NULL;

 DATAFILE *datos_graficos= NULL;   //Contiene los iconos y fondos
 DATAFILE *datos_voz= NULL;        //Contiene los samples de voz
 struct TArrayBuffer arrayBuffer;  //Contiene una Lista de buffer Sonido


 char cadenaSonidoTest[255]; //Contiene mensaje de mejor sonido en test
 
 #ifdef ALLEGRO_DOS
  struct time tiempoLocal; //Para la hora del sistema
  struct date diaLocal; //Para el dia del sistema
 #endif

 int anchoX= 640; //Ancho en pixels de pantalla
 int altoY= 480;  //Alto en pixels de pantalla
 int driverSonido= DIGI_AUTODETECT; //se autodetecta el sonido
 int parametroEsperaPTT= 500; //Para la espera d estabilizar PTT en milisegundos
 int intercambio;
 int mulBitsSample=1;  //1 es para 8 bits y 2 para 16 bits, k se multiplica
 boolean modoFullDuplex= FALSE; //Modo fullduplex
 int volumenMaestro= 255; //Volumen de reproduccion
 boolean balizaActiva= FALSE; //Estado de la baliza
 int segundosBaliza=0; //tiempo de la Baliza
 int segBaliza= 60; //captura los segundos de la baliza
 SAMPLE *sonidoAuxBaliza= NULL; //un puntero auxiliar para baliza

 
 /*****************************************************************/
 int LeerSonidoRaw (char *nombre, unsigned char *buffer, int tam);
 int TamanioFichero (char * nombre);
 void inc_segundos(void);

 void InicializaArrayBuffer(int tam);
 void EliminaArrayBuffer();
 int MeterArrayBuffer(unsigned char *dato,int tam);
 void VaciarBuffer();
 void EsperaActivaTeclado(int num);
 void RutinaError(char *cadena);
 void ReproducirSonidoVoz(SAMPLE *sonido,int volumen);

 /*********************************************************************/
 void inc_segundos(void){ segundos++; } END_OF_FUNCTION(inc_segundos);
 /*********************************************************************/

 /**************************************/
 int TamanioFichero (char * nombre){
 //Saca el tamanio del fichero
  int fich; int tam=0;
  fich = open(nombre,O_RDONLY);
  if (fich>=0){ tam=lseek(fich,0,SEEK_END); close(fich); }
  return (tam);
 }

 /**************************************/
 int LeerSonidoRaw (char *nombre, unsigned char *buffer, int tam){
 //Le de manera optimizada un fichero de Sonido RAW
 //Devuelve el numero de bytes leidos. Usado para pruebas
  int fich;
  if (buffer!=NULL){
   fich = open(nombre,O_RDONLY);
   if (fich>=0){
    read(fich,buffer,tam);
    close(fich);
   }
   else return (-1);
   return (0);
  }
  return (-1);
 }

 /**********************************************************/
 void InicializaArrayBuffer(int tam){
  arrayBuffer.num= 0;
  arrayBuffer.buffer= (unsigned char *)malloc(tam*tope_elementos);
 }

 /**********************************************************/
 void EliminaArrayBuffer(){
  if (arrayBuffer.buffer != NULL){
   free (arrayBuffer.buffer);
   arrayBuffer.buffer= NULL;
  }
  arrayBuffer.num= 0;
 }

 /**********************************************************/
 int MeterArrayBuffer(unsigned char *dato,int tam){
  unsigned char i= arrayBuffer.num;
  int a,cont=0;
  if (i<tope_elementos){
   if (arrayBuffer.buffer != NULL){
    for (a=(i*tam);a<((i+1)*tam);a++,cont++)
     arrayBuffer.buffer[a]= dato[cont];
    arrayBuffer.num++;
   }
  }
  if (arrayBuffer.num >= tope_elementos) return (TRUE); //Esta lleno
  else return (FALSE); //No esta lleno
 } 

 /**********************************************************/
 void VaciarBuffer(){
  //Pone a 0 los elementos a grabar
  arrayBuffer.num= 0;
 }

 /**********************************************************/
 void EsperaActivaTeclado(int num){
  //Espera num segundos o k se pulse una tecla
  int antes;
  antes=segundos;
  while (((segundos-antes)<num)&&(keypressed()==FALSE));
  //clear_keybuf(); //No vacio el teclado para salir
 }

 /**********************************************************/ 
 void RutinaError(char *cadena){
  //Gestiona los errores. Muestra el texto de error y sale del programa
  set_gfx_mode(GFX_TEXT,80,25,0,0);
  allegro_message(cadena);
  allegro_exit();  
  exit(-1);  
 }

 /**********************************************************/
 void ReproducirSonidoVoz(SAMPLE *sonido,int volumen){
  //Reproduce un SAMPLE reservando voz
  int voz;
  if (sonido!=NULL){
   voz= allocate_voice(sonido);
   if (voz!=-1){
    voice_set_volume(voz,volumen);
    voice_start(voz);
    while ((voice_get_position(voz)>=0)&&(!keypressed()));
    voice_stop(voz);
    deallocate_voice(voz);
   }
  }
 }
#endif
