o
    i,                  
   @   s   d Z ddlZddlZddlmZ ddlmZ zddlZW n  ey< Z	 ze
de	  e
d ede	 dZ	[	ww ejjejjejjejjejjejjdZejjejjejjejjejjd	Zd
efddZdefddZG dd dZdS )z)Krisp Instance manager for pipecat audio.    N)Lock)loggerzException: zDIn order to use the Krisp instance, you need to install krisp_audio.zMissing module: )i@  i>  i]  i }  iD  i  )
                sample_ratec                 C   B   | t vrddd tt  D }td|  d| dt |  S )a   Convert integer sample rate to Krisp SDK enum value.

    Args:
        sample_rate: Sample rate in Hz (e.g., 16000, 24000, 48000).

    Returns:
        Corresponding Krisp SDK SampleRate enum value.

    Raises:
        ValueError: If the sample rate is not supported by Krisp SDK.
    , c                 s       | ]}t |V  qd S Nstr).0rate r   P/home/ubuntu/.local/lib/python3.10/site-packages/pipecat/audio/krisp_instance.py	<genexpr>7   s    z+int_to_krisp_sample_rate.<locals>.<genexpr>zUnsupported sample rate: z Hz. Supported rates: z Hz)KRISP_SAMPLE_RATESjoinsortedkeys
ValueError)r	   supported_ratesr   r   r   int_to_krisp_sample_rate*   s   r   frame_duration_msc                 C   r
   )a3  Convert integer frame duration to Krisp SDK enum value.

    Args:
        frame_duration_ms: Frame duration in milliseconds (e.g., 10, 20, 30).

    Returns:
        Corresponding Krisp SDK FrameDuration enum value.

    Raises:
        ValueError: If the frame duration is not supported by Krisp SDK.
    r   c                 s   r   r   r   )r   durationr   r   r   r   K   s    
z.int_to_krisp_frame_duration.<locals>.<genexpr>zUnsupported frame duration: z ms. Supported durations: z ms)KRISP_FRAME_DURATIONSr   r   r   r   )r   supported_durationsr   r   r   int_to_krisp_frame_duration>   s   

r    c                   @   s   e Zd ZdZdZe ZdZedd Z	edd Z
edd	efd
dZedd ZedefddZedefddZedd ZdS )KrispVivaSDKManagerz=Singleton manager for Krisp VIVA SDK with reference counting.Fr   c                 C   s   t d|  d|  dS )z(Callback for Krisp SDK licensing errors.zKrisp licensing error: z - N)r   error)r"   error_messager   r   r   _license_callback\      z%KrispVivaSDKManager._license_callbackc                 C   s   t d| d|   dS )z+Thread-safe callback for Krisp SDK logging.[z] N)r   info)log_message	log_levelr   r   r   _log_callbacka   r%   z!KrispVivaSDKManager._log_callback api_keyc                 C   s   | j  | jdkrnzL|ptjdd}ztd|| j| jtj	j
 W n ty5   td| jtj	j
 Y nw d| _t }td|j d|j d|j  t| j W n tym } zd| _td|   d	}~ww |  jd
7  _td| j  W d	   d	S 1 sw   Y  d	S )ab  Acquire a reference to the SDK (initializes if needed).

        Call this when creating a filter instance.

        Args:
            api_key: Krisp SDK API key. If empty, falls back to the
                KRISP_VIVA_API_KEY environment variable.

        Raises:
            Exception: If SDK initialization fails (propagated from krisp_audio)
        r   KRISP_VIVA_API_KEYr+   Tz.Krisp Audio Python SDK initialized - Version: .Fz!Krisp SDK initialization failed: N   Krisp SDK reference count: )_lock_reference_countosenvirongetkrisp_audio
globalInitr$   r*   LogLevelOff	TypeError_initialized
getVersionr   debugmajorminorpatchatexitregister_force_cleanup	Exceptionr"   )clsr,   keySDK_VERSIONer   r   r   acquiref   sH   
"zKrispVivaSDKManager.acquirec                 C   s   | j r | jdkrM|  jd8  _td| j  | jdkrU| jr]zt  d| _td W n5 tyL } ztd|  d| _W Y d}~n%d}~ww W d   dS W d   dS W d   dS W d   dS W d   dS 1 sxw   Y  dS )z{Release a reference to the SDK (destroys if last reference).

        Call this when destroying a filter instance.
        r   r/   r0   Fz3Krisp Audio SDK destroyed (all references released)z Error during Krisp SDK cleanup: N)	r1   r2   r   r=   r;   r6   globalDestroyrD   r"   rE   rH   r   r   r   release   s0   

"zKrispVivaSDKManager.releasereturnc                 C   0   | j  | jW  d   S 1 sw   Y  dS )zwGet the current reference count.

        Returns:
            Current number of active references to the SDK.
        N)r1   r2   rE   r   r   r   get_reference_count      $z'KrispVivaSDKManager.get_reference_countc                 C   rN   )z~Check if the SDK is currently initialized.

        Returns:
            True if SDK is initialized, False otherwise.
        N)r1   r;   rO   r   r   r   is_initialized   rQ   z"KrispVivaSDKManager.is_initializedc                 C   s   | j J | jr5ztd| j d t  d| _W n" ty4 } ztd|  W Y d}~nd}~ww W d   dS W d   dS W d   dS 1 sPw   Y  dS )z)Force cleanup on program exit (failsafe).z0Force cleaning up Krisp SDK at exit (ref count: )Fz'Error during forced Krisp SDK cleanup: N)	r1   r;   r   warningr2   r6   rJ   rD   r"   rK   r   r   r   rC      s$   
	"z"KrispVivaSDKManager._force_cleanupN)r+   )__name__
__module____qualname____doc__r;   r   r1   r2   staticmethodr$   r*   classmethodr   rI   rL   intrP   boolrR   rC   r   r   r   r   r!   U   s&    

1
		r!   )rX   rA   r3   	threadingr   logurur   r6   ModuleNotFoundErrorrH   r"   rD   SamplingRateSr8000Hz	Sr16000Hz	Sr24000Hz	Sr32000Hz	Sr44100Hz	Sr48000Hzr   FrameDurationFd10msFd15msFd20msFd30msFd32msr   r[   r   r    r!   r   r   r   r   <module>   s:   

	