U
    -Z$d9  ã                   @   sD   d Z ddlZddlmZ ddd„Zdd	d
„Zddd„Zddd„ZdS )zE
Various functions for finding/manipulating silence in AudioSegments
é    Né   )Údb_to_floatéè  éðÿÿÿc                 C   sö   t | ƒ}||k rg S t|ƒ| j }g }|| }td|d |ƒ}|| rTt ||g¡}|D ](}| ||| … }	|	j|krX| |¡ qX|sŠg S g }
| d¡}|}|D ]>}||| k}||| k}|sÚ|rÚ|
 ||| g¡ |}|}q |
 ||| g¡ |
S )ay  
    Returns a list of all silent sections [start, end] in milliseconds of audio_segment.
    Inverse of detect_nonsilent()

    audio_segment - the segment to find silence in
    min_silence_len - the minimum length for any silent section
    silence_thresh - the upper bound for how quiet is silent in dFBS
    seek_step - step size for interating over the segment in ms
    r   r   )	Úlenr   Zmax_possible_amplitudeÚrangeÚ	itertoolsÚchainZrmsÚappendÚpop)Úaudio_segmentÚmin_silence_lenÚsilence_threshÚ	seek_stepZseg_lenZsilence_startsZlast_slice_startZslice_startsÚiZaudio_sliceÚsilent_rangesZprev_iZcurrent_range_startZsilence_start_iZ
continuousZsilence_has_gap© r   ú1/tmp/pip-unpacked-wheel-94qg_ebr/pydub/silence.pyÚdetect_silence	   s>    


ÿÿr   c           
      C   s¤   t | |||ƒ}t| ƒ}|s$d|ggS |d d dkrH|d d |krHg S d}g }|D ]\}}	| ||g¡ |	}qT|	|kr†| ||g¡ |d ddgkr | d¡ |S )ay  
    Returns a list of all nonsilent sections [start, end] in milliseconds of audio_segment.
    Inverse of detect_silent()

    audio_segment - the segment to find silence in
    min_silence_len - the minimum length for any silent section
    silence_thresh - the upper bound for how quiet is silent in dFBS
    seek_step - step size for interating over the segment in ms
    r   r   )r   r   r
   r   )
r   r   r   r   r   Zlen_segZ
prev_end_iZnonsilent_rangesZstart_iZend_ir   r   r   Údetect_nonsilentL   s     

 
r   éd   c                    s–   dd„ }t ˆtƒr"ˆrtˆ ƒnd‰‡fdd„tˆ |||ƒD ƒ}||ƒD ]<\}}|d }	|d }
|
|	k rF|	|
 d |d< |d |d< qF‡ fdd„|D ƒS )	am  
    Returns list of audio segments from splitting audio_segment on silent sections

    audio_segment - original pydub.AudioSegment() object

    min_silence_len - (in ms) minimum length of a silence to be used for
        a split. default: 1000ms

    silence_thresh - (in dBFS) anything quieter than this will be
        considered silence. default: -16dBFS

    keep_silence - (in ms or True/False) leave some silence at the beginning
        and end of the chunks. Keeps the sound from sounding like it
        is abruptly cut off.
        When the length of the silence is less than the keep_silence duration
        it is split evenly between the preceding and following non-silent
        segments.
        If True is specified, all the silence is kept, if False none is kept.
        default: 100ms

    seek_step - step size for interating over the segment in ms
    c                 S   s"   t  | ¡\}}t|dƒ t||ƒS )z$s -> (s0,s1), (s1,s2), (s2, s3), ...N)r   ÚteeÚnextÚzip)ÚiterableÚaÚbr   r   r   ÚpairwiseŠ   s    
z"split_on_silence.<locals>.pairwiser   c                    s    g | ]\}}|ˆ  |ˆ  g‘qS r   r   ©Ú.0ÚstartÚend)Úkeep_silencer   r   Ú
<listcomp>“   s   ÿz$split_on_silence.<locals>.<listcomp>r   é   c                    s,   g | ]$\}}ˆ t |d ƒt|tˆ ƒƒ… ‘qS )r   )ÚmaxÚminr   r   )r   r   r   r#       s   ÿ)Ú
isinstanceÚboolr   r   )r   r   r   r"   r   r   Zoutput_rangesZrange_iZrange_iiZlast_endZ
next_startr   )r   r"   r   Úsplit_on_silencep   s    

ý
þr)   ç      IÀé
   c                 C   sJ   d}|dkst ‚| ||| … j|k r<|t| ƒk r<||7 }qt|t| ƒƒS )a  
    Returns the millisecond/index that the leading silence ends.

    audio_segment - the segment to find silence in
    silence_threshold - the upper bound for how quiet is silent in dFBS
    chunk_size - chunk size for interating over the segment in ms
    r   )ÚAssertionErrorZdBFSr   r&   )ZsoundZsilence_thresholdÚ
chunk_sizeZtrim_msr   r   r   Údetect_leading_silence¦   s
    "
r.   )r   r   r   )r   r   r   )r   r   r   r   )r*   r+   )Ú__doc__r   Úutilsr   r   r   r)   r.   r   r   r   r   Ú<module>   s   
C
$  ÿ
6