o
    )i0                     @   s2  d Z ddlZddlZddlmZ ddlmZ ddlm	Z	 dd	gZ
ejd
d
ddejdejfddZejd
d
ddd Zejd
d
d	
d!dejdejdedejfddZ	
d!dejdejdedejfddZ	
	
d"de	de	dededejf
dd	Zejd
d
d	
	
d"dejdejdejdedef
dd ZdS )#zMatching functions    N   )ParameterError)valid_intervals   )_SequenceLikematch_intervalsmatch_eventsT)Znopythoncacheint_aint_bc                 C   s   | d |d g}|d |d k r|   | d |d g}|d |d k r(|   |d |d  }|dk r6d}|d |d  }|dkrF|| S dS )zJaccard similarity between two intervals

    Parameters
    ----------
    int_a, int_b : np.ndarrays, shape=(2,)

    Returns
    -------
    Jaccard similarity between intervals
    r   r   g        )reverse)r
   r   ZendsZstartsintersectionunion r   d/var/www/html/eduruby.in/lip-sync/lip-sync-env/lib/python3.10/site-packages/librosa/util/matching.py	__jaccard   s   r   c                 C   s6   d}d}|D ]}t | || }||kr||}}q|S )z4Find the best Jaccard match from query to candidates)r   )queryintervals_to
candidatesZ
best_scoreZbest_idxidxZscorer   r   r   __match_interval_overlaps/   s   
r   intervals_fromr   strictreturnc                 C   s  t |dddf }t |dddf }||df }||df }t j|| dddf dd}t j|| dddf dd}t jt| tjd}	tt| D ]x}
| |
 }||
 }||
 }t|d| t||d @ }t|dkr{t	||||	|
< qN|rt
t j}t j}||
 dkr|d |||
 d   }||
 d t|k r|||
 d  |d  }||k r|||
 d  |	|
< qN|||
 d  |	|
