# -*- coding:gbk -*-
'''
ÕâÊÇÔÚget_pitch»ù´¡ÉÏ×ö¸Ä½øºóµÄpitchÌáÈ¡³ÌÐò
Ö÷ÒªÇø±ðÔÚÓÚroi_listµÄÌáÈ¡ÍêÈ«ÒÀÕÕstt±ß½çÀ´,²»¹ý×óÓÒÒô½ÚµÄbegt,endtÈÔÈ»ÊÇ.f0ÀïµÄ
(0)°ÑÔ­Ê¼ROIÔ­Ôò±ê×¼½µÖÁinterval > 200ms
(1)ÔÚclass ROIÀïÃæÌí¼ÓÒ»Ïîstt_roi = (stt_roi_begt,stt_roi_endt),³õÊ¼ÖµÎªNone
(2)find_ROIËã·¨
    time = (stt_roi_begt + stt_roi_endt)/2
    CENTER = (L.e + R.b)/2
    ¶ÔÓÚÃ¿Ò»¸ötime,ÕÒºÍtimeÀëµÃ×î½üµÄCENTER,Õâ¸öÔ­Ê¼ROI¾ÍÊÇ¶ÔÓ¦¸Ãstt_roi
    È»ºó°ÑÔ­Ê¼ROIÖÐÌí¼Óstt_roiÏî,ËùÓÐstt_roi¶¼ÓÐÁË¶ÔÓ¦Ö®ºó,É¾È¥roi_listÖÐÎ´ÄÜÆ¥Åästt_roiµÄÏî
(3)find_ROIÖÐ¾Í°ÑÒô½Ú¶ÔÓ¦µ½×Ö,Òò´Ëattach2zi¿ÉÒÔÉ¾µô²»ÒªÁË
³ýÁËfind_ROIº¯Êý¸Ä±äÖ®Íâ,Ö®ºóattach2spkÐèÒª¸Ä±ä(²»¸ÄÒ²¿ÉÒÔ),¿ÉÒÔÖ±½ÓÀûÓÃmake_train_fileÖÐ
¶ÔÓ¦Ëµ»°ÈËµÄËã·¨
'''
from __future__ import division
import re
import matplotlib.pyplot as plt
import numpy as np
import pickle
import os
import time
from copy import deepcopy
import win32com.client

class syllable():
    '''Òô½ÚÀà£¬f0_sequenceÊÇÃ¿Ò»Ö¡µÄf0ÐÎ³ÉµÄÐòÁÐ'''
    def __init__(self, begt='', endt='', f0_sequence=[], spk=""):
        if begt and endt and f0_sequence:
            self.begt = begt
            self.endt = endt
            self.f0_sequence = f0_sequence
            self.spk = spk  #Õâ¸öÒô½ÚµÄËµ»°ÈË
            self.zi = ""    #Õâ¸öÒô½Ú¶ÔÓ¦µÄÆ´Òô
    def __str__(self):
        return self.begt+' '+self.endt+' '+self.zi+' '+'spk:'+self.spk+' '+ \
            str(np.array(self.f0_sequence,dtype=np.float).mean())

class ROI():
    '''ROIÀà,×óÓÒ¸÷ÓÐÒ»¸öÒô½Ú,ÕâÀïµÄROIÖ¸µÄÊÇ´óÓÚ200msÍ£¶Ù´¦'''
    def __init__(self):
        self.LEFT = syllable()
        self.RIGHT = syllable()
        self.stt_roi = None
    def begt(self):
        '''·µ»ØintervalµÄ¿ªÊ¼Ê±¼ä'''
        return self.LEFT.endt
    def endt(self):
        '''·µ»ØintervalµÄ½áÊøÊ±¼ä'''
        return self.RIGHT.begt
    def __str__(self):
        return str(self.LEFT)+' '+str(self.RIGHT)

class spk_roi():
    '''ÕâÊÇ´æ´¢Ä³Ò»¸öËµ»°ÈËÔÚËùÓÐroi´¦µÄÒô½ÚÐÅÏ¢'''
    def __init__(self, spk=0, frame_seq=[]):
        self.spk = spk    #Ëµ»°ÈË
        self.frame_seq = frame_seq[:] #Ö¡µÄÐòÁÐ,´æ´¢Æ½»¬Ö®ºóµÄf0,°ÑÍ¬Ò»¸öËµ»°ÈËµÄÃ¿Ò»Ö¡¶¼·Å½øÀ´
        self.avg = 0    #Õâ¸öspkµÄf0Æ½¾ùÖµ
        self.sd = 0     #Õâ¸öspkµÄf0±ê×¼²î
    def __str__(self):
        return 'speaker'+self.spk+' ¾ùÖµ '+self.avg+' ±ê×¼²î ' + self.sd

