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

461 lines
14 KiB
Python

"""
音频效果处理器
处理各种音频效果,如混响、回声、滤波等
"""
import uuid
from typing import Dict, List, Any, Optional
import math
class AudioEffectProcessor:
"""
音频效果处理器
处理各种音频效果,如混响、回声、滤波等
"""
def __init__(self, plugin):
"""
初始化音频效果处理器
Args:
plugin: 3D音频插件实例
"""
self.plugin = plugin
self.effects: Dict[str, Dict[str, Any]] = {}
self.sound_effects: Dict[str, List[str]] = {} # 音效与效果的关联
self.stats = {
'total_effects': 0,
'active_effects': 0,
'effects_applied': 0
}
def create_effect(self, effect_type: str, parameters: Dict[str, Any]) -> str:
"""
创建音频效果
Args:
effect_type: 效果类型 ('reverb', 'echo', 'lowpass', 'highpass', 'distortion')
parameters: 效果参数
Returns:
效果ID
"""
try:
# 生成唯一ID
effect_id = str(uuid.uuid4())
# 创建效果对象
effect = {
'id': effect_id,
'type': effect_type,
'parameters': parameters.copy(),
'active': True
}
# 存储效果
self.effects[effect_id] = effect
# 更新统计信息
self.stats['total_effects'] += 1
self.stats['active_effects'] += 1
print(f"✓ 音频效果创建成功: {effect_id} ({effect_type})")
return effect_id
except Exception as e:
print(f"✗ 创建音频效果失败: {e}")
return ""
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:
# 从所有音效中移除该效果
for sound_id, effect_list in self.sound_effects.items():
if effect_id in effect_list:
effect_list.remove(effect_id)
# 删除效果
del self.effects[effect_id]
# 更新统计信息
self.stats['active_effects'] -= 1
print(f"✓ 音频效果已删除: {effect_id}")
return True
except Exception as e:
print(f"✗ 删除音频效果失败: {e}")
return False
def apply_effect_to_sound(self, sound_id: str, effect_id: str) -> bool:
"""
应用效果到音效
Args:
sound_id: 音源ID
effect_id: 效果ID
Returns:
是否应用成功
"""
# 检查音源和效果是否存在
if sound_id not in self.plugin.audio_source_manager.audio_sources:
print(f"✗ 音源不存在: {sound_id}")
return False
if effect_id not in self.effects:
print(f"✗ 效果不存在: {effect_id}")
return False
try:
# 初始化音效的效果列表
if sound_id not in self.sound_effects:
self.sound_effects[sound_id] = []
# 添加效果到音效
if effect_id not in self.sound_effects[sound_id]:
self.sound_effects[sound_id].append(effect_id)
# 更新统计信息
self.stats['effects_applied'] += 1
effect_type = self.effects[effect_id]['type']
print(f"✓ 效果已应用到音效: {effect_id} ({effect_type}) -> {sound_id}")
return True
else:
print(f"⚠ 效果已应用于该音效: {effect_id} -> {sound_id}")
return True
except Exception as e:
print(f"✗ 应用效果到音效失败: {e}")
return False
def remove_effect_from_sound(self, sound_id: str, effect_id: str) -> bool:
"""
从音效移除效果
Args:
sound_id: 音源ID
effect_id: 效果ID
Returns:
是否移除成功
"""
# 检查音源和效果是否存在
if sound_id not in self.plugin.audio_source_manager.audio_sources:
print(f"✗ 音源不存在: {sound_id}")
return False
if effect_id not in self.effects:
print(f"✗ 效果不存在: {effect_id}")
return False
try:
# 检查效果是否已应用于该音效
if sound_id in self.sound_effects and effect_id in self.sound_effects[sound_id]:
self.sound_effects[sound_id].remove(effect_id)
# 更新统计信息
self.stats['effects_applied'] -= 1
effect_type = self.effects[effect_id]['type']
print(f"✓ 效果已从音效移除: {effect_id} ({effect_type}) -> {sound_id}")
return True
else:
print(f"⚠ 效果未应用于该音效: {effect_id} -> {sound_id}")
return True
except Exception as e:
print(f"✗ 从音效移除效果失败: {e}")
return False
def set_effect_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
print(f"✓ 效果参数已设置: {effect_id}.{parameter} = {value}")
return True
except Exception as e:
print(f"✗ 设置效果参数失败: {e}")
return False
def get_effect_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
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
print(f"✓ 效果已禁用: {effect_id}")
return True
except Exception as e:
print(f"✗ 禁用效果失败: {e}")
return False
def get_effect_type(self, effect_id: str) -> str:
"""
获取效果类型
Args:
effect_id: 效果ID
Returns:
效果类型
"""
if effect_id not in self.effects:
return ""
return self.effects[effect_id]['type']
def get_sound_effects(self, sound_id: str) -> List[str]:
"""
获取音效应用的效果列表
Args:
sound_id: 音源ID
Returns:
效果ID列表
"""
return self.sound_effects.get(sound_id, []).copy()
def process_audio_with_effects(self, sound_id: str, audio_data: Any) -> Any:
"""
使用效果处理音频数据
Args:
sound_id: 音源ID
audio_data: 音频数据
Returns:
处理后的音频数据
"""
# 这是一个简化的实现
# 实际应用中需要根据效果类型对音频数据进行处理
if sound_id not in self.sound_effects:
return audio_data
# 获取应用到该音效的所有效果
effect_ids = self.sound_effects[sound_id]
# 按顺序应用效果
processed_data = audio_data
for effect_id in effect_ids:
if effect_id in self.effects and self.effects[effect_id]['active']:
effect = self.effects[effect_id]
processed_data = self._apply_single_effect(processed_data, effect)
return processed_data
def _apply_single_effect(self, audio_data: Any, effect: Dict[str, Any]) -> Any:
"""
应用单个效果到音频数据
Args:
audio_data: 音频数据
effect: 效果配置
Returns:
处理后的音频数据
"""
# 这是一个简化的实现
# 实际应用中需要根据效果类型对音频数据进行处理
effect_type = effect['type']
parameters = effect['parameters']
# 根据效果类型进行处理
if effect_type == 'reverb':
# 混响效果处理
processed_data = self._apply_reverb(audio_data, parameters)
elif effect_type == 'echo':
# 回声效果处理
processed_data = self._apply_echo(audio_data, parameters)
elif effect_type == 'lowpass':
# 低通滤波效果处理
processed_data = self._apply_lowpass_filter(audio_data, parameters)
elif effect_type == 'highpass':
# 高通滤波效果处理
processed_data = self._apply_highpass_filter(audio_data, parameters)
elif effect_type == 'distortion':
# 失真效果处理
processed_data = self._apply_distortion(audio_data, parameters)
else:
# 未知效果类型,不处理
processed_data = audio_data
return processed_data
def _apply_reverb(self, audio_data: Any, parameters: Dict[str, Any]) -> Any:
"""
应用混响效果
Args:
audio_data: 音频数据
parameters: 效果参数
Returns:
处理后的音频数据
"""
# 这是一个简化的实现
# 实际应用中需要对音频数据进行混响处理
return audio_data
def _apply_echo(self, audio_data: Any, parameters: Dict[str, Any]) -> Any:
"""
应用回声效果
Args:
audio_data: 音频数据
parameters: 效果参数
Returns:
处理后的音频数据
"""
# 这是一个简化的实现
# 实际应用中需要对音频数据进行回声处理
return audio_data
def _apply_lowpass_filter(self, audio_data: Any, parameters: Dict[str, Any]) -> Any:
"""
应用低通滤波效果
Args:
audio_data: 音频数据
parameters: 效果参数
Returns:
处理后的音频数据
"""
# 这是一个简化的实现
# 实际应用中需要对音频数据进行低通滤波处理
return audio_data
def _apply_highpass_filter(self, audio_data: Any, parameters: Dict[str, Any]) -> Any:
"""
应用高通滤波效果
Args:
audio_data: 音频数据
parameters: 效果参数
Returns:
处理后的音频数据
"""
# 这是一个简化的实现
# 实际应用中需要对音频数据进行高通滤波处理
return audio_data
def _apply_distortion(self, audio_data: Any, parameters: Dict[str, Any]) -> Any:
"""
应用失真效果
Args:
audio_data: 音频数据
parameters: 效果参数
Returns:
处理后的音频数据
"""
# 这是一个简化的实现
# 实际应用中需要对音频数据进行失真处理
return audio_data
def cleanup(self):
"""清理所有资源"""
self.effects.clear()
self.sound_effects.clear()
self.stats = {
'total_effects': 0,
'active_effects': 0,
'effects_applied': 0
}
print("✓ 音频效果处理器资源已清理")
def get_stats(self) -> Dict[str, int]:
"""
获取统计信息
Returns:
统计信息字典
"""
return self.stats.copy()