o
    si2                     @   s   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l	mZ ddd	Zejddd
fddZdd ZdejddfddZdd Zdd ZdS )z}
Methods which sonify annotations for "evaluation by ear".
All functions return a raw signal at the specified sampling rate.
    N)
as_strided)interp1d   )util)chordc                 C   s   |du r*t dt j t |d  d d|  }|t t |d  |d  9 }|du r=t|  | |jd  d }t |}| D ]/}t|| }||jd  }||krZ |S ||krm|d||  ||d<  |S ||||< qD|S )	a  Return a signal with the signal 'click' placed at each specified time

    Parameters
    ----------
    times : np.ndarray
        times to place clicks, in seconds
    fs : int
        desired sampling rate of the output signal
    click : np.ndarray
        click signal, defaults to a 1 kHz blip
    length : int
        desired number of samples in the output signal,
        defaults to ``times.max()*fs + click.shape[0] + 1``

    Returns
    -------
    click_signal : np.ndarray
        Synthesized click signal

    N   g?i  g      ?{Gz?r   r   )	npsinpiarangeexpintmaxshapezeros)timesfsclicklengthclick_signaltimestartend r   C/home/ubuntu/.local/lib/python3.10/site-packages/mir_eval/sonify.pyclicks   s$   *"
r   r   c              	   C   sB  d}|j dkrt|ddtjf |ddtjf f}d}|du r+tt|| }t|| }	|rI|jd | jd krIt|t||	gf}|jd | jd kr_t	d|j d| j |jd | jd krut	d	|j d| j ddg}
g }|
 dkrd|
d< |d|
 g || | |	k rd|
d< || |	g tj| d
|
fdd} t|}t|dddf dk|dddf |	k}| dd|f } t|| d|	}|jd }t| d} t|}| jd dkr|S tj| dd|k}| |ddf } || }|dkr>t|dddf | | ddd|f dd| dddf | dddf fd}|t|}nt| dddf d|f}t|D ]9\}}t|||||}dt||  }t|| }tjj|| |dd}|dd  |dt| | 7  < qPt| }|t|jjkr|| }|S )aK  Reverse synthesis of a time-frequency representation of a signal

    Parameters
    ----------
    gram : np.ndarray
        ``gram[n, m]`` is the magnitude of ``frequencies[n]``
        from ``times[m]`` to ``times[m + 1]``

        Non-positive magnitudes are interpreted as silence.

    frequencies : np.ndarray
        array of size ``gram.shape[0]`` denoting the frequency (in Hz) of
        each row of gram

    times : np.ndarray, shape= ``(gram.shape[1],)`` or ``(gram.shape[1], 2)``
        Either the start time (in seconds) of each column in the gram,
        or the time interval (in seconds) corresponding to each column.

    fs : int
        desired sampling rate of the output signal

    function : function
        function to use to synthesize notes, should be :math:`2\pi`-periodic

    length : int
        desired number of samples in the output signal,
        defaults to ``times[-1]*fs``

    n_dec : int
        the number of decimals used to approximate each sonfied frequency.
        Defaults to 1 decimal place. Higher precision will be slower.

    threshold : float
        optimizes synthesis to only occur for frequencies that have a
        linear magnitude of at least one element in gram above the given threshold.

    Returns
    -------
    output : np.ndarray
        synthesized version of the piano roll

    Fr   NTr   ztimes.shape=z! is incompatible with gram.shape=zfrequencies.shape=)r   r   constant)mode)axisprevious)kindbounds_error
fill_valuer   same)ndimr	   hstacknewaxisr   r   floatr   vstack
ValueErrorminappendpadlogical_andclipmaximumr   r   r   tile	enumerate_fast_synthesizeonesscipysignalconvolvelenabsfinfodtypetiny)gramfrequenciesr   r   functionr   n_dec	thresholdtime_convertedlast_time_in_secspaddingstackingidxn_timesoutput	freq_keepinterpolatorr7   n	frequencywaveperiodfiltersignal_nnormr   r   r   time_frequency@   sv   .
*

,