class tone_roi():
    '''ÕâÊÇ´æ´¢Ä³Ò»ÖÖtoneÔÚËùÓÐroi´¦µÄÒô½ÚÐÅÏ¢'''
    def __init__(self, tone='', frame_seq=[]):
        self.tone = tone    #Òôµ÷,È¡Öµ·¶Î§'1','2','3','4'
        self.frame_seq = frame_seq[:] #ÕâµØ·½Ò»¶¨Òª¿½±´,²»È»Ö®ºóÐÞ¸ÄÕâ¸öÐòÁÐÊ±roi.LEFT.f0_sequenceÒ²±äÁË
        self.avg = 0    
        self.sd = 0     
    def __str__(self):
        return 'tone'+self.tone+' ¾ùÖµ '+self.avg+' ±ê×¼²î ' + self.sd

def pre_process(f0_file):    
    '''Ô­À´µÄ.f0ÎÄ¼þ²»ºÃÓÃ£¬ÕâÀï°ÑÈ¥µôÇ°ÈýÐÐ£¬²¢°ÑÖÃÐÅ¶ÈµÄµØ·½Ìæ»»³ÉÕâÒ»Ö¡µÄÆðÊ¼Ê±¼ä£¬
        ·½±ãºóÐø¼ÆËã'''
    f0_file.readline()
    f0_file.readline()
    f0_file.readline()  #Ç°ÈýÐÐÃ»ÓÃ
    lines = f0_file.readlines()
    f0_file_name = os.path.split(f0_file.name)[1]
    if not os.path.exists('output'):
        os.mkdir('output')
    useful_file = open('output\\%s.use' % f0_file_name,'w+')   #Éú³É.f0.useÎÄ¼þ£¬ÊÇºóÃæÕæÕýÒªÓÃµÄf0ÎÄ¼þ
    i = 0
    for line in lines[:-1]:
        begt = i*0.01   #10msÒ»Ö¡
        f0_of_thisframe = line.split()[0] 
        useful_file.write(f0_of_thisframe + ' ' + format(begt,'0.2f') + '\n')
        i += 1
    begt = i*0.01   
    f0_of_thisframe = line.split()[0] 
    useful_file.write(f0_of_thisframe + ' ' + format(begt,'0.2f'))  #×îºóÒ»ÐÐ²»¼Ó»»ÐÐ
    f0_file.close()
    useful_file.seek(0,0)   #ÈÃÎÄ¼þÖ¸Õë»Øµ½ÎÄ¼þÆðÊ¼´¦
    return useful_file

