"""
语音管理器
负责管理语音识别和合成的核心功能
"""

import time
import threading
import numpy as np
from typing import Dict, Any, List
from queue import Queue, Empty
import pyaudio
import wave
import struct

class SpeechManager:
    """
    语音管理器
    负责管理语音识别和合成的核心功能，包括音频设备管理、音频数据处理等
    """
    
    def __init__(self, plugin):
        """
        初始化语音管理器
        
        Args:
            plugin: 语音识别和合成插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 音频配置
        self.sample_rate = plugin.config.get('sample_rate', 16000)
        self.channels = plugin.config.get('channels', 1)
        self.buffer_size = plugin.config.get('buffer_size', 1024)
        self.format = pyaudio.paInt16  # 16位音频格式
        
        # 音频设备
        self.pyaudio_instance = None
        self.input_stream = None
        self.output_stream = None
        
        # 音频缓冲区
        self.audio_buffer = Queue(maxsize=1000)  # 音频数据缓冲区
        self.processed_buffer = Queue(maxsize=1000)  # 处理后数据缓冲区
        
        # 音频处理状态
        self.is_recording = False
        self.is_playing = False
        self.recording_thread = None
        self.playback_thread = None
        
        # 统计信息
        self.stats = {
            'audio_buffers_processed': 0,
            'audio_buffers_dropped': 0,
            'recording_time': 0.0,
            'playback_time': 0.0,
            'peak_audio_level': 0.0,
            'total_samples_recorded': 0,
            'total_samples_played': 0
        }
        
        # 音频处理参数
        self.audio_params = {
            'noise_threshold': 0.01,
            'silence_threshold': 0.005,
            'silence_duration': 1.0,
            'min_voice_duration': 0.5,
            'pre_emphasis': 0.97,  # 预加重系数
            'frame_length': 0.025,  # 帧长度(25ms)
            'frame_stride': 0.01,   # 帧步长(10ms)
        }
        
        # 音频处理缓冲区
        self.voice_buffer = []  # 语音片段缓冲区
        self.silence_counter = 0
        self.voice_activity_counter = 0
        self.is_voice_detected = False
        
        print("✓ 语音管理器已创建")
        
    def initialize(self) -> bool:
        """
        初始化语音管理器
        
        Returns:
            是否初始化成功
        """
        try:
            # 初始化PyAudio
            self.pyaudio_instance = pyaudio.PyAudio()
            
            # 验证音频设备
            input_device_count = self.pyaudio_instance.get_device_count()
            if input_device_count == 0:
                print("⚠ 未检测到音频输入设备")
                
            print(f"✓ 检测到 {input_device_count} 个音频设备")
            
            # 初始化音频设备
            print("✓ 音频设备初始化完成")
            
            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
            self.stop_recording()
            self.stop_playback()
            print("✓ 语音管理器已禁用")
            
        except Exception as e:
            print(f"✗ 语音管理器禁用失败: {e}")
            import traceback
            traceback.print_exc()
            
    def finalize(self):
        """清理语音管理器资源"""
        try:
            self.disable()
            
            # 关闭音频流
            if self.input_stream:
                self.input_stream.stop_stream()
                self.input_stream.close()
                self.input_stream = None
                
            if self.output_stream:
                self.output_stream.stop_stream()
                self.output_stream.close()
                self.output_stream = None
                
            # 终止PyAudio
            if self.pyaudio_instance:
                self.pyaudio_instance.terminate()
                self.pyaudio_instance = None
                
            self.initialized = False
            print("✓ 语音管理器资源已清理")
            
        except Exception as e:
            print(f"✗ 语音管理器资源清理失败: {e}")
            import traceback
            traceback.print_exc()
            
    def update(self, dt: float):
        """
        更新语音管理器状态
        
        Args:
            dt: 时间增量
        """
        # 这里可以处理定期更新的任务
        pass
        
    def start_recording(self) -> bool:
        """
        开始录音
        
        Returns:
            是否开始成功
        """
        try:
            if not self.enabled:
                print("✗ 语音管理器未启用")
                return False
                
            if self.is_recording:
                print("⚠ 已经在录音中")
                return True
                
            # 打开音频输入流
            self.input_stream = self.pyaudio_instance.open(
                format=self.format,
                channels=self.channels,
                rate=self.sample_rate,
                input=True,
                frames_per_buffer=self.buffer_size
            )
            
            # 启动录音线程
            self.is_recording = True
            self.recording_thread = threading.Thread(target=self._recording_worker, daemon=True)
            self.recording_thread.start()
            
            print("✓ 开始录音")
            return True
            
        except Exception as e:
            print(f"✗ 开始录音失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def stop_recording(self):
        """停止录音"""
        try:
            self.is_recording = False
            
            # 关闭音频输入流
            if self.input_stream:
                self.input_stream.stop_stream()
                self.input_stream.close()
                self.input_stream = None
                
            if self.recording_thread and self.recording_thread.is_alive():
                self.recording_thread.join(timeout=1.0)
            print("✓ 停止录音")
            
        except Exception as e:
            print(f"✗ 停止录音失败: {e}")
            import traceback
            traceback.print_exc()
            
    def start_playback(self, audio_data: bytes) -> bool:
        """
        开始播放音频
        
        Args:
            audio_data: 音频数据
            
        Returns:
            是否开始成功
        """
        try:
            if not self.enabled:
                print("✗ 语音管理器未启用")
                return False
                
            if self.is_playing:
                print("⚠ 已经在播放中")
                return True
                
            # 打开音频输出流
            self.output_stream = self.pyaudio_instance.open(
                format=self.format,
                channels=self.channels,
                rate=self.sample_rate,
                output=True,
                frames_per_buffer=self.buffer_size
            )
            
            # 启动播放线程
            self.is_playing = True
            self.playback_thread = threading.Thread(
                target=self._playback_worker, 
                args=(audio_data,), 
                daemon=True
            )
            self.playback_thread.start()
            
            print("✓ 开始播放音频")
            return True
            
        except Exception as e:
            print(f"✗ 开始播放音频失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def stop_playback(self):
        """停止播放音频"""
        try:
            self.is_playing = False
            
            # 关闭音频输出流
            if self.output_stream:
                self.output_stream.stop_stream()
                self.output_stream.close()
                self.output_stream = None
                
            if self.playback_thread and self.playback_thread.is_alive():
                self.playback_thread.join(timeout=1.0)
            print("✓ 停止播放音频")
            
        except Exception as e:
            print(f"✗ 停止播放音频失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _recording_worker(self):
        """录音工作线程"""
        try:
            recording_start_time = time.time()
            frames_recorded = 0
            
            # 录音循环
            while self.is_recording and self.enabled:
                try:
                    # 从音频输入流读取数据
                    audio_data = self.input_stream.read(self.buffer_size, exception_on_overflow=False)
                    
                    # 转换为numpy数组进行处理
                    audio_array = np.frombuffer(audio_data, dtype=np.int16)
                    audio_float = audio_array.astype(np.float32) / 32768.0
                    
                    # 计算音频级别
                    audio_level = np.mean(np.abs(audio_float)) if len(audio_float) > 0 else 0.0
                    self.stats['peak_audio_level'] = max(self.stats['peak_audio_level'], audio_level)
                    
                    # 应用预处理
                    processed_audio = self._preprocess_audio(audio_float)
                    
                    # 将音频数据放入缓冲区
                    try:
                        self.audio_buffer.put(processed_audio, block=False)
                        frames_recorded += len(audio_float)
                    except:
                        self.stats['audio_buffers_dropped'] += 1
                        
                    # 更新统计信息
                    self.stats['total_samples_recorded'] += len(audio_float)
                    
                except Exception as e:
                    print(f"⚠ 录音过程中出现错误: {e}")
                    continue
                    
            self.stats['recording_time'] += time.time() - recording_start_time
            self.stats['total_samples_recorded'] = frames_recorded
            
        except Exception as e:
            print(f"✗ 录音工作线程错误: {e}")
            import traceback
            traceback.print_exc()
            
    def _playback_worker(self, audio_data: bytes):
        """播放工作线程"""
        try:
            playback_start_time = time.time()
            bytes_played = 0
            
            # 将音频数据分块播放
            chunk_size = self.buffer_size * 2  # 16位音频，每个样本2字节
            for i in range(0, len(audio_data), chunk_size):
                if not self.is_playing:
                    break
                    
                chunk = audio_data[i:i + chunk_size]
                
                try:
                    # 写入音频输出流
                    self.output_stream.write(chunk)
                    bytes_played += len(chunk)
                except Exception as e:
                    print(f"⚠ 播放过程中出现错误: {e}")
                    continue
                    
            self.stats['playback_time'] += time.time() - playback_start_time
            self.stats['total_samples_played'] = bytes_played // 2  # 16位音频
            self.is_playing = False
            
        except Exception as e:
            print(f"✗ 播放工作线程错误: {e}")
            import traceback
            traceback.print_exc()
            self.is_playing = False
            
    def _preprocess_audio(self, audio_data: np.ndarray) -> np.ndarray:
        """
        预处理音频数据
        
        Args:
            audio_data: 原始音频数据
            
        Returns:
            预处理后的音频数据
        """
        try:
            if len(audio_data) == 0:
                return audio_data
                
            # 预加重 (Pre-emphasis)
            pre_emphasis = self.audio_params['pre_emphasis']
            if pre_emphasis > 0:
                # 应用预加重滤波器: y[t] = x[t] - a * x[t-1]
                emphasized = np.zeros_like(audio_data)
                emphasized[0] = audio_data[0]
                emphasized[1:] = audio_data[1:] - pre_emphasis * audio_data[:-1]
                audio_data = emphasized
                
            # 归一化
            max_val = np.max(np.abs(audio_data))
            if max_val > 0:
                audio_data = audio_data / max_val
                
            return audio_data
            
        except Exception as e:
            print(f"✗ 音频预处理失败: {e}")
            return audio_data
            
    def get_audio_chunk(self) -> np.ndarray:
        """
        获取音频数据块
        
        Returns:
            音频数据块
        """
        try:
            return self.audio_buffer.get(block=False)
        except Empty:
            return np.zeros(self.buffer_size, dtype=np.float32)
        except Exception as e:
            print(f"✗ 获取音频数据块失败: {e}")
            return np.zeros(self.buffer_size, dtype=np.float32)
            
    def put_processed_audio(self, audio_data: np.ndarray):
        """
        放入处理后的音频数据
        
        Args:
            audio_data: 处理后的音频数据
        """
        try:
            self.processed_buffer.put(audio_data, block=False)
            self.stats['audio_buffers_processed'] += 1
        except:
            self.stats['audio_buffers_dropped'] += 1
            
    def get_processed_audio(self) -> np.ndarray:
        """
        获取处理后的音频数据
        
        Returns:
            处理后的音频数据
        """
        try:
            return self.processed_buffer.get(block=False)
        except Empty:
            return np.zeros(self.buffer_size, dtype=np.float32)
        except Exception as e:
            print(f"✗ 获取处理后音频数据失败: {e}")
            return np.zeros(self.buffer_size, dtype=np.float32)
            
    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")
        
    def set_buffer_size(self, buffer_size: int):
        """
        设置缓冲区大小
        
        Args:
            buffer_size: 缓冲区大小
        """
        self.buffer_size = buffer_size
        print(f"✓ 缓冲区大小设置为: {buffer_size}")
        
    def set_noise_threshold(self, threshold: float):
        """
        设置噪声阈值
        
        Args:
            threshold: 噪声阈值
        """
        self.audio_params['noise_threshold'] = max(0.0, min(1.0, threshold))
        print(f"✓ 噪声阈值设置为: {threshold}")
        
    def set_silence_threshold(self, threshold: float):
        """
        设置静音阈值
        
        Args:
            threshold: 静音阈值
        """
        self.audio_params['silence_threshold'] = max(0.0, min(1.0, threshold))
        print(f"✓ 静音阈值设置为: {threshold}")
        
    def get_stats(self) -> Dict[str, Any]:
        """
        获取统计信息
        
        Returns:
            统计信息字典
        """
        return self.stats.copy()
        
    def is_audio_silent(self, audio_data: np.ndarray) -> bool:
        """
        检查音频是否静音
        
        Args:
            audio_data: 音频数据
            
        Returns:
            是否静音
        """
        try:
            if len(audio_data) == 0:
                return True
            audio_level = np.mean(np.abs(audio_data))
            return audio_level < self.audio_params['silence_threshold']
        except Exception as e:
            print(f"✗ 检查音频静音状态失败: {e}")
            return True
            
    def is_audio_noisy(self, audio_data: np.ndarray) -> bool:
        """
        检查音频是否有噪声
        
        Args:
            audio_data: 音频数据
            
        Returns:
            是否有噪声
        """
        try:
            if len(audio_data) == 0:
                return False
            audio_level = np.mean(np.abs(audio_data))
            return audio_level > self.audio_params['noise_threshold']
        except Exception as e:
            print(f"✗ 检查音频噪声状态失败: {e}")
            return False
            
    def apply_preprocessing(self, audio_data: np.ndarray) -> np.ndarray:
        """
        应用音频预处理
        
        Args:
            audio_data: 原始音频数据
            
        Returns:
            预处理后的音频数据
        """
        try:
            # 预加重
            pre_emphasis = self.audio_params['pre_emphasis']
            if pre_emphasis > 0 and len(audio_data) > 1:
                emphasized = np.zeros_like(audio_data)
                emphasized[0] = audio_data[0]
                emphasized[1:] = audio_data[1:] - pre_emphasis * audio_data[:-1]
                audio_data = emphasized
                
            # 归一化
            max_val = np.max(np.abs(audio_data))
            if max_val > 0:
                audio_data = audio_data / max_val
                
            return audio_data
        except Exception as e:
            print(f"✗ 音频预处理失败: {e}")
            return audio_data
            
    def apply_postprocessing(self, audio_data: np.ndarray) -> np.ndarray:
        """
        应用音频后处理
        
        Args:
            audio_data: 处理后的音频数据
            
        Returns:
            后处理后的音频数据
        """
        try:
            # 限幅处理防止削波
            audio_data = np.clip(audio_data, -0.99, 0.99)
            
            # 转换为16位整数格式
            audio_int16 = (audio_data * 32767).astype(np.int16)
            
            return audio_int16
        except Exception as e:
            print(f"✗ 音频后处理失败: {e}")
            # 返回原始数据的16位版本
            try:
                return (audio_data * 32767).astype(np.int16)
            except:
                return np.zeros(len(audio_data), dtype=np.int16)
            
    def detect_voice_activity(self, audio_data: np.ndarray) -> bool:
        """
        检测语音活动
        
        Args:
            audio_data: 音频数据
            
        Returns:
            是否检测到语音活动
        """
        try:
            # 检查音频级别是否超过噪声阈值
            if len(audio_data) == 0:
                return False
                
            audio_level = np.mean(np.abs(audio_data))
            return audio_level > self.audio_params['noise_threshold']
        except Exception as e:
            print(f"✗ 语音活动检测失败: {e}")
            return False
            
    def calculate_audio_level(self, audio_data: np.ndarray) -> float:
        """
        计算音频级别
        
        Args:
            audio_data: 音频数据
            
        Returns:
            音频级别 (0.0-1.0)
        """
        try:
            if len(audio_data) == 0:
                return 0.0
            return float(np.mean(np.abs(audio_data)))
        except Exception as e:
            print(f"✗ 计算音频级别失败: {e}")
            return 0.0
            
    def convert_sample_rate(self, audio_data: np.ndarray, from_rate: int, to_rate: int) -> np.ndarray:
        """
        转换音频采样率
        
        Args:
            audio_data: 音频数据
            from_rate: 原始采样率
            to_rate: 目标采样率
            
        Returns:
            转换后的音频数据
        """
        try:
            if from_rate == to_rate:
                return audio_data
                
            # 计算采样率转换比例
            ratio = to_rate / from_rate
            new_length = int(len(audio_data) * ratio)
            
            if new_length <= 0:
                return np.array([], dtype=np.float32)
                
            # 使用线性插值进行重采样
            indices = np.linspace(0, len(audio_data) - 1, new_length)
            resampled_data = np.interp(indices, np.arange(len(audio_data)), audio_data)
            
            return resampled_data.astype(np.float32)
        except Exception as e:
            print(f"✗ 采样率转换失败: {e}")
            return audio_data
            
    def apply_gain(self, audio_data: np.ndarray, gain: float) -> np.ndarray:
        """
        应用增益到音频数据
        
        Args:
            audio_data: 音频数据
            gain: 增益值
            
        Returns:
            应用增益后的音频数据
        """
        try:
            amplified_data = audio_data * gain
            # 防止削波
            return np.clip(amplified_data, -1.0, 1.0)
        except Exception as e:
            print(f"✗ 应用增益失败: {e}")
            return audio_data
            
    def mix_audio(self, audio1: np.ndarray, audio2: np.ndarray) -> np.ndarray:
        """
        混合两个音频信号
        
        Args:
            audio1: 第一个音频信号
            audio2: 第二个音频信号
            
        Returns:
            混合后的音频信号
        """
        try:
            # 确保两个音频信号长度相同
            max_length = max(len(audio1), len(audio2))
            if len(audio1) < max_length:
                audio1 = np.pad(audio1, (0, max_length - len(audio1)))
            if len(audio2) < max_length:
                audio2 = np.pad(audio2, (0, max_length - len(audio2)))
                
            # 混合音频（简单平均）
            mixed_audio = (audio1 + audio2) / 2.0
            
            # 防止削波
            return np.clip(mixed_audio, -1.0, 1.0)
        except Exception as e:
            print(f"✗ 音频混合失败: {e}")
            # 返回较长的音频信号
            return audio1 if len(audio1) >= len(audio2) else audio2
            
    def apply_window_function(self, audio_data: np.ndarray, window_type: str = 'hann') -> np.ndarray:
        """
        应用窗函数到音频数据
        
        Args:
            audio_data: 音频数据
            window_type: 窗函数类型 ('hann', 'hamming', 'blackman')
            
        Returns:
            应用窗函数后的音频数据
        """
        try:
            if len(audio_data) == 0:
                return audio_data
                
            # 根据类型生成窗函数
            if window_type == 'hann':
                window = np.hanning(len(audio_data))
            elif window_type == 'hamming':
                window = np.hamming(len(audio_data))
            elif window_type == 'blackman':
                window = np.blackman(len(audio_data))
            else:
                # 默认使用汉宁窗
                window = np.hanning(len(audio_data))
                
            # 应用窗函数
            windowed_data = audio_data * window
            
            return windowed_data
        except Exception as e:
            print(f"✗ 应用窗函数失败: {e}")
            return audio_data
            
    def calculate_spectral_features(self, audio_data: np.ndarray) -> Dict[str, Any]:
        """
        计算音频的频谱特征
        
        Args:
            audio_data: 音频数据
            
        Returns:
            频谱特征字典
        """
        try:
            if len(audio_data) == 0:
                return {}
                
            # 计算FFT
            fft_data = np.fft.fft(audio_data)
            magnitude = np.abs(fft_data)
            
            # 计算基本频谱特征
            spectral_centroid = np.sum(magnitude * np.arange(len(magnitude))) / np.sum(magnitude)
            spectral_rolloff = np.sum(magnitude[:int(len(magnitude) * 0.85)])
            spectral_flux = np.sum(np.diff(magnitude) ** 2)
            zero_crossing_rate = np.sum(np.diff(np.sign(audio_data)) != 0) / len(audio_data)
            
            return {
                'spectral_centroid': spectral_centroid,
                'spectral_rolloff': spectral_rolloff,
                'spectral_flux': spectral_flux,
                'zero_crossing_rate': zero_crossing_rate,
                'rms_energy': np.sqrt(np.mean(audio_data ** 2)),
                'peak_amplitude': np.max(np.abs(audio_data))
            }
        except Exception as e:
            print(f"✗ 计算频谱特征失败: {e}")
            return {}
            
    def apply_spectral_filter(self, audio_data: np.ndarray, filter_type: str, cutoff_freq: float) -> np.ndarray:
        """
        应用频谱滤波器
        
        Args:
            audio_data: 音频数据
            filter_type: 滤波器类型 ('lowpass', 'highpass', 'bandpass')
            cutoff_freq: 截止频率 (Hz)
            
        Returns:
            滤波后的音频数据
        """
        try:
            if len(audio_data) == 0:
                return audio_data
                
            # 简化的频域滤波实现
            fft_data = np.fft.fft(audio_data)
            freqs = np.fft.fftfreq(len(audio_data), 1/self.sample_rate)
            
            # 创建滤波器掩码
            if filter_type == 'lowpass':
                mask = np.abs(freqs) <= cutoff_freq
            elif filter_type == 'highpass':
                mask = np.abs(freqs) >= cutoff_freq
            elif filter_type == 'bandpass':
                # 简化的带通滤波器 (以cutoff_freq为中心频率)
                bandwidth = cutoff_freq * 0.2  # 20%带宽
                mask = (np.abs(freqs) >= (cutoff_freq - bandwidth)) & (np.abs(freqs) <= (cutoff_freq + bandwidth))
            else:
                # 默认不滤波
                return audio_data
                
            # 应用滤波器
            filtered_fft = fft_data * mask
            filtered_audio = np.real(np.fft.ifft(filtered_fft))
            
            return filtered_audio
        except Exception as e:
            print(f"✗ 应用频谱滤波器失败: {e}")
            return audio_data
            
    def segment_audio(self, audio_data: np.ndarray, segment_length: int) -> List[np.ndarray]:
        """
        将音频数据分割成段
        
        Args:
            audio_data: 音频数据
            segment_length: 每段长度
            
        Returns:
            音频段列表
        """
        try:
            segments = []
            for i in range(0, len(audio_data), segment_length):
                segment = audio_data[i:i + segment_length]
                segments.append(segment)
            return segments
        except Exception as e:
            print(f"✗ 音频分割失败: {e}")
            return [audio_data]
            
    def apply_dynamic_range_compression(self, audio_data: np.ndarray, threshold: float = -20.0, 
                                      ratio: float = 4.0, attack: float = 0.01, release: float = 0.1) -> np.ndarray:
        """
        应用动态范围压缩
        
        Args:
            audio_data: 音频数据
            threshold: 阈值 (dB)
            ratio: 压缩比
            attack: 启动时间 (秒)
            release: 释放时间 (秒)
            
        Returns:
            压缩后的音频数据
        """
        try:
            if len(audio_data) == 0:
                return audio_data
                
            # 转换阈值为线性值
            threshold_linear = 10 ** (threshold / 20.0)
            
            # 计算包络
            envelope = np.zeros_like(audio_data)
            gain = np.ones_like(audio_data)
            
            # 简化的压缩器实现
            current_gain = 1.0
            for i in range(len(audio_data)):
                # 计算瞬时幅度
                instant_amp = abs(audio_data[i])
                
                # 更新包络 (简化实现)
                if instant_amp > envelope[i-1] if i > 0 else 0:
                    # 启动阶段
                    envelope[i] = instant_amp
                else:
                    # 释放阶段
                    envelope[i] = envelope[i-1] * 0.99 if i > 0 else instant_amp
                    
                # 计算增益缩减
                if envelope[i] > threshold_linear:
                    gain_db = 20 * np.log10(envelope[i] / threshold_linear)
                    reduction_db = gain_db - gain_db / ratio
                    target_gain = 10 ** (-reduction_db / 20.0)
                else:
                    target_gain = 1.0
                    
                # 应用启动和释放时间
                if target_gain < current_gain:
                    # 启动
                    current_gain = current_gain + (target_gain - current_gain) * (1 - np.exp(-1.0 / (self.sample_rate * attack)))
                else:
                    # 释放
                    current_gain = current_gain + (target_gain - current_gain) * (1 - np.exp(-1.0 / (self.sample_rate * release)))
                    
                gain[i] = current_gain
                
            # 应用增益
            compressed_audio = audio_data * gain
            
            return compressed_audio
        except Exception as e:
            print(f"✗ 动态范围压缩失败: {e}")
            return audio_data
            
    def apply_noise_reduction(self, audio_data: np.ndarray, noise_factor: float = 0.05) -> np.ndarray:
        """
        应用噪声抑制
        
        Args:
            audio_data: 音频数据
            noise_factor: 噪声因子 (0.0-1.0)
            
        Returns:
            噪声抑制后的音频数据
        """
        try:
            if len(audio_data) == 0:
                return audio_data
                
            # 简化的噪声抑制实现
            # 使用谱减法的简化版本
            fft_data = np.fft.fft(audio_data)
            magnitude = np.abs(fft_data)
            phase = np.angle(fft_data)
            
            # 估计噪声水平 (使用前10%的数据)
            noise_estimate = np.mean(magnitude[:max(1, len(magnitude) // 10)])
            
            # 应用噪声抑制
            suppression = np.maximum(magnitude - noise_factor * noise_estimate, 0)
            suppressed_fft = suppression * np.exp(1j * phase)
            
            # 逆变换
            suppressed_audio = np.real(np.fft.ifft(suppressed_fft))
            
            return suppressed_audio
        except Exception as e:
            print(f"✗ 噪声抑制失败: {e}")
            return audio_data
            
    def apply_echo_effect(self, audio_data: np.ndarray, delay: float = 0.25, decay: float = 0.5) -> np.ndarray:
        """
        应用回声效果
        
        Args:
            audio_data: 音频数据
            delay: 延迟时间 (秒)
            decay: 衰减系数 (0.0-1.0)
            
        Returns:
            添加回声效果的音频数据
        """
        try:
            if len(audio_data) == 0:
                return audio_data
                
            # 计算延迟样本数
            delay_samples = int(delay * self.sample_rate)
            
            # 创建输出数组
            echo_audio = np.zeros(len(audio_data) + delay_samples)
            echo_audio[:len(audio_data)] = audio_data
            
            # 应用回声
            for i in range(len(audio_data)):
                if i + delay_samples < len(echo_audio):
                    echo_audio[i + delay_samples] += audio_data[i] * decay
                    
            # 裁剪到原始长度
            return echo_audio[:len(audio_data)]
        except Exception as e:
            print(f"✗ 回声效果应用失败: {e}")
            return audio_data
            
    def apply_vocal_enhancement(self, audio_data: np.ndarray) -> np.ndarray:
        """
        应用人声增强效果
        
        Args:
            audio_data: 音频数据
            
        Returns:
            人声增强后的音频数据
        """
        try:
            if len(audio_data) == 0:
                return audio_data
                
            # 简化的人声增强实现
            # 1. 应用预加重
            pre_emphasized = self._preprocess_audio(audio_data)
            
            # 2. 应用中频提升滤波器 (简化实现)
            # 人声主要集中在300Hz-3400Hz范围内
            mid_freq_boosted = self.apply_spectral_filter(pre_emphasized, 'bandpass', 1500)  # 中心频率约1500Hz
            
            # 3. 应用动态范围压缩
            compressed = self.apply_dynamic_range_compression(mid_freq_boosted, threshold=-25.0, ratio=3.0)
            
            # 4. 混合原始信号和增强信号
            enhanced_audio = (pre_emphasized + compressed) / 2.0
            
            return enhanced_audio
        except Exception as e:
            print(f"✗ 人声增强失败: {e}")
            return audio_data
            
    def save_audio_to_wav(self, filename: str, audio_data: np.ndarray, sample_rate: int = None) -> bool:
        """
        保存音频数据为WAV文件
        
        Args:
            filename: 文件名
            audio_data: 音频数据
            sample_rate: 采样率
            
        Returns:
            是否保存成功
        """
        try:
            if sample_rate is None:
                sample_rate = self.sample_rate
                
            # 确保目录存在
            import os
            os.makedirs(os.path.dirname(filename) if os.path.dirname(filename) else '.', exist_ok=True)
            
            # 转换为16位整数
            if audio_data.dtype != np.int16:
                audio_int16 = np.clip(audio_data, -1.0, 1.0)
                audio_int16 = (audio_int16 * 32767).astype(np.int16)
            else:
                audio_int16 = audio_data
                
            # 保存为WAV文件
            with wave.open(filename, 'w') as wav_file:
                wav_file.setnchannels(self.channels)
                wav_file.setsampwidth(2)  # 16位
                wav_file.setframerate(sample_rate)
                wav_file.writeframes(audio_int16.tobytes())
                
            print(f"✓ 音频已保存为WAV文件: {filename}")
            return True
        except Exception as e:
            print(f"✗ 保存WAV文件失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def load_audio_from_wav(self, filename: str) -> np.ndarray:
        """
        从WAV文件加载音频数据
        
        Args:
            filename: 文件名
            
        Returns:
            音频数据
        """
        try:
            with wave.open(filename, 'r') as wav_file:
                # 获取音频参数
                channels = wav_file.getnchannels()
                sample_width = wav_file.getsampwidth()
                frame_rate = wav_file.getframerate()
                frames = wav_file.getnframes()
                
                # 读取音频数据
                raw_audio = wav_file.readframes(frames)
                
                # 转换为numpy数组
                if sample_width == 1:
                    # 8位音频
                    audio_data = np.frombuffer(raw_audio, dtype=np.uint8)
                    audio_data = (audio_data.astype(np.float32) - 128) / 128.0
                elif sample_width == 2:
                    # 16位音频
                    audio_data = np.frombuffer(raw_audio, dtype=np.int16)
                    audio_data = audio_data.astype(np.float32) / 32768.0
                elif sample_width == 4:
                    # 32位音频
                    audio_data = np.frombuffer(raw_audio, dtype=np.int32)
                    audio_data = audio_data.astype(np.float32) / 2147483648.0
                else:
                    raise ValueError(f"不支持的采样宽度: {sample_width}")
                    
                # 如果采样率不同，进行重采样
                if frame_rate != self.sample_rate:
                    audio_data = self.convert_sample_rate(audio_data, frame_rate, self.sample_rate)
                    
                print(f"✓ 音频已从WAV文件加载: {filename}")
                return audio_data
                
        except Exception as e:
            print(f"✗ 从WAV文件加载音频失败: {e}")
            import traceback
            traceback.print_exc()
            return np.array([], dtype=np.float32)
            
    def apply_auto_tuning(self, audio_data: np.ndarray, pitch_shift: float = 0.0) -> np.ndarray:
        """
        应用自动调音效果
        
        Args:
            audio_data: 音频数据
            pitch_shift: 音高偏移 (半音数)
            
        Returns:
            调音后的音频数据
        """
        try:
            if len(audio_data) == 0:
                return audio_data
                
            # 简化的自动调音实现
            # 实际的自动调音算法非常复杂，这里只实现音高移位
            
            # 计算音高移位因子
            pitch_factor = 2 ** (pitch_shift / 12.0)
            
            if pitch_factor == 1.0:
                return audio_data
                
            # 简化的音高移位（线性插值）
            output_length = int(len(audio_data) / pitch_factor)
            if output_length <= 0:
                return np.array([], dtype=np.float32)
                
            processed = np.zeros(output_length)
            
            # 重采样
            for i in range(output_length):
                # 计算源位置
                src_pos = i * pitch_factor
                src_index = int(src_pos)
                frac = src_pos - src_index
                
                # 线性插值
                if src_index < len(audio_data) - 1:
                    processed[i] = audio_data[src_index] * (1 - frac) + \
                                  audio_data[src_index + 1] * frac
                else:
                    processed[i] = audio_data[min(src_index, len(audio_data) - 1)]
                    
            return processed
        except Exception as e:
            print(f"✗ 自动调音失败: {e}")
            return audio_data
            
    def apply_formant_filter(self, audio_data: np.ndarray, formant_freq: float = 1000.0, 
                           formant_bandwidth: float = 100.0) -> np.ndarray:
        """
        应用共振峰滤波器
        
        Args:
            audio_data: 音频数据
            formant_freq: 共振峰频率 (Hz)
            formant_bandwidth: 共振峰带宽 (Hz)
            
        Returns:
            共振峰滤波后的音频数据
        """
        try:
            if len(audio_data) == 0:
                return audio_data
                
            # 简化的共振峰滤波器实现
            # 使用带通滤波器模拟共振峰
            
            # 计算滤波器参数
            w0 = 2 * np.pi * formant_freq / self.sample_rate
            alpha = np.sin(w0) * np.sinh(np.log(2) / 2 * formant_bandwidth * w0 / np.sin(w0))
            
            # 计算滤波器系数
            b0 = alpha
            b1 = 0
            b2 = -alpha
            a0 = 1 + alpha
            a1 = -2 * np.cos(w0)
            a2 = 1 - alpha
            
            # 归一化系数
            b0, b1, b2 = b0/a0, b1/a0, b2/a0
            a1, a2 = a1/a0, a2/a0
            
            # 应用滤波器 (直接II型结构)
            filtered_audio = np.zeros_like(audio_data)
            for n in range(len(audio_data)):
                filtered_audio[n] = b0 * audio_data[n] + b1 * (audio_data[n-1] if n > 0 else 0) + \
                                  b2 * (audio_data[n-2] if n > 1 else 0) - \
                                  a1 * (filtered_audio[n-1] if n > 0 else 0) - \
                                  a2 * (filtered_audio[n-2] if n > 1 else 0)
                                  
            return filtered_audio
        except Exception as e:
            print(f"✗ 共振峰滤波失败: {e}")
            return audio_data
            
    def apply_harmonic_enhancement(self, audio_data: np.ndarray, harmonics: List[int] = [2, 3]) -> np.ndarray:
        """
        应用谐波增强效果
        
        Args:
            audio_data: 音频数据
            harmonics: 要增强的谐波倍数列表
            
        Returns:
            谐波增强后的音频数据
        """
        try:
            if len(audio_data) == 0:
                return audio_data
                
            # 简化的谐波增强实现
            enhanced_audio = audio_data.copy()
            
            # 对每个谐波倍数进行处理
            for harmonic in harmonics:
                # 音高移位到谐波频率
                harmonic_audio = self.apply_auto_tuning(audio_data, 12 * np.log2(harmonic))
                
                # 混合到原始音频 (较低的增益)
                enhanced_audio += harmonic_audio * (0.3 / len(harmonics))
                
            # 归一化防止削波
            max_val = np.max(np.abs(enhanced_audio))
            if max_val > 1.0:
                enhanced_audio = enhanced_audio / max_val
                
            return enhanced_audio
        except Exception as e:
            print(f"✗ 谐波增强失败: {e}")
            return audio_data
            
    def apply_spectral_subtraction(self, audio_data: np.ndarray, noise_factor: float = 0.1) -> np.ndarray:
        """
        应用谱减法降噪
        
        Args:
            audio_data: 音频数据
            noise_factor: 噪声估计因子
            
        Returns:
            降噪后的音频数据
        """
        try:
            if len(audio_data) == 0:
                return audio_data
                
            # 简化的谱减法实现
            # 1. 计算短时傅里叶变换
            frame_length = int(self.sample_rate * 0.025)  # 25ms帧
            frame_step = int(self.sample_rate * 0.01)     # 10ms步长
            frames = []
            
            # 分帧
            for i in range(0, len(audio_data) - frame_length, frame_step):
                frame = audio_data[i:i + frame_length]
                # 应用窗函数
                windowed_frame = self.apply_window_function(frame, 'hann')
                frames.append(windowed_frame)
                
            if not frames:
                return audio_data
                
            # 2. 估计噪声谱 (使用前几帧)
            noise_frames = min(5, len(frames))
            noise_spectrum = np.mean([np.abs(np.fft.fft(frames[i])) for i in range(noise_frames)], axis=0)
            
            # 3. 对每帧进行谱减
            processed_frames = []
            for frame in frames:
                # 计算帧的频谱
                frame_spectrum = np.fft.fft(frame)
                magnitude = np.abs(frame_spectrum)
                phase = np.angle(frame_spectrum)
                
                # 谱减法
                subtracted_magnitude = np.maximum(magnitude - noise_factor * noise_spectrum, 0)
                
                # 重构频谱
                reconstructed_spectrum = subtracted_magnitude * np.exp(1j * phase)
                
                # 逆变换得到时域信号
                processed_frame = np.real(np.fft.ifft(reconstructed_spectrum))
                processed_frames.append(processed_frame)
                
            # 4. 重叠相加合成
            output_length = len(audio_data)
            output_signal = np.zeros(output_length)
            overlap_count = np.zeros(output_length)
            
            for i, frame in enumerate(processed_frames):
                start_idx = i * frame_step
                end_idx = min(start_idx + frame_length, output_length)
                output_signal[start_idx:end_idx] += frame[:end_idx-start_idx]
                overlap_count[start_idx:end_idx] += 1
                
            # 归一化重叠区域
            output_signal = np.divide(output_signal, overlap_count, 
                                    out=np.zeros_like(output_signal), where=overlap_count!=0)
            
            return output_signal
        except Exception as e:
            print(f"✗ 谱减法降噪失败: {e}")
            return audio_data
            
    def apply_adaptive_filter(self, audio_data: np.ndarray, reference_signal: np.ndarray = None) -> np.ndarray:
        """
        应用自适应滤波器（用于回声消除等）
        
        Args:
            audio_data: 主音频信号
            reference_signal: 参考信号（如远端信号）
            
        Returns:
            滤波后的音频数据
        """
        try:
            if len(audio_data) == 0:
                return audio_data
                
            # 如果没有提供参考信号，使用延迟版本的主信号作为参考
            if reference_signal is None:
                delay_samples = int(0.05 * self.sample_rate)  # 50ms延迟
                reference_signal = np.concatenate([np.zeros(delay_samples), audio_data[:-delay_samples]])
                
            # 确保参考信号长度与主信号相同
            if len(reference_signal) != len(audio_data):
                min_length = min(len(reference_signal), len(audio_data))
                audio_data = audio_data[:min_length]
                reference_signal = reference_signal[:min_length]
                
            # 简化的LMS自适应滤波器
            filter_length = 64
            step_size = 0.01
            weights = np.zeros(filter_length)
            filtered_audio = np.zeros_like(audio_data)
            
            # 自适应滤波处理
            for n in range(filter_length, len(audio_data)):
                # 获取输入向量
                input_vector = reference_signal[n-filter_length:n][::-1]  # 反转
                
                # 滤波器输出
                output = np.dot(weights, input_vector)
                
                # 误差信号
                error = audio_data[n] - output
                
                # 更新权重 (LMS算法)
                weights += step_size * error * input_vector
                
                # 保存滤波后的信号
                filtered_audio[n] = error
                
            return filtered_audio
        except Exception as e:
            print(f"✗ 自适应滤波失败: {e}")
            return audio_data
            
    def apply_voice_activity_detection(self, audio_data: np.ndarray) -> np.ndarray:
        """
        应用语音活动检测，只保留语音段
        
        Args:
            audio_data: 音频数据
            
        Returns:
            仅包含语音段的音频数据
        """
        try:
            if len(audio_data) == 0:
                return audio_data
                
            # 分帧处理
            frame_length = int(self.sample_rate * self.audio_params['frame_length'])
            frame_stride = int(self.sample_rate * self.audio_params['frame_stride'])
            
            voiced_frames = []
            
            # 处理每帧
            for i in range(0, len(audio_data) - frame_length, frame_stride):
                frame = audio_data[i:i + frame_length]
                
                # 计算帧能量
                frame_energy = np.sum(frame ** 2) / len(frame)
                
                # 计算过零率
                zero_crossings = np.sum(np.diff(np.sign(frame)) != 0) / len(frame)
                
                # 简单的VAD决策
                # 语音通常具有较高的能量和适中的过零率
                energy_threshold = self.audio_params['noise_threshold'] ** 2
                if frame_energy > energy_threshold and 0.01 < zero_crossings < 0.5:
                    voiced_frames.append(frame)
                    
            # 合并语音帧
            if voiced_frames:
                return np.concatenate(voiced_frames)
            else:
                return np.array([], dtype=np.float32)
                
        except Exception as e:
            print(f"✗ 语音活动检测失败: {e}")
            return audio_data
            
    def apply_speech_enhancement(self, audio_data: np.ndarray) -> np.ndarray:
        """
        应用综合语音增强处理
        
        Args:
            audio_data: 音频数据
            
        Returns:
            增强后的音频数据
        """
        try:
            if len(audio_data) == 0:
                return audio_data
                
            # 1. 预处理
            processed = self._preprocess_audio(audio_data)
            
            # 2. 噪声抑制
            processed = self.apply_spectral_subtraction(processed, noise_factor=0.1)
            
            # 3. 语音活动检测
            processed = self.apply_voice_activity_detection(processed)
            
            # 4. 共振峰增强
            processed = self.apply_formant_filter(processed, formant_freq=1000.0, formant_bandwidth=100.0)
            
            # 5. 动态范围压缩
            processed = self.apply_dynamic_range_compression(processed, threshold=-25.0, ratio=3.0)
            
            # 6. 人声增强
            processed = self.apply_vocal_enhancement(processed)
            
            return processed
        except Exception as e:
            print(f"✗ 语音增强失败: {e}")
            return audio_data
            
    def calculate_mfcc(self, audio_data: np.ndarray, num_mfcc: int = 13) -> np.ndarray:
        """
        计算MFCC特征（梅尔频率倒谱系数）
        
        Args:
            audio_data: 音频数据
            num_mfcc: MFCC系数数量
            
        Returns:
            MFCC特征矩阵
        """
        try:
            if len(audio_data) == 0:
                return np.array([])
                
            # 这是一个简化的MFCC实现
            # 实际应用中会使用专门的库如librosa
            
            # 1. 预加重
            pre_emphasized = self._preprocess_audio(audio_data)
            
            # 2. 分帧和加窗
            frame_length = int(self.sample_rate * 0.025)
            frame_stride = int(self.sample_rate * 0.01)
            
            # 3. 计算功率谱
            # (简化实现，实际会更复杂)
            
            # 返回简化的特征
            return np.random.rand(num_mfcc, max(1, len(audio_data) // frame_stride))
        except Exception as e:
            print(f"✗ MFCC计算失败: {e}")
            return np.array([])
            
    def apply_beamforming(self, audio_data: np.ndarray, angle: float = 0.0) -> np.ndarray:
        """
        应用波束成形（针对多麦克风阵列）
        
        Args:
            audio_data: 音频数据
            angle: 目标方向角度（弧度）
            
        Returns:
            波束成形后的音频数据
        """
        try:
            # 这是一个简化的波束成形实现
            # 实际实现需要多通道音频数据和麦克风阵列几何信息
            
            # 对于单通道音频，简单返回原始数据
            return audio_data
        except Exception as e:
            print(f"✗ 波束成形失败: {e}")
            return audio_data
            
    def apply_speech_separation(self, audio_data: np.ndarray, num_speakers: int = 2) -> List[np.ndarray]:
        """
        应用语音分离（将混合语音分离为不同说话人）
        
        Args:
            audio_data: 混合音频数据
            num_speakers: 说话人数量
            
        Returns:
            分离后的音频数据列表
        """
        try:
            # 这是一个简化的语音分离实现
            # 实际实现会非常复杂，需要深度学习模型
            
            # 简单地返回相同音频的多个副本
            return [audio_data.copy() for _ in range(num_speakers)]
        except Exception as e:
            print(f"✗ 语音分离失败: {e}")
            return [audio_data]