EG/plugins/user/haptic_feedback_system/effects/effect_processor.py
2025-12-12 16:16:15 +08:00

1180 lines
43 KiB
Python

"""
效果处理器模块
负责创建和处理各种触觉效果
"""
import time
import math
from typing import Dict, Any, List, Optional
import threading
import random
class EffectType:
"""效果类型常量"""
SIMPLE = "simple"
PERIODIC = "periodic"
ENVELOPE = "envelope"
RAMP = "ramp"
CUSTOM = "custom"
NOISE = "noise"
IMPULSE = "impulse"
EXPLOSION = "explosion"
TEXTURE = "texture"
WIND = "wind"
WATER = "water"
HEAT = "heat"
COLD = "cold"
VIBRATION = "vibration"
PULSE = "pulse"
class EffectProcessor:
"""
效果处理器
负责创建和处理各种触觉效果
"""
def __init__(self, plugin):
"""
初始化效果处理器
Args:
plugin: 触觉反馈系统插件实例
"""
self.plugin = plugin
self.enabled = False
self.initialized = False
# 效果模板
self.effect_templates = {}
# 自定义效果
self.custom_effects = {}
self.effect_counter = 0
# 效果参数
self.effect_parameters = {
'simple': {
'intensity': (0.0, 1.0),
'duration': (0.01, 10.0)
},
'periodic': {
'intensity': (0.0, 1.0),
'duration': (0.01, 10.0),
'frequency': (1.0, 100.0),
'amplitude': (0.0, 1.0),
'offset': (0.0, 1.0),
'phase': (0.0, 360.0),
'waveform': ['sine', 'square', 'triangle', 'sawtooth']
},
'envelope': {
'intensity': (0.0, 1.0),
'duration': (0.01, 10.0),
'attack_time': (0.0, 2.0),
'attack_level': (0.0, 1.0),
'fade_time': (0.0, 2.0),
'fade_level': (0.0, 1.0),
'sustain_level': (0.0, 1.0)
},
'ramp': {
'intensity': (0.0, 1.0),
'duration': (0.01, 10.0),
'start_level': (0.0, 1.0),
'end_level': (0.0, 1.0),
'curve_type': ['linear', 'exponential', 'logarithmic']
},
'noise': {
'intensity': (0.0, 1.0),
'duration': (0.01, 10.0),
'frequency': (1.0, 100.0),
'noise_type': ['white', 'pink', 'brown']
},
'impulse': {
'intensity': (0.0, 1.0),
'duration': (0.001, 1.0),
'sharpness': (0.0, 1.0),
'shape': ['gaussian', 'exponential', 'linear']
},
'explosion': {
'intensity': (0.0, 1.0),
'duration': (0.1, 5.0),
'rise_time': (0.01, 1.0),
'fall_time': (0.1, 2.0),
'frequency_start': (20.0, 100.0),
'frequency_end': (5.0, 50.0)
},
'texture': {
'intensity': (0.0, 1.0),
'duration': (0.1, 10.0),
'frequency': (5.0, 50.0),
'roughness': (0.0, 1.0),
'spacing': (0.01, 1.0)
},
'wind': {
'intensity': (0.0, 1.0),
'duration': (0.5, 30.0),
'frequency': (0.1, 10.0),
'turbulence': (0.0, 1.0),
'direction_variability': (0.0, 1.0)
},
'water': {
'intensity': (0.0, 1.0),
'duration': (0.5, 30.0),
'frequency': (0.5, 20.0),
'wave_height': (0.1, 5.0),
'viscosity': (0.1, 10.0)
}
}
# 预定义效果
self.predefined_effects = {
'click': {
'type': EffectType.IMPULSE,
'intensity': 0.8,
'duration': 0.05,
'sharpness': 0.9,
'shape': 'gaussian'
},
'buzz': {
'type': EffectType.PERIODIC,
'intensity': 0.6,
'duration': 0.5,
'frequency': 50.0,
'amplitude': 0.5,
'waveform': 'sine'
},
'rumble': {
'type': EffectType.PERIODIC,
'intensity': 0.7,
'duration': 1.0,
'frequency': 20.0,
'amplitude': 0.6,
'waveform': 'sine'
},
'pulse': {
'type': EffectType.PERIODIC,
'intensity': 0.5,
'duration': 0.3,
'frequency': 30.0,
'amplitude': 0.4,
'waveform': 'sine'
},
'heartbeat': {
'type': EffectType.ENVELOPE,
'intensity': 0.6,
'duration': 1.5,
'attack_time': 0.1,
'attack_level': 0.8,
'fade_time': 0.3,
'fade_level': 0.2,
'sustain_level': 0.5
},
'explosion': {
'type': EffectType.EXPLOSION,
'intensity': 1.0,
'duration': 2.0,
'rise_time': 0.05,
'fall_time': 0.8,
'frequency_start': 80.0,
'frequency_end': 10.0
},
'impact': {
'type': EffectType.IMPULSE,
'intensity': 0.9,
'duration': 0.1,
'sharpness': 0.7,
'shape': 'exponential'
},
'texture_rough': {
'type': EffectType.TEXTURE,
'intensity': 0.4,
'duration': 2.0,
'frequency': 15.0,
'roughness': 0.8,
'spacing': 0.05
},
'texture_smooth': {
'type': EffectType.TEXTURE,
'intensity': 0.3,
'duration': 2.0,
'frequency': 8.0,
'roughness': 0.2,
'spacing': 0.1
},
'wind_light': {
'type': EffectType.WIND,
'intensity': 0.2,
'duration': 5.0,
'frequency': 0.5,
'turbulence': 0.3,
'direction_variability': 0.2
},
'wind_strong': {
'type': EffectType.WIND,
'intensity': 0.7,
'duration': 5.0,
'frequency': 2.0,
'turbulence': 0.8,
'direction_variability': 0.5
},
'water_shallow': {
'type': EffectType.WATER,
'intensity': 0.3,
'duration': 3.0,
'frequency': 2.0,
'wave_height': 0.5,
'viscosity': 1.0
},
'water_deep': {
'type': EffectType.WATER,
'intensity': 0.6,
'duration': 3.0,
'frequency': 0.8,
'wave_height': 2.0,
'viscosity': 3.0
}
}
# 效果混合
self.effect_mixing = {
'max': self._mix_max,
'add': self._mix_add,
'multiply': self._mix_multiply,
'average': self._mix_average,
'weighted': self._mix_weighted
}
# 波形生成器
self.waveform_generators = {
'sine': self._generate_sine_wave,
'square': self._generate_square_wave,
'triangle': self._generate_triangle_wave,
'sawtooth': self._generate_sawtooth_wave
}
# 噪声生成器
self.noise_generators = {
'white': self._generate_white_noise,
'pink': self._generate_pink_noise,
'brown': self._generate_brown_noise
}
# 脉冲形状生成器
self.impulse_shapes = {
'gaussian': self._generate_gaussian_impulse,
'exponential': self._generate_exponential_impulse,
'linear': self._generate_linear_impulse
}
# 统计信息
self.stats = {
'templates_created': 0,
'effects_generated': 0,
'effects_processed': 0,
'custom_effects': 0,
'waveforms_generated': 0,
'noise_samples': 0
}
# 回调函数
self.effect_callbacks = {
'effect_created': [],
'effect_processed': [],
'template_registered': [],
'waveform_generated': []
}
# 缓存
self.waveform_cache = {}
self.noise_cache = {}
# 随机数生成器
self.random_generator = random.Random()
print("✓ 效果处理器已创建")
def initialize(self) -> bool:
"""
初始化效果处理器
Returns:
是否初始化成功
"""
try:
# 注册预定义效果为模板
for name, effect_data in self.predefined_effects.items():
self.register_effect_template(name, effect_data)
# 初始化缓存
self._initialize_cache()
self.initialized = True
print("✓ 效果处理器初始化完成")
return True
except Exception as e:
print(f"✗ 效果处理器初始化失败: {e}")
import traceback
traceback.print_exc()
return False
def enable(self) -> bool:
"""
启用效果处理器
Returns:
是否启用成功
"""
try:
if not self.initialized:
print("✗ 效果处理器未初始化")
return False
self.enabled = True
print("✓ 效果处理器已启用")
return True
except Exception as e:
print(f"✗ 效果处理器启用失败: {e}")
import traceback
traceback.print_exc()
return False
def disable(self):
"""禁用效果处理器"""
try:
self.enabled = False
print("✓ 效果处理器已禁用")
except Exception as e:
print(f"✗ 效果处理器禁用失败: {e}")
import traceback
traceback.print_exc()
def finalize(self):
"""清理效果处理器资源"""
try:
self.disable()
self.effect_templates.clear()
self.custom_effects.clear()
self.effect_callbacks.clear()
self.waveform_cache.clear()
self.noise_cache.clear()
self.initialized = False
print("✓ 效果处理器资源已清理")
except Exception as e:
print(f"✗ 效果处理器资源清理失败: {e}")
import traceback
traceback.print_exc()
def update(self, dt: float):
"""
更新效果处理器状态
Args:
dt: 时间增量
"""
try:
if not self.enabled:
return
# 清理缓存(定期清理以节省内存)
self._cleanup_cache()
except Exception as e:
print(f"✗ 效果处理器更新失败: {e}")
import traceback
traceback.print_exc()
def _initialize_cache(self):
"""初始化缓存"""
try:
# 预生成常用波形
common_frequencies = [10, 20, 30, 50, 100]
common_durations = [0.1, 0.5, 1.0, 2.0]
for freq in common_frequencies:
for duration in common_durations:
cache_key = f"sine_{freq}_{duration}"
self.waveform_cache[cache_key] = self._generate_sine_wave(freq, duration, 100)
print("✓ 波形缓存初始化完成")
except Exception as e:
print(f"✗ 波形缓存初始化失败: {e}")
def _cleanup_cache(self):
"""清理缓存"""
try:
# 保持缓存大小在合理范围内
max_cache_size = 1000
if len(self.waveform_cache) > max_cache_size:
# 移除最旧的一半缓存
keys_to_remove = list(self.waveform_cache.keys())[:max_cache_size//2]
for key in keys_to_remove:
del self.waveform_cache[key]
if len(self.noise_cache) > max_cache_size:
# 移除最旧的一半缓存
keys_to_remove = list(self.noise_cache.keys())[:max_cache_size//2]
for key in keys_to_remove:
del self.noise_cache[key]
except Exception as e:
print(f"✗ 缓存清理失败: {e}")
def register_effect_template(self, name: str, template: Dict[str, Any]) -> bool:
"""
注册效果模板
Args:
name: 模板名称
template: 模板数据
Returns:
是否注册成功
"""
try:
self.effect_templates[name] = template.copy()
self.stats['templates_created'] += 1
# 触发模板注册回调
self._trigger_effect_callback('template_registered', {
'template_name': name,
'template_data': template
})
print(f"✓ 效果模板已注册: {name}")
return True
except Exception as e:
print(f"✗ 效果模板注册失败: {e}")
return False
def unregister_effect_template(self, name: str) -> bool:
"""
注销效果模板
Args:
name: 模板名称
Returns:
是否注销成功
"""
try:
if name in self.effect_templates:
del self.effect_templates[name]
print(f"✓ 效果模板已注销: {name}")
return True
else:
print(f"✗ 效果模板不存在: {name}")
return False
except Exception as e:
print(f"✗ 效果模板注销失败: {e}")
return False
def create_effect_from_template(self, template_name: str,
overrides: Dict[str, Any] = None) -> Optional[Dict[str, Any]]:
"""
从模板创建效果
Args:
template_name: 模板名称
overrides: 覆盖参数
Returns:
效果数据字典或None
"""
try:
if template_name not in self.effect_templates:
print(f"✗ 效果模板不存在: {template_name}")
return None
# 获取模板数据
template = self.effect_templates[template_name].copy()
# 应用覆盖参数
if overrides:
template.update(overrides)
# 添加创建时间戳
template['created_time'] = time.time()
# 触发效果创建回调
self._trigger_effect_callback('effect_created', {
'template_name': template_name,
'effect_data': template
})
self.stats['effects_generated'] += 1
print(f"✓ 效果已从模板创建: {template_name}")
return template
except Exception as e:
print(f"✗ 从模板创建效果失败: {e}")
return None
def create_custom_effect(self, effect_type: str, parameters: Dict[str, Any]) -> int:
"""
创建自定义效果
Args:
effect_type: 效果类型
parameters: 效果参数
Returns:
效果ID
"""
try:
effect_id = self.effect_counter
self.effect_counter += 1
custom_effect = {
'id': effect_id,
'type': effect_type,
'parameters': parameters,
'created_time': time.time()
}
self.custom_effects[effect_id] = custom_effect
self.stats['custom_effects'] += 1
# 触发效果创建回调
self._trigger_effect_callback('effect_created', {
'effect_id': effect_id,
'effect_data': custom_effect
})
print(f"✓ 自定义效果已创建: {effect_type} (ID: {effect_id})")
return effect_id
except Exception as e:
print(f"✗ 自定义效果创建失败: {e}")
return -1
def remove_custom_effect(self, effect_id: int) -> bool:
"""
移除自定义效果
Args:
effect_id: 效果ID
Returns:
是否移除成功
"""
try:
if effect_id in self.custom_effects:
del self.custom_effects[effect_id]
self.stats['custom_effects'] -= 1
print(f"✓ 自定义效果已移除: ID {effect_id}")
return True
else:
print(f"✗ 自定义效果不存在: ID {effect_id}")
return False
except Exception as e:
print(f"✗ 自定义效果移除失败: {e}")
return False
def get_custom_effect(self, effect_id: int) -> Optional[Dict[str, Any]]:
"""
获取自定义效果
Args:
effect_id: 效果ID
Returns:
效果数据字典或None
"""
return self.custom_effects.get(effect_id)
def get_all_custom_effects(self) -> Dict[int, Dict[str, Any]]:
"""
获取所有自定义效果
Returns:
所有自定义效果字典
"""
return self.custom_effects.copy()
def process_effect(self, effect_data: Dict[str, Any], time_progress: float) -> float:
"""
处理效果并计算当前强度
Args:
effect_data: 效果数据
time_progress: 时间进度(0.0-1.0)
Returns:
当前强度值(0.0-1.0)
"""
try:
effect_type = effect_data.get('type', EffectType.SIMPLE)
intensity = effect_data.get('intensity', 1.0)
# 根据效果类型计算强度
if effect_type == EffectType.SIMPLE:
current_intensity = self._process_simple_effect(effect_data, time_progress)
elif effect_type == EffectType.PERIODIC:
current_intensity = self._process_periodic_effect(effect_data, time_progress)
elif effect_type == EffectType.ENVELOPE:
current_intensity = self._process_envelope_effect(effect_data, time_progress)
elif effect_type == EffectType.RAMP:
current_intensity = self._process_ramp_effect(effect_data, time_progress)
elif effect_type == EffectType.NOISE:
current_intensity = self._process_noise_effect(effect_data, time_progress)
elif effect_type == EffectType.IMPULSE:
current_intensity = self._process_impulse_effect(effect_data, time_progress)
elif effect_type == EffectType.EXPLOSION:
current_intensity = self._process_explosion_effect(effect_data, time_progress)
elif effect_type == EffectType.TEXTURE:
current_intensity = self._process_texture_effect(effect_data, time_progress)
elif effect_type == EffectType.WIND:
current_intensity = self._process_wind_effect(effect_data, time_progress)
elif effect_type == EffectType.WATER:
current_intensity = self._process_water_effect(effect_data, time_progress)
elif effect_type == EffectType.CUSTOM:
current_intensity = self._process_custom_effect(effect_data, time_progress)
else:
current_intensity = intensity # 默认返回固定强度
# 应用总体强度
current_intensity *= intensity
# 触发效果处理回调
self._trigger_effect_callback('effect_processed', {
'effect_data': effect_data,
'time_progress': time_progress,
'current_intensity': current_intensity
})
self.stats['effects_processed'] += 1
return max(0.0, min(1.0, current_intensity))
except Exception as e:
print(f"✗ 效果处理失败: {e}")
return 0.0
def _process_simple_effect(self, effect_data: Dict[str, Any], time_progress: float) -> float:
"""处理简单效果"""
return 1.0 # 固定强度
def _process_periodic_effect(self, effect_data: Dict[str, Any], time_progress: float) -> float:
"""处理周期性效果"""
try:
frequency = effect_data.get('frequency', 10.0)
amplitude = effect_data.get('amplitude', 1.0)
offset = effect_data.get('offset', 0.0)
phase = effect_data.get('phase', 0.0)
waveform = effect_data.get('waveform', 'sine')
duration = effect_data.get('duration', 1.0)
# 生成波形
generator = self.waveform_generators.get(waveform, self._generate_sine_wave)
cache_key = f"{waveform}_{frequency}_{duration}"
# 检查缓存
if cache_key in self.waveform_cache:
waveform_data = self.waveform_cache[cache_key]
else:
# 生成波形数据
sample_count = max(100, int(frequency * duration * 10))
waveform_data = generator(frequency, duration, sample_count)
self.waveform_cache[cache_key] = waveform_data
self.stats['waveforms_generated'] += 1
# 计算当前样本索引
sample_index = int(time_progress * (len(waveform_data) - 1))
sample_index = max(0, min(len(waveform_data) - 1, sample_index))
# 获取波形值
waveform_value = waveform_data[sample_index]
# 应用振幅和偏移
result = offset + amplitude * waveform_value
return max(0.0, min(1.0, result))
except Exception as e:
print(f"✗ 周期性效果处理失败: {e}")
return 0.0
def _process_envelope_effect(self, effect_data: Dict[str, Any], time_progress: float) -> float:
"""处理包络效果"""
try:
attack_time = effect_data.get('attack_time', 0.1)
attack_level = effect_data.get('attack_level', 1.0)
fade_time = effect_data.get('fade_time', 0.1)
fade_level = effect_data.get('fade_level', 0.0)
sustain_level = effect_data.get('sustain_level', 0.5)
duration = effect_data.get('duration', 1.0)
if time_progress <= attack_time / duration:
# 攻击阶段
attack_progress = time_progress / (attack_time / duration)
return attack_progress * attack_level
elif time_progress >= 1.0 - (fade_time / duration):
# 衰减阶段
fade_progress = (time_progress - (1.0 - (fade_time / duration))) / (fade_time / duration)
return fade_level + (1.0 - fade_progress) * (sustain_level - fade_level)
else:
# 保持阶段
return sustain_level
except Exception as e:
print(f"✗ 包络效果处理失败: {e}")
return 0.0
def _process_ramp_effect(self, effect_data: Dict[str, Any], time_progress: float) -> float:
"""处理斜坡效果"""
try:
start_level = effect_data.get('start_level', 0.0)
end_level = effect_data.get('end_level', 1.0)
curve_type = effect_data.get('curve_type', 'linear')
if curve_type == 'exponential':
# 指数曲线
return start_level + (end_level - start_level) * (time_progress ** 2)
elif curve_type == 'logarithmic':
# 对数曲线
if time_progress <= 0:
return start_level
return start_level + (end_level - start_level) * math.log10(1 + 9 * time_progress)
else:
# 线性曲线
return start_level + (end_level - start_level) * time_progress
except Exception as e:
print(f"✗ 斜坡效果处理失败: {e}")
return 0.0
def _process_noise_effect(self, effect_data: Dict[str, Any], time_progress: float) -> float:
"""处理噪声效果"""
try:
frequency = effect_data.get('frequency', 10.0)
noise_type = effect_data.get('noise_type', 'white')
duration = effect_data.get('duration', 1.0)
# 生成噪声
generator = self.noise_generators.get(noise_type, self._generate_white_noise)
cache_key = f"{noise_type}_{frequency}_{duration}"
# 检查缓存
if cache_key in self.noise_cache:
noise_data = self.noise_cache[cache_key]
else:
# 生成噪声数据
sample_count = max(100, int(frequency * duration * 10))
noise_data = generator(sample_count)
self.noise_cache[cache_key] = noise_data
self.stats['noise_samples'] += sample_count
# 计算当前样本索引
sample_index = int(time_progress * (len(noise_data) - 1))
sample_index = max(0, min(len(noise_data) - 1, sample_index))
# 获取噪声值
noise_value = noise_data[sample_index]
return max(0.0, min(1.0, noise_value))
except Exception as e:
print(f"✗ 噪声效果处理失败: {e}")
return 0.0
def _process_impulse_effect(self, effect_data: Dict[str, Any], time_progress: float) -> float:
"""处理脉冲效果"""
try:
duration = effect_data.get('duration', 0.1)
sharpness = effect_data.get('sharpness', 0.5)
shape = effect_data.get('shape', 'gaussian')
# 生成脉冲
generator = self.impulse_shapes.get(shape, self._generate_gaussian_impulse)
# 计算脉冲值
impulse_value = generator(time_progress, sharpness)
return max(0.0, min(1.0, impulse_value))
except Exception as e:
print(f"✗ 脉冲效果处理失败: {e}")
return 0.0
def _process_explosion_effect(self, effect_data: Dict[str, Any], time_progress: float) -> float:
"""处理爆炸效果"""
try:
rise_time = effect_data.get('rise_time', 0.05)
fall_time = effect_data.get('fall_time', 0.5)
frequency_start = effect_data.get('frequency_start', 80.0)
frequency_end = effect_data.get('frequency_end', 10.0)
duration = effect_data.get('duration', 1.0)
# 计算频率变化
frequency = frequency_start + (frequency_end - frequency_start) * time_progress
# 计算振幅包络
if time_progress <= rise_time / duration:
# 上升阶段
envelope = time_progress / (rise_time / duration)
else:
# 下降阶段
fall_progress = (time_progress - (rise_time / duration)) / ((duration - rise_time) / duration)
envelope = max(0.0, 1.0 - fall_progress)
# 生成振动
vibration = math.sin(2 * math.pi * frequency * time_progress * duration)
result = envelope * (vibration + 1.0) / 2.0 # 转换到0-1范围
return max(0.0, min(1.0, result))
except Exception as e:
print(f"✗ 爆炸效果处理失败: {e}")
return 0.0
def _process_texture_effect(self, effect_data: Dict[str, Any], time_progress: float) -> float:
"""处理纹理效果"""
try:
frequency = effect_data.get('frequency', 10.0)
roughness = effect_data.get('roughness', 0.5)
spacing = effect_data.get('spacing', 0.1)
# 生成纹理模式
texture_position = time_progress * frequency
texture_phase = texture_position - math.floor(texture_position)
# 根据粗糙度调整强度
if texture_phase < spacing:
# 纹理凸起
intensity = 1.0 - (texture_phase / spacing) * roughness
else:
# 纹理凹陷
intensity = 0.5 + 0.5 * roughness * math.sin(2 * math.pi * texture_phase)
return max(0.0, min(1.0, intensity))
except Exception as e:
print(f"✗ 纹理效果处理失败: {e}")
return 0.0
def _process_wind_effect(self, effect_data: Dict[str, Any], time_progress: float) -> float:
"""处理风效果"""
try:
frequency = effect_data.get('frequency', 1.0)
turbulence = effect_data.get('turbulence', 0.5)
direction_variability = effect_data.get('direction_variability', 0.3)
# 基础风模式
base_wind = math.sin(2 * math.pi * frequency * time_progress)
# 添加湍流
turbulence_effect = turbulence * math.sin(2 * math.pi * frequency * 5 * time_progress)
# 添加方向变化
direction_effect = direction_variability * math.sin(2 * math.pi * frequency * 0.2 * time_progress)
# 组合效果
result = (base_wind + turbulence_effect + direction_effect) / 3.0
result = (result + 1.0) / 2.0 # 转换到0-1范围
return max(0.0, min(1.0, result))
except Exception as e:
print(f"✗ 风效果处理失败: {e}")
return 0.0
def _process_water_effect(self, effect_data: Dict[str, Any], time_progress: float) -> float:
"""处理水效果"""
try:
frequency = effect_data.get('frequency', 1.0)
wave_height = effect_data.get('wave_height', 1.0)
viscosity = effect_data.get('viscosity', 1.0)
# 主波浪
main_wave = math.sin(2 * math.pi * frequency * time_progress)
# 次级波浪
secondary_wave = 0.5 * math.sin(2 * math.pi * frequency * 2.5 * time_progress + 0.5)
# 粘性阻尼
damping = math.exp(-viscosity * time_progress)
# 组合效果
result = (main_wave + secondary_wave) * damping * wave_height
result = (result + 1.0) / 2.0 # 转换到0-1范围
return max(0.0, min(1.0, result))
except Exception as e:
print(f"✗ 水效果处理失败: {e}")
return 0.0
def _process_custom_effect(self, effect_data: Dict[str, Any], time_progress: float) -> float:
"""处理自定义效果"""
# 这里可以实现更复杂的自定义效果处理逻辑
parameters = effect_data.get('parameters', {})
custom_intensity = parameters.get('intensity_multiplier', 1.0)
return custom_intensity # 默认返回固定强度
def _generate_sine_wave(self, frequency: float, duration: float, samples: int) -> List[float]:
"""生成正弦波"""
wave = []
for i in range(samples):
t = i / (samples - 1) * duration
value = math.sin(2 * math.pi * frequency * t)
wave.append(value)
return wave
def _generate_square_wave(self, frequency: float, duration: float, samples: int) -> List[float]:
"""生成方波"""
wave = []
for i in range(samples):
t = i / (samples - 1) * duration
value = 1.0 if math.sin(2 * math.pi * frequency * t) >= 0 else -1.0
wave.append(value)
return wave
def _generate_triangle_wave(self, frequency: float, duration: float, samples: int) -> List[float]:
"""生成三角波"""
wave = []
for i in range(samples):
t = i / (samples - 1) * duration
value = 2 * abs(2 * (frequency * t - math.floor(frequency * t + 0.5))) - 1
wave.append(value)
return wave
def _generate_sawtooth_wave(self, frequency: float, duration: float, samples: int) -> List[float]:
"""生成锯齿波"""
wave = []
for i in range(samples):
t = i / (samples - 1) * duration
value = 2 * (frequency * t - math.floor(frequency * t + 0.5))
wave.append(value)
return wave
def _generate_white_noise(self, samples: int) -> List[float]:
"""生成白噪声"""
noise = []
for _ in range(samples):
value = self.random_generator.uniform(-1.0, 1.0)
noise.append(value)
return noise
def _generate_pink_noise(self, samples: int) -> List[float]:
"""生成粉红噪声"""
noise = []
b = [0.0] * 7
for _ in range(samples):
white = self.random_generator.uniform(-1.0, 1.0)
b[0] = 0.99886 * b[0] + white * 0.0555179
b[1] = 0.99332 * b[1] + white * 0.0750759
b[2] = 0.96900 * b[2] + white * 0.1538520
b[3] = 0.86650 * b[3] + white * 0.3104856
b[4] = 0.55000 * b[4] + white * 0.5329522
b[5] = -0.7616 * b[5] - white * 0.0168980
pink = b[0] + b[1] + b[2] + b[3] + b[4] + b[5] + b[6] + white * 0.5362
b[6] = white * 0.115926
noise.append(pink / 5.0) # 归一化
return noise
def _generate_brown_noise(self, samples: int) -> List[float]:
"""生成布朗噪声"""
noise = []
last = 0.0
for _ in range(samples):
white = self.random_generator.uniform(-1.0, 1.0)
brown = (last + (0.02 * white)) / 1.02
last = brown
noise.append(brown * 3.5) # 补偿幅度
return noise
def _generate_gaussian_impulse(self, time_progress: float, sharpness: float) -> float:
"""生成高斯脉冲"""
try:
# 高斯函数: exp(-(x^2)/(2*sigma^2))
sigma = 0.2 * (1.0 - sharpness * 0.8) # 根据锐度调整宽度
x = (time_progress - 0.5) * 2 # 调整到-1到1范围
value = math.exp(-(x*x) / (2 * sigma * sigma))
return value
except Exception:
return 0.0
def _generate_exponential_impulse(self, time_progress: float, sharpness: float) -> float:
"""生成指数脉冲"""
try:
if time_progress < 0.5:
# 上升阶段
rise_factor = 1.0 + 9.0 * sharpness # 1到10
value = 1.0 - math.exp(-rise_factor * time_progress * 2)
else:
# 下降阶段
fall_factor = 1.0 + 9.0 * (1.0 - sharpness) # 1到10
value = math.exp(-fall_factor * (time_progress - 0.5) * 2)
return value
except Exception:
return 0.0
def _generate_linear_impulse(self, time_progress: float, sharpness: float) -> float:
"""生成线性脉冲"""
try:
peak_position = 0.3 + 0.4 * sharpness # 0.3到0.7
if time_progress < peak_position:
# 上升阶段
value = time_progress / peak_position
else:
# 下降阶段
value = 1.0 - (time_progress - peak_position) / (1.0 - peak_position)
return max(0.0, value)
except Exception:
return 0.0
def mix_effects(self, effects: List[Dict[str, Any]], time_progress: float,
mix_mode: str = 'max', weights: List[float] = None) -> float:
"""
混合多个效果
Args:
effects: 效果数据列表
time_progress: 时间进度(0.0-1.0)
mix_mode: 混合模式('max', 'add', 'multiply', 'average', 'weighted')
weights: 权重列表(用于加权混合)
Returns:
混合后的强度值(0.0-1.0)
"""
try:
intensities = []
for effect_data in effects:
intensity = self.process_effect(effect_data, time_progress)
intensities.append(intensity)
if not intensities:
return 0.0
# 根据混合模式计算最终强度
if mix_mode == 'weighted' and weights:
mix_function = self._mix_weighted
return mix_function(intensities, weights)
else:
mix_function = self.effect_mixing.get(mix_mode, self._mix_max)
return mix_function(intensities)
except Exception as e:
print(f"✗ 效果混合失败: {e}")
return 0.0
def _mix_max(self, intensities: List[float]) -> float:
"""最大值混合"""
return max(intensities)
def _mix_add(self, intensities: List[float]) -> float:
"""加法混合"""
return min(1.0, sum(intensities))
def _mix_multiply(self, intensities: List[float]) -> float:
"""乘法混合"""
result = 1.0
for intensity in intensities:
result *= max(0.0, intensity) # 避免负值影响
return result
def _mix_average(self, intensities: List[float]) -> float:
"""平均值混合"""
return sum(intensities) / len(intensities) if intensities else 0.0
def _mix_weighted(self, intensities: List[float], weights: List[float]) -> float:
"""加权混合"""
if len(intensities) != len(weights):
return self._mix_average(intensities)
weighted_sum = sum(intensity * weight for intensity, weight in zip(intensities, weights))
total_weight = sum(weights)
return weighted_sum / total_weight if total_weight > 0 else 0.0
def get_effect_parameters(self, effect_type: str) -> Dict[str, tuple]:
"""
获取效果参数信息
Args:
effect_type: 效果类型
Returns:
参数信息字典
"""
return self.effect_parameters.get(effect_type, {})
def get_predefined_effects(self) -> Dict[str, Dict[str, Any]]:
"""
获取预定义效果
Returns:
预定义效果字典
"""
return self.predefined_effects.copy()
def _trigger_effect_callback(self, callback_type: str, data: Dict[str, Any]):
"""
触发效果回调
Args:
callback_type: 回调类型
data: 回调数据
"""
try:
if callback_type in self.effect_callbacks:
for callback in self.effect_callbacks[callback_type]:
try:
callback(data)
except Exception as e:
print(f"✗ 效果回调执行失败: {e}")
except Exception as e:
print(f"✗ 效果回调触发失败: {e}")
def register_effect_callback(self, callback_type: str, callback: callable):
"""
注册效果回调
Args:
callback_type: 回调类型
callback: 回调函数
"""
try:
if callback_type in self.effect_callbacks:
self.effect_callbacks[callback_type].append(callback)
print(f"✓ 效果回调已注册: {callback_type}")
else:
print(f"✗ 无效的回调类型: {callback_type}")
except Exception as e:
print(f"✗ 效果回调注册失败: {e}")
def unregister_effect_callback(self, callback_type: str, callback: callable):
"""
注销效果回调
Args:
callback_type: 回调类型
callback: 回调函数
"""
try:
if callback_type in self.effect_callbacks:
if callback in self.effect_callbacks[callback_type]:
self.effect_callbacks[callback_type].remove(callback)
print(f"✓ 效果回调已注销: {callback_type}")
except Exception as e:
print(f"✗ 效果回调注销失败: {e}")
def get_stats(self) -> Dict[str, int]:
"""
获取统计信息
Returns:
统计信息字典
"""
return self.stats.copy()
def reset_stats(self):
"""重置统计信息"""
try:
self.stats = {
'templates_created': 0,
'effects_generated': 0,
'effects_processed': 0,
'custom_effects': 0,
'waveforms_generated': 0,
'noise_samples': 0
}
print("✓ 效果处理器统计信息已重置")
except Exception as e:
print(f"✗ 效果处理器统计信息重置失败: {e}")