ó
    á“,jMl  ã                   óŒ   • S r SSKrSSKJrJrJrJrJrJr  SSK	J
r
  SSKrSSKJr  \" SSS9 " S	 S
5      5       r " S S5      rg)as  
#######
Segment
#######

.. plot:: pyplots/segment.py

:class:`pyannote.core.Segment` instances describe temporal fragments (*e.g.* of an audio file). The segment depicted above can be defined like that:

.. code-block:: ipython

  In [1]: from pyannote.core import Segment

  In [2]: segment = Segment(start=5, end=15)

  In [3]: print(segment)

It is nothing more than 2-tuples augmented with several useful methods and properties:

.. code-block:: ipython

  In [4]: start, end = segment

  In [5]: start

  In [6]: segment.end

  In [7]: segment.duration  # duration (read-only)

  In [8]: segment.middle  # middle (read-only)

  In [9]: segment & Segment(3, 12)  # intersection

  In [10]: segment | Segment(3, 12)  # union

  In [11]: segment.overlaps(3)  # does segment overlap time t=3?


Use `Segment.set_precision(ndigits)` to automatically round start and end timestamps to `ndigits` precision after the decimal point.
To ensure consistency between `Segment` instances, it is recommended to call this method only once, right after importing `pyannote.core.Segment`.

.. code-block:: ipython

  In [12]: Segment(1/1000, 330/1000) == Segment(1/1000, 90/1000+240/1000)
  Out[12]: False

  In [13]: Segment.set_precision(ndigits=4)

  In [14]: Segment(1/1000, 330/1000) == Segment(1/1000, 90/1000+240/1000)
  Out[14]: True

See :class:`pyannote.core.Segment` for the complete reference.
é    N)ÚUnionÚOptionalÚTupleÚListÚIteratorÚIterableé   )Ú	Alignment)Ú	dataclassT)ÚfrozenÚorderc                   ó  • \ rS rSr% SrSr\\S'   Sr\\S'   \	SS\
\   4S jj5       rS	 rS
 r\S\4S j5       r\S\4S j5       rS\\   4S jrSS jrS S jrS rSS S\4S jrS\S\4S jrS!S jrS!S jrS\S\4S jrS rS rS r Sr!g)"ÚSegmenté]   ar  
Time interval

Parameters
----------
start : float
    interval start time, in seconds.
end : float
    interval end time, in seconds.


Segments can be compared and sorted using the standard operators:

>>> Segment(0, 1) == Segment(0, 1.)
True
>>> Segment(0, 1) != Segment(3, 4)
True
>>> Segment(0, 1) < Segment(2, 3)
True
>>> Segment(0, 1) < Segment(0, 2)
True
>>> Segment(1, 2) < Segment(0, 3)
False

Note
----
A segment is smaller than another segment if one of these two conditions is verified:

  - `segment.start < other_segment.start`
  - `segment.start == other_segment.start` and `segment.end < other_segment.end`

ç        ÚstartÚendNÚndigitsc                 ó$   • U c  Sq SqgSq SU * -  qg)am  Automatically round start and end timestamps to `ndigits` precision after the decimal point

To ensure consistency between `Segment` instances, it is recommended to call this method only 
once, right after importing `pyannote.core.Segment`.

Usage
-----
>>> from pyannote.core import Segment
>>> Segment.set_precision(2)
>>> Segment(1/3, 2/3)
<Segment(0.33, 0.67)>
NFg�íµ ÷Æ°>Té
   )ÚAUTO_ROUND_TIMEÚSEGMENT_PRECISION)r   s    Ú£C:\Users\johnn\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\LocalCache\local-packages\Python313\site-packages\pyannote/core/segment.pyÚset_precisionÚSegment.set_precision‚   s&   € ð" ‰?à#ˆOà $Ñà"ˆOØ "¨ xÑ 0Ñó    c                 óT   • [        U R                  U R                  -
  [        :„  5      $ )uÞ   Emptiness

>>> if segment:
...    # segment is not empty.
... else:
...    # segment is empty.

