#include "proto.h"
#include "phonemes.h"
#include "features.h"
#include "gen.h"

void
gen_plosive(phone,segdur,prev_feat,next_feat,next_phone)
int phone;
int segdur;
unsigned long prev_feat;
unsigned long next_feat;
int next_phone;
{unsigned long features  = Features[phone];
 int j, time_count, time_const, off;
 float f0_temp, f1_temp, f2_temp, f3_temp, bw1_temp, bw2_temp, bw3_temp;
 float av_temp;

 if ((features & VOICE) && !(next_feat & VOWEL))
  av[0] -= 20;

 if (phone == pGG || phone == pGP)
  av[0] -= 10;

 if (next_feat != -1)
  {
   if (next_feat & VOWEL)
    {
     translate_phone(next_phone, &off);
     f1[1] = (float) Vowels[off][0][F1];
     f2[1] = (float) Vowels[off][0][F2];
     f3[1] = (float) Vowels[off][0][F3];
     bw1[1] = (float) Vowels[off][0][BW1];
     bw2[1] = (float) Vowels[off][0][BW2];
     bw3[1] = (float) Vowels[off][0][BW3];
    }
   else if (next_feat & SONOR)
    {
     translate_phone(next_phone, &off);
     f1[1] = (float) Sonorants[off][F1];
     f2[1] = (float) Sonorants[off][F2];
     f3[1] = (float) Sonorants[off][F3];
     bw1[1] = (float) Sonorants[off][BW1];
     bw2[1] = (float) Sonorants[off][BW2];
     bw3[1] = (float) Sonorants[off][BW3];
    }
  }
 if (prev_feat != -1)
  {
   /* voice onset time = 4 frames = 40 ms*/
   if (prev_feat & VOICE)
    {
     for (j = 0; j < 4; j++)
      {
       Frames[total_frame_count].f0 = LastTarget.f0;
       Frames[total_frame_count].f1 = LastTarget.f1;
       Frames[total_frame_count].f2 = LastTarget.f2;
       Frames[total_frame_count].f3 = LastTarget.f3;
       Frames[total_frame_count].bw1 = LastTarget.bw1;
       Frames[total_frame_count].bw2 = LastTarget.bw2;
       Frames[total_frame_count].bw3 = LastTarget.bw3;
       Frames[total_frame_count].fnz = LastTarget.fnz;
       Frames[total_frame_count].fnp = LastTarget.fnp;;
       Frames[total_frame_count].av = 0;
       Frames[total_frame_count].tlt = 0;
       Frames[total_frame_count].asp = 0;
       Frames[total_frame_count].af = 0;
       Frames[total_frame_count].a1 = LastTarget.a1;
       Frames[total_frame_count].a2 = LastTarget.a2;
       Frames[total_frame_count].a3 = LastTarget.a3;
       Frames[total_frame_count].a4 = LastTarget.a4;
       Frames[total_frame_count].a5 = LastTarget.a5;
       Frames[total_frame_count].a6 = LastTarget.a6;
       Frames[total_frame_count++].ab = LastTarget.ab;
      }
    }
  }

 if (phone == pBB || phone == pDD)
  time_const = segdur * 2;
 else
  time_const = segdur;

 time_count = 0;
 f0_temp = f0[0];
 f1_temp = f1[0];
 f2_temp = f2[0];
 f3_temp = f3[0];
 bw1_temp = bw1[0];
 bw2_temp = bw2[0];
 bw3_temp = bw3[0];
 av_temp = av[0];

 for (j = 0; j < segdur; j += 10)
  {
   Frames[total_frame_count].f0 = (int) f0_temp;
   Frames[total_frame_count].f1 = (int) f1_temp;
   Frames[total_frame_count].f2 = (int) f2_temp;
   Frames[total_frame_count].f3 = (int) f3_temp;
   Frames[total_frame_count].bw1 = (int) bw1_temp;
   Frames[total_frame_count].bw2 = (int) bw2_temp;
   Frames[total_frame_count].bw3 = (int) bw3_temp;
   Frames[total_frame_count].fnz = (int) fnz;
   Frames[total_frame_count].fnp = (int) fnp;
   Frames[total_frame_count].av = (int) av_temp;
   Frames[total_frame_count].tlt = 0;
   Frames[total_frame_count].asp = (int) asp;
   Frames[total_frame_count].af = (int) af;
   Frames[total_frame_count].a1 = (int) a1;
   Frames[total_frame_count].a2 = (int) a2;
   Frames[total_frame_count].a3 = (int) a3;
   Frames[total_frame_count].a4 = (int) a4;
   Frames[total_frame_count].a5 = (int) a5;
   Frames[total_frame_count].a6 = (int) a6;
   Frames[total_frame_count].ab = (int) ab;

   if (next_feat != -1)
    if ((next_feat & VOWEL) || (next_feat & SONOR))
     {
      if (phone == pGP || phone == pGG)
       av_temp -= 3;
      if (phone == pBB || phone == pDD)
       av_temp -= 5;

      f0_temp = gen_curve(f0[0], f0[1], time_const / 4, time_count);
      f1_temp = gen_curve(f1[0], f1[1], time_const / 4, time_count);
      f2_temp = gen_curve(f2[0], f2[1], time_const / 4, time_count);
      f3_temp = gen_curve(f3[0], f3[1], time_const / 4, time_count);
      bw1_temp = gen_curve(bw1[0], bw1[1], time_const / 4, time_count);
      bw2_temp = gen_curve(bw2[0], bw2[1], time_const / 4, time_count);
      bw3_temp = gen_curve(bw3[0], bw3[1], time_const / 4, time_count);
      time_count += 10;
     }

   switch (phone)
    {
     case pPP:
      {
       if (j == 20)
        Frames[total_frame_count].af = 60;
       else if (j > 30 && j < 60)
        Frames[total_frame_count].asp = 60;
      }
      break;
     case pTT:
      {
       if (j == 10)
        Frames[total_frame_count].af = 55;
       if (j >= 10)
        Frames[total_frame_count].asp = 45;
      }
      break;
     case pTQ:
      {
       if (j == 20)
        Frames[total_frame_count].af = 51;
       if (j >= 20)
        Frames[total_frame_count].asp = 51;
      }
      break;
     case pKK:
      {
       if (j == 0)
        Frames[total_frame_count].af = 45;
      }
      break;
     case pKP:
      {
       /* voice onset for /Kh/ = 60ms */
       if (j == 0)
        Frames[total_frame_count].af = 55;
       else
        Frames[total_frame_count].asp = 50;
      }
      break;
     case pGG:
      {
       /* voice onset = 10ms */
       if (j >= (segdur - 10))
        Frames[total_frame_count].av = 0;
      }
      break;
     case pGP:
      {
       /* voice onset = 10ms */
       if (j >= (segdur - 10))
        {
         Frames[total_frame_count].av = 0;
         Frames[total_frame_count].asp = 55;
        }
      }
      break;
     case pBB:
      {
       if (j < 10 || j > 40)
        Frames[total_frame_count].av = 0;
       if (j >= 20)
        Frames[total_frame_count].asp = 40;
      }
      break;
     case pDD:
      {
       if (j < 10)
        {
         Frames[total_frame_count].av = 0;
        }
      }
      break;
     case pJJ:
      {
       if (j == 0 || j == 10)
        {
         Frames[total_frame_count].asp = 60;
        }
       if (j <= 40 && j > 0)
        {
         Frames[total_frame_count].av = 60;
        }
      }
      break;
     case pCH:
      {
       /* voice onset for /Kh/ = 60ms */
       if (j == 0)
        Frames[total_frame_count].af = 55;
       else
        Frames[total_frame_count].asp = 50;
      }
      break;
    }
   total_frame_count++;
  }
 /* retain block copy till we make LastTarget a pointer */
 LastTarget = Frames[total_frame_count - 1];
}
