#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <math.h>
#include <unistd.h>
#include <errno.h>
#define MINIMUM_ELEMENTS 6
#define MAXIMUM_ELEMENTS 40
#define MOVING_AVERAGE 2
static int fd_fifocr = -1;
static const char *fifocr="kbfifo_c";
void cwprt(int numel, int wsp, int didah[], float peak, int freq,
           int num_min);
static int write_to_fifocr(char *s1, int wspace);

int main()
{
  int i, nl, dtzndz[8], num_line[16], numx20, sumc, freq;
  int j=-1, numc=0, nums=1000, num_min=25, wordsp=0, done=0, numx=0;
  int sumnl[MOVING_AVERAGE]={25, 25};
  int n=MOVING_AVERAGE-1;
  char buffer[64];
  float dum, sum20, scdat, hfpeak;
  float peak=1.6, pmx=0.;

  fd_fifocr = open(fifocr, O_WRONLY);
  if(fd_fifocr<0)
   {
    printf("cannot open %s\n", fifocr);
    exit(2);
   }
  fgets(buffer, sizeof(buffer), stdin);
  fgets(buffer, sizeof(buffer), stdin);
  for( ; ; )
   {
    sum20 = 0.;
    numx20 = 0;
    for(i=0; i<20; i++)
     {
      if(fscanf(stdin, "%f%f", &dum, &scdat)==EOF)
       {
        close(fd_fifocr);
        exit(1);
       }
      sum20 += fabsf(scdat);
      if((pmx>=0. && scdat<0.) || (pmx<0. && scdat>=0.))
       {
        numx20++;
        pmx = scdat;
       }
     }
    if(sum20>peak)
     peak = sum20;
    else if(peak>1.6)
     peak *= .999;
    hfpeak = .5*peak;
    if(!nums)
     {
      if(sum20>=hfpeak)
       {
        numc++;
        numx += numx20;
       }
      else
       {
        if(numc>=MINIMUM_ELEMENTS)
         {
          j++;
          num_line[j] = numc;
          nums = 1;
         }
        numc = 0;
       }
     }
    else
     {
      if(sum20<hfpeak)
       {
        nums++;
        if(j>-1)
         {
          if(nums>2*num_min)
           done = 1;
         }
        else if(nums>(19*num_min)/4)
         wordsp = 1;
       }
      else
       {
        if(nums<MINIMUM_ELEMENTS)
         {
          numc = num_line[j]+nums;
          j--;
          nums = 0;
         }
        else
         {
          if(j>-1)
           {
            j++;
            num_line[j] = nums;
            if(j==15)
             done = 1;
           }
          nums = 0;
          numc = 1;
          numx += numx20;
         }
       }
     }
    if(done)
     {
      nl = 0;
      n++;
      n %= MOVING_AVERAGE;
      sumnl[n] = 0;
      sumc = 0;
      for(i=0; i<=j; i++)
       {
        if(i%2)
         {
          sumnl[n] += num_line[i];
          nl++;
         }
        else
         {
          sumnl[n] += num_line[i];
          sumc += num_line[i];
          nl++;
          if(num_line[i]>(3*num_min)/2)
           {
            dtzndz[i/2] = 1;
            nl += 2;
           }
          else
           dtzndz[i/2] = 0;
         }
       }
      sumnl[n] /= nl;
      if(sumnl[n]<MINIMUM_ELEMENTS)
       sumnl[n] = (3*MINIMUM_ELEMENTS)/2;
      else if(sumnl[n]>MAXIMUM_ELEMENTS)
       sumnl[n] = (3*MAXIMUM_ELEMENTS)/4;
      freq = (200*numx)/sumc;
      if(freq>790)
       freq = 790;
      else if(freq<410)
       freq = 410;
      cwprt(j, wordsp, dtzndz, peak, freq, num_min);
      num_min = 0;
      for(i=0; i<MOVING_AVERAGE; i++)
       num_min += sumnl[i];
      num_min /= MOVING_AVERAGE;
      wordsp = 0;
      j = -1;
      done = 0;
      numc = 0;
      numx = 0;
     }
   }
  exit(0);
}

