882 lines
29 KiB
Python
882 lines
29 KiB
Python
"""
|
||
均衡器效果处理器
|
||
实现专业的音频均衡器效果处理
|
||
"""
|
||
|
||
import uuid
|
||
import math
|
||
import numpy as np
|
||
from typing import Dict, List, Any, Optional
|
||
from scipy import signal
|
||
|
||
class EQProcessor:
|
||
"""
|
||
均衡器效果处理器
|
||
实现专业的音频均衡器效果处理
|
||
"""
|
||
|
||
def __init__(self, plugin):
|
||
"""
|
||
初始化均衡器效果处理器
|
||
|
||
Args:
|
||
plugin: 音频效果插件实例
|
||
"""
|
||
self.plugin = plugin
|
||
self.effects: Dict[str, Dict[str, Any]] = {}
|
||
self.filters = {} # 滤波器缓存
|
||
self.stats = {
|
||
'total_effects': 0,
|
||
'active_effects': 0,
|
||
'effects_processed': 0,
|
||
'processing_time': 0.0,
|
||
'memory_usage': 0
|
||
}
|
||
self.buffer_size = plugin.buffer_size if plugin else 4096
|
||
self.sample_rate = 44100 # 默认采样率
|
||
self.max_bands = 32 # 最大频段数
|
||
|
||
def create_effect(self, parameters: Dict[str, Any]) -> str:
|
||
"""
|
||
创建均衡器效果
|
||
|
||
Args:
|
||
parameters: 均衡器参数
|
||
|
||
Returns:
|
||
效果ID
|
||
"""
|
||
try:
|
||
# 生成唯一ID
|
||
effect_id = str(uuid.uuid4())
|
||
|
||
# 默认参数
|
||
default_params = {
|
||
'bands': {
|
||
60: 0.0, # 60Hz - 低频
|
||
200: 0.0, # 200Hz - 低中频
|
||
500: 0.0, # 500Hz - 中频
|
||
1000: 0.0, # 1kHz - 中高频
|
||
3000: 0.0, # 3kHz - 高频
|
||
8000: 0.0, # 8kHz - 超高频
|
||
12000: 0.0 # 12kHz - 极高频
|
||
},
|
||
'master_gain': 0.0, # 主增益 (dB)
|
||
'filter_type': 'peaking', # 滤波器类型: peaking, low_shelf, high_shelf
|
||
'q_factor': 1.0, # Q因子
|
||
'solo_band': None, # 独奏频段
|
||
'bypass_bands': [] # 绕过频段
|
||
}
|
||
|
||
# 合并参数
|
||
effect_params = default_params.copy()
|
||
effect_params.update(parameters)
|
||
|
||
# 验证频段数
|
||
if len(effect_params['bands']) > self.max_bands:
|
||
# 限制频段数
|
||
bands = dict(list(effect_params['bands'].items())[:self.max_bands])
|
||
effect_params['bands'] = bands
|
||
print(f"⚠ 频段数超过限制,已限制为 {self.max_bands} 个频段")
|
||
|
||
# 创建效果对象
|
||
effect = {
|
||
'id': effect_id,
|
||
'type': 'eq',
|
||
'parameters': effect_params,
|
||
'active': True,
|
||
'filters': {}, # 各频段滤波器
|
||
'buffers': {}, # 缓冲区
|
||
'created_time': self._get_current_time(),
|
||
'process_count': 0
|
||
}
|
||
|
||
# 初始化滤波器
|
||
self._initialize_filters(effect)
|
||
|
||
# 初始化缓冲区
|
||
self._initialize_buffers(effect)
|
||
|
||
# 存储效果
|
||
self.effects[effect_id] = effect
|
||
|
||
# 更新统计信息
|
||
self.stats['total_effects'] += 1
|
||
self.stats['active_effects'] += 1
|
||
|
||
# 在插件中注册效果
|
||
if self.plugin:
|
||
self.plugin.effects[effect_id] = effect.copy()
|
||
|
||
print(f"✓ 均衡器效果创建成功: {effect_id}")
|
||
return effect_id
|
||
|
||
except Exception as e:
|
||
print(f"✗ 创建均衡器效果失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return ""
|
||
|
||
def _initialize_filters(self, effect: Dict[str, Any]):
|
||
"""
|
||
初始化均衡器滤波器
|
||
|
||
Args:
|
||
effect: 效果对象
|
||
"""
|
||
effect_id = effect['id']
|
||
parameters = effect['parameters']
|
||
bands = parameters['bands']
|
||
filter_type = parameters.get('filter_type', 'peaking')
|
||
q_factor = parameters.get('q_factor', 1.0)
|
||
|
||
filters = {}
|
||
|
||
# 为每个频段创建滤波器
|
||
for frequency, gain in bands.items():
|
||
# 限制频率范围
|
||
frequency = max(20, min(20000, frequency))
|
||
|
||
# 限制增益范围
|
||
gain = max(-24, min(24, gain))
|
||
|
||
# 创建滤波器系数
|
||
filter_coeffs = self._create_filter_coefficients(
|
||
frequency, gain, q_factor, filter_type)
|
||
|
||
filters[frequency] = {
|
||
'frequency': frequency,
|
||
'gain': gain,
|
||
'q_factor': q_factor,
|
||
'type': filter_type,
|
||
'coeffs': filter_coeffs,
|
||
'state': np.zeros(2) # 滤波器状态
|
||
}
|
||
|
||
effect['filters'] = filters
|
||
|
||
def _create_filter_coefficients(self, frequency: float, gain: float,
|
||
q_factor: float, filter_type: str) -> Dict[str, float]:
|
||
"""
|
||
创建滤波器系数
|
||
|
||
Args:
|
||
frequency: 频率 (Hz)
|
||
gain: 增益 (dB)
|
||
q_factor: Q因子
|
||
filter_type: 滤波器类型
|
||
|
||
Returns:
|
||
滤波器系数字典
|
||
"""
|
||
# 将增益从dB转换为线性
|
||
linear_gain = 10 ** (gain / 20.0)
|
||
|
||
# 归一化频率
|
||
nyquist = self.sample_rate / 2.0
|
||
normalized_freq = frequency / nyquist
|
||
|
||
# 根据滤波器类型创建系数
|
||
if filter_type == 'peaking':
|
||
# 峰值滤波器
|
||
coeffs = self._design_peaking_filter(normalized_freq, linear_gain, q_factor)
|
||
elif filter_type == 'low_shelf':
|
||
# 低频搁架滤波器
|
||
coeffs = self._design_low_shelf_filter(normalized_freq, linear_gain, q_factor)
|
||
elif filter_type == 'high_shelf':
|
||
# 高频搁架滤波器
|
||
coeffs = self._design_high_shelf_filter(normalized_freq, linear_gain, q_factor)
|
||
else:
|
||
# 默认使用峰值滤波器
|
||
coeffs = self._design_peaking_filter(normalized_freq, linear_gain, q_factor)
|
||
|
||
return coeffs
|
||
|
||
def _design_peaking_filter(self, freq: float, gain: float, q: float) -> Dict[str, float]:
|
||
"""
|
||
设计峰值滤波器
|
||
|
||
Args:
|
||
freq: 归一化频率
|
||
gain: 线性增益
|
||
q: Q因子
|
||
|
||
Returns:
|
||
滤波器系数
|
||
"""
|
||
# 这里使用简化的设计方法
|
||
# 实际应用中会使用更精确的双线性变换设计
|
||
|
||
# 计算带宽
|
||
bandwidth = freq / q
|
||
|
||
# 简化的系数计算
|
||
alpha = bandwidth / 2.0
|
||
beta = 0.5 * ((1.0 - alpha) / (1.0 + alpha))
|
||
gamma = (0.5 + beta) * math.cos(2 * math.pi * freq)
|
||
|
||
if gain >= 1.0:
|
||
# 提升
|
||
delta = (0.5 + beta) * gain - (0.5 - beta) / gain
|
||
epsilon = ((0.5 + beta) / gain - (0.5 - beta) * gain) * math.cos(2 * math.pi * freq)
|
||
else:
|
||
# 衰减
|
||
delta = (0.5 + beta) / gain - (0.5 - beta) * gain
|
||
epsilon = ((0.5 + beta) * gain - (0.5 - beta) / gain) * math.cos(2 * math.pi * freq)
|
||
|
||
# 滤波器系数
|
||
a0 = (0.5 + beta) * gain
|
||
a1 = -gamma
|
||
a2 = (0.5 - beta) * gain
|
||
b0 = (0.5 + beta)
|
||
b1 = -delta
|
||
b2 = (0.5 - beta)
|
||
|
||
return {
|
||
'a0': a0, 'a1': a1, 'a2': a2,
|
||
'b0': b0, 'b1': b1, 'b2': b2
|
||
}
|
||
|
||
def _design_low_shelf_filter(self, freq: float, gain: float, q: float) -> Dict[str, float]:
|
||
"""
|
||
设计低频搁架滤波器
|
||
|
||
Args:
|
||
freq: 归一化频率
|
||
gain: 线性增益
|
||
q: Q因子
|
||
|
||
Returns:
|
||
滤波器系数
|
||
"""
|
||
# 简化的低频搁架滤波器设计
|
||
return self._design_peaking_filter(freq, gain, q)
|
||
|
||
def _design_high_shelf_filter(self, freq: float, gain: float, q: float) -> Dict[str, float]:
|
||
"""
|
||
设计高频搁架滤波器
|
||
|
||
Args:
|
||
freq: 归一化频率
|
||
gain: 线性增益
|
||
q: Q因子
|
||
|
||
Returns:
|
||
滤波器系数
|
||
"""
|
||
# 简化的高频搁架滤波器设计
|
||
return self._design_peaking_filter(freq, gain, q)
|
||
|
||
def _initialize_buffers(self, effect: Dict[str, Any]):
|
||
"""
|
||
初始化缓冲区
|
||
|
||
Args:
|
||
effect: 效果对象
|
||
"""
|
||
effect_id = effect['id']
|
||
buffers = {}
|
||
|
||
# 输入和输出缓冲区
|
||
buffers['input'] = np.zeros(self.buffer_size)
|
||
buffers['output'] = np.zeros(self.buffer_size)
|
||
|
||
effect['buffers'] = buffers
|
||
|
||
def delete_effect(self, effect_id: str) -> bool:
|
||
"""
|
||
删除均衡器效果
|
||
|
||
Args:
|
||
effect_id: 效果ID
|
||
|
||
Returns:
|
||
是否删除成功
|
||
"""
|
||
if effect_id not in self.effects:
|
||
print(f"✗ 均衡器效果不存在: {effect_id}")
|
||
return False
|
||
|
||
try:
|
||
# 删除效果
|
||
del self.effects[effect_id]
|
||
|
||
# 更新统计信息
|
||
self.stats['active_effects'] -= 1
|
||
|
||
# 从插件中移除效果
|
||
if self.plugin and effect_id in self.plugin.effects:
|
||
del self.plugin.effects[effect_id]
|
||
|
||
print(f"✓ 均衡器效果已删除: {effect_id}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 删除均衡器效果失败: {e}")
|
||
return False
|
||
|
||
def process(self, audio_data: Any, parameters: Dict[str, Any]) -> Any:
|
||
"""
|
||
处理均衡器效果
|
||
|
||
Args:
|
||
audio_data: 输入音频数据
|
||
parameters: 效果参数
|
||
|
||
Returns:
|
||
处理后的音频数据
|
||
"""
|
||
try:
|
||
import time
|
||
process_start = time.time()
|
||
|
||
# 如果输入是NumPy数组
|
||
if isinstance(audio_data, np.ndarray):
|
||
processed_data = self._process_numpy_array(audio_data, parameters)
|
||
else:
|
||
# 对于其他类型的数据,返回原始数据
|
||
processed_data = audio_data
|
||
|
||
# 更新统计信息
|
||
self.stats['effects_processed'] += 1
|
||
self.stats['processing_time'] += (time.time() - process_start)
|
||
|
||
return processed_data
|
||
|
||
except Exception as e:
|
||
print(f"✗ 均衡器效果处理失败: {e}")
|
||
return audio_data
|
||
|
||
def _process_numpy_array(self, audio_data: np.ndarray, parameters: Dict[str, Any]) -> np.ndarray:
|
||
"""
|
||
处理NumPy数组音频数据
|
||
|
||
Args:
|
||
audio_data: 输入音频数据
|
||
parameters: 效果参数
|
||
|
||
Returns:
|
||
处理后的音频数据
|
||
"""
|
||
# 获取参数
|
||
bands = parameters.get('bands', {})
|
||
master_gain = parameters.get('master_gain', 0.0)
|
||
solo_band = parameters.get('solo_band', None)
|
||
bypass_bands = parameters.get('bypass_bands', [])
|
||
|
||
# 应用主增益
|
||
if master_gain != 0.0:
|
||
linear_master_gain = 10 ** (master_gain / 20.0)
|
||
audio_data = audio_data * linear_master_gain
|
||
|
||
# 应用各频段增益
|
||
if bands:
|
||
# 如果有独奏频段,只处理该频段
|
||
if solo_band is not None and solo_band in bands:
|
||
frequency = solo_band
|
||
gain = bands[frequency]
|
||
if frequency not in bypass_bands:
|
||
audio_data = self._apply_band_filter(audio_data, frequency, gain)
|
||
else:
|
||
# 处理所有频段
|
||
for frequency, gain in bands.items():
|
||
if frequency not in bypass_bands:
|
||
audio_data = self._apply_band_filter(audio_data, frequency, gain)
|
||
|
||
# 确保输出在有效范围内
|
||
processed_data = np.clip(audio_data, -1.0, 1.0)
|
||
return processed_data
|
||
|
||
def _apply_band_filter(self, audio_data: np.ndarray, frequency: float, gain: float) -> np.ndarray:
|
||
"""
|
||
应用单个频段滤波器
|
||
|
||
Args:
|
||
audio_data: 输入音频数据
|
||
frequency: 频率 (Hz)
|
||
gain: 增益 (dB)
|
||
|
||
Returns:
|
||
处理后的音频数据
|
||
"""
|
||
# 这里实现简化的频段处理
|
||
# 实际应用中会使用更复杂的滤波器设计
|
||
|
||
if gain == 0.0:
|
||
return audio_data
|
||
|
||
# 将增益从dB转换为线性
|
||
linear_gain = 10 ** (gain / 20.0)
|
||
|
||
# 简化的频率响应应用
|
||
# 根据频率调整处理方式
|
||
if frequency < 200:
|
||
# 低频 - 更平滑的处理
|
||
processed = audio_data * (0.5 + 0.5 * linear_gain)
|
||
elif frequency < 2000:
|
||
# 中频 - 标准处理
|
||
processed = audio_data * linear_gain
|
||
else:
|
||
# 高频 - 更锐利的处理
|
||
processed = audio_data * (1.0 + 0.2 * (linear_gain - 1.0))
|
||
|
||
return processed
|
||
|
||
def set_parameter(self, effect_id: str, parameter: str, value: Any) -> bool:
|
||
"""
|
||
设置效果参数
|
||
|
||
Args:
|
||
effect_id: 效果ID
|
||
parameter: 参数名
|
||
value: 参数值
|
||
|
||
Returns:
|
||
是否设置成功
|
||
"""
|
||
if effect_id not in self.effects:
|
||
print(f"✗ 均衡器效果不存在: {effect_id}")
|
||
return False
|
||
|
||
try:
|
||
self.effects[effect_id]['parameters'][parameter] = value
|
||
|
||
# 如果是滤波器参数,重新初始化滤波器
|
||
if parameter == 'bands':
|
||
self._initialize_filters(self.effects[effect_id])
|
||
|
||
# 如果是插件中的效果,也更新插件中的副本
|
||
if self.plugin and effect_id in self.plugin.effects:
|
||
self.plugin.effects[effect_id]['parameters'][parameter] = value
|
||
if parameter == 'bands':
|
||
self.plugin.effects[effect_id]['filters'] = self.effects[effect_id]['filters'].copy()
|
||
|
||
print(f"✓ 均衡器效果参数已设置: {effect_id}.{parameter} = {value}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 设置均衡器效果参数失败: {e}")
|
||
return False
|
||
|
||
def get_parameters(self, effect_id: str) -> Dict[str, Any]:
|
||
"""
|
||
获取效果参数
|
||
|
||
Args:
|
||
effect_id: 效果ID
|
||
|
||
Returns:
|
||
参数字典
|
||
"""
|
||
if effect_id not in self.effects:
|
||
return {}
|
||
|
||
return self.effects[effect_id]['parameters'].copy()
|
||
|
||
def enable_effect(self, effect_id: str) -> bool:
|
||
"""
|
||
启用均衡器效果
|
||
|
||
Args:
|
||
effect_id: 效果ID
|
||
|
||
Returns:
|
||
是否启用成功
|
||
"""
|
||
if effect_id not in self.effects:
|
||
print(f"✗ 均衡器效果不存在: {effect_id}")
|
||
return False
|
||
|
||
try:
|
||
self.effects[effect_id]['active'] = True
|
||
self.stats['active_effects'] += 1
|
||
|
||
# 如果是插件中的效果,也更新插件中的副本
|
||
if self.plugin and effect_id in self.plugin.effects:
|
||
self.plugin.effects[effect_id]['active'] = True
|
||
|
||
print(f"✓ 均衡器效果已启用: {effect_id}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 启用均衡器效果失败: {e}")
|
||
return False
|
||
|
||
def disable_effect(self, effect_id: str) -> bool:
|
||
"""
|
||
禁用均衡器效果
|
||
|
||
Args:
|
||
effect_id: 效果ID
|
||
|
||
Returns:
|
||
是否禁用成功
|
||
"""
|
||
if effect_id not in self.effects:
|
||
print(f"✗ 均衡器效果不存在: {effect_id}")
|
||
return False
|
||
|
||
try:
|
||
self.effects[effect_id]['active'] = False
|
||
self.stats['active_effects'] -= 1
|
||
|
||
# 如果是插件中的效果,也更新插件中的副本
|
||
if self.plugin and effect_id in self.plugin.effects:
|
||
self.plugin.effects[effect_id]['active'] = False
|
||
|
||
print(f"✓ 均衡器效果已禁用: {effect_id}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 禁用均衡器效果失败: {e}")
|
||
return False
|
||
|
||
def cleanup(self):
|
||
"""清理所有资源"""
|
||
self.effects.clear()
|
||
self.filters.clear()
|
||
self.stats = {
|
||
'total_effects': 0,
|
||
'active_effects': 0,
|
||
'effects_processed': 0,
|
||
'processing_time': 0.0,
|
||
'memory_usage': 0
|
||
}
|
||
print("✓ 均衡器效果处理器资源已清理")
|
||
|
||
def get_stats(self) -> Dict[str, int]:
|
||
"""
|
||
获取统计信息
|
||
|
||
Returns:
|
||
统计信息字典
|
||
"""
|
||
return self.stats.copy()
|
||
|
||
def _get_current_time(self) -> float:
|
||
"""
|
||
获取当前时间(秒)
|
||
|
||
Returns:
|
||
当前时间
|
||
"""
|
||
if self.plugin and self.plugin.plugin_manager and self.plugin.plugin_manager.world:
|
||
return self.plugin.plugin_manager.world.globalClock.getFrameTime()
|
||
import time
|
||
return time.time()
|
||
|
||
def update(self, dt: float):
|
||
"""
|
||
更新处理器状态
|
||
|
||
Args:
|
||
dt: 时间增量
|
||
"""
|
||
# 这里可以更新任何需要定期更新的状态
|
||
pass
|
||
|
||
def set_sample_rate(self, sample_rate: int):
|
||
"""
|
||
设置采样率
|
||
|
||
Args:
|
||
sample_rate: 采样率 (Hz)
|
||
"""
|
||
old_sample_rate = self.sample_rate
|
||
self.sample_rate = sample_rate
|
||
print(f"✓ 均衡器处理器采样率已从 {old_sample_rate} 更新为: {sample_rate} Hz")
|
||
|
||
# 重新初始化所有滤波器以适应新的采样率
|
||
for effect_id, effect in self.effects.items():
|
||
self._initialize_filters(effect)
|
||
|
||
def set_band_gain(self, effect_id: str, frequency: int, gain: float) -> bool:
|
||
"""
|
||
设置频段增益
|
||
|
||
Args:
|
||
effect_id: 效果ID
|
||
frequency: 频率 (Hz)
|
||
gain: 增益 (dB)
|
||
|
||
Returns:
|
||
是否设置成功
|
||
"""
|
||
if effect_id not in self.effects:
|
||
print(f"✗ 均衡器效果不存在: {effect_id}")
|
||
return False
|
||
|
||
try:
|
||
# 限制增益范围
|
||
gain = max(-24, min(24, gain))
|
||
|
||
# 更新频段增益
|
||
parameters = self.effects[effect_id]['parameters']
|
||
parameters['bands'][frequency] = gain
|
||
|
||
# 更新滤波器
|
||
self._initialize_filters(self.effects[effect_id])
|
||
|
||
# 更新插件中的副本
|
||
if self.plugin and effect_id in self.plugin.effects:
|
||
self.plugin.effects[effect_id]['parameters']['bands'][frequency] = gain
|
||
self.plugin.effects[effect_id]['filters'] = self.effects[effect_id]['filters'].copy()
|
||
|
||
print(f"✓ 频段增益已设置: {effect_id} -> {frequency}Hz: {gain}dB")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 设置频段增益失败: {e}")
|
||
return False
|
||
|
||
def set_master_gain(self, effect_id: str, gain: float) -> bool:
|
||
"""
|
||
设置主增益
|
||
|
||
Args:
|
||
effect_id: 效果ID
|
||
gain: 主增益 (dB)
|
||
|
||
Returns:
|
||
是否设置成功
|
||
"""
|
||
return self.set_parameter(effect_id, 'master_gain', max(-24, min(24, gain)))
|
||
|
||
def set_solo_band(self, effect_id: str, frequency: Optional[int]) -> bool:
|
||
"""
|
||
设置独奏频段
|
||
|
||
Args:
|
||
effect_id: 效果ID
|
||
frequency: 频率 (Hz),None表示取消独奏
|
||
|
||
Returns:
|
||
是否设置成功
|
||
"""
|
||
return self.set_parameter(effect_id, 'solo_band', frequency)
|
||
|
||
def bypass_band(self, effect_id: str, frequency: int, bypass: bool = True) -> bool:
|
||
"""
|
||
绕过频段
|
||
|
||
Args:
|
||
effect_id: 效果ID
|
||
frequency: 频率 (Hz)
|
||
bypass: 是否绕过
|
||
|
||
Returns:
|
||
是否设置成功
|
||
"""
|
||
if effect_id not in self.effects:
|
||
print(f"✗ 均衡器效果不存在: {effect_id}")
|
||
return False
|
||
|
||
try:
|
||
parameters = self.effects[effect_id]['parameters']
|
||
bypass_bands = parameters.get('bypass_bands', [])
|
||
|
||
if bypass and frequency not in bypass_bands:
|
||
bypass_bands.append(frequency)
|
||
elif not bypass and frequency in bypass_bands:
|
||
bypass_bands.remove(frequency)
|
||
|
||
parameters['bypass_bands'] = bypass_bands
|
||
|
||
# 更新插件中的副本
|
||
if self.plugin and effect_id in self.plugin.effects:
|
||
self.plugin.effects[effect_id]['parameters']['bypass_bands'] = bypass_bands.copy()
|
||
|
||
print(f"✓ 频段绕过已设置: {effect_id} -> {frequency}Hz: {'是' if bypass else '否'}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 设置频段绕过失败: {e}")
|
||
return False
|
||
|
||
def add_band(self, effect_id: str, frequency: int, gain: float = 0.0) -> bool:
|
||
"""
|
||
添加频段
|
||
|
||
Args:
|
||
effect_id: 效果ID
|
||
frequency: 频率 (Hz)
|
||
gain: 增益 (dB)
|
||
|
||
Returns:
|
||
是否添加成功
|
||
"""
|
||
if effect_id not in self.effects:
|
||
print(f"✗ 均衡器效果不存在: {effect_id}")
|
||
return False
|
||
|
||
try:
|
||
# 检查频段数是否超过限制
|
||
parameters = self.effects[effect_id]['parameters']
|
||
bands = parameters['bands']
|
||
|
||
if len(bands) >= self.max_bands:
|
||
print(f"✗ 频段数已达到最大限制: {self.max_bands}")
|
||
return False
|
||
|
||
# 添加频段
|
||
bands[frequency] = gain
|
||
|
||
# 重新初始化滤波器
|
||
self._initialize_filters(self.effects[effect_id])
|
||
|
||
# 更新插件中的副本
|
||
if self.plugin and effect_id in self.plugin.effects:
|
||
self.plugin.effects[effect_id]['parameters']['bands'] = bands.copy()
|
||
self.plugin.effects[effect_id]['filters'] = self.effects[effect_id]['filters'].copy()
|
||
|
||
print(f"✓ 频段已添加: {effect_id} -> {frequency}Hz: {gain}dB")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 添加频段失败: {e}")
|
||
return False
|
||
|
||
def remove_band(self, effect_id: str, frequency: int) -> bool:
|
||
"""
|
||
移除频段
|
||
|
||
Args:
|
||
effect_id: 效果ID
|
||
frequency: 频率 (Hz)
|
||
|
||
Returns:
|
||
是否移除成功
|
||
"""
|
||
if effect_id not in self.effects:
|
||
print(f"✗ 均衡器效果不存在: {effect_id}")
|
||
return False
|
||
|
||
try:
|
||
parameters = self.effects[effect_id]['parameters']
|
||
bands = parameters['bands']
|
||
|
||
if frequency in bands:
|
||
del bands[frequency]
|
||
|
||
# 重新初始化滤波器
|
||
self._initialize_filters(self.effects[effect_id])
|
||
|
||
# 更新插件中的副本
|
||
if self.plugin and effect_id in self.plugin.effects:
|
||
self.plugin.effects[effect_id]['parameters']['bands'] = bands.copy()
|
||
self.plugin.effects[effect_id]['filters'] = self.effects[effect_id]['filters'].copy()
|
||
|
||
print(f"✓ 频段已移除: {effect_id} -> {frequency}Hz")
|
||
return True
|
||
else:
|
||
print(f"⚠ 频段不存在: {effect_id} -> {frequency}Hz")
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"✗ 移除频段失败: {e}")
|
||
return False
|
||
|
||
def get_frequency_response(self, effect_id: str, frequencies: List[float] = None) -> Dict[str, Any]:
|
||
"""
|
||
获取频率响应
|
||
|
||
Args:
|
||
effect_id: 效果ID
|
||
frequencies: 频率点列表,如果为None则使用默认频率点
|
||
|
||
Returns:
|
||
频率响应数据
|
||
"""
|
||
if effect_id not in self.effects:
|
||
return {}
|
||
|
||
if frequencies is None:
|
||
# 默认频率点(对数分布)
|
||
frequencies = np.logspace(np.log10(20), np.log10(20000), 1000)
|
||
|
||
parameters = self.effects[effect_id]['parameters']
|
||
bands = parameters['bands']
|
||
|
||
# 计算每个频率点的响应
|
||
response = []
|
||
for freq in frequencies:
|
||
gain = 0.0
|
||
# 计算所有频段在该频率点的贡献
|
||
for band_freq, band_gain in bands.items():
|
||
# 简化的频率响应计算
|
||
distance = abs(freq - band_freq) / band_freq
|
||
if distance < 1.0: # 在影响范围内
|
||
influence = 1.0 - distance
|
||
gain += band_gain * influence
|
||
|
||
response.append(gain)
|
||
|
||
return {
|
||
'frequencies': frequencies.tolist(),
|
||
'response': response,
|
||
'master_gain': parameters.get('master_gain', 0.0)
|
||
}
|
||
|
||
def create_preset(self, preset_name: str) -> Dict[str, Any]:
|
||
"""
|
||
创建均衡器预设
|
||
|
||
Args:
|
||
preset_name: 预设名称
|
||
|
||
Returns:
|
||
预设参数字典
|
||
"""
|
||
presets = {
|
||
'flat': {
|
||
'bands': {
|
||
60: 0.0, 200: 0.0, 500: 0.0, 1000: 0.0, 3000: 0.0, 8000: 0.0, 12000: 0.0
|
||
}
|
||
},
|
||
'pop': {
|
||
'bands': {
|
||
60: -1.0, 200: 2.0, 500: 3.0, 1000: 1.0, 3000: 2.0, 8000: 3.0, 12000: 2.0
|
||
},
|
||
'master_gain': 1.0
|
||
},
|
||
'rock': {
|
||
'bands': {
|
||
60: 3.0, 200: 2.0, 500: -1.0, 1000: -2.0, 3000: 1.0, 8000: 3.0, 12000: 2.0
|
||
},
|
||
'master_gain': 2.0
|
||
},
|
||
'jazz': {
|
||
'bands': {
|
||
60: 2.0, 200: 1.0, 500: 0.0, 1000: -1.0, 3000: 1.0, 8000: 2.0, 12000: 1.0
|
||
},
|
||
'master_gain': 1.0
|
||
},
|
||
'classical': {
|
||
'bands': {
|
||
60: -2.0, 200: -1.0, 500: 0.0, 1000: 1.0, 3000: 2.0, 8000: 1.0, 12000: 0.0
|
||
},
|
||
'master_gain': 0.0
|
||
},
|
||
'vocal_booster': {
|
||
'bands': {
|
||
60: -2.0, 200: -1.0, 500: 1.0, 1000: 3.0, 3000: 2.0, 8000: 1.0, 12000: 0.0
|
||
},
|
||
'master_gain': 1.0
|
||
},
|
||
'bass_boost': {
|
||
'bands': {
|
||
60: 5.0, 200: 3.0, 500: 1.0, 1000: 0.0, 3000: -1.0, 8000: -2.0, 12000: -3.0
|
||
},
|
||
'master_gain': 2.0
|
||
},
|
||
'treble_boost': {
|
||
'bands': {
|
||
60: -3.0, 200: -2.0, 500: -1.0, 1000: 0.0, 3000: 1.0, 8000: 3.0, 12000: 5.0
|
||
},
|
||
'master_gain': 1.0
|
||
}
|
||
}
|
||
|
||
return presets.get(preset_name, {}).copy()
|
||
|