o
    xi*=                     @   sV  d Z ddlZddlZddlZddlZddlmZ ddlmZ ddl	m
Z
mZmZmZmZmZmZ ddlmZ ddlmZ ejZeedrLed	d
 Zned	d

ZeZW d   n1 s_w   Y  dee fddZdee deddfddZdee dedefddZdee deddfddZded fddZ de!de!de"fddZ#de!de!de"fd d!Z$d"d# Z%			$did%ed&ed'e!d(e!d)e"de"fd*d+Z&d,e!d-e!d.ee d/ed0 dee f
d1d2Z'dedefd3d4Z(d5ede!fd6d7Z)	$	djd8e!d9eee
d:f  d;e"d<edeee
d:f ef f
d=d>Z*d?ed,e!d-e!defd@dAZ+dBe!defdCdDZ,	dkdEeee!e!f  dFe!dGe!deee!e!f  fdHdIZ-dJeddfdKdLZ.dMedNedee fdOdPZ/	dldQedRedSee
 dTeddf
dUdVZ0dWee1 dXe"dee
 fdYdZZ2d[ede!fd\d]Z3d^e!d_ee! d`ee! de!fdadbZ4dce!dde!dee!dfe"dee!e!f f
dgdhZ5dS )mz#
Various generic utility functions
    N)	resources)Literal)AnyIteratorListTupleNoReturnTypeOptional)errors)	constantsfilespraatiopraatScriptsreturnc                 C   sB   || vrdS |rt | | ddd | d }|S | |}|S )z1Returns the first/last index of an item in a listN   )lenindex)listvaluereverser    r   Z/home/ubuntu/maya3_transcribe/venv/lib/python3.10/site-packages/praatio/utilities/utils.pyfind   s    
r   
_exception_textc                 C   s   d S Nr   )r   r   r   r   r   
reportNoop(   s   r   	exceptiontextc                 C   s   | |r   r   )r   r    r   r   r   reportException,   s   r!   c                 C   s   t | d S r   )print)r   r    r   r   r   reportWarning0      r#   reportingMode)silencewarningerrorc                 C   s$   t jjtt jjtt jjti}||  S r   )r   ErrorReportingModeSILENCEr   WARNINGr#   ERRORr!   )r%   
modeToFuncr   r   r   getErrorReporter4   s
   r.   timereferenceTimec                 C   s*   | |k r|t jd|  d| d dS dS )N'z&' occurs before minimum allowed time 'TFr   OutOfBoundsr/   r0   errorReporterr   r   r   checkIsUndershoot>      r6   c                 C   s*   | |kr|t jd|  d| d dS dS )Nr1   z%' occurs after maximum allowed time 'TFr2   r4   r   r   r   checkIsOvershootI   r7   r8   c                 C   s   ||j vrt| ||j d S r   )validOptionsr   WrongOption)variableNamer   optionClassr   r   r   validateOptionT   s   
r=   FintervalcmprIntervalpercentThresholdtimeThresholdboundaryInclusivec                 C   s   | dd \}}|dd \}}t dt||t || }	|	dk}
d}|r-||kp,||k}d}|dkrK|
rKt ||t|| }|	t| }||k}|}
d}|dkrY|
rY|	|k}|}
|
p`|p`|p`|}
|
S )a  Checks whether two intervals overlap

    Args:
        interval:
        cmprInterval:
        percentThreshold: if percentThreshold is greater than 0, then
            if the intervals overlap, they must overlap by at least this threshold
            (0.2 would mean 20% overlap considering both intervals)
            (eg [0, 6] and [3,8] have an overlap of 50%. If percentThreshold is set
             to higher than 50%, the intervals will be considered to not overlap.)
        timeThreshold: if greater than 0, then if the intervals overlap,
            they must overlap by at least this threshold
        boundaryInclusive: if true, then two intervals are considered to
            overlap if they share a boundary

    Returns:
        bool:
    N   r   F)maxminfloat)r>   r?   r@   rA   rB   	startTimeendTimecmprStartTimecmprEndTimeoverlapTimeoverlapFlagboundaryOverlapFlagpercentOverlapFlag	totalTimepercentOverlaptimeOverlapFlagr   r   r   intervalOverlapCheckY   s(   rR   startend	intervalsmode)strictlax	truncatedc                 C   s0  t d|tj g }|D ]}d}|j| ks|j|krq|j| kr'|j|kr'|}ne|tjjkr:|j| ks7|j|kr:|}nR|j| krS|j|krS|tjjkrRt|j||j}n9|j| k rl|j|krl|tjjkrkt| |j|j}n |j| kr|j|kr|tjjkr|}n|tjjkrt| ||j}|dur|	| q|S )av  Gets all intervals that exist between /start/ and /end/

    Args:
        start: the target interval start time
        end: the target interval stop time
        intervals: the list of intervals to check
        mode: Determines judgement criteria
            - 'strict', only intervals wholly contained by the target
                interval will be kept
            - 'lax', partially contained intervals will be kept
            - 'truncated', partially contained intervals will be
                truncated to fit within the crop region.

    Returns:
        The list of intervals that overlap with the target interval
    rV   N)