def find_ROI(useful_file, maindir, sttfile, sgmfile):
    '''
    ROI = region of interest
       ÔÚºóÆÚ¼ÆËãµÄÊ±ºò£¬·ÇROI´¦µÄÐÅÏ¢ÆäÊµ¶¼Ã»ÓÐÓÃÉÏ£¬ÏÈÌáÈ¡³öÀ´ÎªºóÃæµÄÆ½»¬¼õÐ¡¼ÆËãÁ¿
    sttÄ¬ÈÏ¾ä×ÓÖ®¼ä×îÐ¡¼ä¸ôÊÇ400ms
    
        ±íÊ¾·¨£º
        
    [-----×ó±ßÒô½Ú------] [------¾²Òô-------] [--------ÓÒ±ßÒô½Ú-------------]
    left_syl_begin   i-1  i      silence_end  silence_end+1   right_syl_end
    
    '''
    sgm = open(maindir+sgmfile)
    stt = open(maindir+sttfile)
    
    stt_lines = stt.readlines()
    sgm_lines = sgm.readlines()

    sgm_meaninful_end = read_sgm(sgm_lines)   #×îºóÒ»¸öreport¶ÎÂäµÄ½áÊøÊ±¼ä
    
    #ÐÎ³ÉsttµÄ[[begt1,endt1,sylidlist=[]],[begt2,endt2,sylidlist=[]]]
    stt_timeline = []
    for line in stt_lines:
        obj = re.search(r'begt=([^ ]+) endt=([^ ]+).*(?<=sylid=)([^\n]+)',line)
        if obj:
            if time_cmp(sgm_meaninful_end, obj.group(1)) > 0:
                sylid_list = obj.group(3).split()
                stt_timeline.append([obj.group(1),obj.group(2),sylid_list])
    
    #ÐÎ³Éstt_roi_list:[(begt1,endt1,sylid_l,sylid_r),...],ÕâÒÑ¾­ÊÇËùÓÐroiÁË
    stt_roi_list = []
    for i in range(len(stt_timeline)-1):
        t = (stt_timeline[i][1],stt_timeline[i+1][0],stt_timeline[i][2][-1],stt_timeline[i+1][2][0])
        stt_roi_list.append(t)
    
    roi_list = []   #´æ´¢ËùÓÐroiÊµÀýµÄÁÐ±í
    lines = useful_file.readlines()
    i = 0
    silence_end = 0

    while i < len(lines)-1: #×îºóÒ»ÐÐÃ»ÓÐ¶«Î÷
        if lines[i].split()[0] == '0.000000e+000':#ÊÇÎÞÉùµÄÖ¡£¬ÍùºóÕÒ¿´ÑÓÉìµ½ÄÄÀï
            isROI,silence_end = find_sequence(lines, i)
            if isROI:   #ÊÇÒ»¸öROI£¬Ôò´´½¨Ò»¸öROIÀàÊµÀý
                roi = ROI()
                left_syl_begin = find_sequence(lines, i-1, False, 'b')  #iÊÇ¾²ÒôÖ¡,i-1²ÅÊÇ×ÇÒôÖ¡
                if silence_end >= len(lines)-1: #¶ÔÓÚmc97418×îºóÒ»¶ÎÊÇ¾²Òô,ÎÞÓÒ±ßÒô½Ú
                    i = silence_end
                    continue  
                else:
                    right_syl_end = find_sequence(lines, silence_end+1, False, 'f')
                roi.LEFT.begt = lines[left_syl_begin].split()[1]
                roi.LEFT.endt = lines[i-1].split()[1]
                roi.LEFT.f0_sequence = [float(l.split()[0]) for l in lines[left_syl_begin:i]]
                
                roi.RIGHT.begt = lines[silence_end+1].split()[1]
                roi.RIGHT.endt = lines[right_syl_end].split()[1]
                roi.RIGHT.f0_sequence = [float(l.split()[0]) for l in lines[silence_end+1:right_syl_end+1]]
                
                if not len(roi_list) or roi_list[-1].RIGHT.begt != roi.LEFT.begt:
                    roi_list.append(roi) #»áÓÐÄÇÖÖÍ¬Ò»¸ö×ÖÔÚ×óÓÒ¶¼ÊÇroiµÄ,ÕâÖÖÖ¡»á¶ÔºóÐøÔì³ÉÓ°Ïì,²»Òª
                i = right_syl_end + 1        
            else:
                i = silence_end + 1
        else:
            i += 1 
    useful_file.seek(0,0)
    
    #É¸Ñ¡roi_list,ÐÂÔöµÄ´úÂë.¶ÔÓÚÃ¿Ò»¸östt_roi,ÔÚroi_listÖÐÕÒµ½¶ÔÓ¦
    for stt_roi in stt_roi_list:
        min_distance = 100000
        for roi in roi_list:
            distance = abs(time_cmp(roi.LEFT.endt,stt_roi[0])+time_cmp(roi.RIGHT.begt,stt_roi[1]))
            if distance < min_distance:
                min_distance = distance
                if min_distance < 3:
                    pass
            else:
                if roi_list[roi_list.index(roi)-1].stt_roi:#¶à¸östt_roi¶ÔÓ¦µ½Ò»¸öpitch_roi,È¡×î½Ó½üµÄÄÇ¸östt_roi
                    if min_distance > roi_list[roi_list.index(roi)-1].mindistance:
                        break
                roi_list[roi_list.index(roi)-1].stt_roi = stt_roi
                roi_list[roi_list.index(roi)-1].mindistance = min_distance
                break
                
    #É¾È¥Ã»ÓÐstt_roi¶ÔÓ¦µÄÔ­Ê¼roi
    roi_list = [roi for roi in roi_list if roi.stt_roi]
    return roi_list


def time_cmp(sgm_time,stt_time):
    '''Èôsgm´ó,·µ»ØÕýÖµ;stt´ó·µ»Ø¸ºÖµ.Á½¸öÊ±¼ä¶¼ÊÇstrÀàÐÍ'''
    stt_time_list = stt_time.split(':')
    stt = 0
    if len(stt_time_list) == 2:
        stt = float(stt_time_list[0])*60 + float(stt_time_list[1])
    if len(stt_time_list) == 3:
        stt = float(stt_time_list[0])*3600 + float(stt_time_list[1])*60 \
                   + float(stt_time_list[2])
    sgm = float(sgm_time)
    return sgm - stt    #·µ»Øfloat

def read_sgm(sgm_lines):
    '''´ÓsgmÎÄ¼þÖÐ¶ÁÈ¡ÐÅÏ¢×îºóÒ»¸öÓÐÒâÒåµÄ¶ÎÂäµÄ½áÊøÊ±¼ä'''
    section_lines = [l for l in sgm_lines if l.startswith('<section')]
    section_lines.reverse()
    for l in section_lines:
        if re.search('type=report',l):#×îºóÒ»¸öÓÐÒâÒåµÄ¶Î
            endt = re.search(r"(?<=endTime=)[\d.]*",l).group()
            return endt #·µ»Ø×îºóÒ»¸öÓÐÒâÒå¶ÎÂäµÄ½áÊøÊ±¼ä   