< qN|	S )z.Numba-accelerated interval matching algorithm.Nr   r   right)ZsideleftZdtype)npargsortsearchsortedemptylennumbaZuint32rangesetr   r   inf)r   r   r   start_indexZ	end_indexZstart_sortedZ
end_sortedZsearch_endsZsearch_startsoutputir   Zafter_queryZbefore_queryr   Zdist_beforeZ
dist_afterr   r   r   __match_intervals<   s4    r*   c              
   C   sj   t | dkst |dkrtdt|  t| zt| ||dW S  ty4 } ztd| |d}~ww )a
  Match one set of time intervals to another.

    This can be useful for tasks such as mapping beat timings
    to segments.

    Each element ``[a, b]`` of ``intervals_from`` is matched to the
    element ``[c, d]`` of ``intervals_to`` which maximizes the
    Jaccard similarity between the intervals::

        max(0, |min(b, d) - max(a, c)|) / |max(d, b) - min(a, c)|

    In ``strict=True`` mode, if there is no interval with positive
    intersection with ``[a,b]``, an exception is thrown.

    In ``strict=False`` mode, any interval ``[a, b]`` that has no
    intersection with any element of ``intervals_to`` is instead
    matched to the interval ``[c, d]`` which minimizes::

        min(|b - c|, |a - d|)

    that is, the disjoint interval [c, d] with a boundary closest
    to [a, b].

    .. note:: An element of ``intervals_to`` may be matched to multiple
       entries of ``intervals_from``.

    Parameters
    ----------
    intervals_from : np.ndarray [shape=(n, 2)]
        The time range for source intervals.
        The ``i`` th interval spans time ``intervals_from[i, 0]``
        to ``intervals_from[i, 1]``.
        ``intervals_from[0, 0]`` should be 0, ``intervals_from[-1, 1]``
        should be the track duration.
    intervals_to : np.ndarray [shape=(m, 2)]
        Analogous to ``intervals_from``.
    strict : bool
        If ``True``, intervals can only match if they intersect.
        If ``False``, disjoint intervals can match.

    Returns
    -------
    interval_mapping : np.ndarray [shape=(n,)]
        For each interval in ``intervals_from``, the
        corresponding interval in ``intervals_to``.

    See Also
    --------
    match_events

    Raises
    ------
    ParameterError
        If either array of input intervals is not the correct shape

        If ``strict=True`` and some element of ``intervals_from`` is disjoint from
        every element of ``intervals_to``.

    Examples
    --------
    >>> ints_from = np.array([[3, 5], [1, 4], [4, 5]])
    >>> ints_to = np.array([[0, 2], [1, 3], [4, 5], [6, 7]])
    >>> librosa.util.match_intervals(ints_from, ints_to)
    array([2, 1, 2], dtype=uint32)
    >>> # [3, 5] => [4, 5]  (ints_to[2])
    >>> # [1, 4] => [1, 3]  (ints_to[1])
    >>> # [4, 5] => [4, 5]  (ints_to[2])

    The reverse matching of the above is not possible in ``strict`` mode
    because ``[6, 7]`` is disjoint from all intervals in ``ints_from``.
    With ``strict=False``, we get the following:

    >>> librosa.util.match_intervals(ints_to, ints_from, strict=False)
    array([1, 1, 2, 2], dtype=uint32)
    >>> # [0, 2] => [1, 4]  (ints_from[1])
    >>> # [1, 3] => [1, 4]  (ints_from[1])
    >>> # [4, 5] => [4, 5]  (ints_from[2])
    >>> # [6, 7] => [4, 5]  (ints_from[2])
    r   z'Attempting to match empty interval list)r   z&Unable to match intervals with strict=N)r"   r   r   r*   )r   r   r   excr   r   r   r   r   s   Revents_from	events_tor   r   c                 C   s   t | dkst |dkrtd|s!|s!tt| |s!td|s/t|t| k r/td|s=t|t| kr=tdtj| tjd}t	|| |||S )a  Match one set of events to another.

    This is useful for tasks such as matching beats to the nearest
    detected onsets, or frame-aligned events to the nearest zero-crossing.

    .. note:: A target event may be matched to multiple source events.

    Examples
    --------
    >>> # Sources are multiples of 7
    >>> s_from = np.arange(0, 100, 7)
    >>> s_from
    array([ 0,  7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91,
           98])
    >>> # Targets are multiples of 10
    >>> s_to = np.arange(0, 100, 10)
    >>> s_to
    array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
    >>> # Find the matching
    >>> idx = librosa.util.match_events(s_from, s_to)
    >>> idx
    array([0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 8, 9, 9])
    >>> # Print each source value to its matching target
    >>> zip(s_from, s_to[idx])
    [(0, 0), (7, 10), (14, 10), (21, 20), (28, 30), (35, 30),
     (42, 40), (49, 50), (56, 60), (63, 60), (70, 70), (77, 80),
     (84, 80), (91, 90), (98, 90)]

    Parameters
    ----------
    events_from : ndarray [shape=(n,)]
        Array of events (eg, times, sample or frame indices) to match from.
    events_to : ndarray [shape=(m,)]
        Array of events (eg, times, sample or frame indices) to
        match against.
    left : bool
    right : bool
        If ``False``, then matched events cannot be to the left (or right)
        of source events.

    Returns
    -------
    event_mapping : np.ndarray [shape=(n,)]
        For each event in ``events_from``, the corresponding event
        index in ``events_to``::

            event_mapping[i] == arg min |events_from[i] - events_to[:]|

    See Also
    --------
    match_intervals

    Raises
    ------
    ParameterError
        If either array of input events is not the correct shape
    r   z$Attempting to match empty event listzWCannot match events with left=right=False and events_from is not contained in events_tozICannot match events with left=False and max(events_to) < max(events_from)zJCannot match events with right=False and min(events_to) > min(events_from)r   )
r"   r   r   allZin1dmaxmin
empty_likeZint32__match_events_helper)r,   r-   r   r   r(   r   r   r   r      s    ?r(   c                 C   sx  t |}|| }t |}|| }t ||}	t|	D ]\}
}d}d}d}t|	}d}d}d}|	|
 }||
 }|t|krB|d8 }|rN|dkrN|d }d}|r^|t|d k r^|d }d}t|| | }|rr|rrt|| | }|r~|r~t|| | }|r|s|| |ks|s||k s||k r||k r|| | |
< q|r||k r|| | |
< q|| | |
< qt | }| ||< |S )NFr   r   r   T)r   r   r    	enumerater"   absr1   )r(   r,   r-   r   r   Zfrom_idxZsorted_fromZto_idxZ	sorted_toZmatching_indicesindZ
middle_indZ	left_flagZ
right_flagZleft_indZ	right_indZ	left_diffZ
right_diffZmid_diffZsorted_from_numZ	solutionsr   r   r   r2   4  sV   
	

r2   )T)TT)__doc__numpyr   r#   
exceptionsr   utilsr   Z_typingr   __all__ZjitZndarrayr   r   boolr*   r   r   r2   r   r   r   r   <module>   sv   
6
c
b