r=   r   CropCollisionrT   rS   LAX	TRUNCATEDIntervallabelappend)rS   rT   rU   rV   containedIntervalsr>   matchedEntryr   r   r   getIntervalsInInterval   s8   
rb   c                 C   s   |  ddS )N"z"")replace)r    r   r   r   escapeQuotes   r$   re   inputStrc                 C   s   d| v rt | S t| S )N.)rF   int)rf   r   r   r   strToIntOrFloat   s   ri   	timestampsortedDataTupleList.fuzzyMatchingstartIc                 C   s  |}d}|du r.	 z|| }W n	 t y   Y nw |d }|| kr(| |kr'|}n|d7 }q	nM|| d }|| }	 z|| }	W n t yL   |d8 }Y n/w |	d }|	}t||  }
t||  }|
|k rm|}|}|
dkrlnn	|
|krv|d8 }n|d7 }q9|}||fS )at  Get the value in the data list (sorted by time) that occurs at this point

    If fuzzyMatching is True, if there is not a value
    at the requested timestamp, the nearest feature value will be taken.

    The procedure assumes that all data is ordered in time.
    dataTupleList should be in the form
    [(t1, v1a, v1b, ..), (t2, v2a, v2b, ..), ..]

    The procedure makes one pass through dataTupleList and one
    pass through self.entries.  If the data is not sequentially
    ordered, the incorrect response will be returned.

    For efficiency purposes, it takes a starting index and returns the ending
    index.
    r   FTr   r   )
IndexErrorabs)rj   rk   rl   rm   ibestRowcurrRowcurrTimebestTime	dataTuplecurrDiffbestDiffretRowr   r   r   getValueAtTime   sV   ry   dataTupleListc                 C   s4   g }| D ]}|d }||kr||kr| | q|S )zGets the values that exist within an interval

    The function assumes that the data is formated as
    [(t1, v1a, v1b, ...), (t2, v2a, v2b, ...)]
    r   )r_   )rz   rS   rT   intervalDataListru   r/   r   r   r   getValuesInInterval*  s   
r|   xc                 C   s$   d}| dkr
d}|S | dk rd}|S )z9Returns 1 if x is positive, 0 if x is 0, and -1 otherwiser   r   r   r   )r}   retValr   r   r   sign:  s   r   	inputListminValuemaxValuec                    s   t dd  D rtdt  t dkr'|dur'|dur'||fg}|S |dur; d d |kr; dd|f |durP d d |k rP ||d f  fddtdt d D }d	d |D }|S )
zInverts the segments of a list of intervals

    e.g.
    [(0,1), (4,5), (7,10)] -> [(1,4), (5,7)]
    [(0.5, 1.2), (3.4, 5.0)] -> [(0.0, 0.5), (1.2, 3.4)]
    c                 S   s   g | ]
}|d  |d kqS r   r   r   .0r>   r   r   r   
<listcomp>M  s    z&invertIntervalList.<locals>.<listcomp>z*Interval start occured before interval endr   Nr   r   c                    s(   g | ]} | d   |d   d fqS )r   r   r   )r   rp   r   r   r   r   a  s    c                 S   s    g | ]}|d  |d kr|qS r   r   r   r   r   r   r   g  s     )anyr   ArgumentErrorsortedr   insertr_   range)r   r   r   invListr   r   r   invertIntervalListD  s    	

