00001 #include "c_lpc10.h" 00002 00003 /**********************************************************/ 00004 /* Place the Analysis window based on the voicing window placement, 00005 onsets, tentative voicing decision, and pitch. Place also energy window. 00006 00007 Case 1: Sustained Voiced Speech 00008 If the five most recent voicing decisions are 00009 voiced, then the window is placed phase-synchronously with the 00010 previous window, as close to the present voicing window if possible. 00011 If onsets bound the voicing window, then preference is given to 00012 a phase-synchronous placement which does not overlap these onsets. 00013 00014 Case 2: Voiced Transition 00015 If at least one voicing decision in AF is voiced, and there are no 00016 onsets, then the window is placed as in case 1. 00017 00018 Case 3: Unvoiced Speech or Onsets 00019 If both voicing decisions in AF are unvoiced, or there are onsets, 00020 then the window is placed coincident with the voicing window. 00021 00022 Note: During phase-synchronous placement of windows, the length 00023 is not altered from MAXWIN, since this would defeat the purpose 00024 of phase-synchronous placement. 00025 00026 Inputs: 00027 . ipitch - pitch in current frame 00028 . voibuf[AF+1][2] - voicing decision for half-frames. 00029 . obound - number of onsets in current frame 00030 . vwin[AF][2] - voicing window position 00031 Outputs: 00032 . awin[AF][2] - analysis window position 00033 . ewin[2] - energy window position for current frame (ewin[AF-1]) 00034 Constants: 00035 . LFRAME - analysis frame length (frame rate) 00036 . MAXWIN - max. analysis window length 00037 . LRANGE - low limit for window placement 00038 . HRANGE - high limit for window placement */ 00039 00040 VOID placea( INDEX ipitch, BOOL voibuf[AF+1][2], INDEX obound, 00041 INDEX vwin[AF][2], INDEX awin[AF][2], INDEX ewin[2] ) 00042 { 00043 #define LRANGE ((AF-2)*LFRAME + 1) 00044 #define HRANGE (AF*LFRAME) 00045 INDEX i, j, k; 00046 BOOL ephase, winv, allv; 00047 00048 /* Check for case 1 and case 2 */ 00049 allv = voibuf[AF-2][1] 00050 && voibuf[AF-1][0] && voibuf[AF-1][1] 00051 && voibuf[AF][0] && voibuf[AF][1]; 00052 00053 winv = (voibuf[AF][0] || voibuf[AF][1]); 00054 00055 if (allv || (winv && (obound == 0))) { 00056 /* APHASE: Phase synchronous window placement. 00057 Get minimum lower index of the window. */ 00058 i = ((LRANGE-1) - awin[AF-2][0] + ipitch ) / ipitch; 00059 i = i * ipitch + awin[AF-2][0]; 00060 /* MAXWIN = the actual length of this frame's analysis window. */ 00061 /* Calculate the location where a perfectly centered window would start. */ 00062 k = (vwin[AF-1][0] + vwin[AF-1][1] - (MAXWIN-1)) >> 1; /* IDIV 2 */ 00063 /* Choose the actual location to be the pitch multiple 00064 closest to this: round((k-i)/ipitch) */ 00065 awin[AF-1][0] = (k>i) ? 00066 i + (INDEX)((2* (k - i) + ipitch) / (2 * ipitch)) * ipitch 00067 : i; 00068 awin[AF-1][1] = awin[AF-1][0] + (MAXWIN-1); 00069 /* If there is an onset bounding the right of the voicing window and the 00070 analysis window overlaps that, then move the analysis window backward 00071 to avoid this onset. */ 00072 if ((obound >= 2) && (awin[AF-1][1] > vwin[AF-1][1])) { 00073 awin[AF-1][0] -= ipitch; 00074 awin[AF-1][1] -= ipitch; 00075 } 00076 /* Similarly for the left of the voicing window. */ 00077 if (((obound == 1) || (obound == 3)) 00078 && (awin[AF-1][0] < vwin[AF-1][0])) { 00079 awin[AF-1][0] += ipitch; 00080 awin[AF-1][1] += ipitch; 00081 } 00082 /* If this placement puts the analysis window above HRANGE, then 00083 move it backward an integer number of pitch periods. */ 00084 while (awin[AF-1][1] > HRANGE) { 00085 awin[AF-1][0] -= ipitch; 00086 awin[AF-1][1] -= ipitch; 00087 } 00088 /* Similarly if the placement puts the analysis window below LRANGE. */ 00089 while (awin[AF-1][0] < LRANGE) { 00090 awin[AF-1][0] += ipitch; 00091 awin[AF-1][1] += ipitch; 00092 } 00093 /* Make Energy window be phase-synchronous. */ 00094 ephase = TRUE; 00095 } 00096 else { /* Case 3 */ 00097 awin[AF-1][0] = vwin[AF-1][0]; 00098 awin[AF-1][1] = vwin[AF-1][1]; 00099 ephase = FALSE; 00100 } 00101 00102 /* RMS is computed over an integer number of pitch periods in the analysis 00103 window. When it is not placed phase-synchronously, it is placed as close 00104 as possible to onsets. */ 00105 if (winv==0) { 00106 ewin[0] = vwin[AF-1][0]; 00107 ewin[1] = vwin[AF-1][1]; 00108 } 00109 else { 00110 j = (INDEX)((awin[AF-1][1] - awin[AF-1][0] + 1) / ipitch) * ipitch; 00111 if (j==0) { 00112 ewin[0] = vwin[AF-1][0]; 00113 ewin[1] = vwin[AF-1][1]; 00114 } 00115 else if ((ephase==0) && (obound == 2)) { 00116 ewin[0] = awin[AF-1][1] - j + 1; 00117 ewin[1] = awin[AF-1][1]; 00118 } 00119 else { 00120 ewin[0] = awin[AF-1][0]; 00121 ewin[1] = awin[AF-1][0] + j - 1; 00122 } 00123 } 00124 } 00125 00126 /**********************************************************/