Skip to content

Commit

Permalink
Update to RC 2
Browse files Browse the repository at this point in the history
  • Loading branch information
Sg4Dylan committed Mar 25, 2019
1 parent 173864b commit 28921d6
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 56 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Emiya Engine 是一个用来丰富音频频谱的脚本。可以将频谱变得

### 当前版本:

`RC Version 1`
`RC Version 2`

### 编年史:

Expand Down Expand Up @@ -41,6 +41,10 @@ Emiya Engine 是一个用来丰富音频频谱的脚本。可以将频谱变得
- `RC 1`
> 加入了参数辅助调整选项
> 尝试在 CopyBand 模式下保护动态范围
- `RC 2`
> 加入了参数自动加载/保存特性
> 加入了截止/调制频率的优化建议
> 提高了系数精度
### RC 版本使用说明:

Expand Down
16 changes: 15 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,19 @@
"ui": "res/window.ui",
"lang": "chs",
"eng": "res/eng.qm",
"chs": "res/chs.ts"
"chs": "res/chs.ts",
"defaultMode": true,
"commOutputSr": 1,
"commInsertSr": 0,
"useSampleOutput": false,
"useOptimizer": false,
"dynProtect": false,
"cbHarmonicHpfCutFreq": 6000,
"cbHarmonicShiftFreq": 16000,
"cbHarmonicGain": 1.5,
"cbPercussiveHpfCutFreq": 6000,
"cbPercussiveShiftFreq": 16000,
"cbPercussiveGain": 2.5,
"akkoJitterDownFactor": 0.02,
"akkoJitterUpFactor": 0.08
}
129 changes: 91 additions & 38 deletions core/copyband.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import librosa
import resampy


