"""
空间音频效果处理器
实现专业的3D空间音频效果处理
"""

import uuid
import math
import numpy as np
from typing import Dict, List, Any, Optional, Tuple
from panda3d.core import Vec3

class SpatialProcessor:
    """
    空间音频效果处理器
    实现专业的3D空间音频效果处理
    """
    
    def __init__(self, plugin):
        """
        初始化空间音频效果处理器
        
        Args:
            plugin: 音频效果插件实例
        """
        self.plugin = plugin
        self.effects: Dict[str, Dict[str, Any]] = {}
        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.speed_of_sound = 343.0  # 声速 (米/秒)
        
    def create_effect(self, parameters: Dict[str, Any]) -> str:
        """
        创建空间音频效果
        
        Args:
            parameters: 空间音频效果参数
            
        Returns:
            效果ID
        """
        try:
            # 生成唯一ID
            effect_id = str(uuid.uuid4())
            
            # 默认参数
            default_params = {
                'source_position': (0.0, 0.0, 0.0),  # 音源位置 (x, y, z)
                'listener_position': (0.0, 0.0, 0.0),  # 听者位置 (x, y, z)
                'listener_orientation': (0.0, 0.0, 0.0),  # 听者方向 (heading, pitch, roll)
                'min_distance': 1.0,      # 最小距离
                'max_distance': 100.0,    # 最大距离
                'rolloff_factor': 1.0,    # 衰减因子
                'cone_inner_angle': 360.0,  # 内锥角 (度)
                'cone_outer_angle': 360.0,  # 外锥角 (度)
                'cone_outer_gain': 1.0,   # 外锥增益
                'doppler_factor': 1.0,    # 多普勒因子
                'spread': 0.0,            # 扩散角度 (度)
                'air_absorption': 0.0,    # 空气吸收
                'room_rolloff': 0.0,      # 房间衰减
                'occlusion': 0.0,         # 遮挡 (0.0-1.0)
                'obstruction': 0.0,       # 阻挡 (0.0-1.0)
                'hrtf_enabled': False,    # HRTF启用
                'reverb_send': 0.0        # 混响发送 (0.0-1.0)
            }
            
            # 合并参数
            effect_params = default_params.copy()
            effect_params.update(parameters)
            
            # 创建效果对象
            effect = {
                'id': effect_id,
                'type': 'spatial',
                'parameters': effect_params,
                'active': True,
                'buffers': {},  # 缓冲区
                'hrtf_filters': {},  # HRTF滤波器
                'distance': 0.0,  # 当前距离
                'azimuth': 0.0,   # 方位角
                'elevation': 0.0, # 仰角
                'created_time': self._get_current_time(),
                'process_count': 0
            }
            
            # 初始化缓冲区
            self._initialize_buffers(effect)
            
            # 初始化HRTF滤波器
            if effect_params.get('hrtf_enabled', False):
                self._initialize_hrtf_filters(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_buffers(self, effect: Dict[str, Any]):
        """
        初始化缓冲区
        
        Args:
            effect: 效果对象
        """
        effect_id = effect['id']
        buffers = {}
        
        # 输入和输出缓冲区
        buffers['input'] = np.zeros(self.buffer_size)
        buffers['output_left'] = np.zeros(self.buffer_size)
        buffers['output_right'] = np.zeros(self.buffer_size)
        
        # 延迟缓冲区（用于多普勒效应）
        buffers['delay_line'] = np.zeros(int(0.1 * self.sample_rate))  # 100ms延迟线
        buffers['delay_index'] = 0
        
        effect['buffers'] = buffers
        
    def _initialize_hrtf_filters(self, effect: Dict[str, Any]):
        """
        初始化HRTF滤波器
        
        Args:
            effect: 效果对象
        """
        # 这里应该加载真实的HRTF数据
        # 简化实现使用生成的滤波器
        
        hrtf_filters = {}
        
        # 为不同的角度生成简化的HRTF滤波器
        for azimuth in range(-180, 181, 15):  # 每15度一个滤波器
            for elevation in range(-90, 91, 15):
                # 生成简化的HRTF滤波器系数
                left_filter = self._generate_simple_hrtf_filter(azimuth, elevation, 'left')
                right_filter = self._generate_simple_hrtf_filter(azimuth, elevation, 'right')
                
                hrtf_filters[(azimuth, elevation)] = {
                    'left': left_filter,
                    'right': right_filter
                }
                
        effect['hrtf_filters'] = hrtf_filters
        
    def _generate_simple_hrtf_filter(self, azimuth: int, elevation: int, channel: str) -> np.ndarray:
        """
        生成简化的HRTF滤波器
        
        Args:
            azimuth: 方位角 (度)
            elevation: 仰角 (度)
            channel: 声道 ('left' 或 'right')
            
        Returns:
            滤波器系数数组
        """
        # 简化的HRTF滤波器生成
        # 实际应用中会使用真实的HRTF测量数据
        
        # 滤波器长度
        filter_length = 64
        
        # 生成基于角度的简化的滤波器
        filter_coeffs = np.zeros(filter_length)
        
        # 基于角度计算延迟和幅度
        if channel == 'left':
            # 左耳滤波器
            delay = max(0, int((1.0 - math.cos(math.radians(azimuth))) * 10))
            amplitude = 0.5 + 0.5 * math.cos(math.radians(azimuth))
        else:
            # 右耳滤波器
            delay = max(0, int((1.0 - math.cos(math.radians(-azimuth))) * 10))
            amplitude = 0.5 + 0.5 * math.cos(math.radians(-azimuth))
            
        # 应用延迟和幅度
        if delay < filter_length:
            filter_coeffs[delay] = amplitude
            
        return filter_coeffs
        
    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:
            处理后的音频数据
        """
        # 获取参数
        source_pos = Vec3(*parameters.get('source_position', (0.0, 0.0, 0.0)))
        listener_pos = Vec3(*parameters.get('listener_position', (0.0, 0.0, 0.0)))
        listener_orient = parameters.get('listener_orientation', (0.0, 0.0, 0.0))
        min_distance = max(0.1, parameters.get('min_distance', 1.0))
        max_distance = max(min_distance, parameters.get('max_distance', 100.0))
        rolloff_factor = max(0.0, parameters.get('rolloff_factor', 1.0))
        cone_inner_angle = max(0.0, min(360.0, parameters.get('cone_inner_angle', 360.0)))
        cone_outer_angle = max(cone_inner_angle, min(360.0, parameters.get('cone_outer_angle', 360.0)))
        cone_outer_gain = max(0.0, min(1.0, parameters.get('cone_outer_gain', 1.0)))
        doppler_factor = max(0.0, parameters.get('doppler_factor', 1.0))
        spread = max(0.0, parameters.get('spread', 0.0))
        air_absorption = max(0.0, parameters.get('air_absorption', 0.0))
        occlusion = max(0.0, min(1.0, parameters.get('occlusion', 0.0)))
        obstruction = max(0.0, min(1.0, parameters.get('obstruction', 0.0)))
        hrtf_enabled = parameters.get('hrtf_enabled', False)
        reverb_send = max(0.0, min(1.0, parameters.get('reverb_send', 0.0)))
        
        # 计算距离
        distance = (source_pos - listener_pos).length()
        
        # 计算方位角和仰角
        azimuth, elevation = self._calculate_angles(source_pos, listener_pos, listener_orient)
        
        # 计算音量衰减
        volume = self._calculate_volume_attenuation(
            distance, min_distance, max_distance, rolloff_factor)
            
        # 计算锥形效应
        cone_gain = self._calculate_cone_gain(
            source_pos, listener_pos, listener_orient,
            cone_inner_angle, cone_outer_angle, cone_outer_gain)
            
        # 计算遮挡和阻挡
        occlusion_gain = 1.0 - occlusion * 0.8  # 最多减少80%音量
        obstruction_gain = 1.0 - obstruction * 0.5  # 最多减少50%音量
        
        # 计算多普勒效应
        doppler_shift = self._calculate_doppler_shift(
            source_pos, listener_pos, doppler_factor)
            
        # 计算空气吸收
        air_absorption_gain = 1.0 - (distance / max_distance) * air_absorption * 0.5
        
        # 综合增益
        total_gain = (volume * cone_gain * occlusion_gain * 
                     obstruction_gain * air_absorption_gain)
        
        # 创建输出数组
        if audio_data.ndim == 1:
            # 单声道输入，生成立体声输出
            output_left = np.zeros_like(audio_data)
            output_right = np.zeros_like(audio_data)
            
            for i in range(len(audio_data)):
                sample = audio_data[i]
                
                # 应用增益
                processed_sample = sample * total_gain
                
                # 应用HRTF或简单立体声处理
                if hrtf_enabled:
                    # 简化的HRTF应用
                    left_sample, right_sample = self._apply_hrtf(
                        processed_sample, azimuth, elevation)
                else:
                    # 简单的立体声平移
                    left_sample, right_sample = self._simple_stereo_pan(
                        processed_sample, azimuth, spread)
                        
                output_left[i] = left_sample
                output_right[i] = right_sample
                
            # 合并为立体声数组
            output_data = np.array([output_left, output_right])
            
        else:
            # 多声道处理
            if audio_data.shape[0] >= 2:
                # 已经是立体声，应用空间效果
                output_left = np.zeros_like(audio_data[0])
                output_right = np.zeros_like(audio_data[1])
                
                for i in range(audio_data.shape[1]):
                    left_sample = audio_data[0, i] * total_gain
                    right_sample = audio_data[1, i] * total_gain
                    
                    # 应用HRTF或简单立体声处理
                    if hrtf_enabled:
                        # 简化的HRTF应用
                        new_left, new_right = self._apply_hrtf(
                            (left_sample + right_sample) * 0.5, azimuth, elevation)
                        output_left[i] = new_left
                        output_right[i] = new_right
                    else:
                        # 简单的立体声平移
                        new_left, new_right = self._simple_stereo_pan(
                            (left_sample + right_sample) * 0.5, azimuth, spread)
                        output_left[i] = new_left
                        output_right[i] = new_right
                        
                output_data = np.array([output_left, output_right])
            else:
                # 其他多声道情况，返回原始数据
                output_data = audio_data
                
        # 确保输出在有效范围内
        processed_data = np.clip(output_data, -1.0, 1.0)
        return processed_data
        
    def _calculate_angles(self, source_pos: Vec3, listener_pos: Vec3, 
                         listener_orient: Tuple[float, float, float]) -> Tuple[float, float]:
        """
        计算方位角和仰角
        
        Args:
            source_pos: 音源位置
            listener_pos: 听者位置
            listener_orient: 听者方向
            
        Returns:
            (方位角, 仰角) (度)
        """
        # 计算相对位置
        relative_pos = source_pos - listener_pos
        
        # 计算方位角 (水平角度)
        azimuth = math.degrees(math.atan2(relative_pos.x, -relative_pos.y))
        
        # 计算仰角 (垂直角度)
        distance_xy = math.sqrt(relative_pos.x**2 + relative_pos.y**2)
        elevation = math.degrees(math.atan2(relative_pos.z, distance_xy))
        
        return azimuth, elevation
        
    def _calculate_volume_attenuation(self, distance: float, min_distance: float, 
                                    max_distance: float, rolloff_factor: float) -> float:
        """
        计算音量衰减
        
        Args:
            distance: 距离
            min_distance: 最小距离
            max_distance: 最大距离
            rolloff_factor: 衰减因子
            
        Returns:
            音量增益 (0.0-1.0)
        """
        if distance <= min_distance:
            return 1.0
        elif distance >= max_distance:
            return 0.0
        else:
            # 反距离衰减模型
            gain = min_distance / (min_distance + rolloff_factor * (distance - min_distance))
            return max(0.0, min(1.0, gain))
            
    def _calculate_cone_gain(self, source_pos: Vec3, listener_pos: Vec3, 
                           listener_orient: Tuple[float, float, float],
                           inner_angle: float, outer_angle: float, outer_gain: float) -> float:
        """
        计算锥形效应增益
        
        Args:
            source_pos: 音源位置
            listener_pos: 听者位置
            listener_orient: 听者方向
            inner_angle: 内锥角 (度)
            outer_angle: 外锥角 (度)
            outer_gain: 外锥增益
            
        Returns:
            锥形增益 (0.0-1.0)
        """
        # 简化的锥形效应计算
        # 实际应用中需要考虑音源的朝向
        
        if inner_angle >= 360.0 and outer_angle >= 360.0:
            return 1.0
            
        # 计算听者相对于音源的角度
        relative_pos = listener_pos - source_pos
        angle = math.degrees(math.acos(relative_pos.normalized().dot(Vec3(0, -1, 0))))
        
        if angle <= inner_angle / 2.0:
            return 1.0
        elif angle >= outer_angle / 2.0:
            return outer_gain
        else:
            # 线性插值
            t = (angle - inner_angle / 2.0) / (outer_angle / 2.0 - inner_angle / 2.0)
            return 1.0 - t * (1.0 - outer_gain)
            
    def _calculate_doppler_shift(self, source_pos: Vec3, listener_pos: Vec3, 
                               doppler_factor: float) -> float:
        """
        计算多普勒频移
        
        Args:
            source_pos: 音源位置
            listener_pos: 听者位置
            doppler_factor: 多普勒因子
            
        Returns:
            频移比率
        """
        # 简化的多普勒效应计算
        # 实际应用中需要考虑音源和听者的速度
        
        if doppler_factor <= 0.0:
            return 1.0
            
        # 计算相对速度（简化为距离变化率）
        relative_velocity = (source_pos - listener_pos).length() / self.sample_rate
        ratio = (self.speed_of_sound - doppler_factor * relative_velocity) / self.speed_of_sound
        return max(0.5, min(2.0, ratio))
        
    def _apply_hrtf(self, sample: float, azimuth: float, elevation: float) -> Tuple[float, float]:
        """
        应用HRTF
        
        Args:
            sample: 输入样本
            azimuth: 方位角 (度)
            elevation: 仰角 (度)
            
        Returns:
            (左声道样本, 右声道样本)
        """
        # 简化的HRTF应用
        # 实际应用中会使用真实的HRTF滤波器
        
        # 量化角度以匹配预生成的滤波器
        azimuth_quantized = int(round(azimuth / 15.0)) * 15
        elevation_quantized = int(round(elevation / 15.0)) * 15
        
        # 限制角度范围
        azimuth_quantized = max(-180, min(180, azimuth_quantized))
        elevation_quantized = max(-90, min(90, elevation_quantized))
        
        # 简化的HRTF效果
        left_gain = 0.5 + 0.5 * math.cos(math.radians(azimuth))
        right_gain = 0.5 + 0.5 * math.cos(math.radians(-azimuth))
        
        # 应用仰角影响
        elevation_factor = math.cos(math.radians(elevation))
        left_gain *= elevation_factor
        right_gain *= elevation_factor
        
        return sample * left_gain, sample * right_gain
        
    def _simple_stereo_pan(self, sample: float, azimuth: float, spread: float) -> Tuple[float, float]:
        """
        简单的立体声平移
        
        Args:
            sample: 输入样本
            azimuth: 方位角 (度)
            spread: 扩散角度
            
        Returns:
            (左声道样本, 右声道样本)
        """
        # 将角度转换为-1到1的平移值
        pan = math.sin(math.radians(azimuth))
        
        # 应用扩散
        if spread > 0:
            spread_factor = 1.0 - spread / 180.0
            pan *= spread_factor
            
        # 计算左右声道增益
        left_gain = 0.5 - 0.5 * pan
        right_gain = 0.5 + 0.5 * pan
        
        return sample * left_gain, sample * right_gain
        
    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
            
            # 如果HRTF启用状态改变，重新初始化滤波器
            if parameter == 'hrtf_enabled':
                if value:
                    self._initialize_hrtf_filters(self.effects[effect_id])
                else:
                    self.effects[effect_id]['hrtf_filters'] = {}
            
            # 如果是插件中的效果，也更新插件中的副本
            if self.plugin and effect_id in self.plugin.effects:
                self.plugin.effects[effect_id]['parameters'][parameter] = value
                if parameter == 'hrtf_enabled':
                    self.plugin.effects[effect_id]['hrtf_filters'] = \
                        self.effects[effect_id]['hrtf_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.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)
        """
        self.sample_rate = sample_rate
        print(f"✓ 空间音频效果处理器采样率已设置: {sample_rate} Hz")
        
    def set_source_position(self, effect_id: str, position: Tuple[float, float, float]) -> bool:
        """
        设置音源位置
        
        Args:
            effect_id: 效果ID
            position: 位置 (x, y, z)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'source_position', position)
        
    def set_listener_position(self, effect_id: str, position: Tuple[float, float, float]) -> bool:
        """
        设置听者位置
        
        Args:
            effect_id: 效果ID
            position: 位置 (x, y, z)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'listener_position', position)
        
    def set_listener_orientation(self, effect_id: str, orientation: Tuple[float, float, float]) -> bool:
        """
        设置听者方向
        
        Args:
            effect_id: 效果ID
            orientation: 方向 (heading, pitch, roll)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'listener_orientation', orientation)
        
    def set_distance_model(self, effect_id: str, min_distance: float, 
                          max_distance: float, rolloff_factor: float) -> bool:
        """
        设置距离模型参数
        
        Args:
            effect_id: 效果ID
            min_distance: 最小距离
            max_distance: 最大距离
            rolloff_factor: 衰减因子
            
        Returns:
            是否设置成功
        """
        success = True
        success &= self.set_parameter(effect_id, 'min_distance', max(0.1, min_distance))
        success &= self.set_parameter(effect_id, 'max_distance', max(min_distance, max_distance))
        success &= self.set_parameter(effect_id, 'rolloff_factor', max(0.0, rolloff_factor))
        return success
        
    def set_cone_effect(self, effect_id: str, inner_angle: float, 
                       outer_angle: float, outer_gain: float) -> bool:
        """
        设置锥形效应参数
        
        Args:
            effect_id: 效果ID
            inner_angle: 内锥角 (度)
            outer_angle: 外锥角 (度)
            outer_gain: 外锥增益
            
        Returns:
            是否设置成功
        """
        success = True
        success &= self.set_parameter(effect_id, 'cone_inner_angle', max(0.0, min(360.0, inner_angle)))
        success &= self.set_parameter(effect_id, 'cone_outer_angle', max(inner_angle, min(360.0, outer_angle)))
        success &= self.set_parameter(effect_id, 'cone_outer_gain', max(0.0, min(1.0, outer_gain)))
        return success
        
    def set_doppler_factor(self, effect_id: str, factor: float) -> bool:
        """
        设置多普勒因子
        
        Args:
            effect_id: 效果ID
            factor: 多普勒因子
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'doppler_factor', max(0.0, factor))
        
    def set_spread(self, effect_id: str, spread: float) -> bool:
        """
        设置扩散角度
        
        Args:
            effect_id: 效果ID
            spread: 扩散角度 (度)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'spread', max(0.0, spread))
        
    def set_air_absorption(self, effect_id: str, absorption: float) -> bool:
        """
        设置空气吸收
        
        Args:
            effect_id: 效果ID
            absorption: 空气吸收系数
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'air_absorption', max(0.0, min(1.0, absorption)))
        
    def set_occlusion(self, effect_id: str, occlusion: float) -> bool:
        """
        设置遮挡系数
        
        Args:
            effect_id: 效果ID
            occlusion: 遮挡系数 (0.0-1.0)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'occlusion', max(0.0, min(1.0, occlusion)))
        
    def set_obstruction(self, effect_id: str, obstruction: float) -> bool:
        """
        设置阻挡系数
        
        Args:
            effect_id: 效果ID
            obstruction: 阻挡系数 (0.0-1.0)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'obstruction', max(0.0, min(1.0, obstruction)))
        
    def enable_hrtf(self, effect_id: str, enable: bool) -> bool:
        """
        启用/禁用HRTF
        
        Args:
            effect_id: 效果ID
            enable: 是否启用
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'hrtf_enabled', enable)
        
    def set_reverb_send(self, effect_id: str, send: float) -> bool:
        """
        设置混响发送量
        
        Args:
            effect_id: 效果ID
            send: 混响发送量 (0.0-1.0)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'reverb_send', max(0.0, min(1.0, send)))
        
    def get_distance(self, effect_id: str) -> float:
        """
        获取当前距离
        
        Args:
            effect_id: 效果ID
            
        Returns:
            距离值
        """
        if effect_id not in self.effects:
            return 0.0
            
        return self.effects[effect_id].get('distance', 0.0)
        
    def get_angles(self, effect_id: str) -> Tuple[float, float]:
        """
        获取当前角度
        
        Args:
            effect_id: 效果ID
            
        Returns:
            (方位角, 仰角) (度)
        """
        if effect_id not in self.effects:
            return (0.0, 0.0)
            
        effect = self.effects[effect_id]
        return (effect.get('azimuth', 0.0), effect.get('elevation', 0.0))
        
    def create_preset(self, preset_name: str) -> Dict[str, Any]:
        """
        创建空间音频效果预设
        
        Args:
            preset_name: 预设名称
            
        Returns:
            预设参数字典
        """
        presets = {
            'close': {
                'min_distance': 0.5,
                'max_distance': 20.0,
                'rolloff_factor': 1.0,
                'doppler_factor': 1.0,
                'air_absorption': 0.0
            },
            'medium': {
                'min_distance': 1.0,
                'max_distance': 50.0,
                'rolloff_factor': 0.8,
                'doppler_factor': 0.8,
                'air_absorption': 0.1
            },
            'far': {
                'min_distance': 5.0,
                'max_distance': 100.0,
                'rolloff_factor': 0.5,
                'doppler_factor': 0.5,
                'air_absorption': 0.3
            },
            'outdoor': {
                'min_distance': 2.0,
                'max_distance': 200.0,
                'rolloff_factor': 0.3,
                'doppler_factor': 1.0,
                'air_absorption': 0.5
            },
            'indoor': {
                'min_distance': 0.5,
                'max_distance': 30.0,
                'rolloff_factor': 1.2,
                'doppler_factor': 0.7,
                'air_absorption': 0.0
            },
            'underwater': {
                'min_distance': 1.0,
                'max_distance': 40.0,
                'rolloff_factor': 0.2,
                'doppler_factor': 0.3,
                'air_absorption': 0.8,
                'speed_of_sound': 1500.0  # 水中声速
            }
        }
        
        return presets.get(preset_name, {}).copy()

