00001 #include "c_lpc10.h" 00002 00003 /**********************************************************/ 00004 /* Voicing window placement. 00005 00006 Arguments 00007 . osbuf - Buffer which holds sorted indexes of onsets 00008 . osptr - Free pointer into {osbuf} 00009 . vwin - Buffer of Voicing Window Positions (Modified) 00010 . obound - This variable is set by this procedure and used 00011 . in placing analysis windows (placea). Bit 1 00012 . indicates whether an onset bounds the left side 00013 . of the voicing window, and bit 2 indicates whether 00014 . an onset bounds the right side of the voicing window. 00015 Variables 00016 . lrange, hrange - Range in which window is placed 00017 . osptr1 - {osptr} excluding samaples in 3F 00018 00019 Voicing Window Placement 00020 . 00021 . __________________ __________________ ______________ 00022 . | | | 00023 . | 1F | 2F | 3F ... 00024 . |__________________|__________________|______________ 00025 . 00026 . Previous | 00027 . Window | 00028 . ...________| 00029 . 00030 . | | 00031 . ------>| This window's placement range |<------ 00032 . | | 00033 . 00034 . There are three cases. Note that these are different from those 00035 . given in the LPC-10e phase 1 report. 00036 . 00037 . 1. If there are no onsets in this range, then the voicing window 00038 . is centered in the pitch window. If such a placement is not within 00039 . the window's placement range, then the window is placed in the left- 00040 . most portion of the placement range. Its length is always MAXWIN. 00041 . 00042 . 2. If the first onset is in 2F and there is sufficient room to place 00043 . the window immediately before this onset, then the window is placed 00044 . there, and its length is set to the maximum possible under these 00045 . constraints. 00046 . 00047 . "Critical Region Exception": If there is another onset in 2F 00048 . such that a window can be placed between the two onsets, the 00049 . window is placed there (ie, as in case 3). 00050 . 00051 . 3. Otherwise, the window is placed immediately AFter the onset. The 00052 . window's length 00053 . is the longest length that can fit in the range under these constraints, 00054 . except that the window may be shortened even further to avoid overlapping 00055 . other onsets in the placement range. In any case, the window's length 00056 . is at least MINWIN. 00057 . 00058 . Note that the values of MINWIN and LFRAME must be chosen such 00059 . that case 2 = false implies case 3 = true. This means that 00060 . MINWIN <= LFRAME/2. If this were not the case, then a fourth case 00061 . would have to be added for when the window cannot fit either before 00062 . or AFter the onset. 00063 . 00064 . Note also that onsets which weren't in 2F last time may be in 1F this 00065 . time, due to the filter delays in computing onsets. The result is that 00066 . occasionally a voicing window will overlap that onset. The only way 00067 . to circumvent this problem is to add more delay in processing input 00068 . speech. In the trade-off between delay and window-placement, window 00069 . placement lost. */ 00070 00071 VOID placev( INDEX osbuf[OSLEN], INDEX osptr, 00072 INDEX* obound, INDEX vwin[AF][2] ) 00073 { 00074 INDEX lrange, hrange, i, q, osptr1, tmp; 00075 BOOL crit; 00076 00077 /* Compute the placement range */ 00078 lrange = ((vwin[AF-2][1] > (AF-2)*LFRAME) 00079 ? vwin[AF-2][1]+1 : (AF-2)*LFRAME+1); 00080 hrange = AF * LFRAME; 00081 00082 /* Compute OSPTR1, so the following code only looks at relevant onsets. */ 00083 for (osptr1 = osptr; osptr1 > 0; osptr1--) { 00084 if (osbuf[osptr1 - 1] <= hrange) 00085 break; 00086 } 00087 00088 /* Check for case 1 first (fast case): */ 00089 if ((!osptr1) || (osbuf[osptr1 - 1] < lrange)) { 00090 vwin[AF-1][0] = (vwin[AF-2][1]>=DVWINL)?vwin[AF-2][1]+1:DVWINL; 00091 vwin[AF-1][1] = vwin[AF-1][0] + MAXWIN - 1; 00092 *obound = 0; 00093 } 00094 else { 00095 /* Search backward in OSBUF for first onset in range. 00096 This code relies on the above check being performed first. */ 00097 for (q = osptr1-1; q > 0; q--) { 00098 if (osbuf[q-1] < lrange) 00099 break; 00100 } 00101 00102 /* Check for case 2 (placement before onset): 00103 Check for critical region exception: */ 00104 crit = FALSE; 00105 for (i = q + 1; i < osptr1; i++) { 00106 if (osbuf[i] - osbuf[q] >= MINWIN) { 00107 crit = TRUE; 00108 break; 00109 } 00110 } 00111 00112 tmp = lrange+(MINWIN-1); 00113 if ((crit==FALSE)&&(osbuf[q]> MMAX((AF-1)*LFRAME, tmp))) { 00114 vwin[AF-1][1] = osbuf[q] - 1; 00115 tmp = vwin[AF-1][1] - (MAXWIN-1); 00116 vwin[AF-1][0] = MMAX(lrange, tmp); 00117 *obound = 2; 00118 } 00119 00120 /* Case 3 (placement after onset) */ 00121 else { 00122 vwin[AF-1][0] = osbuf[q]; 00123 00124 while (1) { 00125 q++; 00126 if (q < osptr1) { 00127 if (osbuf[q] <= vwin[AF-1][0] + MAXWIN) { 00128 if (osbuf[q] < vwin[AF-1][0] + MINWIN) 00129 continue; 00130 vwin[AF-1][1] = osbuf[q] - 1; 00131 *obound = 3; 00132 } 00133 else { 00134 tmp = vwin[AF-1][0] + MAXWIN - 1; 00135 vwin[AF-1][1] = MMIN(tmp, hrange); 00136 *obound = 1; 00137 } 00138 } 00139 else { 00140 tmp = vwin[AF-1][0] + MAXWIN - 1; 00141 vwin[AF-1][1] = MMIN(tmp, hrange); 00142 *obound = 1; 00143 } 00144 break; 00145 } /* while */ 00146 } 00147 } 00148 } 00149 00150 /**********************************************************/