7.6 La aplicación delay

La transmisión de datos a través de la red, o incluso a través de la pila de protocolos TCP/IP dentro de un mismo host introduce un retraso aperciable en la transmisión de las señales. Para poder controlar dicho retraso se ha implementado un sencillo programa en C llamado delay que retrasa la salida estándar respecto de la entrada estándar un número determinado de milisegundos. Más tarde veremos algún ejemplo de su uso.

7.6.1 delay.c

/******************************************************************************  
 * delay.c -- Retrasa la salida estándar respecto de la entrada estándar  
 *            un número determinado de milisegundos.  
 *  
 * gse. 2006.  
 *****************************************************************************/  
 
/******************************************************************************  
 *  
 * Ficheros cabecera.  
 *  
 *****************************************************************************/  
 
/* Entrada y salida de streams buffereados. */  
#include <stdio.h>  
 
/* Biblioteca de funciones estándar (exit(), EXIT_SUCCESS,  
   EXIT_FAILURE, ...) */  
#include <stdlib.h>  
 
/* Manipulación de cadenas y movimiento de memoria (memset(), ...). */  
#include <string.h>  
 
/* Biblioteca estándar de funciones relacionadas con el sistema  
   operativo Unix (read(), write(), getopt(), ...). */  
#include <unistd.h>  
 
/* Signals (interrupciones) (signal(), SIGINT). */  
#include <signal.h>  
 
/******************************************************************************  
 *  
 * Definiciones.  
 *  
 *****************************************************************************/  
 
/* Retraso por defecto (en milisegundos). */  
#define DELAY 500  
 
/* Frecuencia de muestreo por defecto. */  
#define RATE 44100  
 
/* Número de canales por defecto. */  
#define CHANNELS 2  
 
/* Bytes por muestra por defecto. */  
#define PRECISSION 2  
 
/******************************************************************************  
 *  
 * Variable globales.  
 *  
 *****************************************************************************/  
 
/******************************************************************************  
 *  
 * Funciones.  
 *  
 *****************************************************************************/  
 
/* Cuerpo principal del programa. */  
int main(int argc, char *argv[]) {  
  work(argc, argv);  
  return EXIT_SUCCESS;  
}  
 
work(int argc, char *argv[]) {  
 
  /* Si pulsamos CRTL+C, el programa acaba ejecutando la función  
     end(). */  
  void end() {  
    fprintf(stderr,"%s: CTRL+C detected. Exiting ... ",argv[0]);  
    fprintf(stderr,"done\n");  
    exit(EXIT_SUCCESS);  
  }  
  signal(SIGINT, end);  //activando la senal SIGINT  
 
  /* Retraso en segundos. */  
  float delay = DELAY;  
 
  /* Frecuencia de muestreo. */  
  int rate = RATE;  
 
  /* Canales. */  
  int channels = CHANNELS;  
 
  /* Precisión de las muestras (en bytes). */  
  int precission = PRECISSION;  
 
  int c;  
  while ((c = getopt (argc, argv, "d:r:c:p:")) != -1) {  
    switch (c) {  
    case ’d’:  
      delay = atof(optarg);  
      break;  
    case ’r’:  
      rate = atoi(optarg);  
      break;  
    case ’c’:  
      channels = atoi(optarg);  
      break;  
    case ’p’:  
      precission = atoi(optarg);  
      break;  
    case ’?’:  
      if (isprint (optopt))  
        fprintf (stderr, "Unknown option ‘-%c’.\n", optopt);  
      else  
        fprintf (stderr,  
                 "Unknown option character ‘\\x%x’.\n",  
                 optopt);  
      return 1;  
    default:  
      abort ();  
    }  
  }  
 
  fprintf(stderr,"%s: delay (in miliseconds) = \"%f\"\n",  
          argv[0],delay);  
  fprintf(stderr,"%s: sampling rate = \"%d\"\n",  
          argv[0],rate);  
  fprintf(stderr,"%s: number of channels = \"%d\"\n",  
          argv[0],channels);  
  fprintf(stderr,"%s: number of bytes per sample = \"%d\"\n",  
          argv[0],precission);  
 
  int buffer_size = (int)(delay*rate*channels*precission/1000.0);  
 
  fprintf(stderr,"%s: buffer size (in bytes) = \"%d\"\n",  
          argv[0],buffer_size);  
 
  char *buffer = (char *)malloc(buffer_size*sizeof(char));  
  char *beg_ptr = buffer;  
  char *end_ptr = buffer + buffer_size;  
 
  int i;  
  for(i=0; i<buffer_size; i++) {  
    buffer[i] = 0;  
  }  
 
  for(;;) {  
    /* Buffer con el audio */  
    //char buffer[BUFFER_SIZE];  
    /* Leémos la stdin */  
    char buff[512];  
    write(1, (void *)buffer, 512);  
    int bytes_read = read(0, (void *)buffer, 512);  
    buffer += bytes_read;  
    if(buffer >= end_ptr) buffer = beg_ptr;  
  }  
 
}