import numpy as np
from scipy.signal import butter, sosfilt
from .base import BaseProcessorModule

class SubSynthModule(BaseProcessorModule):
    """Sub-Harmonic Synthesizer to fix 'Thin' low-end."""
    
    def process(self, audio: np.ndarray, amount: float = 0.0, freq_hz: float = 60.0) -> np.ndarray:
        if amount <= 0: return audio
        
        sr = self.sample_rate
        duration = len(audio) / sr
        t = np.linspace(0, duration, len(audio), endpoint=False)
        
        # 1. Generate Sub-Octave Sine
        sub_sine = np.sin(2 * np.pi * freq_hz * t)
        
        # 2. Envelope Follower (ensure sub only plays when audio is present)
        if audio.ndim > 1: mono = np.mean(audio, axis=1)
        else: mono = audio
        
        win_size = int(sr * 0.05)
        envelope = np.convolve(np.abs(mono), np.ones(win_size)/win_size, mode='same')
        sub_signal = sub_sine * envelope * amount
        
        # Convert sub to stereo if needed
        if audio.ndim > 1:
            sub_signal = np.column_stack((sub_signal, sub_signal))
            
        # 3. Blend
        return audio + sub_signal