void cwprt(int numel, int wsp, int didah[], float peak, int freq,
           int num_min)
{
  int ivol;
  char nlpvfm[5];
  char nlp='*';

  switch (numel)
   {
    case 0 :
     if(didah[0])
      nlp = 'T';
     else
      nlp = 'E';
     break;
    case 2 :
     if(didah[0])
      {
       if(didah[1])
        nlp = 'M';
       else
        nlp = 'N';
      }
     else
      {
       if(didah[1])
        nlp = 'A';
       else
        nlp = 'I';
      }
     break;
    case 4 :
     if(didah[0])
      {
       if(didah[1])
        {
         if(didah[2])
          nlp = 'O';
         else
          nlp = 'G';
        }
       else
        {
         if(didah[2])
          nlp = 'K';
         else
          nlp = 'D';
        }
      }
     else
      {
       if(didah[1])
        {
         if(didah[2])
          nlp = 'W';
         else
          nlp = 'R';
        }
       else
        {
         if(didah[2])
          nlp = 'U';
         else
          nlp = 'S';
        }
      }
     break;
    case 6 :
     if(didah[0])
      {
       if(didah[1])
        {
         if(didah[2])
          {
           nlp = '#';
          }
         else
          {
           if(didah[3])
            nlp = 'Q';
           else
            nlp = 'Z';
          }
        }
       else
        {
         if(didah[2])
          {
           if(didah[3])
            nlp = 'Y';
           else
            nlp = 'C';
          }
         else
          {
           if(didah[3])
            nlp = 'X';
           else
            nlp = 'B';
          }
        }
      }
     else
      {
       if(didah[1])
        {
         if(didah[2])
          {
           if(didah[3])
            nlp = 'J';
           else
            nlp = 'P';
          }
         else
          {
           if(didah[3])
            nlp = '#';
           else
            nlp = 'L';
          }
        }
       else
        {
         if(didah[2])
          {
           if(didah[3])
            nlp = '#';
           else
            nlp = 'F';
          }
         else
          {
           if(didah[3])
            nlp = 'V';
           else
            nlp = 'H';
          }
        }
      }
     break;
    case 8 :
     if(didah[0])
      {
       if(didah[1])
        {
         if(didah[2])
          {
           if(didah[3])
            {
             if(didah[4])
              nlp = '0';
             else
              nlp = '9';
            }
           else
            {
             if(didah[4])
              nlp = '#';
             else
              nlp = '8';
            }
          }
         else
          {
           if(didah[3])
            nlp = '#';
           else
            {
             if(didah[4])
              nlp = '#';
             else
              nlp = '7';
            }
          }
        }
       else
        {
         if(didah[2])
          nlp = '#';
         else
          {
           if(didah[3])
            {
             if(didah[4])
              nlp = '#';
             else
              nlp = '/';
            }
           else
            {
             if(didah[4])
              nlp = '=';
             else
              nlp = '6';
            }
          }
        }
      }
     else
      {
       if(didah[1])
        {
         if(didah[2])
          {
           if(didah[3])
            {
             if(didah[4])
              nlp = '1';
             else
              nlp = '#';
            }
           else
            nlp = '#';
          }
         else
          {
           if(didah[3])
            {
             if(didah[4])
              nlp = '#';
             else
              nlp = '+';
            }
           else
            {
             if(didah[4])
              nlp = '#';
             else
              nlp = '$';
            }
          }
        }
       else
        {
         if(didah[2])
          {
           if(didah[3])
            {
             if(didah[4])
              nlp = '2';
             else
              nlp = '#';
            }
           else
            nlp = '#';
          }
         else
          {
           if(didah[3])
            {
             if(didah[4])
              nlp = '3';
             else
              nlp = '#';
            }
           else
            {
             if(didah[4])
              nlp = '4';
             else
              nlp = '5';
            }
          }
        }
      }
     break;
    case 10 :
     if(didah[0])
      {
       if(didah[1])
        if(!didah[2] && !didah[3])
         if(didah[4] && didah[5])
          nlp = ',';
      }
     else
      {
       if(!didah[1])
        {
        if(didah[2] && didah[3])
         if(!didah[4] && !didah[5])
          nlp = '?';
        }
       else
        {
        if(!didah[2] && didah[3])
         if(!didah[4] && didah[5])
          nlp = '.';
        }
      }
     break;
   }
  ivol = peak*10.;
  ivol += 66;
  if(ivol>119)
   ivol = 119;
  nlpvfm[0] = ' ';
  nlpvfm[1] = nlp;
  nlpvfm[2] = -ivol;     //81-119
  nlpvfm[3] = -freq/10;  //41-79
  nlpvfm[4] = -num_min;  //6-40
  if(write_to_fifocr (nlpvfm, wsp)==EPIPE)
   {
    close(fd_fifocr);
    exit(1);
   }
}

static int write_to_fifocr(char *s1, int wspace)
{
  int ls1, iwrite;
  int nbytes=0, wtf=0;

  ls1 = wspace+4;
  while(nbytes<ls1)
   {
    iwrite = write(fd_fifocr, s1+nbytes+1-wspace, ls1-nbytes);
    if(iwrite>0)
     nbytes += iwrite;
    else
     {
      if(iwrite<0)
       wtf = errno;
      break;
     }
   }
  return wtf;
}
