o
    9wi-                     @   s(  d Z ddlmZ ddlmZ ddlmZmZ ddlZddl	Z
ddlZddlmZmZmZmZ ddlmZ e			dd	ed
ee deeee
jf  fddZej			dde
jd	ed
ee deeee
jf  fddZej			dded	ed
ee dee fddZG dd dZG dd dZdS )z
# Signal processing
    )singledispatch)zip_longest)OptionalUnionN)
AnnotationSegmentSlidingWindowFeatureTimeline)pairwise      ?onsetoffsetinitial_statec                 C   s   t d)a  (Batch) hysteresis thresholding

    Parameters
    ----------
    scores : numpy.ndarray or SlidingWindowFeature
        (num_chunks, num_frames, num_classes)- or (num_frames, num_classes)-shaped scores.
    onset : float, optional
        Onset threshold. Defaults to 0.5.
    offset : float, optional
        Offset threshold. Defaults to `onset`.
    initial_state : np.ndarray or bool, optional
        Initial state.

    Returns
    -------
    binarized : same as scores
        Binarized scores with same shape and type as scores.

    Reference
    ---------
    https://stackoverflow.com/questions/23289976/how-to-find-zero-crossings-with-hysteresis
    z=scores must be of type numpy.ndarray or SlidingWindowFeatures)NotImplementedError)scoresr   r   r    r   X/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/pyannote/audio/utils/signal.pybinarize,   s   r   r   c              	   C   s6  |p|}| j \}}t| } |du r!| dddf d||  k}n%t|tr1|tj|ftd }nt|tjrF|j |fks?J |jtksFJ t||dfj	}| |k}| |k |B }t
ttdd |D dd	ij	}|jswtj| td|B S tj|dd
}	tt||dfj	}
t|	||
||
|	d f f |S )a  (Batch) hysteresis thresholding

    Parameters
    ----------
    scores : numpy.ndarray
        (num_frames, num_classes)-shaped scores.
    onset : float, optional
        Onset threshold. Defaults to 0.5.
    offset : float, optional
        Offset threshold. Defaults to `onset`.
    initial_state : np.ndarray or bool, optional
        Initial state.

    Returns
    -------
    binarized : same as scores
        Binarized scores with same shape and type as scores.
    Nr   r   )dtype   c                 S   s   g | ]	}t |d  qS )r   )npnonzero).0oonr   r   r   
<listcomp>   s    z$binarize_ndarray.<locals>.<listcomp>	fillvalue)axis)shaper   
nan_to_num
isinstanceboolonesndarrayr   tileTarraylistr   size
zeros_likecumsumarangewhere)r   r   r   r   
batch_size
num_frameson	off_or_onwell_defined_idxsame_assamplesr   r   r   binarize_ndarrayN   s2   


r4   c           	   	   C   s   |p|}| j jdkr1| j j\}}tj| j d||d}t||||d}tdtj|d||d | jS | j jdkra| j j\}}}tj| j d|||d	}t||||d}tdtj|d
|||d	 | jS td)a  (Batch) hysteresis thresholding

    Parameters
    ----------
    scores : SlidingWindowFeature
        (num_chunks, num_frames, num_classes)- or (num_frames, num_classes)-shaped scores.
    onset : float, optional
        Onset threshold. Defaults to 0.5.
    offset : float, optional
        Offset threshold. Defaults to `onset`.
    initial_state : np.ndarray or bool, optional
        Initial state.

    Returns
    -------
    binarized : same as scores
        Binarized scores with same shape and type as scores.

       z
f k -> k f)fk)r   r   r         ?z
k f -> f k   zc f k -> (c k) f)cr6   r7   z(c k) f -> c f kz[Shape of scores must be (num_chunks, num_frames, num_classes) or (num_frames, num_classes).)	datandimr   einops	rearranger   r   sliding_window
ValueError)	r   r   r   r   r.   num_classesr;   	binarized
num_chunksr   r   r   binarize_swf   s@   
	rD   c                       s^   e Zd ZdZ						ddedee deded	ed