def find_sequence(lines, index, zero=True, direction=None):
    '''´Ëº¯ÊýÓÃÓÚÔÚlinesÖÐÕÒµ½Á¬ÐøµÄÈ«0»òÕß·Ç0ÐòÁÐµÄ½áÊø
        ²ÎÊý£º
        lines-ÐÐµÄ¼¯ºÏ
        index-Ñ°ÕÒµÄÆðµã£¬¼´ÆðÊ¼ÐÐºÅ
        zero-True(Ä¬ÈÏ)´ú±íÕÒ0ÐòÁÐ,False´ú±íÕÒ·Ç0ÐòÁÐ
        direction-ÐèÕÒµÄ·½Ïò,'b'ÊÇÍù»ØÕÒ,'f'ÊÇÍùÇ°ÕÒ,Õë¶ÔROI×óÓÒµÄÒô½Ú·½ÏòÐèÒªÖ¸¶¨
        ·µ»ØÖµ£º
                ÁíÒ»¶Ë¶ÔÓ¦µÄlinesÐòÁÐµÄÐòºÅ
    '''
    if zero:#ÕÒ0ÐòÁÐ¼´Á¬ÐøµÄ¾²ÒôÖ¡£¬·½ÏòÖ»¿ÉÄÜÊÇforward
        silence_begin = index   #ÕâÒ»¶Î¾²Òô¿ªÊ¼µÄÖ¡ÐòºÅ
        num = len(lines) 
        while index < num-1:  #¾²Òô¶Î
            index += 1 
            if lines[index].split()[0] != '0.000000e+000': 
                break
        if index - silence_begin > 19 and silence_begin > 0 and index < num-1:  #¾²Òô¶Î´óÓÚ200ms,ÐÂµÄROI
            return True,index-1   #ÕâÀïµÄindexÊÇ¾²ÒôÖ¡ÐòÁÐÖ®ºóµÄÄÇÒ»Ö¡
        else:
            return False,index-1
    else:#ÕÒ·Ç¾²ÒôÐòÁÐ
        while lines[index].split()[0] != '0.000000e+000':
            if direction == 'b':
                index -= 1
            elif direction == 'f':
                index += 1
                if index >= len(lines) - 1:
                    break
            else:
                print('dir input error')
                return
        if direction == 'b':
            return index+1
        if direction == 'f':
            return index-1
    

def median_filter(roi_list):
    '''
        ÖÐÖµÂË²¨£¬´°³¤¶È=7£¬Êä³öµ½.f0.mfÎÄ¼þ
    '''
    def do_filtering(s):
        '''¶¨Òå¶ÔÐòÁÐ×öÂË²¨µÄº¯Êý'''
        length = len(s)
        new_s = [0 for i in range(length)]  #ÂË²¨Ö®ºóµÄÐòÁÐ
        if length < 7:
            new_s = s    #³¤¶ÈÐ¡ÓÚ7¾Í²»ÂË²¨
        else:
            new_s[0] = sum(s[:4])/4
            new_s[1] = sum(s[:5])/5
            new_s[2] = sum(s[:6])/6
            for i in range(3,length-3):
                new_s[i] = sum(s[i-3:i+4])/7
            new_s[-1] = sum(s[-4:])/4
            new_s[-2] = sum(s[-5:])/5
            new_s[-3] = sum(s[-6:])/6
        return new_s
    
    for roi in roi_list:
        roi.LEFT.f0_sequence = do_filtering(roi.LEFT.f0_sequence)
        roi.RIGHT.f0_sequence = do_filtering(roi.RIGHT.f0_sequence)
            
            
def SLM(roi_list,filename):
    '''ÔËÓÃ±àÒëºÃµÄSLM¿ÉÖ´ÐÐÎÄ¼þ½øÐÐÂË²¨,´«Èëf0_sequence'''
    start = time.time()
    #new_roi_list = []   #»áÓÐf0-sequence³¤¶ÈµÈÓÚ1µÄÇé¿ö
    h = win32com.client.Dispatch('matlab.application')
    #h.Execute("cd 'D:\ZY\Graduation Design\FeatureExtraction\Pitch\SLMtools'")
    cwd = os.getcwd()
    directory = cwd + r'\SLMtools'
    h.Execute("cd '%s'" % directory)
    for roi in roi_list:
        index = roi_list.index(roi)
        h.Execute("SLM(" + str(roi.LEFT.f0_sequence)+",'"+filename+str(index)+"',0"+')')
        h.Execute("SLM(" + str(roi.RIGHT.f0_sequence)+",'"+filename+str(index)+"',1"+')')
        
        '''»ñµÃ×ó±ßÒô½ÚÂË²¨½á¹û²¢¸üÐÂroi.LEFT.f0_sequence'''
        curve_file = open('curve/'+filename+str(index)+'_l'+'.curve','r')   #´ò¿ªmatlabÉú³ÉµÄ.curveÎÄ¼þ
        x_line_l = curve_file.readline()
        y_line_l = curve_file.readline()  #ÔÚmatlabÉú³ÉµÄ.curveÎÄ¼þÖÐ,Ö»ÓÐÁ½ÐÐ,µÚÒ»ÐÐÊÇxÐòÁÐ,¶þÐÐyÐòÁÐ
        y_l = y_line_l.split()
        curve_file.close()
        num_interval = len(roi.LEFT.f0_sequence) - 1
        for i in range(num_interval+1):  
            k = round(1001/num_interval*i)
            if k >= len(y_l):
                k = len(y_l) - 1
            roi.LEFT.f0_sequence[i] = y_l[k] #ÂË²¨Ö®ºóµÄÐòÁÐ³¤¶ÈÊÇ1001
            
        '''»ñµÃÓÒ±ßÒô½ÚÂË²¨½á¹û²¢¸üÐÂroi.RIGHT.f0_sequence'''
        curve_file = open('curve/'+filename+str(index)+'_r'+'.curve','r')  
        y_l = y_line_l.split()
        x_line_r = curve_file.readline()
        y_line_r = curve_file.readline()
        y_r = y_line_r.split()
        curve_file.close()
        num_interval = len(roi.RIGHT.f0_sequence) - 1 #f0_sequenceµÄ¼ä¸ôÊýÄ¿
        for i in range(num_interval+1):
            k = round(1001/num_interval*i)
            if k >= len(y_l):
                k = len(y_l) - 1
            roi.RIGHT.f0_sequence[i] = y_r[k]
        #print(index)
        
        '''
        x = x_line_l.split()
        for item in x:
            item = float(item)
        for item in y_l:
            item = float(item)
        plt.Figure()
        plt.plot(x,y_l,'red')
        y_ori = roi.LEFT.f0_sequence
        x = range(len(roi.LEFT.f0_sequence))
        plt.plot(x,y_ori,'blue')
        plt.show()
        '''
    end = time.time()
    print('ºÄÊ±:',end - start)


