
     it-                        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       Zej2                  	 	 	 dde
j.                  ded	ee   d
eeee
j.                  f      fd       Zej2                  	 	 	 ddeded	ee   d
ee   fd       Z G d d      Z G d d      Zy)z
# Signal processing
    )singledispatch)zip_longest)OptionalUnionN)
AnnotationSegmentSlidingWindowFeatureTimeline)pairwisestring_generatoronsetoffsetinitial_statec                     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   s       p/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/pyannote/audio/utils/signal.pybinarizer   ,   s    : G     r   c                    |xs |}| j                   \  }}t        j                  |       } || dddf   d||z   z  k\  }nqt        |t              r |t        j
                  |ft              z  }nAt        |t        j                        r'|j                   |fk(  sJ |j                  t        k(  sJ t        j                  ||df      j                  }| |kD  }| |k  |z  }t        j                  t        t        |D cg c]  }t        j                  |      d    c}ddi            j                  }	|	j                  st        j                  | t              |z  S t        j                   |d      }
t        j                  t        j"                  |      |df      j                  }t        j$                  |
|||	||
dz
  f   f   |      S c c}w )	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         ?)dtype   	fillvalue)axis)shapenp
nan_to_num
isinstanceboolonesndarrayr   tileTarraylistr   nonzerosize
zeros_likecumsumarangewhere)r   r   r   r   
batch_size
num_frameson	off_or_onoonwell_defined_idxsame_assampless               r   binarize_ndarrayr6   N   s   4 _uF#\\J
]]6"Fq!tuv~(>>	M4	(%T(JJ	M2::	.""zm333""d***GGMJ?;==M	%B&B&I xx[C#2::c?1-CRrRSa 
   }}V40=@@ ii	*Gggbii
+j!_=??G88G-gw{.BCCDm  Ds   =Gc           
      z   |xs |}| j                   j                  dk(  r{| j                   j                  \  }}t        j                  | j                   d||      }t        ||||      }t        dt        j                  |d||      z  | j                        S | j                   j                  dk(  r~| j                   j                  \  }}}t        j                  | j                   d|||	      }t        ||||      }t        dt        j                  |d
|||	      z  | 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)cr9   r:   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_chunkss	            r   binarize_swfrG      sB   6 _uF{{1"(++"3"3
K\Z;WfM
	 $y,*TU!!
 	
 
		Q	.4kk.?.?+
JKK+zZ;
 fM
	 $-z[ !!
 	
 i
 	
r   c                   `     e Zd ZdZ	 	 	 	 	 	 ddedee   dedededef fdZd	ed
efdZ	 x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   r   min_duration_onmin_duration_off	pad_onset
pad_offsetc                 ~    t         |           || _        |xs || _        || _        || _        || _        || _        y N)super__init__r   r   rL   rM   rJ   rK   )selfr   r   rJ   rK   rL   rM   	__class__s          r   rQ   zBinarize.__init__   s@     	
o"$. 0r   r   returnc                    |j                   j                  \  }}|j                  }t        |      D cg c]  }||   j                   }}t               }t               }t        |j                   j                        D ]  \  }	}
|j                  |	n|j                  |	   }t        |      }|d   }|
d   | j                  kD  }t        |dd |
dd       D ]]  \  }}|rB|| j                  k  st        || j                  z
  || j                   z         }||||f<   |}d}J|| j                  kD  sZ|}d}_ |st        || j                  z
  | j                   z         }||||f<    | j                   dkD  s| j                  dkD  s| j"                  dkD  r|j%                  | j"                        }| j&                  dkD  r@t)        |j+                               D ]$  \  }}|j,                  | j&                  k  s |||f= & |S c c}w )zBinarize detection scores

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

        Returns
        -------
        active : Annotation
            Binarized scores.
        Nr   r   FT        )collar)r>   r   rB   rangemiddler   r   	enumerater%   labelsnextr   zipr   r   rL   rM   rK   supportrJ   r'   
itertracksduration)rR   r   r/   rD   framesi
timestampsactivetrack_generatorr:   k_scoreslabeltrackstart	is_activetyregionsegments                      r   __call__zBinarize.__call__   s    #)++"3"3
K&&05j0AB0A1fQi&&0A
B *,$V[[]]3KAx.AFMM!4DE)E qME djj0IJqrNHQRL91 4;;!()?T__AT!U05vu}- !$)	
 4::~ !$(	! :&  !7T__9LM(-vu}%; 4B ??S DNNS$8D<Q<QTW<W^^4+@+@^AF !#"&v'8'8':";##d&:&::w~. #< a Cs   H)r   NrV   rV   rV   rV   )__name__
__module____qualname____doc__floatr   rQ   r	   r   ro   __classcell__rS   s   @r   rI   rI      sv    6 "&!$"%11 1 	1
  1 1 1*@3 @
 @r   rI   c                   >     e Zd ZdZ	 	 ddedef fdZdefdZ x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.
    alphamin_durationc                 F    t         t        |           || _        || _        y rO   )rP   rx   rQ   ry   rz   )rR   ry   rz   rS   s      r   rQ   zPeak.__init__L  s!    
 	dD"$
(r   r   c           	         |j                   dk7  rt        d      t        |      }|j                  }|j                  }t        dt        t        j                  | j                  |z                    }t        j                  j                  |dd |      d   }t        j                  |D cg c]$  }||   | j                  kD  s||   j                  & c}      }t        j                   |d   j"                  g|||   j$                  gg      }	t'               }
t)        t+        |	            D ]%  \  }\  }}t-        ||      }|
j/                  |       ' |
S c c}w )zPeak detection

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

        Returns
        -------
        segmentation : Timeline
            Partition.
        r   z$Peak expects one-dimensional scores.N)orderr   )	dimensionrC   lenrB   stepmaxintr   rintrz   scipysignal	argrelmaxr&   ry   rY   hstackri   endr
   rZ   r   r   add)rR   r   r/   ra   	precisionr}   indicesrb   	peak_time
boundariessegmentationri   r   rn   s                 r   ro   zPeak.__call__U  s6    q CDD[
&&KK	As2774#4#4y#@ABC,,((%(@CHH'.Iw!&)djj2HVAYwI
	 YY 19vj?Q?U?U>VWX
z(*)=>OA|seS)GW%  ?  Js   -EE)r   r;   )	rp   rq   rr   rs   rt   rQ   r	   ro   ru   rv   s   @r   rx   rx   A  s4     !)) )"3 "r   rx   )r   NN)rs   	functoolsr   	itertoolsr   typingr   r   r@   numpyr   scipy.signalr   pyannote.corer   r   r	   r
   pyannote.core.utils.generatorsr   r   rt   r!   r#   r   registerr6   rG   rI   rx    r   r   <module>r      sH  : % ! "    M M E  "7;	 UO E$

"234	 B 
 "7;	>JJ>> UO> E$

"234	> >B 
 "$(	;
 ;
;
 UO;
 D>	;
 ;
|o od6 6r   