r   pathc                 C   s   t j| st |  dS dS )zpCreate a new directory

    Unlike os.mkdir, it does not throw an exception if the directory already exists
    N)osr   existsmkdir)r   r   r   r   makeDirl  s   r   txtsubStrc                 C   sH   g }d}	 z|  ||}W n
 ty   Y |S w |t| |d7 }q)z<Find the starting indicies of all instances of subStr in txtr   Tr   )r   
ValueErrorr_   rh   )r   r   	indexListr   r   r   r   findAllu  s   r   praatEXEscriptFNargListcwdc                 C   sl   t j| st| t j|st|dd |D }| d|g| }tj||d}| r4t|d S )Nc                 S   s   g | ]}d | qS )z%sr   )r   argr   r   r   r     s    z"runPraatScript.<locals>.<listcomp>z--run)r   )	r   r   r   r   FileNotFound
subprocessPopenwaitPraatExecutionFailed)r   r   r   r   cmdList	myProcessr   r   r   runPraatScript  s   


r   listOfListsenforceLengthc                    s>   |du rt | d  t fdd| D stdtj|  S )zA safe version of python's zip()

    If two sublists are of different sizes, python's zip will truncate
    the output to be the smaller of the two.

    safeZip throws an exception if the size of the any sublist is different
    from the rest.
    Tr   c                    s   g | ]} t |kqS r   )r   )r   subListlengthr   r   r     s    zsafeZip.<locals>.<listcomp>z"Lists to zip have different sizes.)r   allr   SafeZipException	itertoolszip_longest)r   r   r   r   r   safeZip  s
   	

r   wavFNc                 C   s4   t | d}| }|d }|d }t|| }|S )z@For internal use.  See praatio.audio.QueryWav() for general use.rrC      )waveopen	getparamsrF   )r   	audiofileparams	frameratenframesdurationr   r   r   getWavDuration  s   r   
targetTime
candidateA
candidateBc                 C   s   |du r|du rt d|du r|dur|}|S |du r%|dur%|}|S |durC|durCt||  }t||  }||krA|}|S |}|S )aq  Chooses the closest time between two options that straddle the target time

    Args:
        targetTime: the time to compare against
        candidateA: the first candidate
        candidateB: the second candidate

    Returns:
        the closer of the two options to the target time
    Raises:
        ArgumentError: When no left or right candidate is provided
    NzMust provide at)r   r   ro   )r   r   r   closestTimeaDiffbDiffr   r   r   chooseClosestTime  s    

r   rG   r   rD   r   c                 C   sF   |du r| }| |8 } n| | }| dk rd} | |fS ||kr|}| |fS )a}  returns an interval before or after some start time

    The returned timestamps will be between 0 and max

    Args:
        startTime: the time to get the interval from
        duration: duration of the interval
        max: the maximum allowed time
        reverse: is the interval before or after the targetTime?

    Returns:
        the start and end time of an interval
    Tr   r   )rG   r   rD   r   rH   r   r   r   getInterval  s   
r   )r   r   F)Fr   )NNr   )6__doc__r   r   r   r   	importlibr   typing_extensionsr   typingr   r   r   r   r   r	   r
   praatio.utilitiesr   r   r]   hasattrr   scriptsPathr   rh   r   BaseExceptionstrr   r!   r#   r.   rF   boolr6   r8   r=   rR   rb   re   ri   ry   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s    $


<
E
H
(	

#