def core(
input_path,output_path,
output_sr=48000,inter_sr=1,
Expand All @@ -14,6 +13,7 @@ def core(
):

def hpd_n_shift(data, lpf, sft, gain):
sr = output_sr*inter_sr
# 高通滤波
b,a = signal.butter(3,lpf/(sr/2),'high')
data = librosa.stft(signal.filtfilt(b,a,librosa.istft(data)))
Expand Down Expand Up @@ -58,7 +58,6 @@ def hpd_n_shift(data, lpf, sft, gain):
adp_power = np.mean(np.abs(adp))
src_power = np.mean(np.abs(chan))
src_f = 1-(adp_power/src_power)
d_ls.append(src_f)
adp += src_f*chan
chan *= 0
chan += adp
Expand All @@ -80,59 +79,115 @@ def hpd_n_shift(data, lpf, sft, gain):
# 参数优化
if not opti_mode:
return
optimizer(output_path,
optimizer(input_path,output_path,
percussive_hpfc,percussive_stf,
percussive_gain,msgbox)


def optimizer(
input_path,
output_path,
hpf_cut_freq,
hpf_mod_freq,
hpf_gain,
msgbox
):

# 加载音频
y, sr = librosa.load(output_path,mono=False,sr=None)
# 产生 STFT 谱
stft_list = [librosa.stft(chan) for chan in y]
def envelope_detect():

# 加载音频
y, sr = librosa.load(input_path,mono=False,sr=None)
# 产生 STFT 谱
stft_list = [librosa.stft(chan) for chan in y]
# 阈值
t_gain = 85
# 频谱边缘
edge_freq = 0

for chan in stft_list:
chan_sum = chan[:,0]
for i in range(1,chan.shape[1]):
chan_sum = np.add(chan_sum,chan[:,i])

chan_sum = np.abs(chan_sum)
chan_max = np.max(chan_sum)

# 滑动窗口
for p in range(len(chan_sum)):
s_win = 8
s_mean = 0
if p+s_win<len(chan_sum):
s_mean = np.mean(chan_sum[p:p+s_win])
else:
s_mean = np.mean(
np.append(
chan_sum[p:len(chan_sum)],
np.repeat(chan_sum[len(chan_sum)-1],p+s_win-len(chan_sum))
)
)
if s_mean < (chan_max/(np.exp2((t_gain)/6))):
edge_freq += p*sr/2/1024
break

edge_freq /= 2
if edge_freq > 2500:
edge_freq -= 3500
return edge_freq

# 加载
l_power = 0
h_power = 0
for chan in stft_list:
# 截止频率为 hpf_cut_freq 的 HPF
b,a = signal.butter(11,hpf_cut_freq/(sr/2),'high')
l_data = librosa.stft(signal.filtfilt(b,a,librosa.istft(chan)))
l_power_sum = np.mean(np.abs(l_data.real))
def hpf_gain_calc():
# 加载音频
y, sr = librosa.load(output_path,mono=False,sr=None)
# 产生 STFT 谱
stft_list = [librosa.stft(chan) for chan in y]

# 截止频率为 hpf_mod_freq 的 HPF
b,a = signal.butter(11,hpf_mod_freq/(sr/2),'high')
h_data = librosa.stft(signal.filtfilt(b,a,librosa.istft(chan)))
h_power_sum = np.mean(np.abs(h_data.real))
# 加载
l_power = 0
h_power = 0

# 移相差分
l_power_sum -= h_power_sum
for chan in stft_list:
# 截止频率为 hpf_cut_freq 的 HPF
b,a = signal.butter(11,hpf_cut_freq/(sr/2),'high')
l_data = librosa.stft(signal.filtfilt(b,a,librosa.istft(chan)))
l_power_sum = np.mean(np.abs(l_data.real))

# 截止频率为 hpf_mod_freq 的 HPF
b,a = signal.butter(11,hpf_mod_freq/(sr/2),'high')
h_data = librosa.stft(signal.filtfilt(b,a,librosa.istft(chan)))
h_power_sum = np.mean(np.abs(h_data.real))

# 移相差分
l_power_sum -= h_power_sum

# 合并音轨数据
l_power += l_power_sum
h_power += h_power_sum

# 测试 HPF 输出
chan *= 0
chan += h_data

# 频带比例矫正能量比例
pf = ((sr/2)-hpf_mod_freq)/(hpf_mod_freq-hpf_cut_freq)
l_power *= pf
# 计算当前增益比率
lnh_power = np.log2(l_power/h_power) * 6
# 如果是正数,就是增益偏小
target_r = np.exp2((lnh_power-14.8)/6)
recomm_r = target_r*hpf_gain

# 合并音轨数据
l_power += l_power_sum
h_power += h_power_sum
#istft_list = [librosa.istft(chan) for chan in stft_list]
#librosa.output.write_wav('kk.wav', np.array(istft_list), sr)

# 测试 HPF 输出
chan *= 0
chan += h_data
return l_power, h_power, lnh_power, recomm_r, sr

edge_freq = envelope_detect()
l_power, h_power, lnh_power, recomm_r, sr = hpf_gain_calc()

# 频带比例矫正能量比例
pf = ((sr/2)-hpf_mod_freq)/(hpf_mod_freq-hpf_cut_freq)
l_power *= pf
# 计算当前增益比率
lnh_power = np.log2(l_power/h_power) * 6
# 如果是正数,就是增益偏小
target_r = np.exp2((lnh_power-14.8)/6)
recomm_r = target_r*hpf_gain
# Tips
tips = ''
tips = '频率设置建议:\n'
tips += f'建议截止频率:{edge_freq*0.4}Hz\n'
tips += f'建议调制频率:{edge_freq}Hz\n\n'
tips += '增益设置建议:\n'
tips += f'来源加和:{l_power}\n'
tips += f'目标加和:{h_power}\n'
tips += f'当前增益:{lnh_power} dB\n'
Expand All @@ -142,5 +197,3 @@ def optimizer(
tips += '建议维持冲击增益,微调谐波增益!'

msgbox.emit('优化建议',tips,1)
#istft_list = [librosa.istft(chan) for chan in stft_list]
#librosa.output.write_wav('kk.wav', np.array(istft_list), sr)
37 changes: 37 additions & 0 deletions main.pyw
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow):
self.lang = json.loads(open('res/lang.json','rb').read())[Config['lang']]
self.input_path,self.output_path = None, None
self.is_started = False
self.load_config()

def _bind_ui_(self):
self.selectInputFile.clicked.connect(lambda:self.openfile(False))
Expand All @@ -67,6 +68,8 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow):
QtWidgets.QMessageBox.warning(self,self.lang['MsgBoxW'],self.lang['LackFile'],QtWidgets.QMessageBox.Ok)
return

self.save_config()

mode = 1
if self.useCopyBand.isChecked():
mode = 0
Expand Down Expand Up @@ -115,6 +118,40 @@ class MainUI(QtWidgets.QMainWindow, Ui_MainWindow):
QtWidgets.QMessageBox.critical(self, title, text)
else:
QtWidgets.QMessageBox.information(self, title, text)

def load_config(self):
self.useCopyBand.setChecked(Config.get('defaultMode',True))
self.commOutputSr.setCurrentIndex(Config.get('commOutputSr',1))
self.commInsertSr.setCurrentIndex(Config.get('commInsertSr',0))
self.useSampleOutput.setChecked(Config.get('useSampleOutput',False))
self.useOptimizer.setChecked(Config.get('useOptimizer',False))
self.dynProtect.setChecked(Config.get('dynProtect',False))
self.cbHarmonicHpfCutFreq.setValue(Config.get('cbHarmonicHpfCutFreq',6000))
self.cbHarmonicShiftFreq.setValue(Config.get('cbHarmonicShiftFreq',16000))
self.cbHarmonicGain.setValue(Config.get('cbHarmonicGain',1.5))
self.cbPercussiveHpfCutFreq.setValue(Config.get('cbPercussiveHpfCutFreq',6000))
self.cbPercussiveShiftFreq.setValue(Config.get('cbPercussiveShiftFreq',16000))
self.cbPercussiveGain.setValue(Config.get('cbPercussiveGain',2.5))
self.akkoJitterDownFactor.setValue(Config.get('akkoJitterDownFactor',0.02))
self.akkoJitterUpFactor.setValue(Config.get('akkoJitterUpFactor',0.08))

def save_config(self):
Config['defaultMode'] = self.useCopyBand.isChecked()
Config['commOutputSr'] = self.commOutputSr.currentIndex()
Config['commInsertSr'] = self.commInsertSr.currentIndex()
Config['useSampleOutput'] = self.useSampleOutput.isChecked()
Config['useOptimizer'] = self.useOptimizer.isChecked()
Config['dynProtect'] = self.dynProtect.isChecked()
Config['cbHarmonicHpfCutFreq'] = int(self.cbHarmonicHpfCutFreq.value())
Config['cbHarmonicShiftFreq'] = int(self.cbHarmonicShiftFreq.value())
Config['cbHarmonicGain'] = float(self.cbHarmonicGain.value())
Config['cbPercussiveHpfCutFreq'] = int(self.cbPercussiveHpfCutFreq.value())
Config['cbPercussiveShiftFreq'] = int(self.cbPercussiveShiftFreq.value())
Config['cbPercussiveGain'] = float(self.cbPercussiveGain.value())
Config['akkoJitterDownFactor'] = float(self.akkoJitterDownFactor.value())
Config['akkoJitterUpFactor'] = float(self.akkoJitterUpFactor.value())
with open('config.json','wb') as wp:
wp.write(json.dumps(Config,indent = 4).encode('UTF-8'))


if __name__ == "__main__":
Expand Down
Loading

0 comments on commit 28921d6

Please sign in to comment.