From c5da25e211bde4fe2a1a023ff3c8f5fefa454155 Mon Sep 17 00:00:00 2001 From: Cykrt Date: Sat, 11 Feb 2017 11:30:58 +0800 Subject: [PATCH 1/3] Improved log system use logging module instead of simple print --- EmiyaEngine.py | 196 +++++++++++++++++++++++++++++---------------- GUI_EmiyaEngine.py | 149 +++++++++++++++++++--------------- 2 files changed, 214 insertions(+), 131 deletions(-) diff --git a/EmiyaEngine.py b/EmiyaEngine.py index afcf0b6..9c89e67 100644 --- a/EmiyaEngine.py +++ b/EmiyaEngine.py @@ -18,8 +18,24 @@ import scipy import librosa import resampy +import logging from colorama import Fore, Back, init +logging.basicConfig( + level=logging.DEBUG, + format='%(asctime)s [line:%(lineno)d] \ + %(levelname)s %(message)s', + datefmt='%a, %d %b %Y %H:%M:%S', + filename='Emiya.log', + filemode='a+' +) +logger = logging.getLogger("EmiaLog") +console = logging.StreamHandler() +console.setLevel(logging.INFO) +# add the handler to the root logger +logger.addHandler(console) + + class EmiyaEngineCore: ReadyFilePath = '' # 输入文件名 @@ -35,7 +51,7 @@ class EmiyaEngineCore: AnalysisWindow = False # 分析接续点用的单边FFT是否加窗 MidSRCFalse = False # SRC开关, 为True时就会取消掉SRC步骤 MidPrint = False # 打印细节日志开关 - MidPrintProgress = True # 打印进度信息 + MidPrintProgress = True # 打印进度信息 def __init__(self, _InputFilePath, _DebugSwitch, _SplitSize, _WindowSwitch): # 输入样本: @@ -57,90 +73,115 @@ def __init__(self, _InputFilePath, _DebugSwitch, _SplitSize, _WindowSwitch): self.ProcessCore() def LoadFile(self): - self.BeforeSignal, self.BeforeSignalSR = librosa.load(self.ReadyFilePath, sr=None, mono=False) + self.BeforeSignal, self.BeforeSignalSR = librosa.load( + self.ReadyFilePath, sr=None, mono=False) self.AfterSignalLeft = np.array([()]) self.AfterSignalRight = np.array([()]) - print("Load signal complete. ChannelCount: %s SampleRate: %s Hz" % (str(len(self.BeforeSignal)), str(self.BeforeSignalSR))) + # print("Load signal complete. ChannelCount: %s SampleRate: %s Hz" % + # (str(len(self.BeforeSignal)), str(self.BeforeSignalSR))) + logger.info("Load signal complete. ChannelCount: %s SampleRate: %s Hz" % ( + str(len(self.BeforeSignal)), str(self.BeforeSignalSR))) def MidUpSRC(self): # 重采样loss样本到96K - print("Please wait for SRC.") + # print("Please wait for SRC.") + logger.info("Please wait for SRC.") self.MidSignalSR = 96000 self.AfterSignalSR = self.MidSignalSR if self.MidSRCFalse: self.MidSignal = self.BeforeSignal else: - self.MidSignal = resampy.resample(self.BeforeSignal, self.BeforeSignalSR, self.MidSignalSR, filter='kaiser_best') - print("Signal SRC complete.") + self.MidSignal = resampy.resample( + self.BeforeSignal, self.BeforeSignalSR, self.MidSignalSR, filter='kaiser_best') + # print("Signal SRC complete.") + logging.info("Signal SRC complete.") - def MidFindThresholdPoint(self,_MidFFTResultSingle,_FFTPointCount): + def MidFindThresholdPoint(self, _MidFFTResultSingle, _FFTPointCount): # 鉴定频谱基本参数 - _MidAmpData = abs(_MidFFTResultSingle[range(_FFTPointCount//2)]) + _MidAmpData = abs(_MidFFTResultSingle[range(_FFTPointCount // 2)]) # Step0. 找出基波幅度 _MidBaseFreqAmp = _MidAmpData.max() if self.MidPrint: - print("Signal max AMP -> %s" % _MidBaseFreqAmp) + # print("Signal max AMP -> %s" % _MidBaseFreqAmp) + logger.debug("Signal max AMP -> %s" % _MidBaseFreqAmp) # Step1. 找出接续的阈值 _MidThresholdHit = 1.0e-11 # 方差判定阈值 _MidThresholdPoint = 0 # 最后的阈值点 - _MidFindRange = int((_FFTPointCount/2)-1) # 搜索的范围 - _MidStartFindPos = round(2000/(48000/(_FFTPointCount/2))) # 从2K频点附近开始寻找,加快速度 + _MidFindRange = int((_FFTPointCount / 2) - + 1) # 搜索的范围 + _MidStartFindPos = round( + 2000 / (48000 / (_FFTPointCount / 2))) # 从2K频点附近开始寻找,加快速度 _MidStartFlag = True # 循环用的启动Flag _MidLoopCount = 0 # 循环计数器 _MidLegalFreq = 22000 # 判定结果合法的阈值频率 _MidForwardFreq = 3000 # 前向修正频率 _MidOrderFreq = 16000 # 钦定频率 # Rev.1: 检查接续点是否符合常理 - while _MidStartFlag or _MidThresholdPoint>round(_MidLegalFreq/(48000/(_FFTPointCount/2))): + while _MidStartFlag or _MidThresholdPoint > round(_MidLegalFreq / (48000 / (_FFTPointCount / 2))): _MidStartFlag = False - if (_MidThresholdPoint*(48000/(_FFTPointCount/2))) > int(self.BeforeSignalSR/2): + if (_MidThresholdPoint * (48000 / (_FFTPointCount / 2))) > int(self.BeforeSignalSR / 2): _MidThresholdHit *= 2 - for i in range(_MidStartFindPos,_MidFindRange): - if i+5>_MidFindRange: + for i in range(_MidStartFindPos, _MidFindRange): + if i + 5 > _MidFindRange: break # 计算连续五个采样*3 的方差,与阈值比较,判断频谱消失的位置 - if np.var(_MidAmpData[i:i+4]) < _MidThresholdHit and \ - np.var(_MidAmpData[i+1:i+5]) < _MidThresholdHit: + if np.var(_MidAmpData[i:i + 4]) < _MidThresholdHit and \ + np.var(_MidAmpData[i + 1:i + 5]) < _MidThresholdHit: # 定位到当前位置的前500Hz位置 - _MidThresholdPoint = i-round(_MidForwardFreq/(48000/(_FFTPointCount/2))) + _MidThresholdPoint = i - \ + round(_MidForwardFreq / (48000 / (_FFTPointCount / 2))) break # 错误超过5把就强行钦定频率为18K _MidLoopCount += 1 if _MidLoopCount > 5: - _MidThresholdPoint = round(_MidOrderFreq/(48000/(_FFTPointCount/2))) + _MidThresholdPoint = round( + _MidOrderFreq / (48000 / (_FFTPointCount / 2))) break # 打印函数返回信息 if self.MidPrint: - print("Signal threshold point -> %s @ %sHz Max Amp -> %s" % (_MidThresholdPoint,_MidThresholdPoint*(48000/(_MidFindRange+1)),_MidBaseFreqAmp)) + # print("Signal threshold point -> %s @ %sHz Max Amp -> %s" % (_MidThresholdPoint, + # _MidThresholdPoint * (48000 / (_MidFindRange + 1)), _MidBaseFreqAmp)) + logger.debug("Signal threshold point -> %s @ %sHz Max Amp -> %s" % (_MidThresholdPoint, + _MidThresholdPoint * (48000 / (_MidFindRange + 1)), _MidBaseFreqAmp)) # _MidThresholdPoint = round(21000/(48000/(_FFTPointCount/2))) return _MidBaseFreqAmp, _MidThresholdPoint - def MidInsertJitter(self,_MidFFTResultDouble,_FFTPointCount,_MidThresholdPoint,_MidBaseFreqAmp): + def MidInsertJitter(self, _MidFFTResultDouble, _FFTPointCount, _MidThresholdPoint, _MidBaseFreqAmp): # 构造抖动 if _MidThresholdPoint <= 0: return _MidFFTResultDouble - for i in range(_MidThresholdPoint,_FFTPointCount-_MidThresholdPoint): + for i in range(_MidThresholdPoint, _FFTPointCount - _MidThresholdPoint): # Rev.0: 调整生成概率,频率越高概率越低 # Rev.1: 加入幅值判定,幅度越大概率越大 - _GenPossible = abs((_FFTPointCount/2)-i)/((_FFTPointCount/2)-_MidThresholdPoint)*(_MidBaseFreqAmp/0.22) - if random.randint(0, 1000000) < 800000 * _GenPossible: # 0<=x<=10 + _GenPossible = abs((_FFTPointCount / 2) - i) / ((_FFTPointCount / + 2) - _MidThresholdPoint) * (_MidBaseFreqAmp / 0.22) + if random.randint(0, 1000000) < 800000 * _GenPossible: # 0<=x<=10 _MidRealValue = abs(_MidFFTResultDouble.real[i]) - _BaseJitterMin = _MidRealValue * 0.5 * (1-_GenPossible) + _BaseJitterMin = _MidRealValue * 0.5 * (1 - _GenPossible) _BaseJitterMax = _MidRealValue * 6 * _GenPossible _AmpJitterMin = _MidBaseFreqAmp * _MidRealValue * 0.5 _AmpJitterMax = _MidBaseFreqAmp * _MidRealValue * 2 - _AmpJitterPrefix = -1 if random.randint(0, 100000) < 50000 else 1 - _MiditterPrefix = -1 if random.randint(0, 100000) < 50000 else 1 - _MidDeltaJitterValue = random.uniform(_BaseJitterMin,_BaseJitterMax) + _AmpJitterPrefix * random.uniform(_AmpJitterMin,_AmpJitterMax) - _MidFFTResultDouble.real[i] += _MiditterPrefix * _MidDeltaJitterValue + _AmpJitterPrefix = - \ + 1 if random.randint(0, 100000) < 50000 else 1 + _MiditterPrefix = - \ + 1 if random.randint(0, 100000) < 50000 else 1 + _MidDeltaJitterValue = random.uniform( + _BaseJitterMin, _BaseJitterMax) + _AmpJitterPrefix * random.uniform(_AmpJitterMin, _AmpJitterMax) + _MidFFTResultDouble.real[ + i] += _MiditterPrefix * _MidDeltaJitterValue return _MidFFTResultDouble def FinSaveFile(self): init(autoreset=True) - OutputFilePath = os.path.abspath(os.path.join(self.ReadyFilePath, os.pardir)) + "\\" + OutputFilePath = os.path.abspath( + os.path.join(self.ReadyFilePath, os.pardir)) + "\\" OutputFileName = OutputFilePath + 'Output_%s.wav' % uuid.uuid4().hex - librosa.output.write_wav(OutputFileName, self.AfterSignal, self.AfterSignalSR) - print(Back.GREEN + Fore.WHITE + "SAVE DONE" + Back.BLACK + " Output path -> " + OutputFileName) + librosa.output.write_wav( + OutputFileName, self.AfterSignal, self.AfterSignalSR) + # print(Back.GREEN + Fore.WHITE + "SAVE DONE" + + # Back.BLACK + " Output path -> " + OutputFileName) + logger.info(Back.GREEN + Fore.WHITE + "SAVE DONE" + + Back.BLACK + " Output path -> " + OutputFileName) def ProcessCore(self): # 初始化彩色命令行 @@ -152,8 +193,8 @@ def ProcessCore(self): # 信号总长度 _MidSignalLength = len(self.MidSignal[ChannelIndex]) # FFT分割数量 - _FFTPointCount = 1024 # 至少2048点,避免计算错误 - _MidDivCount = math.floor(_MidSignalLength/_FFTPointCount) + _FFTPointCount = 1024 # 至少2048点,避免计算错误 + _MidDivCount = math.floor(_MidSignalLength / _FFTPointCount) # 实际重叠操作数量 = FFT分割数量 * 分块次数 _EachLength = 512 # 补偿标记, 标记有效时, 说明已经到了序列尾部, 因停止继续循环运算 @@ -164,12 +205,12 @@ def ProcessCore(self): _TempArrayRight = np.array([()]) _TempAppendCount = 0 # 除了最后一块,每一块都是取计算结果时域的前512点 - for SamplePointIndex in range(_MidDivCount+1): - StartPos = SamplePointIndex*_FFTPointCount - EndPos = SamplePointIndex*_FFTPointCount+_FFTPointCount + for SamplePointIndex in range(_MidDivCount + 1): + StartPos = SamplePointIndex * _FFTPointCount + EndPos = SamplePointIndex * _FFTPointCount + _FFTPointCount _EachPieceLeft = np.array([()]) _EachPieceRight = np.array([()]) - for EachFourPiece in range(int(_FFTPointCount/_EachLength)): + for EachFourPiece in range(int(_FFTPointCount / _EachLength)): StartPos += EachFourPiece * _EachLength EndPos += EachFourPiece * _EachLength # 若超出范围, 需将本次计算完整保留接续有效部分(除去补零部分) @@ -184,64 +225,84 @@ def ProcessCore(self): # 执行FFT运算, 单边谱用于分析, 双边谱用于处理 if self.AnalysisWindow: _TempSignal *= scipy.signal.hann(_FFTPointCount, sym=0) - _MidFFTResultDouble = np.fft.fft(_TempSignal,_FFTPointCount)/(_FFTPointCount) - _MidFFTResultSingle = np.fft.fft(_TempSignal,_FFTPointCount)/(_FFTPointCount/2) + _MidFFTResultDouble = np.fft.fft( + _TempSignal, _FFTPointCount) / (_FFTPointCount) + _MidFFTResultSingle = np.fft.fft( + _TempSignal, _FFTPointCount) / (_FFTPointCount / 2) # 获取当前分段最大振幅, 处理阈值点 - _MidBaseFreqAmp, _MidThresholdPoint = self.MidFindThresholdPoint(_MidFFTResultSingle,_FFTPointCount) + _MidBaseFreqAmp, _MidThresholdPoint = self.MidFindThresholdPoint( + _MidFFTResultSingle, _FFTPointCount) # 构造抖动到当前FFT实际值上 - _MidFFTAfterJitter = self.MidInsertJitter(_MidFFTResultDouble,_FFTPointCount,_MidThresholdPoint,_MidBaseFreqAmp) + _MidFFTAfterJitter = self.MidInsertJitter( + _MidFFTResultDouble, _FFTPointCount, _MidThresholdPoint, _MidBaseFreqAmp) # 逆变换IFFT - _MidTimerDomSignal = np.fft.ifft(_MidFFTAfterJitter,n=_FFTPointCount) + _MidTimerDomSignal = np.fft.ifft( + _MidFFTAfterJitter, n=_FFTPointCount) # 接续到新信号上 _AppendLength = _EachLength if SuffixFlag: - _AppendLength = _FFTPointCount-SuffixLength + _AppendLength = _FFTPointCount - SuffixLength _MidAppendSignal = _MidTimerDomSignal[0:_AppendLength] if self.MidPrint: - print("Per each length -> %s" % len(_MidAppendSignal)) + # print("Per each length -> %s" % len(_MidAppendSignal)) + logger.debug("Per each length -> %s" % len(_MidAppendSignal)) if ChannelIndex == 0: - _EachPieceLeft = np.append(_EachPieceLeft, _MidAppendSignal) + _EachPieceLeft = np.append( + _EachPieceLeft, _MidAppendSignal) else: - _EachPieceRight = np.append(_EachPieceRight, _MidAppendSignal) + _EachPieceRight = np.append( + _EachPieceRight, _MidAppendSignal) # 及时跳出尾部 if SuffixFlag: break # 先倒腾到临时数组,倒腾500次给放回大数组 if _TempAppendCount < self.SplitSize and not SuffixFlag: # 已消耗时间 - _MidUsedTime = datetime.datetime.now()-_MidStartTime + _MidUsedTime = datetime.datetime.now() - _MidStartTime # 估算剩余时间 - _MidEtaTime = ((datetime.datetime.now()-_MidStartTime)/((SamplePointIndex+1)/_MidDivCount))-_MidUsedTime + _MidEtaTime = ((datetime.datetime.now() - _MidStartTime) / + ((SamplePointIndex + 1) / _MidDivCount)) - _MidUsedTime # 构造显示文本 if ChannelIndex == 0: - _TempArrayLeft = np.append(_TempArrayLeft, _EachPieceLeft) + _TempArrayLeft = np.append( + _TempArrayLeft, _EachPieceLeft) if self.MidPrintProgress: - print("Left channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount-1) + Fore.WHITE + " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) + # print("Left channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount - 1) + Fore.WHITE + + # " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) + logger.info("Left channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount - 1) + Fore.WHITE + + " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) else: - _TempArrayRight = np.append(_TempArrayRight, _EachPieceRight) + _TempArrayRight = np.append( + _TempArrayRight, _EachPieceRight) if self.MidPrintProgress: - print("Right channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount-1) + Fore.WHITE + " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) + # print("Right channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount - 1) + Fore.WHITE + + # " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) + logger.info("Right channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount - 1) + Fore.WHITE + + " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) else: _TempAppendCount = 0 if ChannelIndex == 0: - self.AfterSignalLeft = np.append(self.AfterSignalLeft, _TempArrayLeft) + self.AfterSignalLeft = np.append( + self.AfterSignalLeft, _TempArrayLeft) _TempArrayLeft = np.array([()]) else: - self.AfterSignalRight = np.append(self.AfterSignalRight, _TempArrayRight) + self.AfterSignalRight = np.append( + self.AfterSignalRight, _TempArrayRight) _TempArrayRight = np.array([()]) # 倒腾计数器 _TempAppendCount += 1 if SuffixFlag: break - self.AfterSignal = np.array([self.AfterSignalLeft.real, self.AfterSignalRight.real]) + self.AfterSignal = np.array( + [self.AfterSignalLeft.real, self.AfterSignalRight.real]) self.FinSaveFile() -def Main(_input,_debug,_size,_window): - Processor = EmiyaEngineCore(_input,_debug,_size,_window) +def Main(_input, _debug, _size, _window): + Processor = EmiyaEngineCore(_input, _debug, _size, _window) if __name__ == "__main__": - + parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter, description='Emiya Engine\n' 'Version: Alpha.0 Rev.2\n' @@ -249,14 +310,14 @@ def Main(_input,_debug,_size,_window): '真正重要的東西, 只用眼睛是看不見的, \n' '只要蘊藏著想成為真物的意志, 偽物就比真物還要來得真實.') parser.add_argument('-i', '--input', help='待处理文件的绝对路径, 同一路径可直接输入文件名. 例如: \n' - 'Music_ready_test.mp3') + 'Music_ready_test.mp3') parser.add_argument('-d', '--debug', help='调试等级设定. 默认 1 级. \n' - '设置为 0 时, 只显示任务起始日志; \n' - '设置为 1 时, 额外显示进度日志; \n' - '设置为 2 时, 额外显示处理细节日志') + '设置为 0 时, 只显示任务起始日志; \n' + '设置为 1 时, 额外显示进度日志; \n' + '设置为 2 时, 额外显示处理细节日志') parser.add_argument('-s', '--size', help='倒腾区大小. 默认 500. \n' - '使用倒腾区是因为 numpy 做大数组 append 速度远低于小数组, \n' - '故加入小数组多倒腾一手, 这个参数就是小数组的尺寸.') + '使用倒腾区是因为 numpy 做大数组 append 速度远低于小数组, \n' + '故加入小数组多倒腾一手, 这个参数就是小数组的尺寸.') parser.add_argument('-w', '--window', help='分析用汉宁Hann双余弦窗启用开关. 默认不使用.\n' '输入 0 代表不使用, 1 代表使用.') @@ -265,7 +326,7 @@ def Main(_input,_debug,_size,_window): _debug = args.debug _size = args.size _window = args.window - + if not _input: print("缺少输入文件参数,请使用 --help 参考!") exit(1) @@ -275,6 +336,5 @@ def Main(_input,_debug,_size,_window): _size = 500 if not _window: _window = 0 - - Main(_input,_debug,_size,_window) + Main(_input, _debug, _size, _window) diff --git a/GUI_EmiyaEngine.py b/GUI_EmiyaEngine.py index 99b830c..5d3108e 100644 --- a/GUI_EmiyaEngine.py +++ b/GUI_EmiyaEngine.py @@ -9,9 +9,25 @@ import scipy import librosa import resampy +import logging from colorama import Fore, Back, init from PyQt5 import QtCore, QtGui, QtWidgets +logging.basicConfig( + level=logging.DEBUG, + format='%(asctime)s [line:%(lineno)d] \ + %(levelname)s %(message)s', + datefmt='%a, %d %b %Y %H:%M:%S', + filename='Emiya.log', + filemode='a+' +) +logger = logging.getLogger("EmiaLog") +console = logging.StreamHandler() +console.setLevel(logging.INFO) +# add the handler to the root logger +logger.addHandler(console) + + class EmiyaEngineCore(QtCore.QThread): Update = QtCore.pyqtSignal([str, str, int]) @@ -31,9 +47,9 @@ class EmiyaEngineCore(QtCore.QThread): AnalysisWindow = False # 分析接续点用的单边FFT是否加窗 MidSRCFalse = False # SRC开关, 为True时就会取消掉SRC步骤 MidPrint = False # 打印细节日志开关 - MidPrintProgress = True # 打印进度信息 + MidPrintProgress = True # 打印进度信息 - def __init__(self,parent,_InputFilePath,_OutputFilePath,_DebugSwitch,_SplitSize,_WindowSwitch): + def __init__(self, parent, _InputFilePath, _OutputFilePath, _DebugSwitch, _SplitSize, _WindowSwitch): super(EmiyaEngineCore, self).__init__(parent) # QtCore.QThread.__init__(self,parent) self.ReadyFilePath = _InputFilePath @@ -53,26 +69,30 @@ def LoadFile(self): self.BeforeSignal, self.BeforeSignalSR = librosa.load(self.ReadyFilePath, sr=None, mono=False) self.AfterSignalLeft = np.array([()]) self.AfterSignalRight = np.array([()]) - print("Load signal complete. ChannelCount: %s SampleRate: %s Hz" % (str(len(self.BeforeSignal)), str(self.BeforeSignalSR))) + # print("Load signal complete. ChannelCount: %s SampleRate: %s Hz" % (str(len(self.BeforeSignal)), str(self.BeforeSignalSR))) + logger.info("Load signal complete. ChannelCount: %s SampleRate: %s Hz" % (str(len(self.BeforeSignal)), str(self.BeforeSignalSR))) def MidUpSRC(self): # 重采样loss样本到96K - print("Please wait for SRC.") + # print("Please wait for SRC.") + logger.info("Please wait for SRC.") self.MidSignalSR = 96000 self.AfterSignalSR = self.MidSignalSR if self.MidSRCFalse: self.MidSignal = self.BeforeSignal else: self.MidSignal = resampy.resample(self.BeforeSignal, self.BeforeSignalSR, self.MidSignalSR, filter='kaiser_best') - print("Signal SRC complete.") + # print("Signal SRC complete.") + logger.info("Signal SRC complete.") - def MidFindThresholdPoint(self,_MidFFTResultSingle,_FFTPointCount): + def MidFindThresholdPoint(self, _MidFFTResultSingle, _FFTPointCount): # 鉴定频谱基本参数 _MidAmpData = abs(_MidFFTResultSingle[range(_FFTPointCount//2)]) # Step0. 找出基波幅度 _MidBaseFreqAmp = _MidAmpData.max() if self.MidPrint: - print("Signal max AMP -> %s" % _MidBaseFreqAmp) + # print("Signal max AMP -> %s" % _MidBaseFreqAmp) + logger.debug("Signal max AMP -> %s" % _MidBaseFreqAmp) # Step1. 找出接续的阈值 _MidThresholdHit = 1.0e-11 # 方差判定阈值 _MidThresholdPoint = 0 # 最后的阈值点 @@ -84,39 +104,40 @@ def MidFindThresholdPoint(self,_MidFFTResultSingle,_FFTPointCount): _MidForwardFreq = 3000 # 前向修正频率 _MidOrderFreq = 16000 # 钦定频率 # Rev.1: 检查接续点是否符合常理 - while _MidStartFlag or _MidThresholdPoint>round(_MidLegalFreq/(48000/(_FFTPointCount/2))): + while _MidStartFlag or _MidThresholdPoint > round(_MidLegalFreq / (48000 / (_FFTPointCount / 2))): _MidStartFlag = False - if (_MidThresholdPoint*(48000/(_FFTPointCount/2))) > int(self.BeforeSignalSR/2): + if (_MidThresholdPoint * (48000 / (_FFTPointCount / 2))) > int(self.BeforeSignalSR / 2): _MidThresholdHit *= 2 - for i in range(_MidStartFindPos,_MidFindRange): - if i+5>_MidFindRange: + for i in range(_MidStartFindPos, _MidFindRange): + if i + 5 > _MidFindRange: break # 计算连续五个采样*3 的方差,与阈值比较,判断频谱消失的位置 - if np.var(_MidAmpData[i:i+4]) < _MidThresholdHit and \ - np.var(_MidAmpData[i+1:i+5]) < _MidThresholdHit: + if np.var(_MidAmpData[i:i + 4]) < _MidThresholdHit and \ + np.var(_MidAmpData[i + 1:i + 5]) < _MidThresholdHit: # 定位到当前位置的前500Hz位置 - _MidThresholdPoint = i-round(_MidForwardFreq/(48000/(_FFTPointCount/2))) + _MidThresholdPoint = i - round(_MidForwardFreq / (48000 / (_FFTPointCount / 2))) break # 错误超过5把就强行钦定频率为18K _MidLoopCount += 1 if _MidLoopCount > 5: - _MidThresholdPoint = round(_MidOrderFreq/(48000/(_FFTPointCount/2))) + _MidThresholdPoint = round(_MidOrderFreq / (48000 / (_FFTPointCount / 2))) break # 打印函数返回信息 if self.MidPrint: - print("Signal threshold point -> %s @ %sHz Max Amp -> %s" % (_MidThresholdPoint,_MidThresholdPoint*(48000/(_MidFindRange+1)),_MidBaseFreqAmp)) + # print("Signal threshold point -> %s @ %sHz Max Amp -> %s" % (_MidThresholdPoint, _MidThresholdPoint * (48000 / (_MidFindRange + 1)), _MidBaseFreqAmp)) + logger.debug("Signal threshold point -> %s @ %sHz Max Amp -> %s" % (_MidThresholdPoint, _MidThresholdPoint * (48000 / (_MidFindRange + 1)), _MidBaseFreqAmp)) # _MidThresholdPoint = round(21000/(48000/(_FFTPointCount/2))) return _MidBaseFreqAmp, _MidThresholdPoint - def MidInsertJitter(self,_MidFFTResultDouble,_FFTPointCount,_MidThresholdPoint,_MidBaseFreqAmp): + def MidInsertJitter(self, _MidFFTResultDouble, _FFTPointCount, _MidThresholdPoint, _MidBaseFreqAmp): # 构造抖动 if _MidThresholdPoint <= 0: return _MidFFTResultDouble - for i in range(_MidThresholdPoint,_FFTPointCount-_MidThresholdPoint): + for i in range(_MidThresholdPoint, _FFTPointCount - _MidThresholdPoint): # Rev.0: 调整生成概率,频率越高概率越低 # Rev.1: 加入幅值判定,幅度越大概率越大 _GenPossible = abs((_FFTPointCount/2)-i)/((_FFTPointCount/2)-_MidThresholdPoint)*(_MidBaseFreqAmp/0.22) - if random.randint(0, 1000000) < 800000 * _GenPossible: # 0<=x<=10 + if random.randint(0, 1000000) < 800000 * _GenPossible: # 0<=x<=10 _MidRealValue = abs(_MidFFTResultDouble.real[i]) _BaseJitterMin = _MidRealValue * 0.5 * (1-_GenPossible) _BaseJitterMax = _MidRealValue * 6 * _GenPossible @@ -124,7 +145,7 @@ def MidInsertJitter(self,_MidFFTResultDouble,_FFTPointCount,_MidThresholdPoint,_ _AmpJitterMax = _MidBaseFreqAmp * _MidRealValue * 2 _AmpJitterPrefix = -1 if random.randint(0, 100000) < 50000 else 1 _MiditterPrefix = -1 if random.randint(0, 100000) < 50000 else 1 - _MidDeltaJitterValue = random.uniform(_BaseJitterMin,_BaseJitterMax) + _AmpJitterPrefix * random.uniform(_AmpJitterMin,_AmpJitterMax) + _MidDeltaJitterValue = random.uniform(_BaseJitterMin, _BaseJitterMax) + _AmpJitterPrefix * random.uniform(_AmpJitterMin, _AmpJitterMax) _MidFFTResultDouble.real[i] += _MiditterPrefix * _MidDeltaJitterValue return _MidFFTResultDouble @@ -135,7 +156,8 @@ def FinSaveFile(self): SaveFilePath = os.path.abspath(os.path.join(self.ReadyFilePath, os.pardir)) + "\\" OutputFileName = SaveFilePath + 'Output_%s.wav' % uuid.uuid4().hex librosa.output.write_wav(SaveFilePath, self.AfterSignal, self.AfterSignalSR) - print(Back.GREEN + Fore.WHITE + "SAVE DONE" + Back.BLACK + " Output path -> " + SaveFilePath) + # print(Back.GREEN + Fore.WHITE + "SAVE DONE" + Back.BLACK + " Output path -> " + SaveFilePath) + logger.info(Back.GREEN + Fore.WHITE + "SAVE DONE" + Back.BLACK + " Output path -> " + SaveFilePath) def run(self): # 加载文件启动SRC @@ -152,7 +174,7 @@ def run(self): # 信号总长度 _MidSignalLength = len(self.MidSignal[ChannelIndex]) # FFT分割数量 - _FFTPointCount = 1024 # 至少2048点,避免计算错误 + _FFTPointCount = 1024 # 至少2048点,避免计算错误 _MidDivCount = math.floor(_MidSignalLength/_FFTPointCount) # 实际重叠操作数量 = FFT分割数量 * 分块次数 _EachLength = 512 @@ -184,21 +206,22 @@ def run(self): # 执行FFT运算, 单边谱用于分析, 双边谱用于处理 if self.AnalysisWindow: _TempSignal *= scipy.signal.hann(_FFTPointCount, sym=0) - _MidFFTResultDouble = np.fft.fft(_TempSignal,_FFTPointCount)/(_FFTPointCount) - _MidFFTResultSingle = np.fft.fft(_TempSignal,_FFTPointCount)/(_FFTPointCount/2) + _MidFFTResultDouble = np.fft.fft(_TempSignal, _FFTPointCount) / (_FFTPointCount) + _MidFFTResultSingle = np.fft.fft(_TempSignal, _FFTPointCount) / (_FFTPointCount / 2) # 获取当前分段最大振幅, 处理阈值点 - _MidBaseFreqAmp, _MidThresholdPoint = self.MidFindThresholdPoint(_MidFFTResultSingle,_FFTPointCount) + _MidBaseFreqAmp, _MidThresholdPoint = self.MidFindThresholdPoint(_MidFFTResultSingle, _FFTPointCount) # 构造抖动到当前FFT实际值上 - _MidFFTAfterJitter = self.MidInsertJitter(_MidFFTResultDouble,_FFTPointCount,_MidThresholdPoint,_MidBaseFreqAmp) + _MidFFTAfterJitter = self.MidInsertJitter(_MidFFTResultDouble, _FFTPointCount, _MidThresholdPoint, _MidBaseFreqAmp) # 逆变换IFFT - _MidTimerDomSignal = np.fft.ifft(_MidFFTAfterJitter,n=_FFTPointCount) + _MidTimerDomSignal = np.fft.ifft(_MidFFTAfterJitter, n=_FFTPointCount) # 接续到新信号上 _AppendLength = _EachLength if SuffixFlag: _AppendLength = _FFTPointCount-SuffixLength _MidAppendSignal = _MidTimerDomSignal[0:_AppendLength] if self.MidPrint: - print("Per each length -> %s" % len(_MidAppendSignal)) + # print("Per each length -> %s" % len(_MidAppendSignal)) + logger.debug("Per each length -> %s" % len(_MidAppendSignal)) if ChannelIndex == 0: _EachPieceLeft = np.append(_EachPieceLeft, _MidAppendSignal) else: @@ -220,17 +243,19 @@ def run(self): else: _MidTotalEtaTime = _MidEtaTime # 进度比例 - _MidProgressRate = round(50*(SamplePointIndex+1)/_MidDivCount)+(50 if ChannelIndex == 1 else 0) - self.Update.emit(str(_MidTotalUsedTime)[:-5],str(_MidTotalEtaTime)[:-5],_MidProgressRate) + _MidProgressRate = round(50 * (SamplePointIndex + 1) / _MidDivCount) + (50 if ChannelIndex == 1 else 0) + self.Update.emit(str(_MidTotalUsedTime)[:-5], str(_MidTotalEtaTime)[:-5], _MidProgressRate) # 构造显示文本 if ChannelIndex == 0: _TempArrayLeft = np.append(_TempArrayLeft, _EachPieceLeft) if self.MidPrintProgress: - print("Left channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount-1) + Fore.WHITE + " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) + # print("Left channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount-1) + Fore.WHITE + " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) + logger.info("Left channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount-1) + Fore.WHITE + " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) else: _TempArrayRight = np.append(_TempArrayRight, _EachPieceRight) if self.MidPrintProgress: - print("Right channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount-1) + Fore.WHITE + " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) + # print("Right channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount-1) + Fore.WHITE + " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) + logger.info("Right channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount-1) + Fore.WHITE + " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) else: _TempAppendCount = 0 if ChannelIndex == 0: @@ -249,18 +274,18 @@ def run(self): class EmiyaEngineGUI(object): - + ''' Emiya Engine GUI ARGS ''' - + InputFilePath = '' OutputFilePath = '' IsUseWindow = False SplitSize = 500 IsStarted = False SubCore = QtCore.pyqtSignal() - + def __init__(self, MainWindow): - + MainWindow.setObjectName("MainWindow") MainWindow.resize(615, 272) MainWindow.setMinimumSize(QtCore.QSize(615, 272)) @@ -272,7 +297,7 @@ def __init__(self, MainWindow): MainWindow.setWindowTitle("Emiya Engine - 只要蘊藏著想成為真物的意志, 偽物就比真物還要來得真實") self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") - + self.Input_Label = QtWidgets.QLabel(self.centralwidget) self.Input_Label.setGeometry(QtCore.QRect(20, 20, 101, 16)) font = QtGui.QFont() @@ -280,7 +305,7 @@ def __init__(self, MainWindow): font.setPointSize(11) self.Input_Label.setFont(font) self.Input_Label.setObjectName("Input_Label") - + self.InputLineBox = QtWidgets.QLineEdit(self.centralwidget) self.InputLineBox.setGeometry(QtCore.QRect(130, 20, 401, 21)) font = QtGui.QFont() @@ -288,7 +313,7 @@ def __init__(self, MainWindow): font.setPointSize(10) self.InputLineBox.setFont(font) self.InputLineBox.setObjectName("InputLineBox") - + self.InputButton = QtWidgets.QPushButton(self.centralwidget) self.InputButton.setGeometry(QtCore.QRect(540, 20, 51, 21)) font = QtGui.QFont() @@ -297,7 +322,7 @@ def __init__(self, MainWindow): self.InputButton.setFont(font) self.InputButton.setObjectName("InputButton") self.InputButton.clicked.connect(self.SetInputFilePath) - + self.OutputLineBox = QtWidgets.QLineEdit(self.centralwidget) self.OutputLineBox.setGeometry(QtCore.QRect(130, 50, 401, 21)) font = QtGui.QFont() @@ -305,7 +330,7 @@ def __init__(self, MainWindow): font.setPointSize(10) self.OutputLineBox.setFont(font) self.OutputLineBox.setObjectName("OutputLineBox") - + self.OutputButton = QtWidgets.QPushButton(self.centralwidget) self.OutputButton.setGeometry(QtCore.QRect(540, 50, 51, 21)) font = QtGui.QFont() @@ -314,7 +339,7 @@ def __init__(self, MainWindow): self.OutputButton.setFont(font) self.OutputButton.setObjectName("OutputButton") self.OutputButton.clicked.connect(self.SetOutputFilePath) - + self.Output_Label = QtWidgets.QLabel(self.centralwidget) self.Output_Label.setGeometry(QtCore.QRect(20, 50, 101, 16)) font = QtGui.QFont() @@ -322,7 +347,7 @@ def __init__(self, MainWindow): font.setPointSize(11) self.Output_Label.setFont(font) self.Output_Label.setObjectName("Output_Label") - + self.IsUseWindowCheck = QtWidgets.QCheckBox(self.centralwidget) self.IsUseWindowCheck.setGeometry(QtCore.QRect(50, 90, 181, 31)) font = QtGui.QFont() @@ -332,7 +357,7 @@ def __init__(self, MainWindow): self.IsUseWindowCheck.setChecked(False) self.IsUseWindowCheck.setObjectName("IsUseWindowCheck") self.IsUseWindowCheck.stateChanged.connect(self.SetIsUseWindowCheck) - + self.SplitSizeSpin = QtWidgets.QSpinBox(self.centralwidget) self.SplitSizeSpin.setGeometry(QtCore.QRect(350, 90, 71, 31)) self.SplitSizeSpin.setMinimum(100) @@ -341,7 +366,7 @@ def __init__(self, MainWindow): self.SplitSizeSpin.setProperty("value", 500) self.SplitSizeSpin.setObjectName("SplitSizeSpin") self.SplitSizeSpin.valueChanged.connect(self.SetSplitSize) - + self.SplitSize_Label = QtWidgets.QLabel(self.centralwidget) self.SplitSize_Label.setGeometry(QtCore.QRect(250, 90, 91, 31)) font = QtGui.QFont() @@ -349,7 +374,7 @@ def __init__(self, MainWindow): font.setPointSize(11) self.SplitSize_Label.setFont(font) self.SplitSize_Label.setObjectName("SplitSize_Label") - + self.StartButton = QtWidgets.QPushButton(self.centralwidget) self.StartButton.setGeometry(QtCore.QRect(460, 90, 91, 31)) font = QtGui.QFont() @@ -358,11 +383,11 @@ def __init__(self, MainWindow): self.StartButton.setFont(font) self.StartButton.setObjectName("StartButton") self.StartButton.clicked.connect(self.RunProcess) - + self.groupBox = QtWidgets.QGroupBox(self.centralwidget) self.groupBox.setGeometry(QtCore.QRect(20, 130, 571, 101)) self.groupBox.setObjectName("groupBox") - + self.UsedTime_Label = QtWidgets.QLabel(self.groupBox) self.UsedTime_Label.setGeometry(QtCore.QRect(30, 30, 101, 16)) font = QtGui.QFont() @@ -370,12 +395,12 @@ def __init__(self, MainWindow): font.setPointSize(11) self.UsedTime_Label.setFont(font) self.UsedTime_Label.setObjectName("UsedTime_Label") - + self.GlobalProgressBar = QtWidgets.QProgressBar(self.groupBox) self.GlobalProgressBar.setGeometry(QtCore.QRect(100, 60, 451, 23)) self.GlobalProgressBar.setProperty("value", 0) self.GlobalProgressBar.setObjectName("GlobalProgressBar") - + self.GlobalProgressBar_Label = QtWidgets.QLabel(self.groupBox) self.GlobalProgressBar_Label.setGeometry(QtCore.QRect(30, 60, 61, 21)) font = QtGui.QFont() @@ -383,25 +408,25 @@ def __init__(self, MainWindow): font.setPointSize(11) self.GlobalProgressBar_Label.setFont(font) self.GlobalProgressBar_Label.setObjectName("GlobalProgressBar_Label") - + self.UsedTime = QtWidgets.QLabel(self.groupBox) self.UsedTime.setGeometry(QtCore.QRect(150, 30, 101, 16)) font = QtGui.QFont() font.setFamily("微软雅黑") font.setPointSize(11) self.UsedTime.setFont(font) - self.UsedTime.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.UsedTime.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) self.UsedTime.setObjectName("UsedTime") - + self.EtaTime = QtWidgets.QLabel(self.groupBox) self.EtaTime.setGeometry(QtCore.QRect(410, 30, 91, 16)) font = QtGui.QFont() font.setFamily("微软雅黑") font.setPointSize(11) self.EtaTime.setFont(font) - self.EtaTime.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.EtaTime.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) self.EtaTime.setObjectName("EtaTime") - + self.EtaTime_Label = QtWidgets.QLabel(self.groupBox) self.EtaTime_Label.setGeometry(QtCore.QRect(290, 30, 101, 16)) font = QtGui.QFont() @@ -409,7 +434,7 @@ def __init__(self, MainWindow): font.setPointSize(11) self.EtaTime_Label.setFont(font) self.EtaTime_Label.setObjectName("EtaTime_Label") - + MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 615, 22)) @@ -429,7 +454,6 @@ def __init__(self, MainWindow): self.TextedUI(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) - def TextedUI(self, MainWindow): _translate = QtCore.QCoreApplication.translate @@ -450,13 +474,12 @@ def TextedUI(self, MainWindow): self.menu_F.setTitle(_translate("MainWindow", "文件(&F)")) self.action_OpenFile.setText(_translate("MainWindow", "打开(&O)")) self.action_Exit.setText(_translate("MainWindow", "退出(&E)")) - def SetInputFilePath(self): self.InputFilePath = str(QtWidgets.QFileDialog.getOpenFileName(None, "选择待处理的文件")[0]) if self.InputFilePath: self.InputLineBox.setText(self.InputFilePath) - + def SetOutputFilePath(self): self.OutputFilePath = str(QtWidgets.QFileDialog.getSaveFileName(None, "设置输出文件的位置及文件名")[0]) if self.OutputFilePath: @@ -478,7 +501,7 @@ def RunProcess(self): if self.InputFilePath and self.OutputFilePath: self.IsStarted = True self.StartButton.setText("停止处理") - self.CoreObject=EmiyaEngineCore(None,self.InputFilePath,self.OutputFilePath,1,self.SplitSize,self.IsUseWindow) + self.CoreObject = EmiyaEngineCore(None, self.InputFilePath, self.OutputFilePath, 1, self.SplitSize, self.IsUseWindow) self.CoreObject.Update.connect(self.UpdateState) self.CoreObject.Finish.connect(self.DetectEnd) self.CoreObject.start() @@ -489,13 +512,14 @@ def RunProcess(self): self.UsedTime.setText("00:00:00") self.EtaTime.setText("00:00:00") self.GlobalProgressBar.setValue(0) - print("所有处理已停止") + # print("所有处理已停止") + logger.info("所有处理已停止") def DetectEnd(self): self.IsStarted = False self.StartButton.setText("开始处理") - def UpdateState(self,_TimeUsed,_EtaTime,_ProgressRate): + def UpdateState(self, _TimeUsed, _EtaTime, _ProgressRate): self.UsedTime.setText(str(_TimeUsed)) self.EtaTime.setText(str(_EtaTime)) self.GlobalProgressBar.setValue(_ProgressRate) @@ -509,4 +533,3 @@ def UpdateState(self,_TimeUsed,_EtaTime,_ProgressRate): # ui.setupUi(MainWindow) MainWindow.show() sys.exit(app.exec_()) - From 52a97a4dbc0c7dd1cdcd01a7c6ccaa501c4172b8 Mon Sep 17 00:00:00 2001 From: Cykrt Date: Sat, 11 Feb 2017 11:48:38 +0800 Subject: [PATCH 2/3] improve debug system several bug fixed --- EmiyaEngine.py | 9 ++++----- GUI_EmiyaEngine.py | 11 +++++------ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/EmiyaEngine.py b/EmiyaEngine.py index 9c89e67..6e81370 100644 --- a/EmiyaEngine.py +++ b/EmiyaEngine.py @@ -27,13 +27,12 @@ %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', filename='Emiya.log', - filemode='a+' + filemode='w+' ) logger = logging.getLogger("EmiaLog") -console = logging.StreamHandler() -console.setLevel(logging.INFO) -# add the handler to the root logger -logger.addHandler(console) +# console = logging.StreamHandler() +# console.setLevel(logging.INFO) +# logger.addHandler(console) class EmiyaEngineCore: diff --git a/GUI_EmiyaEngine.py b/GUI_EmiyaEngine.py index 5d3108e..4693b43 100644 --- a/GUI_EmiyaEngine.py +++ b/GUI_EmiyaEngine.py @@ -18,14 +18,13 @@ format='%(asctime)s [line:%(lineno)d] \ %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', - filename='Emiya.log', - filemode='a+' + filename='EmiyaGUI.log', + filemode='w+' ) logger = logging.getLogger("EmiaLog") -console = logging.StreamHandler() -console.setLevel(logging.INFO) -# add the handler to the root logger -logger.addHandler(console) +# console = logging.StreamHandler() +# console.setLevel(logging.INFO) +# logger.addHandler(console) class EmiyaEngineCore(QtCore.QThread): From 8472ce032317ea300493ebc4c07f0900dfcc63a0 Mon Sep 17 00:00:00 2001 From: Cykrt Date: Sat, 11 Feb 2017 14:42:28 +0800 Subject: [PATCH 3/3] improve log system finished. --- EmiyaEngine.py | 64 ++++++++++++++++++++-------------------- GUI_EmiyaEngine.py | 73 ++++++++++++++++++++++++++++++---------------- 2 files changed, 81 insertions(+), 56 deletions(-) diff --git a/EmiyaEngine.py b/EmiyaEngine.py index 6e81370..25e4124 100644 --- a/EmiyaEngine.py +++ b/EmiyaEngine.py @@ -29,7 +29,7 @@ filename='Emiya.log', filemode='w+' ) -logger = logging.getLogger("EmiaLog") +logger = logging.getLogger("EmiyaLog") # console = logging.StreamHandler() # console.setLevel(logging.INFO) # logger.addHandler(console) @@ -50,7 +50,7 @@ class EmiyaEngineCore: AnalysisWindow = False # 分析接续点用的单边FFT是否加窗 MidSRCFalse = False # SRC开关, 为True时就会取消掉SRC步骤 MidPrint = False # 打印细节日志开关 - MidPrintProgress = True # 打印进度信息 + MidPrintProgress = True # 打印进度信息 def __init__(self, _InputFilePath, _DebugSwitch, _SplitSize, _WindowSwitch): # 输入样本: @@ -76,8 +76,8 @@ def LoadFile(self): self.ReadyFilePath, sr=None, mono=False) self.AfterSignalLeft = np.array([()]) self.AfterSignalRight = np.array([()]) - # print("Load signal complete. ChannelCount: %s SampleRate: %s Hz" % - # (str(len(self.BeforeSignal)), str(self.BeforeSignalSR))) + print("Load signal complete. ChannelCount: %s SampleRate: %s Hz" % ( + str(len(self.BeforeSignal)), str(self.BeforeSignalSR))) logger.info("Load signal complete. ChannelCount: %s SampleRate: %s Hz" % ( str(len(self.BeforeSignal)), str(self.BeforeSignalSR))) @@ -92,7 +92,7 @@ def MidUpSRC(self): else: self.MidSignal = resampy.resample( self.BeforeSignal, self.BeforeSignalSR, self.MidSignalSR, filter='kaiser_best') - # print("Signal SRC complete.") + print("Signal SRC complete.") logging.info("Signal SRC complete.") def MidFindThresholdPoint(self, _MidFFTResultSingle, _FFTPointCount): @@ -101,15 +101,13 @@ def MidFindThresholdPoint(self, _MidFFTResultSingle, _FFTPointCount): # Step0. 找出基波幅度 _MidBaseFreqAmp = _MidAmpData.max() if self.MidPrint: - # print("Signal max AMP -> %s" % _MidBaseFreqAmp) - logger.debug("Signal max AMP -> %s" % _MidBaseFreqAmp) + print("Signal max AMP -> %s" % _MidBaseFreqAmp) + logger.debug("Signal max AMP -> %s" % _MidBaseFreqAmp) # Step1. 找出接续的阈值 _MidThresholdHit = 1.0e-11 # 方差判定阈值 _MidThresholdPoint = 0 # 最后的阈值点 - _MidFindRange = int((_FFTPointCount / 2) - - 1) # 搜索的范围 - _MidStartFindPos = round( - 2000 / (48000 / (_FFTPointCount / 2))) # 从2K频点附近开始寻找,加快速度 + _MidFindRange = int((_FFTPointCount / 2) - 1) # 搜索的范围 + _MidStartFindPos = round(2000 / (48000 / (_FFTPointCount / 2)))# 从2K频点附近开始寻找,加快速度 _MidStartFlag = True # 循环用的启动Flag _MidLoopCount = 0 # 循环计数器 _MidLegalFreq = 22000 # 判定结果合法的阈值频率 @@ -127,8 +125,7 @@ def MidFindThresholdPoint(self, _MidFFTResultSingle, _FFTPointCount): if np.var(_MidAmpData[i:i + 4]) < _MidThresholdHit and \ np.var(_MidAmpData[i + 1:i + 5]) < _MidThresholdHit: # 定位到当前位置的前500Hz位置 - _MidThresholdPoint = i - \ - round(_MidForwardFreq / (48000 / (_FFTPointCount / 2))) + _MidThresholdPoint = i - round(_MidForwardFreq / (48000 / (_FFTPointCount / 2))) break # 错误超过5把就强行钦定频率为18K _MidLoopCount += 1 @@ -138,10 +135,14 @@ def MidFindThresholdPoint(self, _MidFFTResultSingle, _FFTPointCount): break # 打印函数返回信息 if self.MidPrint: - # print("Signal threshold point -> %s @ %sHz Max Amp -> %s" % (_MidThresholdPoint, - # _MidThresholdPoint * (48000 / (_MidFindRange + 1)), _MidBaseFreqAmp)) - logger.debug("Signal threshold point -> %s @ %sHz Max Amp -> %s" % (_MidThresholdPoint, - _MidThresholdPoint * (48000 / (_MidFindRange + 1)), _MidBaseFreqAmp)) + print("Signal threshold point -> %s @ %sHz Max Amp -> %s" % (_MidThresholdPoint, + _MidThresholdPoint * + (48000 / (_MidFindRange + 1)), + _MidBaseFreqAmp)) + logger.debug("Signal threshold point -> %s @ %sHz Max Amp -> %s" % (_MidThresholdPoint, + _MidThresholdPoint * + (48000 / (_MidFindRange + 1)), + _MidBaseFreqAmp)) # _MidThresholdPoint = round(21000/(48000/(_FFTPointCount/2))) return _MidBaseFreqAmp, _MidThresholdPoint @@ -266,34 +267,35 @@ def ProcessCore(self): _TempArrayLeft = np.append( _TempArrayLeft, _EachPieceLeft) if self.MidPrintProgress: - # print("Left channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount - 1) + Fore.WHITE + - # " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) - logger.info("Left channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount - 1) + Fore.WHITE + - " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) + print("Left channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + + str(_MidDivCount - 1) + Fore.WHITE + " TIME USED -> " + Fore.YELLOW + + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) + logger.info("Left channel progress rate -> " + str(SamplePointIndex) + " / " + + str(_MidDivCount - 1) + " TIME USED -> " + + str(_MidUsedTime) + " ETA -> " + str(_MidEtaTime)) else: _TempArrayRight = np.append( _TempArrayRight, _EachPieceRight) if self.MidPrintProgress: - # print("Right channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount - 1) + Fore.WHITE + - # " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) - logger.info("Right channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount - 1) + Fore.WHITE + - " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) + print("Right channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + + str(_MidDivCount - 1) + Fore.WHITE + " TIME USED -> " + Fore.YELLOW + + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) + logger.info("Right channel progress rate -> " + str(SamplePointIndex) + " / " + + str(_MidDivCount - 1) + " TIME USED -> " + + str(_MidUsedTime) + " ETA -> " + str(_MidEtaTime)) else: _TempAppendCount = 0 if ChannelIndex == 0: - self.AfterSignalLeft = np.append( - self.AfterSignalLeft, _TempArrayLeft) + self.AfterSignalLeft = np.append(self.AfterSignalLeft, _TempArrayLeft) _TempArrayLeft = np.array([()]) else: - self.AfterSignalRight = np.append( - self.AfterSignalRight, _TempArrayRight) + self.AfterSignalRight = np.append(self.AfterSignalRight, _TempArrayRight) _TempArrayRight = np.array([()]) # 倒腾计数器 _TempAppendCount += 1 if SuffixFlag: break - self.AfterSignal = np.array( - [self.AfterSignalLeft.real, self.AfterSignalRight.real]) + self.AfterSignal = np.array([self.AfterSignalLeft.real, self.AfterSignalRight.real]) self.FinSaveFile() diff --git a/GUI_EmiyaEngine.py b/GUI_EmiyaEngine.py index 4693b43..feb3904 100644 --- a/GUI_EmiyaEngine.py +++ b/GUI_EmiyaEngine.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- + import os import argparse import datetime @@ -21,7 +22,7 @@ filename='EmiyaGUI.log', filemode='w+' ) -logger = logging.getLogger("EmiaLog") +logger = logging.getLogger("EmiyaLog") # console = logging.StreamHandler() # console.setLevel(logging.INFO) # logger.addHandler(console) @@ -68,20 +69,23 @@ def LoadFile(self): self.BeforeSignal, self.BeforeSignalSR = librosa.load(self.ReadyFilePath, sr=None, mono=False) self.AfterSignalLeft = np.array([()]) self.AfterSignalRight = np.array([()]) - # print("Load signal complete. ChannelCount: %s SampleRate: %s Hz" % (str(len(self.BeforeSignal)), str(self.BeforeSignalSR))) - logger.info("Load signal complete. ChannelCount: %s SampleRate: %s Hz" % (str(len(self.BeforeSignal)), str(self.BeforeSignalSR))) + print("Load signal complete. ChannelCount: %s SampleRate: %s Hz" % (str(len(self.BeforeSignal)), + str(self.BeforeSignalSR))) + logger.info("Load signal complete. ChannelCount: %s SampleRate: %s Hz" % (str(len(self.BeforeSignal)), + str(self.BeforeSignalSR))) def MidUpSRC(self): # 重采样loss样本到96K - # print("Please wait for SRC.") + print("Please wait for SRC.") logger.info("Please wait for SRC.") self.MidSignalSR = 96000 self.AfterSignalSR = self.MidSignalSR if self.MidSRCFalse: self.MidSignal = self.BeforeSignal else: - self.MidSignal = resampy.resample(self.BeforeSignal, self.BeforeSignalSR, self.MidSignalSR, filter='kaiser_best') - # print("Signal SRC complete.") + self.MidSignal = resampy.resample(self.BeforeSignal, self.BeforeSignalSR, + self.MidSignalSR, filter='kaiser_best') + print("Signal SRC complete.") logger.info("Signal SRC complete.") def MidFindThresholdPoint(self, _MidFFTResultSingle, _FFTPointCount): @@ -90,8 +94,8 @@ def MidFindThresholdPoint(self, _MidFFTResultSingle, _FFTPointCount): # Step0. 找出基波幅度 _MidBaseFreqAmp = _MidAmpData.max() if self.MidPrint: - # print("Signal max AMP -> %s" % _MidBaseFreqAmp) - logger.debug("Signal max AMP -> %s" % _MidBaseFreqAmp) + print("Signal max AMP -> %s" % _MidBaseFreqAmp) + logger.debug("Signal max AMP -> %s" % _MidBaseFreqAmp) # Step1. 找出接续的阈值 _MidThresholdHit = 1.0e-11 # 方差判定阈值 _MidThresholdPoint = 0 # 最后的阈值点 @@ -123,8 +127,14 @@ def MidFindThresholdPoint(self, _MidFFTResultSingle, _FFTPointCount): break # 打印函数返回信息 if self.MidPrint: - # print("Signal threshold point -> %s @ %sHz Max Amp -> %s" % (_MidThresholdPoint, _MidThresholdPoint * (48000 / (_MidFindRange + 1)), _MidBaseFreqAmp)) - logger.debug("Signal threshold point -> %s @ %sHz Max Amp -> %s" % (_MidThresholdPoint, _MidThresholdPoint * (48000 / (_MidFindRange + 1)), _MidBaseFreqAmp)) + print("Signal threshold point -> %s @ %sHz Max Amp -> %s" % (_MidThresholdPoint, + _MidThresholdPoint * + (48000 / (_MidFindRange + 1)), + _MidBaseFreqAmp)) + logger.debug("Signal threshold point -> %s @ %sHz Max Amp -> %s" % (_MidThresholdPoint, + _MidThresholdPoint * + (48000 / (_MidFindRange + 1)), + _MidBaseFreqAmp)) # _MidThresholdPoint = round(21000/(48000/(_FFTPointCount/2))) return _MidBaseFreqAmp, _MidThresholdPoint @@ -144,7 +154,8 @@ def MidInsertJitter(self, _MidFFTResultDouble, _FFTPointCount, _MidThresholdPoin _AmpJitterMax = _MidBaseFreqAmp * _MidRealValue * 2 _AmpJitterPrefix = -1 if random.randint(0, 100000) < 50000 else 1 _MiditterPrefix = -1 if random.randint(0, 100000) < 50000 else 1 - _MidDeltaJitterValue = random.uniform(_BaseJitterMin, _BaseJitterMax) + _AmpJitterPrefix * random.uniform(_AmpJitterMin, _AmpJitterMax) + _MidDeltaJitterValue = random.uniform(_BaseJitterMin, _BaseJitterMax) + \ + _AmpJitterPrefix * random.uniform(_AmpJitterMin, _AmpJitterMax) _MidFFTResultDouble.real[i] += _MiditterPrefix * _MidDeltaJitterValue return _MidFFTResultDouble @@ -155,8 +166,8 @@ def FinSaveFile(self): SaveFilePath = os.path.abspath(os.path.join(self.ReadyFilePath, os.pardir)) + "\\" OutputFileName = SaveFilePath + 'Output_%s.wav' % uuid.uuid4().hex librosa.output.write_wav(SaveFilePath, self.AfterSignal, self.AfterSignalSR) - # print(Back.GREEN + Fore.WHITE + "SAVE DONE" + Back.BLACK + " Output path -> " + SaveFilePath) - logger.info(Back.GREEN + Fore.WHITE + "SAVE DONE" + Back.BLACK + " Output path -> " + SaveFilePath) + print(Back.GREEN + Fore.WHITE + "SAVE DONE" + Back.BLACK + " Output path -> " + SaveFilePath) + logger.info("SAVE DONE Output path -> " + SaveFilePath) def run(self): # 加载文件启动SRC @@ -208,9 +219,11 @@ def run(self): _MidFFTResultDouble = np.fft.fft(_TempSignal, _FFTPointCount) / (_FFTPointCount) _MidFFTResultSingle = np.fft.fft(_TempSignal, _FFTPointCount) / (_FFTPointCount / 2) # 获取当前分段最大振幅, 处理阈值点 - _MidBaseFreqAmp, _MidThresholdPoint = self.MidFindThresholdPoint(_MidFFTResultSingle, _FFTPointCount) + _MidBaseFreqAmp, _MidThresholdPoint = self.MidFindThresholdPoint(_MidFFTResultSingle, + _FFTPointCount) # 构造抖动到当前FFT实际值上 - _MidFFTAfterJitter = self.MidInsertJitter(_MidFFTResultDouble, _FFTPointCount, _MidThresholdPoint, _MidBaseFreqAmp) + _MidFFTAfterJitter = self.MidInsertJitter(_MidFFTResultDouble, _FFTPointCount, + _MidThresholdPoint, _MidBaseFreqAmp) # 逆变换IFFT _MidTimerDomSignal = np.fft.ifft(_MidFFTAfterJitter, n=_FFTPointCount) # 接续到新信号上 @@ -219,8 +232,8 @@ def run(self): _AppendLength = _FFTPointCount-SuffixLength _MidAppendSignal = _MidTimerDomSignal[0:_AppendLength] if self.MidPrint: - # print("Per each length -> %s" % len(_MidAppendSignal)) - logger.debug("Per each length -> %s" % len(_MidAppendSignal)) + print("Per each length -> %s" % len(_MidAppendSignal)) + logger.debug("Per each length -> %s" % len(_MidAppendSignal)) if ChannelIndex == 0: _EachPieceLeft = np.append(_EachPieceLeft, _MidAppendSignal) else: @@ -242,19 +255,28 @@ def run(self): else: _MidTotalEtaTime = _MidEtaTime # 进度比例 - _MidProgressRate = round(50 * (SamplePointIndex + 1) / _MidDivCount) + (50 if ChannelIndex == 1 else 0) + _MidProgressRate = round(50 * (SamplePointIndex + 1) / _MidDivCount) + \ + (50 if ChannelIndex == 1 else 0) self.Update.emit(str(_MidTotalUsedTime)[:-5], str(_MidTotalEtaTime)[:-5], _MidProgressRate) # 构造显示文本 if ChannelIndex == 0: _TempArrayLeft = np.append(_TempArrayLeft, _EachPieceLeft) if self.MidPrintProgress: - # print("Left channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount-1) + Fore.WHITE + " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) - logger.info("Left channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount-1) + Fore.WHITE + " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) + print("Left channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + + str(_MidDivCount-1) + Fore.WHITE + " TIME USED -> " + Fore.YELLOW + + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) + logger.info("Left channel progress rate -> " + str(SamplePointIndex) + " / " + + str(_MidDivCount-1) + " TIME USED -> " + + str(_MidUsedTime) + " ETA -> " + str(_MidEtaTime)) else: _TempArrayRight = np.append(_TempArrayRight, _EachPieceRight) if self.MidPrintProgress: - # print("Right channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount-1) + Fore.WHITE + " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) - logger.info("Right channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + str(_MidDivCount-1) + Fore.WHITE + " TIME USED -> " + Fore.YELLOW + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) + print("Right channel progress rate -> " + Fore.CYAN + str(SamplePointIndex) + " / " + + str(_MidDivCount-1) + Fore.WHITE + " TIME USED -> " + Fore.YELLOW + + str(_MidUsedTime) + Fore.WHITE + " ETA -> " + Fore.GREEN + str(_MidEtaTime)) + logger.info("Right channel progress rate -> " + str(SamplePointIndex) + " / " + + str(_MidDivCount-1) + " TIME USED -> " + + str(_MidUsedTime) + " ETA -> " + str(_MidEtaTime)) else: _TempAppendCount = 0 if ChannelIndex == 0: @@ -274,7 +296,7 @@ def run(self): class EmiyaEngineGUI(object): - ''' Emiya Engine GUI ARGS ''' + # Emiya Engine GUI ARGS InputFilePath = '' OutputFilePath = '' @@ -500,7 +522,8 @@ def RunProcess(self): if self.InputFilePath and self.OutputFilePath: self.IsStarted = True self.StartButton.setText("停止处理") - self.CoreObject = EmiyaEngineCore(None, self.InputFilePath, self.OutputFilePath, 1, self.SplitSize, self.IsUseWindow) + self.CoreObject = EmiyaEngineCore(None, self.InputFilePath, self.OutputFilePath, + 1, self.SplitSize, self.IsUseWindow) self.CoreObject.Update.connect(self.UpdateState) self.CoreObject.Finish.connect(self.DetectEnd) self.CoreObject.start() @@ -511,7 +534,7 @@ def RunProcess(self): self.UsedTime.setText("00:00:00") self.EtaTime.setText("00:00:00") self.GlobalProgressBar.setValue(0) - # print("所有处理已停止") + print("所有处理已停止") logger.info("所有处理已停止") def DetectEnd(self):