def attach2spk(filename,roi_list,filedir):
    '''°ÑÃ¿¸öroiµÄLEFT,RIGHT¶¼¶ÔÓ¦µ½Ëµ»°ÈË,ÓÃresÎÄ¼þ¡£
            Í¬Ê±Éú³ÉÃ¿¸öËµ»°ÈËµÄroi´¦Òô½ÚµÄÖ¡pitchÐòÁÐ,ÓÉÓÚÊÇÎªÁË¼ÆËãÆ½¾ùÖµºÍ±ê×¼²î,¹ÊÁ¬ÔÚÒ»Æð¾ÍÐÐÁË¡£
            ´æ´¢½á¹¹ÊÇÒ»¸ö×Öµä,keyÊÇspkµÄ±àºÅ,valueÊÇclass spk_roiÊµÀý                   
    '''
    res_file = open(filedir + filename + '.res')
    lines = res_file.readlines()
    res_list = []   #´æ´¢ÐÎÊ½[([begt1,endt1],spk1),([begt2,endt2],spk2),...]
    for line in lines:
        result = re.search(r"(?<=begt=)([^ ]*).*(?<=endt=)([^ ]*).*(?<=clusid=)(\d*)",line)
        if result:
            begt = hms2s(result.group(1))
            endt = hms2s(result.group(2))
            spk = result.group(3)
            res_list.append(([begt,endt],spk))
            
    spk_roi_dict = {}
    for roi in roi_list:
        '''±éÀúroi_list¾¡Á¿°ÑÃ¿¸öÒô½Ú¶¼¶ÔÓ¦'''
        ifmatch_l = 0   #flag
        ifmatch_r = 0
        l_begt = float(roi.LEFT.begt)
        l_endt = float(roi.LEFT.endt) 
        r_begt = float(roi.RIGHT.begt)
        r_endt = float(roi.RIGHT.endt) 
        for item in res_list:
            if l_begt >= float(item[0][0]) and l_endt <= float(item[0][1]):
                '''×óÒô½ÚÍêÃÀ¶ÔÓ¦'''
                roi.LEFT.spk = item[1]
                if item[1] in list(spk_roi_dict.keys()):
                    '''ÒÑ´´½¨Õâ¸öspk,Ö±½ÓÑÓÕ¹frame_seq¼´¿É'''
                    spk_roi_dict[item[1]].frame_seq.extend(roi.LEFT.f0_sequence)
                else:
                    '''ÒÔÇ°Ã»³öÏÖ¹ýÕâ¸öspk,ÔÚ×ÖµäÖÐÌí¼ÓÒ»Ïî'''
                    spk_roi_dict[item[1]] = spk_roi(item[1],roi.LEFT.f0_sequence)
                index = res_list.index(item)
                ifmatch_l = 1
                if index > 0:
                    del res_list[0:index]   #Æ¥ÅäÖ®ºó,É¾³ýÖ®Ç°µÄÏîÄ¿,¼Ó¿ìÖ®ºóµÄËÑË÷ËÙ¶È
                break
        for item in res_list:
            if r_begt >= float(item[0][0]) and r_endt <= float(item[0][1]):
                '''ÓÒÒô½ÚÍêÃÀ¶ÔÓ¦¡£ÒòÎªÓÒ±ßÒô½Ú¿Ï¶¨±ÈÍ¬Ò»¸öroiµÄ×ó±ßÒô½ÚÖ»ÊÇÉÔ¿¿ºó,¼ÓÉÏÖ®Ç°×óÒô½ÚÆ¥ÅäÉÏÊ±\
                                É¾µôÁËres_listÖÐÒÑ¾­²»¿ÉÄÜÆ¥ÅäÉÏµÄÔªËØ,ËùÒÔÓÒ±ß¿Ï¶¨ÔÚµÚÒ»/¶þ´Î¾ÍÆ¥ÅäÉÏ(Èç¹ûÄÜÆ¥Åä)'''
                roi.RIGHT.spk = item[1]
                if item[1] in list(spk_roi_dict.keys()):
                    spk_roi_dict[item[1]].frame_seq.extend(roi.RIGHT.f0_sequence)
                else:
                    spk_roi_dict[item[1]] = spk_roi(item[1],roi.RIGHT.f0_sequence)
                ifmatch_r = 1
                break
        if not ifmatch_l:
            print(roi.LEFT)     #Èç¹ûÃ»ÓÐÆ¥Åä,»á°ÑÒô½ÚÊä³ö¡£
            roi.LEFT.spk = '-1' #²¢¸³ÓèÒ»¸ö²»´æÔÚµÄËµ»°ÈË-1ºÅ
        if not ifmatch_r:
            print(roi.RIGHT)
            roi.RIGHT.spk = '-1' 
            
    '''¼ÆËãÆ½¾ùÖµºÍ·½²î'''        
    for s_r in list(spk_roi_dict.values()): # s_r = spk_roi
        temp_seq = np.array(s_r.frame_seq,dtype=np.float)
        s_r.avg = temp_seq.mean()
        s_r.sd = temp_seq.std()
    return spk_roi_dict