ef fddZdedefddZ	  Z
S )Binarizea  Binarize detection scores using hysteresis thresholding

    Parameters
    ----------
    onset : float, optional
        Onset threshold. Defaults to 0.5.
    offset : float, optional
        Offset threshold. Defaults to `onset`.
    min_duration_on : float, optional
        Remove active regions shorter than that many seconds. Defaults to 0s.
    min_duration_off : float, optional
        Fill inactive regions shorter than that many seconds. Defaults to 0s.
    pad_onset : float, optional
        Extend active regions by moving their start time by that many seconds.
        Defaults to 0s.
    pad_offset : float, optional
        Extend active regions by moving their end time by that many seconds.
        Defaults to 0s.

    Reference
    ---------
    Gregory Gelly and Jean-Luc Gauvain. "Minimum Word Error Training of
    RNN-based Voice Activity Detection", InterSpeech 2015.
    r   N        r   r   min_duration_onmin_duration_off	pad_onset
pad_offsetc                    s6   t    || _|p|| _|| _|| _|| _|| _d S N)super__init__r   r   rI   rJ   rG   rH   )selfr   r   rG   rH   rI   rJ   	__class__r   r   rM      s   



zBinarize.__init__r   returnc                    sn  |j j\}}|j  fddt|D }t }t|j jD ]f\}}|jdu r(|n|j| }|d }	|d | jk}
t	|dd |dd D ]*\}}|
rf|| j
k ret|	| j || j }||||f< |}	d}
qE|| jkro|}	d}
qE|
rt|	| j || j }||||f< q| jdks| jdks| jdkr|j| jd	}| jdkrt| D ]\}}|j| jk r|||f= q|S )
zBinarize detection scores

        Parameters
        ----------
        scores : SlidingWindowFeature
            Detection scores.

        Returns
        -------
        active : Annotation
            Binarized scores.
        c                    s   g | ]} | j qS r   )middler   iframesr   r   r     s    z%Binarize.__call__.<locals>.<listcomp>Nr   r   FTrF   )collar)r;   r   r?   ranger   	enumerater%   labelsr   zipr   r   rI   rJ   rH   supportrG   r'   
itertracksduration)rN   r   r.   rA   
timestampsactiver7   k_scoreslabelstart	is_activetyregionsegmenttrackr   rU   r   __call__   s@   "



zBinarize.__call__)r   NrF   rF   rF   rF   )__name__
__module____qualname____doc__floatr   rM   r   r   rj   __classcell__r   r   rO   r   rE      s,    rE   c                       s>   e Zd ZdZ		ddedef fddZdefd	d
Z  ZS )PeakzPeak detection

    Parameters
    ----------
    alpha : float, optional
        Peak threshold. Defaults to 0.5
    min_duration : float, optional
        Minimum elapsed time between two consecutive peaks. Defaults to 1 second.
    r   r8   alphamin_durationc                    s   t t|   || _|| _d S rK   )rL   rq   rM   rr   rs   )rN   rr   rs   rO   r   r   rM   K  s   
zPeak.__init__r   c                    s   j dkr	tdt}j  j}tdttj	| }t
jjdd |dd }t fdd|D }t d jg| | jgg}t }tt|D ]\}	\}
}t|
|}|| qU|S )zPeak detection

        Parameter
        ---------
        scores : SlidingWindowFeature
            Detection scores.

        Returns
        -------
        segmentation : Timeline
            Partition.
        r   z$Peak expects one-dimensional scores.N)orderr   c                    s$   g | ]}| j kr | jqS r   )rr   rR   rS   rV   r   rN   r   r   r   m  s   $ z!Peak.__call__.<locals>.<listcomp>)	dimensionr@   lenr?   stepmaxintr   rintrs   scipysignal	argrelmaxr&   hstackrc   endr	   rY   r
   r   add)rN   r   r.   	precisionrt   indices	peak_time
boundariessegmentationrT   rc   r   rh   r   ru   r   rj   T  s    
 
zPeak.__call__)r   r8   )	rk   rl   rm   rn   ro   rM   r   rj   rp   r   r   rO   r   rq   @  s    	rq   )r   NN)rn   	functoolsr   	itertoolsr   typingr   r   r=   numpyr   scipy.signalr|   pyannote.corer   r   r   r	   pyannote.core.utils.generatorsr
   ro   r!   r#   r   registerr4   rD   rE   rq   r   r   r   r   <module>   s`   !A>q