/***************************************************************************/
/* Gateway Carpanta:  Cb2Pmr y Pmr2Cb    v 1.2 Beta                        */
/* Autor: Jaime Jose Gavin Sierra                                          */
/* Operador: EC1DLN, ALFA OMEGA 117, Mochilo                               */
/* Alias: JJ                                                               */
/* Correo: jaimejj@mixmail.com                                             */
/* Web: http://www.lanzadera.com/ensamblador                               */
/* Licencia: GPL o gifware                                                 */
/* Bajo FreeDOS (DJGPP) compilar asi:                                      */
/*  gcc -s -O6 carpanta.c -ocarpanta.exe -lalleg -ldzcom                   */
/* Bajo WIN (MINGW32):                                                     */
/*  gcc -s -O6 carpanta.c -owincarpanta.exe libserie.a libtiempo.a -lalleg */
/*  Para estatico antes <allegro.h> #define ALLEGRO_STATICLINK             */
/*  -lalleg_s -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lole32 -ldinput      */
/*  -lddraw -ldxguid -lwinmm -ldsound                                      */
/* Bajo BeOS (gcc)                                                         */
/*  gcc -s -O6 carpanta.c -obeoscarpanta -lalleg-4.1.4                     */
/* Bajo Linux (gcc                                                         */
/*  gcc -s -O6 carpanta.c -olinuxcarpanta `allegro-config --libs`          */
/* Notas: La version bajo WIN padece ciertas incompatibilidades,por lo que */
/*        es mejor compilar solo la version de FreeDOS.                    */
/* Requerimientos: Adaptador Tarjeta de Sonido y PTT AGWPACKET             */
/*                 PC 80386 con 1MB de RAM                                 */
/*                 S.O. FreeDOS, Win9x, ME, NT, 2000, XP, LINUX            */
/*                 Un transceptor de CB,VHF o UHF para emitir en un camino */
/*                 Un PMR o tranceptor bien diferenciado en frecuencia     */
/*                 Uno de los PMR's debe tener VOX, el otro no hace falta  */
/* Tools: RAW2WAV para convertir los logs de RAW a WAV                     */
/*        SB16MIX para activar el MIX del microfono y dema del Sonido bajo */
/*                DOS.En WIN9x se hace desde el control de Sonido.         */
/* Descripcion: Se trata de un software que permite convertir nuestro PC   */
/*              en un GATEWAY de tiempo real.Tambien puede ser usado para  */
/*              monitorizar las transmisiones, e incluso como sistema de   */
/*              manos libres.Se trata, pues de un 3 en 1.                  */
/***************************************************************************/
#define ALLEGRO_STATICLINK //Para windows
#include <allegro.h>
#ifdef ALLEGRO_DOS
 #include "optimiza.c"
 #include <dos.h>
#endif
//Para el SETUP
#define SETUP_EMBEDDED
#define SETUP_TITLE "Configuracion Carpanta 1.2.1B"
#define SETUP_CFG_FILE "allegro.cfg"
#include "setup.c"

#include <stdio.h>
#include <string.h>
#include "datos.h"
#include "voz.h"
#include "cabserie.h"
#include "cabutil.h"
#include "gui.h"