def hms2s(res_time):
    '''°ÑresÖÐµÄÊ±¼äh:m:s×ª»¯ÎªÒÔs±íÊ¾,·½±ãÖ®ºó±È½Ï'''
    res_time_list = res_time.split(':')
    res = 0 #×ª»»ºóµÄÊ±¼ä
    if len(res_time_list) == 2:
        res = float(res_time_list[0])*60 + float(res_time_list[1])
    if len(res_time_list) == 3:
        res = float(res_time_list[0])*3600 + float(res_time_list[1])*60 \
                   + float(res_time_list[2])
    return str(res)

def attach2zi(filename,roi_list,filedir):
    '''°ÑÃ¿¸öroiµÄLEFT,RIGHT¶¼¶ÔÓ¦µ½Êµ¼ÊµÄ×Ö,ÓÃsttÎÄ¼þ¡£'''
    pinyin = open('ChSylName.txt','rt') #Æ´ÒôÎÄ¼þ
    syl_lines = [l.strip() for l in pinyin.readlines()]
    tone_roi_dict = {}  #×Öµä,keyÊÇ4ÖÖtone,valueÊÇtone_roiÀàÊµÀý
            
    for roi in roi_list:
        roi.LEFT.zi = syl_lines[int(roi.stt_roi[2])]
        roi.RIGHT.zi = syl_lines[int(roi.stt_roi[3])]
        tone1 = roi.LEFT.zi[-1]
        tone2 = roi.RIGHT.zi[-1]
        for tone,f0_seq in [(tone1,roi.LEFT.f0_sequence),(tone2,roi.RIGHT.f0_sequence)]:
            if tone in list(tone_roi_dict.keys()):
                tone_roi_dict[tone].frame_seq.extend(f0_seq)
            else:
                tone_roi_dict[tone] = tone_roi(tone,f0_seq)
            
    '''Õë¶ÔtoneµÄ¼ÆËãÆ½¾ùÖµºÍ·½²î'''        
    for t_r in list(tone_roi_dict.values()): # s_r = spk_roi
        temp_seq = np.array(t_r.frame_seq,dtype=np.float)
        t_r.avg = temp_seq.mean()
        t_r.sd = temp_seq.std()
    
    #½«roiÊä³öµ½ÎÄ¼þ½øÐÐ¹Û²ì
    output_roi = open('output\\%s_roi_file.txt' % filename,'wt')
    for roi in roi_list:
        output_roi.write(str(roi.LEFT)+'\n'+str(roi.RIGHT)+'\n\n')
    output_roi.close()
    
    return tone_roi_dict