Note
----
A segment is considered empty if its end time is smaller than its
start time, or its duration is smaller than 1Î¼s.
)Úboolr   r   r   ©Úselfs    r   Ú__bool__ÚSegment.__bool__œ   s"   € ô �T—X‘X §
¡
Ñ*Ô.?Ñ?Ó@Ð@r   c                 ó  • [         (       aw  [        R                  U S[        U R                  [
        -  S-   5      [
        -  5        [        R                  U S[        U R                  [
        -  S-   5      [
        -  5        gg)zERound start and end up to SEGMENT_PRECISION precision (when required)r   ç      à?r   N)r   ÚobjectÚ__setattr__Úintr   r   r   r   s    r   Ú__post_init__ÚSegment.__post_init__«   se   € çŠ?Ü×Ñ˜t W¬c°$·*±*Ô?PÑ2PÐSVÑ2VÓ.WÔZkÑ.kÔlÜ×Ñ˜t U¬C°·±Ô;LÑ0LÈsÑ0RÓ,SÔVgÑ,gÕhð r   Úreturnc                 óF   • U (       a  U R                   U R                  -
  $ S$ )zSegment duration (read-only)r   )r   r   r   s    r   ÚdurationÚSegment.duration±   s   € ö )-ˆt�x‰x˜$Ÿ*™*Ñ$Ð4°"Ð4r   c                 ó:   • SU R                   U R                  -   -  $ )zSegment mid-time (read-only)r$   ©r   r   r   s    r   ÚmiddleÚSegment.middle¶   s   € ð �T—Z‘Z $§(¡(Ñ*Ñ+Ð+r   c              #   óD   #   • U R                   v •  U R                  v •  g7f)zUUnpack segment boundaries
>>> segment = Segment(start, end)
>>> start, end = segment
Nr/   r   s    r   Ú__iter__ÚSegment.__iter__»   s   é € ð
 �j‰jÒØ�h‰h‹ùs   ‚ c                 ó>   • [        U R                  U R                  S9$ )zSGet a copy of the segment

Returns
-------
copy : Segment
    Copy of the segment.
r/   )r   r   r   r   s    r   ÚcopyÚSegment.copyÃ   s   € ô ˜TŸZ™Z¨T¯X©XÑ6Ð6r   Úotherc                 ót   • U R                   UR                   :*  =(       a    U R                  UR                  :¬  $ )z�Inclusion

>>> segment = Segment(start=0, end=10)
>>> Segment(start=3, end=10) in segment:
True
>>> Segment(start=5, end=15) in segment:
False
r/   ©r    r8   s     r   Ú__contains__ÚSegment.__contains__Ñ   s)   € ð —
‘
˜eŸk™kÑ)×F°·±¸E¿I¹IÑ0EÐFr   c                 ó”   • [        U R                  UR                  5      n[        U R                  UR                  5      n[	        X#S9$ )aj  Intersection

>>> segment = Segment(0, 10)
>>> other_segment = Segment(5, 15)
>>> segment & other_segment
<Segment(5, 10)>

Note
----
When the intersection is empty, an empty segment is returned:

>>> segment = Segment(0, 10)
>>> other_segment = Segment(15, 20)
>>> intersection = segment & other_segment
>>> if not intersection:
...    # intersection is empty.
r/   )Úmaxr   Úminr   r   ©r    r8   r   r   s       r   Ú__and__ÚSegment.__and__Ü   s7   € ô$ �D—J‘J §¡Ó,ˆÜ�$—(‘(˜EŸI™IÓ&ˆÜ˜UÑ,Ð,r   c                 óP  • U R                   UR                   :  =(       a     UR                   U R                  [        -
  :  =(       d`    U R                   UR                   :„  =(       a     U R                   UR                  [        -
  :  =(       d    U R                   UR                   :H  $ )z»Check whether two segments intersect each other

Parameters
----------
other : Segment
    Other segment

Returns
-------
intersect : bool
    True if segments intersect, False otherwise
)r   r   r   r:   s     r   Ú
intersectsÚSegment.intersectsò   s{   € ð —
‘
˜UŸ[™[Ñ(÷ ;Ø—‘˜dŸh™hÔ):Ñ:Ñ:÷+à—
‘
˜UŸ[™[Ñ(÷ ;Ø—
‘
˜UŸY™YÔ):Ñ:Ñ:÷+ð —
‘
˜eŸk™kÑ)ð		+r   Útc                 óL   • U R                   U:*  =(       a    U R                  U:¬  $ )z³Check if segment overlaps a given time

Parameters
----------
t : float
    Time, in seconds.

Returns
-------
overlap: bool
    True if segment overlaps time t, False otherwise.
r/   ©r    rF   s     r   ÚoverlapsÚSegment.overlaps  s   € ð �z‰z˜Q‰×0 4§8¡8¨q¡=Ð0r   c                 ó¸   • U (       d  U$ U(       d  U $ [        U R                  UR                  5      n[        U R                  UR                  5      n[	        X#S9$ )a8  Union

>>> segment = Segment(0, 10)
>>> other_segment = Segment(5, 15)
>>> segment | other_segment
<Segment(0, 15)>

Note
----
When a gap exists between the segment, their union covers the gap as well:

>>> segment = Segment(0, 10)
>>> other_segment = Segment(15, 20)
>>> segment | other_segment
<Segment(0, 20)
r/   )r?   r   r>   r   r   r@   s       r   Ú__or__ÚSegment.__or__  sI   € ö& ØˆLæØˆKô �D—J‘J §¡Ó,ˆÜ�$—(‘(˜EŸI™IÓ&ˆÜ˜UÑ,Ð,r   c                 óÆ   • U (       a  U(       d  [        S5      e[        U R                  UR                  5      n[        U R                  UR                  5      n[        X#S9$ )af  Gap

>>> segment = Segment(0, 10)
>>> other_segment = Segment(15, 20)
>>> segment ^ other_segment
<Segment(10, 15)

Note
----
The gap between a segment and an empty segment is not defined.

>>> segment = Segment(0, 10)
>>> empty_segment = Segment(11, 11)
>>> segment ^ empty_segment
ValueError: The gap between a segment and an empty segment is not defined.
z>The gap between a segment and an empty segment is not defined.r/   )Ú
ValueErrorr?   r   r>   r   r   r@   s       r   Ú__xor__ÚSegment.__xor__3  sP   € ö& žeÜð"ó#ð #ô �D—H‘H˜eŸi™iÓ(ˆÜ�$—*‘*˜eŸk™kÓ*ˆÜ˜UÑ,Ð,r   Úsecondsc                 óê   • SSK Jn  US:  n[        U5      nU" US9nUR                  SUR                  -  -   nUR
                  n[        US5      u  pg[        US5      u  p�SU(       a  SOS	XhXS
-  4-  $ )Nr   )Ú	timedelta)rR   i€Q i  é<   z%s%02d:%02d:%02d.%03dÚ-Ú iè  )ÚdatetimerT   ÚabsrR   ÚdaysÚmicrosecondsÚdivmod)	r    rR   rT   ÚnegativeÚtdr[   ÚhoursÚ	remainderÚminutess	            r   Ú_str_helperÚSegment._str_helperO  s�   € Ý&Ø˜Q‘;ˆÜ�g“,ˆÙ˜wÑ'ˆØ—*‘*˜u r§w¡w™Ñ.ˆØ—‘ˆÜ! '¨4Ó0ÑˆÜ! )¨RÓ0ÑˆØ&Þ‰C  eØ DÑ(ð**ñ *ð 	*r   c                 óŒ   • U (       a=  SU R                  U R                  5      < SU R                  U R                  5      < S3$ g)z•Human-readable representation

>>> print(Segment(1337, 1337 + 0.42))
[ 00:22:17.000 -->  00:22:17.420]

Note
----
Empty segments are printed as "[]"
Ú[z --> Ú]z[])rb   r   r   r   s    r   Ú__str__ÚSegment.__str__\  s:   € ÷ Ø$(×$4Ñ$4°T·Z±ZÖ$@Ø$(×$4Ñ$4°T·X±XÖ$>ð@ð @àr   c                 ó8   • SU R                   U R                  4-  $ )zZComputer-readable representation

>>> Segment(1337, 1337 + 0.42)
<Segment(1337, 1337.42)>
z<Segment(%g, %g)>r/   r   s    r   Ú__repr__ÚSegment.__repr__k  s   € ð # d§j¡j°$·(±(Ð%;Ñ;Ð;r   c                 ó  • SSK JnJn  U(       d8  [        R                  " UR                  U R                  R                  S95        gSSK Jn   U" U 5      $ ! [         a    [        R                  " SU  S35         gf = f)zJIPython notebook support

See also
--------
:mod:`pyannote.core.notebook`
r	   )ÚMATPLOTLIB_IS_AVAILABLEÚMATPLOTLIB_WARNING)ÚklassN)Úrepr_segmentzBCouldn't import matplotlib to render the vizualization for object zY. To enable, install the required dependencies with 'pip install pyannore.core[notebook]')
Únotebookrm   rn   ÚwarningsÚwarnÚformatÚ	__class__Ú__name__rp   ÚImportError)r    rm   rn   rp   s       r   Ú
_repr_png_ÚSegment._repr_png_s  s{   € ÷ 	JÞ&Ü�MŠMÐ,×3Ñ3¸$¿.¹.×:QÑ:QÐ3ÐRÔSØå*ð	Ù Ó%Ð%øÜó 	Ü�MŠMØTÐUYÐTZð  [tð  uôváð	ús   ÁA Á$A>Á=A>© ©N)r*   r   )r8   r   )r8   r   r*   r   )"rv   Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   ÚfloatÚ__annotations__r   Ústaticmethodr   r'   r   r!   r(   Úpropertyr,   r0   r   r3   r6   r;   rA   r   rD   rI   rL   rP   Ústrrb   rg   rj   rx   Ú__static_attributes__rz   r   r   r   r   ]   sï   ‡ ñð@ €Eˆ5ÓØ€CˆÓàñ1˜x¨™}ô 1ó ð1ò2Aòið ð5˜%ó 5ó ð5ð ð,˜ó ,ó ð,ð˜( 5™/ô ô7ô	Gò-ð,+ 	ð +¨dô +ð(1˜%ð 1 Dô 1ô-ô<-ð8* 5ð *¨Sô *òò<õr   r   c                   ó>  • \ rS rSrSrS-S jr\S\4S j5       r\S\4S j5       r	\S\4S j5       r
\S\4S	 j5       rS
\S\4S jrS.S\S\S\4S jjr   S/S\\S4   S\S\\   S\\   S\\R*                  \\\      4   4
S jjrS\S\\\4   4S jrS\S\\\4   4S jrS\S\S\4S jrS\S\S\4S jrS\S\4S jrS\S\4S jrS\S\4S  jrS\S\4S! jr S"\S\4S# jr!S\4S$ jr"S\4S% jr#S0S& jr$S\4S' jr%S0S( jr& S1S)\\S4   S*\S\'\   4S+ jjr(S,r)g)2ÚSlidingWindowiˆ  aQ  Sliding window

Parameters
----------
duration : float > 0, optional
    Window duration, in seconds. Default is 30 ms.
step : float > 0, optional
    Step between two consecutive position, in seconds. Default is 10 ms.
start : float, optional
    First start position of window, in seconds. Default is 0.
end : float > `start`, optional
    Default is infinity (ie. window keeps sliding forever)

Examples
--------

>>> sw = SlidingWindow(duration, step, start)
>>> frame_range = (a, b)
>>> frame_range == sw.toFrameRange(sw.toSegment(*frame_range))
... True

>>> segment = Segment(A, B)
>>> new_segment = sw.toSegment(*sw.toFrameRange(segment))
>>> abs(segment) - abs(segment & new_segment) < .5 * sw.step

>>> sw = SlidingWindow(end=0.1)
>>> print(next(sw))
[ 00:00:00.000 -->  00:00:00.030]
>>> print(next(sw))
[ 00:00:00.010 -->  00:00:00.040]
Nc                 óØ   • US::  a  [        S5      eXl        US::  a  [        S5      eX l        X0l        Uc  [        R
                  U l        OXC::  a  [        S5      eX@l        SU l        g )Nr   z'duration' must be a float > 0.z'step' must be a float > 0.z#'end' must be greater than 'start'.éÿÿÿÿ)rO   Ú_SlidingWindow__durationÚ_SlidingWindow__stepÚ_SlidingWindow__startÚnpÚinfÚ_SlidingWindow__endÚ_SlidingWindow__i)r    r,   Ústepr   r   s        r   Ú__init__ÚSlidingWindow.__init__©  sp   € ð �q‹=ÜÐ>Ó?Ð?Ø"Œð �1‹9ÜÐ:Ó;Ð;Ø!Œð $Œð ‰;Ü "§¡ˆD�Jð ‹|Ü Ð!FÓGÐGØ #ŒJð ˆ�r   r*   c                 ó   • U R                   $ )z%Sliding window start time in seconds.)rŒ   r   s    r   r   ÚSlidingWindow.startÄ  s   € ð �|‰|Ðr   c                 ó   • U R                   $ )z#Sliding window end time in seconds.)r�   r   s    r   r   ÚSlidingWindow.endÉ  s   € ð �z‰zÐr   c                 ó   • U R                   $ )zSliding window step in seconds.)r‹   r   s    r   r‘   ÚSlidingWindow.stepÎ  s   € ð �{‰{Ðr   c                 ó   • U R                   $ )z#Sliding window duration in seconds.)rŠ   r   s    r   r,   ÚSlidingWindow.durationÓ  s   € ð �‰Ðr   rF   c                 ó’   • [        [        R                  " XR                  -
  SU R                  -  -
  U R
                  -  5      5      $ )z´Closest frame to timestamp.

Parameters
----------
t : float
    Timestamp, in seconds.

Returns
-------
index : int
    Index of frame whose middle is the closest to `timestamp`

r$   )r'   r�   ÚrintrŒ   rŠ   r‹   rH   s     r   Úclosest_frameÚSlidingWindow.closest_frameØ  s=   € ô ”2—7’7Ø—‘Ñ  T§_¡_Ñ 4Ñ4¸¿¹ÑCó
ó ð 	r   Úfrom_durationÚmodec                 ód  • US:X  a;  [        [        R                  " XR                  -
  U R                  -  5      5      S-   $ US:X  a8  [        [        R                  " XR                  -   U R                  -  5      5      $ US:X  a+  [        [        R
                  " XR                  -  5      5      $ g)aj  Number of frames

Parameters
----------
from_duration : float
    Duration in seconds.
mode : {'strict', 'loose', 'center'}
    In 'strict' mode, computes the maximum number of consecutive frames
    that can be fitted into a segment with duration `from_duration`.
    In 'loose' mode, computes the maximum number of consecutive frames
    intersecting a segment with duration `from_duration`.
    In 'center' mode, computes the average number of consecutive frames
    where the first one is centered on the start time and the last one
    is centered on the end time of a segment with duration
    `from_duration`.

Ústrictr	   ÚlooseÚcenterN)r'   r�   Úfloorr,   r‘   r�   )r    r    r¡   s      r   ÚsamplesÚSlidingWindow.samplesê  s‰   € ð$ �8ÓÜ”r—x’x ·±Ñ!>À$Ç)Á)Ñ KÓLÓMÐPQÑQÐQà�W‹_Ü”r—x’x ·±Ñ!>À$Ç)Á)Ñ KÓLÓMÐMà�XÓÜ”r—w’w ·	±	Ñ 9Ó;Ó<Ð<ð r   ÚfocusÚTimelineÚfixedÚreturn_rangesc                 óp  • SSK Jn  [        U[        U45      (       d  Sn[	        U5      e[        X5      (       aÔ  Ub  Sn[        U5      eU(       ac  / n[        UR                  5       5       HB  u  p‰U R                  X’USS9n
US:X  d  U
S   S   US   S   :”  a  Xz-  nM4  U
S   S   US   S'   MD     U$ [        R                  " UR                  5        V	s/ s H  n	U R                  X’US	S9PM     sn	5      n[        R                  " U5      $ US
:X  aº  UR                  U R                  -
  U R                  -
  U R                  -  n[        [        R                   " U5      5      nUcM  UR"                  U R                  -
  U R                  -  n[        [        R$                  " U5      5      nXŽS-   4n
GO@U R'                  US
S9nXˆU-   4n
GO(US:X  a¸  UR                  U R                  -
  U R                  -  n[        [        R                   " U5      5      nUcY  UR"                  U R                  -
  U R                  -
  U R                  -  n[        [        R$                  " U5      5      nXŽS-   4n
O�U R'                  USS9nXˆU-   4n
OjUS:X  aW  U R)                  UR                  5      nUc"  U R)                  UR"                  5      nXŽS-   4n
O$U R'                  USS9nXˆU-   4n
OSn[        U5      eU(       a  [+        U
5      /$ [        R,                  " [/        U
6 [        R0                  S9$ s  sn	f )aU  Crop sliding window

Parameters
----------
focus : `Segment` or `Timeline`
mode : {'strict', 'loose', 'center'}, optional
    In 'strict' mode, only indices of segments fully included in
    'focus' support are returned. In 'loose' mode, indices of any
    intersecting segments are returned. In 'center' mode, first and
    last positions are chosen to be the positions whose centers are the
    closest to 'focus' start and end times. Defaults to 'loose'.
fixed : float, optional
    Overrides `Segment` 'focus' duration and ensures that the number of
    returned frames is fixed (which might otherwise not be the case
    because of rounding erros).
return_ranges : bool, optional
    Return as list of ranges. Defaults to indices numpy array.

Returns
-------
indices : np.array (or list of ranges)
    Array of unique indices of matching segments
r	   ©rª   z3"focus" must be a `Segment` or `Timeline` instance.z1'fixed' is not supported with `Timeline` 'focus'.T)r¡   r«   r¬   r   r‰   Fr¤   )r¡   r£   r¥   z4'mode' must be one of {'loose', 'strict', 'center'}.)Údtype)Útimelinerª   Ú
isinstancer   Ú	TypeErrorrO   Ú	enumerateÚsupportÚcropr�   ÚhstackÚuniquer   r,   r‘   r'   Úceilr   r¦   r§   rž   ÚlistÚarrayÚrangeÚint64)r    r©   r¡   r«   r¬   rª   ÚmsgÚrangesÚiÚsÚrngÚindicesÚi_Új_ÚjÚns                   r   rµ   ÚSlidingWindow.crop  só  € õ: 	'ä˜%¤'¨8Ð!4×5Ñ5ØGˆCÜ˜C“.Ð ä�e×&Ñ&àÑ ØI�Ü  “oÐ%æØ�ä% e§m¡m£oÖ6‘D�AØŸ)™) A¸Ø26ð $ð 8�Cð ˜A“v  Q¡¨¡¨V°B©Z¸©]Ó!:Ø™šð ),¨A©¨q©	˜˜r™
 1›ñ 7ð �ô —i’iàŸ™œó!*â(�Að —	‘	˜!¨eÀ5�	ÓIÙ(ñ!*ó +ˆGô
 —9’9˜WÓ%Ð%ð �7‹?ð —+‘+ §¡Ñ-°·
±
Ñ:¸d¿i¹iÑGˆBÜ”B—G’G˜B“KÓ ˆAà‰}ð —i‘i $§*¡*Ñ,°·	±	Ñ9�ÜœŸš ›Ó%�Ø˜a™%�j’ð —L‘L ¨W�LÐ5�Ø˜a™%�j’à�XÓð —+‘+ §
¡
Ñ*¨d¯i©iÑ7ˆBÜ”B—G’G˜B“KÓ ˆAà‰}ð —i‘i $§-¡-Ñ/°$·*±*Ñ<ÀÇ	Á	ÑI�ÜœŸš ›Ó%�Ø˜a™%�j‘ð —L‘L ¨X�LÐ6�Ø˜a™%�j‘à�XÓð ×"Ñ" 5§;¡;Ó/ˆAà‰}à×&Ñ& u§y¡yÓ1�Ø˜a™%�j‘à—L‘L ¨X�LÐ6�Ø˜a™%�j‘ð IˆCÜ˜S“/Ð!æÜ˜“I�;Ðä�xŠxœ˜s˜¬2¯8©8Ñ4Ð4ùòE!*s   ÃL3Úsegmentc                 óZ   • [         R                  " S[        5        U R                  U5      $ )Nz)Deprecated in favor of `segment_to_range`)rr   rs   ÚDeprecationWarningÚsegment_to_range)r    rÈ   s     r   ÚsegmentToRangeÚSlidingWindow.segmentToRange„  s%   € Ü�ŠÐAÜ(ô	*à×$Ñ$ WÓ-Ð-r   c                 óˆ   • U R                  UR                  5      n[        UR                  U R                  -  5      S-   nX#4$ )a  Convert segment to 0-indexed frame range

Parameters
----------
segment : Segment

Returns
-------
i0 : int
    Index of first frame
n : int
    Number of frames

Examples
--------

    >>> window = SlidingWindow()
    >>> print window.segment_to_range(Segment(10, 15))
    i0, n

r	   )rž   r   r'   r,   r‘   )r    rÈ   Úi0rÆ   s       r   rË   ÚSlidingWindow.segment_to_range‰  s?   € ð. ×Ñ §¡Ó.ˆô �× Ñ  4§9¡9Ñ,Ó-°Ñ1ˆàˆuˆr   rÏ   rÆ   c                 óZ   • [         R                  " S[        5        U R                  X5      $ )Nz1This is deprecated in favor of `range_to_segment`)rr   rs   rÊ   Úrange_to_segment)r    rÏ   rÆ   s      r   ÚrangeToSegmentÚSlidingWindow.rangeToSegment§  s%   € Ü�ŠÐIÜ(ô	*à×$Ñ$ RÓ+Ð+r   c                 ó¾   • U R                   US-
  U R                  -  -   SU R                  -  -   nX R                  -  nX4-   nUS:X  a  U R                  n[	        X55      $ )aÓ  Convert 0-indexed frame range to segment

Each frame represents a unique segment of duration 'step', centered on
the middle of the frame.

The very first frame (i0 = 0) is the exception. It is extended to the
sliding window start time.

Parameters
----------
i0 : int
    Index of first frame
n : int
    Number of frames

Returns
-------
segment : Segment

Examples
--------

    >>> window = SlidingWindow()
    >>> print window.range_to_segment(3, 2)
    [ --> ]

r$   r   )rŒ   r‹   rŠ   r   r   )r    rÏ   rÆ   r   r,   r   s         r   rÒ   ÚSlidingWindow.range_to_segment¬  s^   € ðF —‘  R¡¨4¯;©;Ñ6Ñ6¸¸d¿o¹oÑ9MÑMˆØ—{‘{‘?ˆØÑˆð �‹7Ø—J‘JˆEä�uÓ"Ð"r   ÚnSamplesc                 óZ   • [         R                  " S[        5        U R                  U5      $ )Nz4This is deprecated in favor of `samples_to_duration`)rr   rs   rÊ   Úsamples_to_duration)r    r×   s     r   ÚsamplesToDurationÚSlidingWindow.samplesToDurationÙ  ó%   € Ü�ŠÐLÜ(ô	*à×'Ñ'¨Ó1Ð1r   Ú	n_samplesc                 ó:   • U R                  SU5      R                  $ )zReturns duration of samplesr   )rÒ   r,   )r    rÝ   s     r   rÙ   Ú!SlidingWindow.samples_to_durationÞ  s   € à×$Ñ$ Q¨	Ó2×;Ñ;Ð;r   r,   c                 óZ   • [         R                  " S[        5        U R                  U5      $ )Nz4This is deprecated in favor of `duration_to_samples`)rr   rs   rÊ   Úduration_to_samples©r    r,   s     r   ÚdurationToSamplesÚSlidingWindow.durationToSamplesâ  rÜ   r   c                 ó>   • U R                  [        SU5      5      S   $ )zReturns samples in durationr   r	   )rË   r   râ   s     r   rá   Ú!SlidingWindow.duration_to_samplesç  s   € à×$Ñ$¤W¨Q°Ó%9Ó:¸1Ñ=Ð=r   r¿   c                 ó„   • U R                   XR                  -  -   nX R                  :¼  a  g[        X"U R                  -   S9$ )z”
Parameters
----------
i : int
    Index of sliding window position

Returns
-------
segment : :class:`Segment`
    Sliding window at ith position

Nr/   )rŒ   r‹   r�   r   rŠ   )r    r¿   r   s      r   Ú__getitem__ÚSlidingWindow.__getitem__ë  s;   € ð —‘˜q§;¡;™Ñ.ˆð —J‘JÓØä˜U°·±Ñ(?Ñ@Ð@r   c                 ó"   • U R                  5       $ r{   )Ú__next__r   s    r   ÚnextÚSlidingWindow.next  s   € Ø�}‰}‹Ðr   c                 ón   • U =R                   S-  sl         X R                      nU(       a  U$ [        5       e)Nr	   )r�   ÚStopIteration)r    Úwindows     r   rë   ÚSlidingWindow.__next__  s*   € Ø�Š�A‰�Ø—h‘h‘ˆæØˆMä“/Ð!r   c                 ó   • SU l         U $ )a  Sliding window iterator

Use expression 'for segment in sliding_window'

Examples
--------

>>> window = SlidingWindow(end=0.1)
>>> for segment in window:
...     print(segment)
[ 00:00:00.000 -->  00:00:00.030]
[ 00:00:00.010 -->  00:00:00.040]
[ 00:00:00.020 -->  00:00:00.050]
[ 00:00:00.030 -->  00:00:00.060]
[ 00:00:00.040 -->  00:00:00.070]
[ 00:00:00.050 -->  00:00:00.080]
[ 00:00:00.060 -->  00:00:00.090]
[ 00:00:00.070 -->  00:00:00.100]
[ 00:00:00.080 -->  00:00:00.110]
[ 00:00:00.090 -->  00:00:00.120]
r‰   )r�   r   s    r   r3   ÚSlidingWindow.__iter__  s   € ð0 ˆŒØˆr   c                 óÒ   • [         R                  " U R                  5      (       a  [        S5      eU R	                  U R                  5      nX   (       a  US-  nX   (       a  M  UnU$ )z¿Number of positions

Equivalent to len([segment for segment in window])

Returns
-------
length : int
    Number of positions taken by the sliding window
    (from start times to end times)

zinfinite sliding window.r	   )r�   Úisinfr�   rO   rž   )r    r¿   Úlengths      r   Ú__len__ÚSlidingWindow.__len__*  sZ   € ô �8Š8�D—J‘J×ÑÜÐ7Ó8Ð8ð ×Ñ˜tŸz™zÓ*ˆà�wØ�‰FˆAð �w‰wàˆàˆr   c                 ó†   • U R                   nU R                  nU R                  nU R                  nU R	                  XX4S9nU$ )zDuplicate sliding window©r,   r‘   r   r   )r,   r‘   r   r   ru   )r    r,   r‘   r   r   Úsliding_windows         r   r6   ÚSlidingWindow.copyC  sF   € à—=‘=ˆØ�y‰yˆØ—
‘
ˆØ�h‰hˆØŸ™Ø°ð (ð 
ˆð Ðr   r´   Ú
align_lastc              #   ó.  #   • SSK Jn  [        X5      (       a  UnO7[        U[        5      (       a  U" U/S9nOS[	        U5       S3n[        U5      eU H»  nUR                  U R                  :  a  M  [        U R                  U R                  UR                  UR                  S9nU H  nX†;   d  M
  Uv •  Un	M     U(       d  Mr  W	R                  UR                  :  d  MŽ  [        UR                  U R                  -
  UR                  S9v •  M½     g7f)	a'  Slide window over support

Parameter
---------
support : Segment or Timeline
    Support on which to slide the window.
align_last : bool, optional
    Yield a final segment so that it aligns exactly with end of support.

Yields
------
chunk : Segment

Example
-------
>>> window = SlidingWindow(duration=2., step=1.)
>>> for chunk in window(Segment(3, 7.5)):
...     print(tuple(chunk))
(3.0, 5.0)
(4.0, 6.0)
(5.0, 7.0)
>>> for chunk in window(Segment(3, 7.5), align_last=True):
...     print(tuple(chunk))
(3.0, 5.0)
(4.0, 6.0)
(5.0, 7.0)
(5.5, 7.5)
r   r®   )Úsegmentsz>"support" must be either a Segment or a Timeline instance (is Ú)rú   r/   N)Úpyannote.corerª   r±   r   Útyper²   r,   r‡   r‘   r   r   )
r    r´   rý   rª   rÿ   r½   rÈ   rð   rÀ   Úlasts
             r   Ú__call__ÚSlidingWindow.__call__N  sò   é € õ@ 	+Ü�g×(Ñ(Ø‰Hä˜¤×)Ñ)Ù¨'¨Ñ3‰Hð Ü $ W£˜¨að1ð ô ˜C“.Ð ãˆGà×Ñ $§-¡-Ó/Ùä"¨D¯M©MØ(,¯	©	Ø)0¯©Ø'.§{¡{ñ4ˆFó
 �à•<Ø’GØ’Dñ	 ÷ ˆz˜dŸh™h¨¯©Õ4Ü G§K¡K°$·-±-Ñ$?Ø")§+¡+ñ/ô /ò#  ùs   ‚B.DÂ4DÃDÃ#2D)Ú
__durationÚ__endÚ__iÚ__startÚ__step)g¸…ëQ¸ž?g{®Gáz„?r   N)r£   )r¤   NF)r*   r‡   )F)*rv   r|   r}   r~   r   r’   rƒ   r€   r   r   r‘   r,   r'   rž   r
   r§   r   r   r   r   r�   Úndarrayr   rµ   r   rÌ   rË   rÓ   rÒ   rÚ   rÙ   rã   rá   rè   rì   rë   r3   r÷   r6   r   r  r…   rz   r   r   r‡   r‡   ˆ  sF  † ñô@ð6 ð�uó ó ðð ð�Uó ó ðð ð�eó ó ðð ð˜%ó ó ðð˜uð ¨ô ñ$= Uð =°)ð =È3õ =ð8  'Ø&*Ø-2ñ}5˜% ¨Ð 3Ñ4ð }5Øð}5à˜U‘Oð}5ð % T™Nð}5ð �"—*‘*˜d 4¨¡9™oÐ-Ñ.õ	}5ð~. gð .°%¸¸S¸±/ô .ð
¨ð °E¸#¸s¸(±Oô ð<, ð ,¨ð ,°ô ,ð
+# 3ð +#¨3ð +#°7ô +#ðZ2¨#ð 2°%ô 2ð
<¨Sð <°Uô <ð2¨%ð 2°Cô 2ð
>¨Eð >°cô >ðA˜Sð A Wô Að0�gô ð"˜'ô "ôð6˜ô ô2	ð %*ñ@/Ø ¨Ð 3Ñ4ð@/à!ð@/à.6°wÑ.?÷@/ð @/r   r‡   )r   rr   Útypingr   r   r   r   r   r   Úutils.typesr
   Únumpyr�   Údataclassesr   r   r‡   rz   r   r   Ú<module>r     sO   ðñ:4ól ß C× Cå "ã Ý !ñ �$˜dÑ#÷gð gó $ðg÷T	F/ò F/r   