/********************************/
int main(int argc,char **argv){
 allegro_init();

 set_window_title("Carpanta v1.2.1B");
 set_display_switch_mode(SWITCH_BACKAMNESIA);

 if (argc<=1){ //No le pasamos argumentos desde linea de comandos
  set_color_depth(8);
  #ifdef ALLEGRO_DOS
   set_gfx_mode(GFX_AUTODETECT,320,200,0,0);
  #endif
  #ifdef ALLEGRO_LINUX
   set_gfx_mode(GFX_AUTODETECT,320,200,0,0);
  #endif
  #ifndef ALLEGRO_DOS
   #ifndef ALLEGRO_LINUX
    set_gfx_mode(GFX_AUTODETECT_WINDOWED,320,200,0,0);
   #endif
  #endif
  install_keyboard();
  install_timer();
  install_mouse();
  show_mouse(NULL);

  datos_graficos= load_datafile("datos.dat");
  if (datos_graficos==NULL)
   RutinaError("Error al cargar el archivo DATOS.DAT\n");

  clear_bitmap(screen);
  set_palette(black_palette);
  blit(datos_graficos[FOTO_OPCIONES].dat,screen,0,0,0,0,320,200);
  set_palette(datos_graficos[PALETA_OPCIONES].dat);
  interfaceGrafico = do_dialog(dialogoOpcionesVideo, -1);
  #ifndef ALLEGRO_DOS
   if (dialogoOpcionesVideo[2].flags == D_SELECTED) tipoPantalla = GFX_AUTODETECT_WINDOWED;
   else tipoPantalla = GFX_AUTODETECT_FULLSCREEN;
  #endif
  if (dialogoOpcionesVideo[3].flags == D_SELECTED) parametroSetup = TRUE;
  else parametroSetup= FALSE;

  //Elijo el driver de video
  #ifdef ALLEGRO_DOS
   switch (dialogoOpcionesVideo[5].d1){
    case 0: tipoPantalla= GFX_AUTODETECT_FULLSCREEN; break;
    case 1: tipoPantalla= GFX_VESA3; break;
    case 2: tipoPantalla= GFX_VESA2L; break;
    case 3: tipoPantalla= GFX_VESA2B; break;
    case 4: tipoPantalla= GFX_VBEAF; break;
    case 5: tipoPantalla= GFX_VESA1; break;
    case 6: tipoPantalla= GFX_XTENDED; break;
    case 7: tipoPantalla= GFX_MODEX; break;
    case 8: tipoPantalla= GFX_VGA; break;
   }
  #endif

  #ifdef ALLEGRO_WINDOWS
   switch (dialogoOpcionesVideo[5].d1){
    case 0: tipoPantalla= GFX_AUTODETECT_FULLSCREEN; break;
    case 1: tipoPantalla= GFX_DIRECTX; break;
    case 2: tipoPantalla= GFX_DIRECTX_ACCEL; break;
    case 3: tipoPantalla= GFX_DIRECTX_SOFT; break;
    case 4: tipoPantalla= GFX_DIRECTX_SAFE; break;
    case 5: tipoPantalla= GFX_DIRECTX_WIN; break;
    case 6: tipoPantalla= GFX_DIRECTX_OVL; break;
    case 7: tipoPantalla= GFX_GDI; break;
   }
   if (dialogoOpcionesVideo[2].flags == D_SELECTED) tipoPantalla = GFX_AUTODETECT_WINDOWED;
  #endif

  #ifdef ALLEGRO_LINUX
   switch (dialogoOpcionesVideo[5].d1){
    case 0: tipoPantalla= GFX_AUTODETECT_FULLSCREEN; break;
    case 1: tipoPantalla= GFX_XWINDOWS; break;
    case 2: tipoPantalla= GFX_XDGA; break;
    case 3: tipoPantalla= GFX_XDGA2; break;
    case 4: tipoPantalla= GFX_FBCON; break;
    case 5: tipoPantalla= GFX_VBEAF; break;
    case 6: tipoPantalla= GFX_SVGALIB; break;
    case 7: tipoPantalla= GFX_VGA; break;
    case 8: tipoPantalla= GFX_MODEX; break;
   }
   if (dialogoOpcionesVideo[2].flags == D_SELECTED) tipoPantalla = GFX_AUTODETECT_WINDOWED;
  #endif

  #ifdef ALLEGRO_BEOS
   switch (dialogoOpcionesVideo[5].d1){
    case 0: tipoPantalla= GFX_AUTODETECT_FULLSCREEN; break;
    case 1: tipoPantalla= GFX_BDIRECTWINDOW; break;
    case 2: tipoPantalla= GFX_BWINDOW; break;
    case 3: tipoPantalla= GFX_BWINDOW_OVERLAY; break;
    case 4: tipoPantalla= GFX_BWINDOWSCREEN_ACCEL; break;
   }
   if (dialogoOpcionesVideo[2].flags == D_SELECTED) tipoPantalla = GFX_AUTODETECT_WINDOWED;
  #endif

  //Elijo la resolucion de video
  switch (dialogoOpcionesVideo[7].d1){
   case 0: anchoX= 640; altoY= 480; break;
   case 1: anchoX= 640; altoY= 400; break;
   case 2: anchoX= 320; altoY= 240; break;
   case 3: anchoX= 320; altoY= 200; break;
  }

  //Elijo el driver de Sonido
  #ifdef ALLEGRO_DOS
   switch(dialogoOpcionesVideo[9].d1){
    case 0: driverSonido= DIGI_AUTODETECT; break;
    case 1: driverSonido= DIGI_SB10; break;
    case 2: driverSonido= DIGI_SB15; break;
    case 3: driverSonido= DIGI_SB20; break;
    case 4: driverSonido= DIGI_SBPRO; break;
    case 5: driverSonido= DIGI_SB16; break;
    case 6: driverSonido= DIGI_AUDIODRIVE; break;
    case 7: driverSonido= DIGI_SOUNDSCAPE; break;
    case 8: driverSonido= DIGI_WINSOUNDSYS; break;
   }
  #endif

  #ifdef ALLEGRO_WINDOWS
   switch(dialogoOpcionesVideo[9].d1){
    case 0: driverSonido= DIGI_AUTODETECT; break;
    case 1: driverSonido= DIGI_DIRECTX(0); break;
    case 2: driverSonido= DIGI_DIRECTX(1); break;
    case 3: driverSonido= DIGI_DIRECTAMX(0); break;
    case 4: driverSonido= DIGI_DIRECTAMX(1); break;
    case 5: driverSonido= DIGI_WAVOUTID(0); break;
    case 6: driverSonido= DIGI_WAVOUTID(1); break;
   }
  #endif

  #ifdef ALLEGRO_LINUX
   switch(dialogoOpcionesVideo[9].d1){
    case 0: driverSonido= DIGI_AUTODETECT; break;
    case 1: driverSonido= DIGI_OSS; break;
    case 2: driverSonido= DIGI_ESD; break;
    case 3: driverSonido= DIGI_ARTS; break;
    case 4: driverSonido= DIGI_ALSA; break;
   }
  #endif

  #ifdef ALLEGRO_BEOS
   switch(dialogoOpcionesVideo[9].d1){
    case 0: driverSonido= DIGI_AUTODETECT; break;
    case 1: driverSonido= DIGI_BEOS; break;
   }
  #endif

  //Elijo la entrada de grabacion
  switch(dialogoOpcionesVideo[11].d1){
   case 0: parametroGrabar= SOUND_INPUT_LINE; break;
   case 1: parametroGrabar= SOUND_INPUT_MIC; break;
   case 2: parametroGrabar= SOUND_INPUT_CD; break;
  }

  //Elijo la frecuencia de muestreo
  switch(dialogoOpcionesVideo[13].d1){
   case 0: parametroKhz= 4000; break;
   case 1: parametroKhz= 5000; break;
   case 2: parametroKhz= 6000; break;
   case 3: parametroKhz= 7000; break;
   case 4: parametroKhz= 8000; break;
   case 5: parametroKhz= 11025; break;
   case 6: parametroKhz= 16000; break;
   case 7: parametroKhz= 22050; break;
   case 8: parametroKhz= 32000; break;
   case 9: parametroKhz= 44100; break;
  }

  //Elijo puerto de TX
  switch(dialogoOpcionesVideo[15].d1){
   case 0: puerto_com= NULO; break;
   case 1: puerto_com= COM1; break;
   case 2: puerto_com= COM2; break;
   case 3: puerto_com= COM3; break;
   case 4: puerto_com= COM4; break;
  }

  if (dialogoOpcionesVideo[23].flags == D_SELECTED){
   set_gfx_mode(GFX_TEXT,80,25,0,0);
   if (install_sound(driverSonido,MIDI_NONE,"")!=-1){
    if (install_sound_input(driverSonido,MIDI_NONE)==0){
     strcpy (cadenaSonidoTest,"Test de grabacion:\n-------------------\nBits: ");
     bitsSample= get_sound_input_cap_bits();
     switch (bitsSample){
      case 0: strcat (cadenaSonidoTest,"no soportada la entrada de audio\n"); break;
      case 8: strcat (cadenaSonidoTest,"8 bits\n"); break;
      case 16: strcat (cadenaSonidoTest,"16 bits\n"); break;
      case 24: strcat (cadenaSonidoTest,"soporte para 8 y 16 bits\n"); break;
     }
     strcat (cadenaSonidoTest,"Full Duplex permitido: ");
     switch (get_sound_input_cap_parm(radioSample,bitsSample,FALSE)){
      case 1: strcat(cadenaSonidoTest,"NO\n");break;
      case 2: strcat(cadenaSonidoTest,"SI\n");break;
     }
     radioSample= get_sound_input_cap_rate(get_sound_input_cap_bits(),FALSE);
     strcat (cadenaSonidoTest,"Frecuencia para los bits anteriores: ");
     tamBuffer= start_sound_input(radioSample,bitsSample,FALSE);
     stop_sound_input(); //Paro de grabar
     allegro_message ("%s%d\nBytes para buffer grabacion: %d",cadenaSonidoTest,radioSample,tamBuffer);
     remove_sound_input();
    }
    else allegro_message("No se permite la grabacion");
    remove_sound();
   }
   else allegro_message("No se permite la reproduccion");
   allegro_exit();
   exit(0);
  }

  switch(dialogoOpcionesVideo[17].d1){
   case 0: bitsSample= 8; break;
   case 1: bitsSample= 16; break;
  }

  //Para elegir la frecuencia de refresco del video
  switch(dialogoOpcionesVideo[19].d1){
   case 1: request_refresh_rate(60); break;
   case 2: request_refresh_rate(70); break;
   case 3: request_refresh_rate(72); break;
   case 4: request_refresh_rate(75); break;
  }

  if (dialogoOpcionesVideo[20].flags==D_SELECTED) modoFullDuplex= TRUE;
  else modoFullDuplex= FALSE;


  switch (dialogoOpcionesVideo[22].d1){
   case 0: volumenMaestro=255; break;
   case 1: volumenMaestro=245; break;
   case 2: volumenMaestro=225; break;
   case 3: volumenMaestro=205; break;
   case 4: volumenMaestro=155; break;
   case 5: volumenMaestro=85; break;
   case 6: volumenMaestro=55; break;
   case 7: volumenMaestro=30; break;
   case 8: volumenMaestro=20; break;
   case 9: volumenMaestro=10; break;
  }

  if (dialogoOpcionesVideo[24].flags == D_SELECTED) parametroPortada = TRUE;
  else parametroPortada = FALSE;


  if (set_gfx_mode(tipoPantalla,anchoX,altoY,0,0)!=0)
   RutinaError("Error video!! Cambie driver o Resolucion de video\n");

  if (parametroSetup==TRUE){ //Para el SETUP
    return setup_main();
    allegro_exit();
    exit(-1);
  }

 #ifdef ALLEGRO_DOS          //Inicializo el Puerto serie
  InicializaPuertoSerie(puerto_com);
 #endif

 #ifdef ALLEGRO_LINUX          //Inicializo el Puerto serie
  InicializaPuertoSerie(puerto_com);
 #endif


 #ifdef ALLEGRO_WINDOWS
  switch (puerto_com){
   case COM1: InicializaPuertoSerieWin(1); break;
   case COM2: InicializaPuertoSerieWin(2); break;
   case COM3: InicializaPuertoSerieWin(3); break;
   case COM4: InicializaPuertoSerieWin(4); break;
  }
 #endif

 PuertoSerie(puerto_com,FALSE); //Desactivo el PTT,xk hay casos de error



  //El interface numero 2,el de parametros de gateway y repetidor
  clear_bitmap(screen);
  set_palette(black_palette);
  stretch_blit(datos_graficos[FOTO_OPCIONES2].dat,screen,0,0,640,480,0,0,anchoX,altoY);
  set_palette(datos_graficos[PALETA_OPCIONES2].dat);
  interfaceGrafico = do_dialog(dialogo, -1); //Muestro el GUI de opciones
  switch (dialogo[3].d1){
   case 0: parametroEfecto= nulo; break;
   case 1: parametroEfecto= vmeter; break;
   case 2: parametroEfecto= vmeter2; break;
   case 3: parametroEfecto= vmeter3; break;
   case 4: parametroEfecto= vmeter4; break;
   case 5: parametroEfecto= transpa1; break;
   case 6: parametroEfecto= transpa2; break;
   case 7: parametroEfecto= degrada1; break;
   case 8: parametroEfecto= degrada2; break;
  }
  if (parametroEfecto != nulo){
   videoTemporal = create_system_bitmap(320,94); //Creo un buffer de video auxiliar
   capturaPantalla = create_system_bitmap(320,94); //Creo una captura de video
  }
  parametroUmbralRX= ((dialogo[5].d1+1)*10);
  parametroTxTope= ((dialogo[7].d1+1)*10);
  parametroSancionTxTope= dialogo[9].d1;//No sumo 1,xk para el caso d escucha
  parametroTxOff= dialogo[11].d1+1;
  parametroTXRX= dialogo[13].d1; //No se suma 1,pk empieza en 0
  if (dialogo[14].flags == D_SELECTED) parametroLogTX= TRUE;
  else parametroLogTX= FALSE;
  if (dialogo[15].flags == D_SELECTED) parametroLogRAW= TRUE;
  else parametroLogRAW= FALSE;
  if (dialogo[16].flags == D_SELECTED) parametroRepe= TRUE;
  else parametroRepe= FALSE;
  parametroEsperaPTT= ((dialogo[18].d1)*100); //Para pasarlo a milisegundos
  //Se si esta activa la baliza
  switch (dialogo[20].d1){
   case 0: balizaActiva= FALSE; break;
   case 1: balizaActiva= TRUE; break;
  }

  if (balizaActiva==TRUE){
   datos_voz= load_datafile("voz.dat");
   if (datos_voz==NULL) RutinaError("Error al cargar el archivo VOZ.DAT\n");
  }//fin if balizaActiva

  //Tiempo en segundos de la baliza
  switch (dialogo[22].d1){
   case 0: segundosBaliza= 60; break; //1 minuto
   case 1: segundosBaliza= 120; break; //2 minutos
   case 2: segundosBaliza= 300; break; //5 minutos
   case 3: segundosBaliza= 600; break; //10 minutos
   case 4: segundosBaliza= 1200; break; //20 minutos
   case 5: segundosBaliza= 1800; break; //30 minutos
   case 6: segundosBaliza= 3000; break; //50 minutos
   case 7: segundosBaliza= 3600; break; //60 minutos= 1hora
  }
 } //Fin if argc>1

 umbral= parametroUmbralRX;
 segSancion= parametroSancionTxTope;
 segSilencio= parametroTxOff;
 segFinTX= parametroTXRX;
 segTope= parametroTxTope;
// set_gfx_mode(GFX_TEXT,80,25,0,0);
// printf("Umbral: %d SancionTX: %d Silencio: %d Tx2Rx: %d TX Tope: %d\n",umbral,segSancion,segSilencio,segFinTX,segTope);
// allegro_exit();
// exit(-1);





 if (install_sound(driverSonido,MIDI_NONE,"")!=-1){
  if (parametroPortada==TRUE) MostrarPortada(); //Muestro el efecto de portada
  MuestraTablero();
  MostrarVideo(video_rx);
  if (install_sound_input(driverSonido,MIDI_NONE)==0){
   set_volume(volumenMaestro,volumenMaestro);
   set_sound_input_source(parametroGrabar);
//   printf ("Linea: %d\n",set_sound_input_source(parametroGrabar));
//   printf ("Linea: %d\n",set_sound_input_source(SOUND_INPUT_LINE));
   //bitsSample = get_sound_input_cap_bits();
   //bitsSample = 8;
   //estereoSample = get_sound_input_cap_stereo();
   estereoSample = FALSE;
   radioSample = get_sound_input_cap_rate(bitsSample, estereoSample);

 /*  #ifdef ALLEGRO_WINDOWS
    if (radioSample != parametroKhz){
     itoa(radioSample, cadenaNumero, 10);
     strcat(cadenaNumero," hz es la frecuencia mejor");
     allegro_message(cadenaNumero);
    }
   #endif*/
//   printf ("Frecuencia mejor: %d\n",radioSample);
   radioSample = parametroKhz;
//   printf ("Frecuencia elegida: %d\n",radioSample);

   if (parametroRepe==TRUE){
    //bufferAudioRepe= (unsigned char *)malloc(radioSample*segTope);
    sonidoRepe = create_sample(bitsSample,FALSE,radioSample,(radioSample*segTope)+radioSample);//Ponemos 1 segundo mas
    if (sonidoRepe==NULL)
     RutinaError("No hay memoria para crear buffer Repetidor\n");

    if (bitsSample==8)
     memset(sonidoRepe->data,0x80,(radioSample*segTope)+radioSample);
    else
     memset(sonidoRepe->data,0x80,((radioSample*segTope)+radioSample)<<1);

    //for (i=0;i<(radioSample*segTope);i++)
     //bufferAudioRepe[i]= 0x80;    
   }


   segundos=0;
   LOCK_VARIABLE(segundos);
   LOCK_FUNCTION(inc_segundos);
   install_int_ex(inc_segundos,SECS_TO_TIMER(1));

   
//   printf("Bits: %d, Estereo: %d, radio: %d\n",bitsSample,estereoSample,radioSample);
//   printf ("Chequeo: %d\n",get_sound_input_cap_parm(radioSample,bitsSample,estereoSample));
   tamBuffer = start_sound_input(radioSample,bitsSample,estereoSample);
//   printf ("Tam: %d\n",tamBuffer);
   if (tamBuffer!=0){   
//    printf ("Tama¤o del buffer: %d\n",tamBuffer);
    bufferSonido = malloc(tamBuffer*bitsSample);
    if (bufferSonido==NULL)
     RutinaError("No hay memoria para crear memoria intermedia para Repetidor\n");
    memset(bufferSonido,0x80,tamBuffer);
    InicializaArrayBuffer(tamBuffer); //Creo un Buffer de tope_elementos elementos


    fichero = open("grabar.raw",O_WRONLY|O_TRUNC|O_CREAT);
    if (fichero!=0){
     numBytes = 0;

     ficheroLog = fopen("log.txt","wa");
     if (ficheroLog!=NULL){
      fprintf(ficheroLog,"Inicio de grabacion\n");
      segAntes= segDespues= segBaliza= segundos;
      estado = fin;
      segTX = segundos;
      grabarFicheroSonido= FALSE;

      
      while (keypressed()!=TRUE){
       numBytes = read_sound_input(bufferSonido);
 //      printf ("%d",numBytes);
       if (numBytes!=0){ //Hay nuevos datos grabados de sonido
 //       printf ("%d %d ",bufferSonido[0],bufferSonido[2]);
        i= 0;
        media=0;
        if (bitsSample==16){ //Para quitar la parte de 16 bits
         for (j=0;j<(tamBuffer-1);j+=2){//E 2§ dato es repetido en MONO
          bufferSonido[j]=bufferSonido[j+1]; //Una chapuza,xo tira
         }
        }        
        while(i<tamBuffer){ //Lo detecto, recorriendo el buffer
         valor = bufferSonido[i];
         if (valor<128) valor=128-valor; //La onda va en unsigned 8 bits
         else valor=valor-128;
         media = media+valor;
         i++;
        } //Fin while i<tamBuffer
        media= media/tamBuffer; //Saco la media de la muestra
 //       printf("%d ",media);
        if (media>umbral){ //Compruebo con el Umbral
         switch (estado){
          case fin: if (sancionTope==FALSE){
                     if (finTX==TRUE){
                      if ((segundos-segTX) >= segFinTX){
                       finTX= FALSE;
                       MostrarVideo(video_rx);
                       grabarFicheroSonido= FALSE;
                      }//fin if segundos-segTX
                     }//fin finTX==TRUE
                     else{
                      segAntes = segDespues = segundos; //Es cuando comienza
                      estado = comienzo;
                      segTX = segDespues;
                      //printf ("CTX %d ",segDespues); //Activar PTT
                      MostrarVideo(video_tx);
                      grabarFicheroSonido= TRUE;
                      if (parametroLogTX==TRUE){
                       fprintf(ficheroLog,"ON %d:%d:%d ",(segundos/3600),(segundos/60),(segundos%60));
                       #ifdef ALLEGRO_DOS
                        gettime(&tiempoLocal);
                        getdate(&diaLocal);
                        fprintf (ficheroLog,"%d:%d:%d %d/%d/%d ",tiempoLocal.ti_hour,tiempoLocal.ti_min,tiempoLocal.ti_sec,diaLocal.da_day,diaLocal.da_mon,diaLocal.da_year);
                       #endif
                       #ifdef ALLEGRO_WINDOWS
                        cogerTiempo(&horita,&minutitos,&segunditos,&diita,&mesito,&anito);
                        fprintf (ficheroLog,"%d:%d:%d %d/%d/%d ",horita,minutitos,segunditos,diita,mesito,anito);
                       #endif
                      }
                      numeroIncidencias++; //Se incrementa las incidencias
                      if (parametroRepe==FALSE) PuertoSerie(puerto_com,TRUE); //Activo el PTT
                      else estadoRepe= iniGraba;
                     }//fin else del if finTX==TRUE
                    }
                    else{ //Espera de segSancion segundos
                     if ((segundos-segTX) >= segSancion){
                      sancionTope= FALSE;
                      MostrarVideo(video_rx);
                      grabarFicheroSonido= FALSE;
                     }//fin if segundos-segTX
                    }//fin else if sancionTope==FALSE

                    break;
          case comienzo: segAntes=segDespues= segundos;
                         if ((segDespues-segTX) >= segTope){
                          //Comprobamos que no se pasa del tope de TX en segundos
                          sancionTope=TRUE;
                          segTX= segDespues;
                          //printf("Tope %d FTX ",segDespues); //Desactivar PTT
                          MostrarVideo(video_sanciontx);
                          grabarFicheroSonido= FALSE;
                          if (parametroLogTX==TRUE){
                           fprintf(ficheroLog,"SANCION OFF %d:%d:%d ",(segundos/3600),(segundos/60),(segundos%60));
                           #ifdef ALLEGRO_DOS
                            gettime(&tiempoLocal);
                            getdate(&diaLocal);
                            fprintf (ficheroLog,"%d:%d:%d %d/%d/%d ",tiempoLocal.ti_hour,tiempoLocal.ti_min,tiempoLocal.ti_sec,diaLocal.da_day,diaLocal.da_mon,diaLocal.da_year);
                           #endif
                           #ifdef ALLEGRO_WINDOWS
                            cogerTiempo(&horita,&minutitos,&segunditos,&diita,&mesito,&anito);
                            fprintf (ficheroLog,"%d:%d:%d %d/%d/%d ",horita,minutitos,segunditos,diita,mesito,anito);
                           #endif                           
                           fprintf (ficheroLog,"\n");
                          }//fin if parametroLogTX
                          if (parametroRepe==FALSE) PuertoSerie(puerto_com,FALSE); //Desactivo el PTT
                          else estadoRepe=finGraba;
                          estado= fin;
                         }//fin if segDespues-segTX
                         break;
         }//fin switch estado
        }//fin if media>umbral
        else{
         switch (estado){
          case fin: if (sancionTope==TRUE){
                     if ((segundos-segTX)>=segSancion){
                      MostrarVideo(video_rx);
                      grabarFicheroSonido= FALSE;
                     }//fin if segundos-segTX
                    }//fin if sancionTope==TRUE
                    else{
                     if (finTX==TRUE){
                      if ((segundos-segTX) >= segFinTX){
                       MostrarVideo(video_rx);
                       grabarFicheroSonido= FALSE;
                      }//fin if segundos-segTX
                     }//fin finTX==TRUE
                    }//fin else if sancionTope==TRUE
                    break;
          case comienzo: segDespues= segundos;
                         if ((segDespues-segAntes) >= segSilencio){ //Espera segSilencio segundos
                          segAntes=segDespues;
                          //printf("FTX %d ",segDespues); //Desactivar PTT
                          MostrarVideo(video_tx2rx);
                          grabarFicheroSonido= FALSE;
                          if (parametroLogTX==TRUE){
                           fprintf(ficheroLog,"OFF %d:%d:%d ",(segundos/3600),(segundos/60),(segundos%60));
                           #ifdef ALLEGRO_DOS
                            gettime(&tiempoLocal);
                            getdate(&diaLocal);
                            fprintf (ficheroLog,"%d:%d:%d %d/%d/%d ",tiempoLocal.ti_hour,tiempoLocal.ti_min,tiempoLocal.ti_sec,diaLocal.da_day,diaLocal.da_mon,diaLocal.da_year);
                           #endif
                           #ifdef ALLEGRO_WINDOWS
                            cogerTiempo(&horita,&minutitos,&segunditos,&diita,&mesito,&anito);
                            fprintf (ficheroLog,"%d:%d:%d %d/%d/%d ",horita,minutitos,segunditos,diita,mesito,anito);
                           #endif                           
                           fprintf (ficheroLog,"\n");
                          }//fin if parametroLogTX
                          if (parametroRepe==FALSE) PuertoSerie(puerto_com,FALSE); //Desactivo el PTT
                          else estadoRepe= finGraba;
                          estado=fin;
                          segTX = segDespues; //Para que espere en el CTX
                          finTX= TRUE;
                         }//fin if seguDespues-segAntes
                         break;
         }//fin switch estado
        }//fin else if media>umbral
        if (parametroEfecto!= nulo){ //Muestra un efecto visual
         MostrarPlugin(parametroEfecto,bufferSonido,tamBuffer,videoTemporal);
        }//fin parametroEfecto

        if (parametroRepe==TRUE){
         //Actua en modo Repe y hay que grabar
         switch (estadoRepe){
          case iniGraba: contBufferRepe= 0;
                         //memcpy (bufferAudioRepe,bufferSonido,tamBuffer);
                         memcpy (sonidoRepe->data,bufferSonido,tamBuffer);
                         contBufferRepe+=tamBuffer;
                         estadoRepe= grabando;
                         if (bitsSample==8) mulBitsSample=1;
                         else mulBitsSample= 2;
                         break;
          case grabando: if (contBufferRepe<(((radioSample*segTope)-tamBuffer)*mulBitsSample)){
                          //memcpy (bufferAudioRepe+contBufferRepe,bufferSonido,tamBuffer);
                          memcpy (sonidoRepe->data+contBufferRepe,bufferSonido,tamBuffer);
                          contBufferRepe+=tamBuffer;
                         }
                         break;
          case finGraba: if (contBufferRepe<(((radioSample*segTope)-tamBuffer)*mulBitsSample)){
                          //memcpy (bufferAudioRepe+contBufferRepe,bufferSonido,tamBuffer);
                          memcpy (sonidoRepe->data+contBufferRepe,bufferSonido,tamBuffer);
                          contBufferRepe+=tamBuffer;
                         }
                         //write(fichero,bufferAudioRepe,contBufferRepe);
                         //memcpy(sonidoRepe->data,bufferAudioRepe,contBufferRepe);
                         estadoRepe= nada;
                         if (modoFullDuplex==FALSE)
                          stop_sound_input(); //Paro de grabar                          
                         vozRepe= allocate_voice(sonidoRepe);
                         if (vozRepe!=-1){
                          PuertoSerie(puerto_com,TRUE); //Activo el PTT
                          MostrarVideo(video_repetidor);
                          rest(parametroEsperaPTT); //Espera estabilizar PTT
                          //rest((parametroTXRX*1000)); //Para evitar ruidos
                          voice_set_volume(vozRepe,volumenMaestro);
                          voice_start(vozRepe);
                          switch (bitsSample){
                           case 8: while ((voice_get_position(vozRepe)>=0)&&(voice_get_position(vozRepe)<(contBufferRepe))&&(!keypressed())); break;
                           case 16: while ((voice_get_position(vozRepe)>=0)&&(voice_get_position(vozRepe)<(contBufferRepe>>1))&&(!keypressed())); break;
                          }
                          voice_stop(vozRepe);
                          deallocate_voice(vozRepe);
                          if (bitsSample==8) //Borro el SAMPLE
                           memset(sonidoRepe->data,0x80,(radioSample*segTope)+radioSample);
                          else
                           memset(sonidoRepe->data,0x80,((radioSample*segTope)+radioSample)<<1);
                         }
                         MostrarVideo(video_tx2rx);
                         PuertoSerie(puerto_com,FALSE); //Desactivo el PTT
                         //rest((parametroTXRX*1000));
                         EsperaActivaTeclado(parametroTXRX);
                         MostrarVideo(video_rx);
                         //play_sample(sonidoRepe,255,0x80,1000,FALSE);
                         if (modoFullDuplex==FALSE){
                          tamAnterior= tamBuffer; //Comienzo a grabar
                          tamBuffer = start_sound_input(radioSample,bitsSample,estereoSample);
                          if (tamBuffer!=tamAnterior)
                           RutinaError("Fallo memoria buffer al grabar en REPETIDOR\n");
                         }     
                         break;
         }
        }
        
        if ((grabarFicheroSonido==TRUE)&&(parametroLogRAW==TRUE)){        
         //printf ("*");
        /* for (i=0;i<(tamBuffer-1);i++){
          bufferSonido[i]/=16;//Lo empaqueto
          bufferSonido[i]=bufferSonido[i]<<4;
          bufferSonido[i+1]/=16;
          bufferSonido[i]=bufferSonido[i]||bufferSonido[i+1];
         }
         write (fichero,bufferSonido,(tamBuffer/2)); //Grabo solo datos de TX*/
         if (MeterArrayBuffer(bufferSonido,tamBuffer)==TRUE){
          write (fichero,arrayBuffer.buffer,(tamBuffer*tope_elementos));
          arrayBuffer.num= 0;
         }//fin if MeterArrayBuffer
         //write (fichero,bufferSonido,(tamBuffer));
        }//fin if grabarFicheroSonido==TRUE
       }//fin if numBytes!=0
       if ((balizaActiva==TRUE)&&(estado==fin)){
        if ((segundos-segBaliza)>= segundosBaliza){
         segBaliza= segundos;
         if (modoFullDuplex==FALSE) stop_sound_input(); //Paro de grabar
         PuertoSerie(puerto_com,TRUE); //Activo el PTT

         sonidoAuxBaliza= NULL;
         if (numeroIncidencias==0)
          sonidoAuxBaliza= datos_voz[SONIDO_0].dat;
         else
          if ((numeroIncidencias>20)&&(numeroIncidencias<30))
           sonidoAuxBaliza= datos_voz[SONIDO_20_y].dat;
          else
           if ((numeroIncidencias>30)&&(numeroIncidencias<40))
            sonidoAuxBaliza= datos_voz[SONIDO_30_y].dat;
           else
            if ((numeroIncidencias>40)&&(numeroIncidencias<50))
             sonidoAuxBaliza= datos_voz[SONIDO_40_y].dat;
            else
             if ((numeroIncidencias>50)&&(numeroIncidencias<60))
              sonidoAuxBaliza= datos_voz[SONIDO_50_y].dat;
             else
              if ((numeroIncidencias>60)&&(numeroIncidencias<70))
               sonidoAuxBaliza= datos_voz[SONIDO_60_y].dat;
              else
               if ((numeroIncidencias>70)&&(numeroIncidencias<80))
                sonidoAuxBaliza= datos_voz[SONIDO_70_y].dat;
               else
                if ((numeroIncidencias>80)&&(numeroIncidencias<90))
                 sonidoAuxBaliza= datos_voz[SONIDO_80_y].dat;
                else
                 if ((numeroIncidencias>90)&&(numeroIncidencias<100))
                  sonidoAuxBaliza= datos_voz[SONIDO_90_y].dat;

         MostrarVideo(video_repetidor);
         rest(parametroEsperaPTT); //Espera estabilizar PTT

         ReproducirSonidoVoz(datos_voz[SONIDO_OPERATIVO].dat,volumenMaestro);
         ReproducirSonidoVoz(datos_voz[SONIDO_INCIDENCIAS].dat,volumenMaestro);
         ReproducirSonidoVoz(sonidoAuxBaliza,volumenMaestro);
         sonidoAuxBaliza= NULL;
         
         if ((numeroIncidencias>9)&&(numeroIncidencias<21)){
          switch (numeroIncidencias){
           case 10: sonidoAuxBaliza= datos_voz[SONIDO_10].dat; break;
           case 11: sonidoAuxBaliza= datos_voz[SONIDO_11].dat; break;
           case 12: sonidoAuxBaliza= datos_voz[SONIDO_12].dat; break;
           case 13: sonidoAuxBaliza= datos_voz[SONIDO_13].dat; break;
           case 14: sonidoAuxBaliza= datos_voz[SONIDO_14].dat; break;
           case 15: sonidoAuxBaliza= datos_voz[SONIDO_15].dat; break;
           case 16: sonidoAuxBaliza= datos_voz[SONIDO_16].dat; break;
           case 17: sonidoAuxBaliza= datos_voz[SONIDO_17].dat; break;
           case 18: sonidoAuxBaliza= datos_voz[SONIDO_18].dat; break;
           case 19: sonidoAuxBaliza= datos_voz[SONIDO_19].dat; break;
           case 20: sonidoAuxBaliza= datos_voz[SONIDO_20].dat; break;
          }
         }
         else{
          switch (numeroIncidencias%10){
           case 1: sonidoAuxBaliza= datos_voz[SONIDO_1].dat; break;
           case 2: sonidoAuxBaliza= datos_voz[SONIDO_2].dat; break;
           case 3: sonidoAuxBaliza= datos_voz[SONIDO_3].dat; break;
           case 4: sonidoAuxBaliza= datos_voz[SONIDO_4].dat; break;
           case 5: sonidoAuxBaliza= datos_voz[SONIDO_5].dat; break;
           case 6: sonidoAuxBaliza= datos_voz[SONIDO_6].dat; break;
           case 7: sonidoAuxBaliza= datos_voz[SONIDO_7].dat; break;
           case 8: sonidoAuxBaliza= datos_voz[SONIDO_8].dat; break;
           case 9: sonidoAuxBaliza= datos_voz[SONIDO_9].dat; break;
          }//fin switch numeroIncidencias%10
          switch (numeroIncidencias){
           case 30: sonidoAuxBaliza= datos_voz[SONIDO_30].dat; break;
           case 40: sonidoAuxBaliza= datos_voz[SONIDO_40].dat; break;
           case 50: sonidoAuxBaliza= datos_voz[SONIDO_50].dat; break;
           case 60: sonidoAuxBaliza= datos_voz[SONIDO_60].dat; break;
           case 70: sonidoAuxBaliza= datos_voz[SONIDO_70].dat; break;
           case 80: sonidoAuxBaliza= datos_voz[SONIDO_80].dat; break;
           case 90: sonidoAuxBaliza= datos_voz[SONIDO_90].dat; break;
           case 100: sonidoAuxBaliza= datos_voz[SONIDO_100].dat; break;           
          }
          if (numeroIncidencias>100) sonidoAuxBaliza= datos_voz[SONIDO_MUCHOS].dat;
         } //fin else numeroIncidencias

         ReproducirSonidoVoz(sonidoAuxBaliza,volumenMaestro);
         MostrarVideo(video_tx2rx);
         PuertoSerie(puerto_com,FALSE); //Desactivo el PTT
         EsperaActivaTeclado(parametroTXRX);
         MostrarVideo(video_rx);
         
         if (modoFullDuplex==FALSE){
          tamAnterior= tamBuffer; //Comienzo a grabar
          tamBuffer = start_sound_input(radioSample,bitsSample,estereoSample);
          if (tamBuffer!=tamAnterior)
           RutinaError("Fallo memoria buffer al grabar en REPETIDOR\n");
         }//fin del if modo duplex
         sonidoAuxBaliza= NULL;
        }//fin if segundos-segBaliza
       }//fin de if baliza activa
      }//fin while!=keypressed
      if ((arrayBuffer.num != 0) && (arrayBuffer.num<tope_elementos)&&(parametroLogRAW==TRUE)){
       //Hay datos de sonido a grabar y los grabo
       write (fichero,arrayBuffer.buffer,(tamBuffer*arrayBuffer.num));
       arrayBuffer.num= 0;
      }//fin if arrayBuffer.num!=0
      if (ficheroLog!=NULL){ fclose(ficheroLog); ficheroLog= NULL;}
     }//fin if ficheroLog!=NULL
     close(fichero);
    }//fin if fichero>=0
    EliminaArrayBuffer(); //Elimino el Array de Sonidos
   }//fin if tamBuffer!=0
   else{
    RutinaError("No se ha podido crear buffer para grabar\n");
   }    

   stop_sound_input();
   if (bufferSonido!=NULL) { free(bufferSonido); bufferSonido = NULL; }

   remove_timer();
   remove_sound_input();
  }
  else{
   RutinaError("No se puede instalar para grabar\nCierre la aplicacion que usa el canal de sonido\n");
  }   

  remove_sound();
 }//fin else if install_sound_input
 else{
  RutinaError("No se puede instalar el controlador de sonido\n");
 }//fin else if install_sound

 //Deteccion de sonido con archivo RAW
/* tamanio = TamanioFichero("11khz2.raw");
 bufferPrueba = (unsigned char*)malloc(tamanio);
 LeerSonidoRaw("11khz2.raw",bufferPrueba,tamanio); //Lo leo
 media = 0;
 i=0;
 LOCK_VARIABLE(segundos);
 LOCK_FUNCTION(inc_segundos);
 install_int_ex(inc_segundos,SECS_TO_TIMER(1));
 
 segAntes= segDespues= segundos;
 estado = fin;

 while(i<tamanio){ //Lo detecto
  valor = bufferPrueba[i];
  if (valor<128) valor=128-valor; //La onda va en unsigned 8 bits
  else valor=valor-128;
//  if (valor>127) valor=valor-127;
  media = media+valor;
  if ((i%tamBuffer)==0){
   rest((tamBuffer/(float)radioSample)*1000); //Simula espera en tiempo real
   media=media/tamBuffer;
//   printf ("M:%d P:%d ",media,i/tamBuffer);
   if (media>10){ //Umbral
    switch (estado){
     case fin: if (sancionTope==FALSE){
                segAntes = segDespues = segundos; //Es cuando comienza
                estado = comienzo;
                segTX = segDespues;
                printf ("CTX %d ",segDespues);
                //Activamos PTT
               }
               else //Espera de 3 segundos
                if ((segundos-segTX)>2){
                 sancionTope= FALSE;
                }
               break;
     case comienzo: segAntes=segDespues= segundos;
                    if ((segDespues-segTX) >= segTope){
                     //Comprobamos que no se pasa del tope de TX en segundos
                     sancionTope=TRUE;
                     segTX= segDespues;
                     printf("Tope %d FTX ",segDespues);
                     //Desactivo PTT
                     estado= fin;
                    }
                    break;
    }
   }
   else{
    switch (estado){
     case fin: break;
     case comienzo: segDespues= segundos;
                    if ((segDespues-segAntes)>0){ //Espera de 1 segundo
                     segAntes=segDespues;
                     printf("FTX %d ",segDespues);
                     estado=fin;
                     //Desactivamos PTT
                    }
                    break;
    }   
   }
   
   media=0;
  }
  //printf ("%d ",bufferPrueba[i]);
  i++;
//  printf ("%d ",bufferPrueba[i]);
//  if (bufferPrueba[i]>=50) printf ("S");
 }*/

 if (parametroEfecto != nulo){//Se elimina el buffer temporal de video
  if (videoTemporal!=NULL){ destroy_bitmap(videoTemporal); videoTemporal=NULL; }
  if (capturaPantalla!=NULL){ destroy_bitmap(capturaPantalla); capturaPantalla=NULL; }
 }

 remove_int(inc_segundos);
 
// if (bufferPrueba!=NULL){ free(bufferPrueba); bufferPrueba= NULL; }

 if (datos_graficos!=NULL){ unload_datafile(datos_graficos); datos_graficos= NULL; }
 if (balizaActiva==TRUE){
  if (datos_voz!=NULL){ unload_datafile(datos_voz); datos_voz= NULL; }
 }

 if (parametroRepe==TRUE){
  //if (bufferAudioRepe!=NULL){ free(bufferAudioRepe);bufferAudioRepe=NULL;}
  if (sonidoRepe!=NULL){ destroy_sample(sonidoRepe); sonidoRepe= NULL;}
 }


 PuertoSerie(puerto_com,FALSE); //Desactivo el PTT,xk hay casos de error
 
 #ifdef ALLEGRO_DOS
  if (puerto_com != NULO) EliminarPuertoSerie();
 #endif

 #ifdef ALLEGRO_LINUX
  if (puerto_com != NULO) EliminarPuertoSerie();
 #endif

 #ifdef ALLEGRO_WINDOWS
  if (puerto_com != NULO) EliminaPuertoSerieWin();
 #endif


 remove_mouse();
 remove_timer();
 remove_keyboard();

 set_gfx_mode(GFX_TEXT,80,25,0,0);

 allegro_exit();
 return(0);
}

END_OF_MAIN();