def normalize(roi_list,roi_dict,mode):
    '''¹éÒ»»¯º¯Êý,spkºÍtone¹éÒ»»¯¶¼ÊÇÓÃÕâ¸öº¯Êý'''
    def calc(f0,avg,sd):
        F0 = ((float(f0))-avg)/sd
        return str(F0)
    
    normalized = deepcopy(roi_list) #list°üº¬¸´ÔÓÔªËØ,ÒªÓÃdeep copy
    
    for roi in normalized:
        if mode == 'spk':
            avg_l = roi_dict[roi.LEFT.spk].avg
            sd_l = roi_dict[roi.LEFT.spk].sd
            avg_r = roi_dict[roi.RIGHT.spk].avg
            sd_r = roi_dict[roi.RIGHT.spk].sd
        elif mode == 'tone':
            tone1 = roi.LEFT.zi[-1]
            tone2 = roi.RIGHT.zi[-1]
            avg_l = roi_dict[tone1].avg
            sd_l = roi_dict[tone1].sd
            avg_r = roi_dict[tone2].avg
            sd_r = roi_dict[tone2].sd
        else:
            print('wrong mode!')    
        roi.LEFT.f0_sequence = [calc(f,avg_l,sd_l) for f in roi.LEFT.f0_sequence]
        roi.RIGHT.f0_sequence = [calc(f,avg_r,sd_r) for f in roi.RIGHT.f0_sequence]
    return normalized
 
def split(roi_list,sgmfilename,filedir):
    '''
        °Ñ¹éÒ»»¯Ö®ºóµÄroiÐòÁÐÇø·Ö³Éutt±ß½çºÍstory±ß½ç,±ÈÈçËµÊäÈëspk_normalized
        Êä³öspk_nor_uttºÍspk_nor_story¡£
        Êµ¼ÊÉÏ¾ÍÊÇÕÒºÍsgmÎÄ¼þÖÐstory·Ö½çÊ±¼ä¶ÔÓ¦µÄroi_listÖÐµÄÔªËØ
        »®·ÖµÄ·½·¨²Î¼û±Ê¼Ç
    '''
    roi_utt = deepcopy(roi_list) #Ã¿´ÎÕÒµ½story±ß½ç¾Í´ÓÀïÃæÉ¾È¥
    roi_story = []
    roi_betime_list = []    #°´Ë³Ðò´æ´¢ËùÓÐroi×óÓÒÒô½Úbegt,endt
    
    for roi in roi_list:
        roi_betime_list.extend([roi.LEFT.begt,roi.LEFT.endt])
        roi_betime_list.extend([roi.RIGHT.begt,roi.RIGHT.endt]) #×Ö·û´®²»¿É±ä,²»ÓÃ¿½±´
    
    '''´ÓsgmÖÐ°ÑÃ¿¸ösectionµÄÆðÊ¼Ê±¼äÌá³öÀ´Ð´ÈëÒ»¸ölist½Ðstory_start'''
    story_start = []
    sgm_file = open(filedir + sgmfilename,'rt')
    lines = sgm_file.readlines()
    section_lines = [l for l in lines if l.startswith('<section')]
    for l in section_lines:
        obj = re.search(r'startTime=([^ ]*)',l)
        if obj:
            story_start.append(obj.group(1))
    del story_start[0]  #¶ÔÓÚ97114,µÚÒ»¸öºÍ×îºóÒ»¸ösection¶¼²»ÊÇÈËËµ»°,ËùÒÔ²»ÄÜËã,É¾µô
    del story_start[-1]
    
    '''
        ¿ªÊ¼ÕÒstory_startµÄÃ¿Ò»¸öÔªËØ(´ÓµÚ¶þ¸ö¿ªÊ¼)ÔÚroi_betime_listÖÐ×î½Ó½üµÄ
        ´æÔÚÕâÑùµÄÇé¿ö:ÐÂÎÅµÄsectionÊÇÐÂÎÅ¼ò½é,¼ä¸ôÊ±¼ä·Ç³£¶Ì,¹Ê¶à¸ösection¿ÉÄÜ¶ÔÓ¦µ½Ò»¸öroi,
        Èç¹ûÃ¿´ÎÉ¾³ýÒÑ¾­±ãÀû¹ýµÃroi_betime_list²¢ÇÒ´Óroi_uttÀïÃæ°Ñ¹ÊÊÂ±ß½çpop³öÀ´,ÄÇÃ´ÏÂÒ»¸ö
    sectionÈç¹û»¹¶ÔÓ¦µ½Í¬Ò»¸öroi¾Í»áµ¼ÖÂÖ®ºóµÄ¶ÔÓ¦È«²¿³öÎÊÌâ.
    '''
    roi_story_index = []    #±£´æstory¶ÔÓ¦µÄroiÔÚÔ­À´roi_listÖÐµÄÐòºÅ
    for ss in story_start[1:]:
        smallest = 1000000
        for time in roi_betime_list:
            delta = abs(float(ss)-float(time))
            if smallest > delta:
                smallest = delta
            else:
                closet_index = roi_betime_list.index(time) - 1
                break   #delta¿ªÊ¼Ôö´ó,ËµÃ÷ÉÏÒ»¸ö¾ÍÊÇ×î½üÊ±¼äµã
        roi_index = int(closet_index/4)#ÒòÎªÉ¾È¥ÁËÒ»²¿·Ö,µÃ¼ÓÉÏ
        try:
            if roi_utt[roi_index] not in roi_story:
                roi_story.append(roi_utt[roi_index]) #ÊµÏÖstorylistµÄ²åÈë
            if roi_index not in roi_story_index:
                roi_story_index.append(roi_index)
        except IndexError:
            pass
       
    roi_story_index.reverse()
    for index in roi_story_index:   #É¾³ýroi_uttÖÐÊôÓÚroi_storyµÄ²¿·Ö
        del roi_utt[index]

    
    #½«story·Ö½ç´¦µÄroiÊä³öµ½ÎÄ¼þ½øÐÐ¹Û²ì
    output_roi = open('output\\%s_roi_story.txt' % sgmfilename[:-4],'wt')
    for roi in roi_story:
        output_roi.write(str(roi.LEFT)+'\n'+str(roi.RIGHT)+'\n\n')
    output_roi.close()
    return roi_utt,roi_story
    
