def reduc(self): """ First target reduction of too close points. """ # initialisations # --------------- xdist = [] ydist = [] dist = [] for i in range(self.nval): xdist.append(-1.) ydist.append(-1.) dist.append(-1.) lf = int(self.lfen2 / 2) xds = yds = 0. np = 0 # xdist and ydist estimations for i in range(self.nval-1): # j1 and j2 estimations (interval min and max values) j1 = 0 if (i > lf): j1 = i - lf j2 = self.nval - 1 if (i+lf < self.nval-1): j2 = i + lf # left (g means left) sxg = syg = 0. ng = 0 for j in range(j1,i+1): if (self.cib[j].get_y() > self.SEUILV): sxg = sxg + self.cib[j].get_x() syg = syg + self.cib[j].get_y() ng = ng + 1 # right (d means right) sxd = syd = 0. nd = 0 for j in range(i+1,j2): if (self.cib[j].get_y() > self.SEUILV): sxd = sxd + self.cib[j].get_x() syd = syd + self.cib[j].get_y() nd = nd + 1 # xdist[i] and ydist[i] evaluations if (nd * ng > 0): xdist[i] = math.fabs (sxg / ng - sxd / nd) ydist[i] = math.fabs (syg / ng - syd / nd) xds = xds + xdist[i] yds = yds + ydist[i] np = np + 1 # end for if np==0 or xds==0. or yds==0.: raise ValueError('Not enough targets with a value more than '+str(self.SEUILV)+' hz \n') # dist estimation (on pondere par la distance moyenne) # ---------------------------------------------------- px = float(np) / xds py = float(np) / yds for i in range(self.nval): if (xdist[i] > 0.): dist[i] = (xdist[i] * px + ydist[i] * py) / (px + py) # Cherche les maxs des pics de dist > seuil # ----------------------------------------- # Seuil = moy des dist ponderees seuil = 2. / (px + py) susseuil = False # Add the start value (=0) xd = [] xd.append(0) xmax = 0 for i in range(self.nval): if (len(xd) > int(self.nval/2)): raise Exception('Too many partitions (',len(xd),')\n') if (susseuil == False): if (dist[i] > seuil): susseuil = True xmax = i else: if (dist[i] > dist[xmax]): xmax = i if (dist[i] < seuil and xmax > 0): xd.append(xmax) susseuil = False # end for # do not forget the last analyzed value! if (susseuil == True): xd.append(xmax) # Add the final value (=nval) xd.append(self.nval) # Partition sur les x # ------------------- for ip in range(len(xd)-1): # bornes partition courante parinf = xd[ip] parsup = xd[ip + 1] sx = sx2 = sy = sy2 = 0. n = 0 # moyenne sigma for j in range(parinf,parsup): # sur la pop d'une partition if (self.cib[j].get_y() > 0.): sx = sx + self.cib[j].get_x() sx2 = sx2 + self.cib[j].get_x() * self.cib[j].get_x() sy = sy + self.cib[j].get_y() sy2 = sy2 + self.cib[j].get_y() * self.cib[j].get_y() n = n + 1 # pour la variance if (n > 1): xm = float(sx) / float(n) ym = float(sy) / float(n) varx = float(sx2) / float(n) - xm * xm vary = float(sy2) / float(n) - ym * ym if (varx <= 0.): # cas ou variance devrait etre == +epsilon varx = 0.1 if (vary <= 0.): vary = 0.1 et2x = self.FSIGMA * math.sqrt (varx) et2y = self.FSIGMA * math.sqrt (vary) seuilbx = xm - et2x seuilhx = xm + et2x seuilby = ym - et2y seuilhy = ym + et2y # Elimination (set cib to 0) for j in range(parinf,parsup): if (self.cib[j].get_y() > 0. and (self.cib[j].get_x() < seuilbx or self.cib[j].get_x() > seuilhx or self.cib[j].get_y() < seuilby or self.cib[j].get_y() > seuilhy)): self.cib[j].set_x(0.) self.cib[j].set_y(0.) # Recalcule moyennes # ------------------ sx = sy = 0. n = 0 for j in range(parinf,parsup): if (self.cib[j].get_y() > 0.): sx = sx + self.cib[j].get_x() sy = sy + self.cib[j].get_y() n = n + 1 # Reduit la liste des cibles if (n > 0): cibred_cour = Targets() cibred_cour.set(sx/n, sy/n, n) ncibr = len(self.cibred) - 1 if (ncibr < 0 ): ncibr = 0 self.cibred.append(cibred_cour) else: # si les cibred[].x ne sont pas strictement croissants # on ecrase la cible ayant le poids le moins fort if (cibred_cour.get_x() > self.cibred[ncibr].get_x()): # 1 cibred en + car t croissant ncibr = ncibr + 1 self.cibred.append(cibred_cour) else: # t <= precedent if (cibred_cour.get_p() > self.cibred[ncibr].get_p()): # si p courant >, ecrase la precedente self.cibred[ncibr].set(cibred_cour.get_x(),cibred_cour.get_y(),cibred_cour.get_p())
def borne(self): """ borne. Principes: calcul borne G (D) si 1ere (derniere) cible est ( > (debut_voisement+halo) ) ( < (fin_voisement -halo) ) ce pt de debut(fin) voisement == frontiere cible extremite == ancre regression quadratique sur Hz de [frontiere ancre] """ halo = self.HALO_BORNE_TRAME ancre = Targets() borne = Targets() # Borne gauche # ------------ # Recherche 1er voise premier_voise=0 while(premier_voise < self.nval and self.hzptr[premier_voise] < self.SEUILV): premier_voise = premier_voise + 1 if( int(self.cibred2[0].get_x()) > (premier_voise + halo) ): # origine des t : ancre.x, et des y : ancre.y ancre = self.cibred2[0] sx2y = 0. sx4 = 0. j = 0 for i in range( int(ancre.get_x()),0): if (self.hzptr[i] > self.SEUILV): x2 = float(j)*float(j) sx2y = sx2y + (x2* (self.hzptr[i] - ancre.get_y())) sx4 = sx4 + (x2*x2) j = j + 1 frontiere = float(premier_voise) a = 0. if sx4 > 0.: a = sx2y / sx4 borne.set_x( frontiere - (ancre.get_x() - frontiere ) ) borne.set_y( ancre.get_y() + (2 * a * (ancre.get_x() - frontiere)*(ancre.get_x() - frontiere)) ) # recherche dernier voisement dernier_voise = self.nval - 1 while ( dernier_voise >=0 and self.hzptr[dernier_voise] < self.SEUILV): dernier_voise = dernier_voise - 1
def cible(self): """ Find momel target points. """ if len(self.hzptr)==0: raise IOError('Momel::momel.py. IOError: empty pitch array') if (self.hzsup < self.hzinf): raise ValueError('Momel::momel.py. Options error: F0 ceiling > F0 threshold') pond = [] pondloc = [] # local copy of pond hzes = [] for ix in range(self.nval): hzes.append(0.) if (self.hzptr[ix] > self.SEUILV): pond.append(1.0) pondloc.append(1.0) else: pond.append(0.0) pondloc.append(0.0) # Examinate each pitch value for ix in range(self.nval): # Current interval to analyze: from dpx to fpx dpx = ix - int(self.lfen1 / 2) fpx = dpx + self.lfen1 + 1 # BB: do not go out of the range! if dpx < 0: dpx = 0 if fpx > self.nval: fpx = self.nval # copy original pond values for the current interval for i in range(dpx,fpx): pondloc[i] = pond[i] nsup = 0 nsupr = -1 xc = yc = 0.0 ret_rgp = True while nsup > nsupr: nsupr = nsup nsup = 0 try: # Estimate values of: a0, a1, a2 self.calcrgp(pondloc, dpx, fpx-1) except Exception: # if calcrgp failed. #print "calcrgp failed: ",e ret_rgp=False break else: # Estimate hzes for ix2 in range(dpx,fpx): hzes[ix2] = self.a0 + (self.a1 + self.a2 * float(ix2)) * float(ix2) for x in range(dpx,fpx): if (self.hzptr[x] == 0. or (hzes[x] / self.hzptr[x]) > self.maxec): nsup = nsup + 1 pondloc[x] = 0.0 # Now estimate xc and yc for the new 'cible' if (ret_rgp==True and self.a2 != 0.0): vxc = (0.0 - self.a1) / (self.a2 + self.a2) if ((vxc > ix - self.lfen1) and (vxc < ix + self.lfen1)): vyc = self.a0 + (self.a1 + self.a2 * vxc) * vxc if (vyc > self.hzinf and vyc < self.hzsup): xc = vxc yc = vyc c = Targets() c.set(xc,yc) self.cib.append(c)