o
    pit-                     @   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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string_generator      ?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   O/home/ubuntu/.local/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   


r5   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)cr7   r8   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@   
	rE   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   rJ   rK   rH   rI   )selfr   r   rH   rI   rJ   rK   	__class__r   r   rN      s   



zBinarize.__init__r   returnc                    s|  |j j\}}|j  fddt|D }t }t }t|j jD ]j\}}|jdu r+|n|j| }	t	|}
|d }|d | j
k}t|dd |dd D ]*\}}|rm|| jk rlt|| j || j }|	|||
f< |}d}qL|| j
krv|}d}qL|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   FTrG   )collar)r<   r   r@   ranger   r   	enumerater&   labelsnextr   zipr   r   rJ   rK   rI   supportrH   r(   
itertracksduration)rO   r   r/   rB   
timestampsactivetrack_generatorr8   k_scoreslabeltrackstart	is_activetyregionsegmentr   rV   r   __call__   sD   "



zBinarize.__call__)r   NrG   rG   rG   rG   )__name__
__module____qualname____doc__floatr   rN   r   r   rm   __classcell__r   r   rP   r   rF      s,    rF   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   r9   alphamin_durationc                    s   t t|   || _|| _d S rL   )rM   rt   rN   ru   rv   )rO   ru   rv   rP   r   r   rN   L  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   )ru   rS   rT   rW   r   rO   r   r   r   n  s   $ z!Peak.__call__.<locals>.<listcomp>)	dimensionrA   lenr@   stepmaxintr   rintrv   scipysignal	argrelmaxr'   hstackrg   endr	   rZ   r
   r   add)rO   r   r/   	precisionrw   indices	peak_time
boundariessegmentationrU   rg   r   rl   r   rx   r   rm   U  s    
 
zPeak.__call__)r   r9   )	rn   ro   rp   rq   rr   rN   r   rm   rs   r   r   rP   r   rt   A  s    	rt   )r   NN)rq   	functoolsr   	itertoolsr   typingr   r   r>   numpyr   scipy.signalr   pyannote.corer   r   r   r	   pyannote.core.utils.generatorsr
   r   rr   r"   r$   r   registerr5   rE   rF   rt   r   r   r   r   <module>   s`   !A>r