def calc16(roi_utt,roi_story,evalute):
    '''
        ¼ÆËã16¸öÖµ,´æÈë×Öµäevaluate
    keyµÄÃû³Æ (story,utt)_(init,final)_(1,2,3,4)
    ''' 
    for roi in roi_utt:
        key_left = 'utt_final_' + roi.LEFT.zi[-1]
        key_right = 'utt_init_' + roi.RIGHT.zi[-1]
        evalute[key_left].extend(roi.LEFT.f0_sequence)
        evalute[key_right].extend(roi.RIGHT.f0_sequence)
    
    for roi in roi_story:
        key_left = 'story_final_' + roi.LEFT.zi[-1]
        key_right = 'story_init_' + roi.RIGHT.zi[-1]
        evalute[key_left].extend(roi.LEFT.f0_sequence)
        evalute[key_right].extend(roi.RIGHT.f0_sequence)

    
def plot_origin(useful_file):
    i = 0
    pitch_contour = []
    
    while i < 9800:
        line = useful_file.readline()
        pitch = line.split()[0] #ÌáÈ¡pitchÐÅÏ¢
        pitch_contour.append(float(pitch))
        i += 1
    '''»­Í¼'''
    plt.Figure()
    x = np.array(range(9800))
    plt.plot(x,pitch_contour)
    plt.xlabel('frame')
    plt.ylabel('pitch(Hz)')
    plt.show()
    
def main(testmode=0):
    filedir = '..\wav_processing\output\\'
    stt_files = [f for f in os.listdir(filedir) if f.endswith('.stt')]
    sgm_files = [f for f in os.listdir(filedir) if f.endswith('.sgm')]
    
    if testmode:
        evalute = {}    #Ã¿´¦ÀíÒ»¸öÎÄ¼þ,evalute¾ÍÐÂ¼ÓÈëÕâ¸öÎÄ¼þµÄroiÐÅÏ¢,×îºó¼ÆËãÆ½¾ùÖµ
        for kind in ['story','utt']:
            for pos in ['init','final']:
                for tone in ['1','2','3','4']:
                    evalute[kind+'_'+pos+'_'+tone] = []
        
    for sttfile,sgmfile in zip(stt_files,sgm_files):
        filename = sttfile.rstrip('.stt')
        if not os.path.exists('output\\%s_roi_list.p' % filename):
            f0_file = open(filedir + filename + '.f0')
            useful_file = pre_process(f0_file)
            roi_list = find_ROI(useful_file,filedir,sttfile,sgmfile)
            median_filter(roi_list)
            SLM(roi_list,filename)
            pickle.dump(roi_list,open('output\\%s_roi_list.p' % filename,'wb'))  #½ÚÊ¡Ê±¼ä,²»È»Ã¿´Î¶¼µÃÂË²¨ºÜºÄÊ±
        else:
            roi_list = pickle.load(open('output\\%s_roi_list.p' % filename,'rb'))
        
        '''¹éÒ»»¯'''
        spk_roi_dict = attach2spk(filename,roi_list,filedir)
        spk_normalized = normalize(roi_list,spk_roi_dict,'spk')   
        pickle.dump(spk_normalized,open('output\\%s_spk_nor.pitch' % filename,'wb'))
        
        tone_roi_dict = attach2zi(filename,spk_normalized,filedir)
        tone_normalized = normalize(spk_normalized,tone_roi_dict,'tone')
        pickle.dump(tone_normalized,open('output\\%s_tone_nor.pitch' % filename,'wb'))
        
        print(filename + 'finished')
        
        if testmode:
            '''»®·Ö³Éutt bundaryºÍstory boundary'''
            #roi_utt,roi_story = split(spk_normalized,sgmfilename)
            #calc16(roi_utt,roi_story)
            roi_utt,roi_story = split(tone_normalized,sgmfile,filedir)
            calc16(roi_utt,roi_story,evalute)
    
    if testmode:
        for key in list(evalute.keys()):
            temp_seq = np.array(evalute[key],dtype=np.float)
            mean = temp_seq.mean()
            evalute[key] = mean

if __name__ == '__main__':
    main()