(rS   c           	      C   sz   t | |} td| | }|dt j t | |  | }tt |t|jd  }t||t	|fd|j
fd}|jS )zEfficiently synthesize a signal.
    Generate one cycle, and simulate arbitrary repetitions
    using array indexing tricks.
    g      $@       @r   )r   strides)r	   roundr   r   r   ceilr)   r   r   r9   itemsizeflat)	rM   rA   r   r@   r   	n_samplesshort_signal	n_repeatslong_signalr   r   r   r4      s    
r4   linearc                 C   s   t |}|du rt|  | }t|d}tj|dd}t| | dtj | | |dddd}|t|}|du rBt	|f}	nt| | ||dddd}
|
t|}	|	|t
| S )a  Sonify a pitch contour.

    Parameters
    ----------
    times : np.ndarray
        time indices for each frequency measurement, in seconds
    frequencies : np.ndarray
        frequency measurements, in Hz.
        Non-positive measurements or NaNs will be interpreted as un-voiced samples.
    fs : int
        desired sampling rate of the output signal
    amplitudes : np.ndarray
        amplitude measurements, nonnegative
        defaults to ``np.ones((length,))``
    function : function
        function to use to synthesize notes, should be :math:`2\pi`-periodic
    length : int
        desired number of samples in the output signal,
        defaults to ``max(times)*fs``
    kind : str
        Interpolation mode for the frequency and amplitude values.
        See: ``scipy.interpolate.interp1d`` for valid settings.

    Returns
    -------
    output : np.ndarray
        synthesized version of the pitch contour
    Ng        F)copyr   )r"   r$   r#   r_   )r)   r   r   r	   r1   
nan_to_numr   r   r   r5   cumsum)r   r?   r   
amplitudesr@   r   r"   f_interpf_esta_esta_interpr   r   r   pitch_contour   s4   
rg   c                 K   s   d}d}d}d}t d| | }t || d  d|d   }	t | j|j}
|
t}
|
|	dd9 }
d	d|d
 d   }t|
|||fi |S )a  Reverse synthesis of a chromagram (semitone matrix)

    Parameters
    ----------
    chromagram : np.ndarray, shape=(12, times.shape[0])
        Chromagram matrix, where each row represents a semitone [C->Bb]
        i.e., ``chromagram[3, j]`` is the magnitude of D# from ``times[j]`` to
        ``times[j + 1]``
    times : np.ndarray, shape=(len(chord_labels),) or (len(chord_labels), 2)
        Either the start time of each column in the chromagram,
        or the time interval corresponding to each column.
    fs : int
        Sampling rate to synthesize audio data at
    **kwargs
        Additional keyword arguments to pass to
        :func:`mir_eval.sonify.time_frequency`

    Returns
    -------
    output : np.ndarray
        Synthesized chromagram

          H         rT   r   r   g     {@E   g      (@)	r	   r   r   r2   Tastyper)   reshaperS   )
chromagramr   r   kwargs	n_octaves	base_notemeanstdnotesshepard_weightr>   r?   r   r   r   chroma@  s    
ry   c                 K   sJ   t | t| \}}}tdd t||D j}t|||fi |S )a  Synthesizes chord labels

    Parameters
    ----------
    chord_labels : list of str
        List of chord label strings.
    intervals : np.ndarray, shape=(len(chord_labels), 2)
        Start and end times of each chord label
    fs : int
        Sampling rate to synthesize at
    **kwargs
        Additional keyword arguments to pass to
        :func:`mir_eval.sonify.time_frequency`

    Returns
    -------
    output : np.ndarray
        Synthesized chord labels

    c                 S   s   g | ]
\}}t ||qS r   )r	   roll).0interval_bitmaprootr   r   r   
<listcomp>  s    
zchords.<locals>.<listcomp>)	r   validate_intervalsr   encode_manyr	   arrayziprn   ry   )chord_labels	intervalsr   rr   rootsinterval_bitmaps_rq   r   r   r   chordso  s   
r   )NN)__doc__numpyr	   scipy.signalr6   numpy.lib.stride_tricksr   scipy.interpolater    r   r   r   r
   rS   r4   rg   ry   r   r   r   r   r   <module>   s     

2
 
!
I/