U
    9%e]>                     @   s  d Z ddlmZmZmZmZmZmZ ddlm	Z	 ddl
Z
ddlmZ ddlZddlmZ ddlmZ dd	lmZ eeed
dZe
jeddZW 5 Q R X eddddddeeeeee f eeeejdddZeddddeee	d ejdddZ edddeee	d eeeef  dddZ eddddeeeeejeeeef  f dddZ eddddddeeeeejeeeef  f dddZ d d! Z!d"d# Z"eddddeeee	d ejd$d%d&Z#edddeeee	d eeeef  d$d'd&Z#eddddeeeeeejeeeef  f d$d(d&Z#eddddddeeeeeejeeeef  f d$d)d&Z#dS )*z#Functions for interval construction    )
CollectionDictListUnionoverloadIterable)LiteralN)resource_filename)	ArrayLike   )cache)_FloatLike_cozintervals.msgpackrbF)strict_map_key
   )level           T)bins_per_octavetuningsort)n_binsfmin	intervalsr   r   r   returnc          	      C   s   t |tr|dkr0d|tjd|td |  }q|dkrFt||d}q|dkr`tdg||d	}q|d
kr|tddg||d	}q|dkrtdddg||d	}nt|}t|}t	| | }tj
dt| | d|  }|rt|}|| S )a  Construct a set of frequencies from an interval set

    Parameters
    ----------
    n_bins : int
        The number of frequencies to generate

    fmin : float > 0
        The minimum frequency

    intervals : str or array of floats in [1, 2)
        If `str`, must be one of the following:
        - `'equal'` - equal temperament
        - `'pythagorean'` - Pythagorean intervals
        - `'ji3'` - 3-limit just intonation
        - `'ji5'` - 5-limit just intonation
        - `'ji7'` - 7-limit just intonation

        Otherwise, an array of intervals in the range [1, 2) can be provided.

    bins_per_octave : int > 0
        If `intervals` is a string specification, how many bins to
        generate per octave.
        If `intervals` is an array, then this parameter is ignored.

    tuning : float
        Deviation from A440 tuning in fractional bins.
        This is only used when `intervals == 'equal'`

    sort : bool
        Sort the intervals in ascending order.

    Returns
    -------
    frequencies : array of float
        The frequencies

    Examples
    --------
    Generate two octaves of Pythagorean intervals starting at 55Hz

    >>> librosa.interval_frequencies(24, fmin=55, intervals="pythagorean", bins_per_octave=12)
    array([ 55.   ,  58.733,  61.875,  66.075,  69.609,  74.334,  78.311,
            82.5  ,  88.099,  92.812,  99.112, 104.414, 110.   , 117.466,
           123.75 , 132.149, 139.219, 148.668, 156.621, 165.   , 176.199,
           185.625, 198.224, 208.828])

    Generate two octaves of 5-limit intervals starting at 55Hz

    >>> librosa.interval_frequencies(24, fmin=55, intervals="ji5", bins_per_octave=12)
    array([ 55.   ,  58.667,  61.875,  66.   ,  68.75 ,  73.333,  77.344,
            82.5  ,  88.   ,  91.667,  99.   , 103.125, 110.   , 117.333,
           123.75 , 132.   , 137.5  , 146.667, 154.687, 165.   , 176.   ,
           183.333, 198.   , 206.25 ])

    Generate three octaves using only three intervals

    >>> intervals = [1, 4/3, 3/2]
    >>> librosa.interval_frequencies(9, fmin=55, intervals=intervals)
    array([ 55.   ,  73.333,  82.5  , 110.   , 146.667, 165.   , 220.   ,
       293.333, 330.   ])
    equalg       @r   ZdtypeZpythagoreanr   r   Zji3   )primesr   r   Zji5   Zji7   N)
isinstancestrnparangefloatpythagorean_intervalsplimit_intervalsarraylenceilmultiplyouterflattenr   )	r   r   r   r   r   r   ratiosZ	n_octavesZ
all_ratios r0   U/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/librosa/core/intervals.pyinterval_frequencies   sD    H
      

r2   .r   r   return_factors)r   r   r4   r   c                 C   s   d S Nr0   r3   r0   r0   r1   r'      s    r'   r   c                 C   s   d S r5   r0   r3   r0   r0   r1   r'      s    c                 C   s   d S r5   r0   r3   r0   r0   r1   r'      s    c                    s   t | t t d \} |dk }||  d7  <  |  d7  <  t |rlt |}|| }nt| }|rt fdd|D S t 	d|S )a  Pythagorean intervals

    Intervals are constructed by stacking ratios of 3/2 (i.e.,
    just perfect fifths) and folding down to a single octave::

        1, 3/2, 9/8, 27/16, 81/64, ...

    Note that this differs from 3-limit just intonation intervals
    in that Pythagorean intervals only use positive powers of 3
    (ascending fifths) while 3-limit intervals use both positive
    and negative powers (descending fifths).

    Parameters
    ----------
    bins_per_octave : int
        The number of intervals to generate
    sort : bool
        If `True` then intervals are returned in ascending order.
        If `False`, then intervals are returned in circle-of-fifths order.
    return_factors : bool
        If `True` then return a list of dictionaries encoding the prime factorization
        of each interval as `{2: p2, 3: p3}` (meaning `3**p3 * 2**p2`).
        If `False` (default), return intervals as an array of floating point numbers.

    Returns
    -------
    intervals : np.ndarray or list of dictionaries
        The constructed interval set. All intervals are mapped
        to the range [1, 2).

    See Also
    --------
    plimit_intervals

    Examples
    --------
    Generate the first 12 intervals

    >>> librosa.pythagorean_intervals(bins_per_octave=12)
    array([1.      , 1.067871, 1.125   , 1.201355, 1.265625, 1.351524,
           1.423828, 1.5     , 1.601807, 1.6875  , 1.802032, 1.898437])
    >>> # Compare to the 12-tone equal temperament intervals:
    >>> 2**(np.arange(12)/12)
    array([1.      , 1.059463, 1.122462, 1.189207, 1.259921, 1.33484 ,
           1.414214, 1.498307, 1.587401, 1.681793, 1.781797, 1.887749])

    Or the first 7, in circle-of-fifths order

    >>> librosa.pythagorean_intervals(bins_per_octave=7, sort=False)
    array([1.      , 1.5     , 1.125   , 1.6875  , 1.265625, 1.898437,
           1.423828])

    Generate the first 7, in circle-of-fifths other and factored form

    >>> librosa.pythagorean_intervals(bins_per_octave=7, sort=False, return_factors=True)
    [
        {2: 0, 3: 0},
        {2: -1, 3: 1},
        {2: -3, 3: 2},
        {2: -4, 3: 3},
        {2: -6, 3: 4},
        {2: -7, 3: 5},
        {2: -9, 3: 6}
    ]
    r   r      c                 3   s"   | ]} |  | d V  qdS ))r   r   Nr0   ).0ipow2Zpow3r0   r1   	<genexpr>   s     z(pythagorean_intervals.<locals>.<genexpr>r   )
r$   r%   modflog2astypeintargsortrangelistpower)r   r   r4   
log_ratios	too_smallidxr0   r9   r1   r'      s    F



c                 C   sr   t |}t |}t |d}|| }t |d}|| }t ||t || }t | || d|  dS )u  Compute the harmonic distance between ratios a and b.

    Harmonic distance is defined as `log2(a * b) - 2*log2(gcd(a, b))` [#]_.

    Here we are expressing a and b as prime factorization exponents,
    and the prime basis are provided in their log2 form.

    .. [#] Tenney, James.
        "On ‘Crystal Growth’ in harmonic space (1993–1998)."
        Contemporary Music Review 27.1 (2008): 47-56.
    r   r      )r$   r)   maximumminimumZarounddot)logsabZa_numZa_denZb_numZb_dengcdr0   r0   r1   __harmonic_distance  s    

rO   c                 C   s    | t| | t|k S )z-Given two tuples of prime powers, break ties.)rJ   r$   abs)rL   rM   rK   r0   r0   r1   _crystal_tie_break!  s    rQ   )r   r   r   r4   r   c                 C   s   d S r5   r0   r   r   r   r4   r0   r0   r1   r(   &  s    r(   c                 C   s   d S r5   r0   rR   r0   r0   r1   r(   1  s    c                 C   s   d S r5   r0   rR   r0   r0   r1   r(   <  s    c                 C   s  t | } t j| t jd}g }tt| D ]>}dgt|  }d||< |t| d||< |t| q*| }t	 }	t
 }
tdgt|  }|
| t|
|k rt j}d}t|D ]\}}d}|
D ]J}||f|	krt||||	||f< |	||f |	||f< ||	||f 7 }q||k s<t ||rt||| |r|}|}q||}|
| |D ]<}tt |t | }||
kr^||kr^|| q^qt jt
|
td}t ||\}}|dk }||  d7  < ||  d8  < |t}|rt |}|| }nt|}|r|g }|D ]P}t	 }|| dkrL||  |d< |dd t| || D  || q&|S t d|S )	u
  Construct p-limit intervals for a given set of prime factors.

    This function is based on the "harmonic crystal growth" algorithm
    of [#1]_ [#2]_.

    .. [#1] Tenney, James.
        "On ‘Crystal Growth’ in harmonic space (1993–1998)."
        Contemporary Music Review 27.1 (2008): 47-56.

    .. [#2] Sabat, Marc, and James Tenney.
        "Three crystal growth algorithms in 23-limit constrained harmonic space."
        Contemporary Music Review 27, no. 1 (2008): 57-78.

    Parameters
    ----------
    primes : array of odd primes
        Which prime factors are to be used
    bins_per_octave : int
        The number of intervals to construct
    sort : bool
        If `True` then intervals are returned in ascending order.
        If `False`, then intervals are returned in crystal growth order.
    return_factors : bool
        If `True` then return a list of dictionaries encoding the prime factorization
        of each interval as `{2: p2, 3: p3, ...}` (meaning `3**p3 * 2**p2`).
        If `False` (default), return intervals as an array of floating point numbers.

    Returns
    -------
    intervals : np.ndarray or list of dictionaries
        The constructed interval set. All intervals are mapped
        to the range [1, 2).

    See Also
    --------
    pythagorean_intervals

    Examples
    --------
    Compare 3-limit tuning to Pythagorean tuning and 12-TET

    >>> librosa.plimit_intervals(primes=[3], bins_per_octave=12)
    array([1.        , 1.05349794, 1.125     , 1.18518519, 1.265625  ,
           1.33333333, 1.40466392, 1.5       , 1.58024691, 1.6875    ,
           1.77777778, 1.8984375 ])
    >>> # Pythagorean intervals:
    >>> librosa.pythagorean_intervals(bins_per_octave=12)
    array([1.        , 1.06787109, 1.125     , 1.20135498, 1.265625  ,
           1.35152435, 1.42382812, 1.5       , 1.60180664, 1.6875    ,
           1.80203247, 1.8984375 ])
    >>> # 12-TET intervals:
    >>> 2**(np.arange(12)/12)
    array([1.        , 1.05946309, 1.12246205, 1.18920712, 1.25992105,
           1.33483985, 1.41421356, 1.49830708, 1.58740105, 1.68179283,
           1.78179744, 1.88774863])

    Create a 7-bin, 5-limit interval set

    >>> librosa.plimit_intervals(primes=[3, 5], bins_per_octave=7)
    array([1.        , 1.125     , 1.25      , 1.33333333, 1.5       ,
           1.66666667, 1.875     ])

    The same example, but now in factored form

    >>> librosa.plimit_intervals(primes=[3, 5], bins_per_octave=7,
    ...                          return_factors=True)
    [
        {},
        {2: -3, 3: 2},
        {2: -2, 5: 1},
        {2: 2, 3: -1},
        {2: -1, 3: 1},
        {3: -1, 5: 1},
        {2: -3, 3: 1, 5: 1}
    ]
    r   r   r6   r   r   c                 S   s"   i | ]\}}|d kr|t |qS )r   )r?   )r7   prC   r0   r0   r1   
<dictcomp>  s       z$plimit_intervals.<locals>.<dictcomp>)r$   Z
atleast_1dr=   Zfloat64rA   r*   appendtuplecopydictrB   inf	enumeraterO   iscloserQ   popr)   r&   r<   rJ   r>   r?   r@   updateziprC   )r   r   r   r4   rK   Zseedsr8   seedZfrontierZ	distancesr   rootZscoreZbest_ffpointZHDsZ	new_point_Znew_seedZpowsrD   r:   rE   rF   Zfactorsvr0   r0   r1   r(   G  sr    T








)$__doc__typingr   r   r   r   r   r   Ztyping_extensionsr   msgpackpkg_resourcesr	   numpyr$   Znumpy.typingr
   _cacher   Z_typingr   open__name__Z_fdescloadZ	INTERVALSr?   r#   r&   boolZndarrayr2   r'   rO   rQ   r(   r0   r0   r0   r1   <module>   s    l	           g 


