U
    5d!                     @   s  d dl mZ d dlZd dlZd dlZd dlmZmZ d dlZd dl	Z	d dl
Z
ddlmZmZ ddlmZmZ d dlZd dlmZ zd dlmZ W n   d dlmZ Y nX d d	lmZ zd d
lmZ W n   eZY nX ddlmZmZmZmZmZmZ ddl m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z' e	j(dkr4e)Z*e+Z,eZG dd de-Z.dd Z/dddZ0eddddgZ1eddddddgZ2dd  Z3d(d!d"Z4d#d$ Z5G d%d& d&e-Z6dd'l7m8Z8 dS ))    )divisionN)TemporaryFileNamedTemporaryFile   )log_conversionlog_subprocess_output)mediainfo_jsonfsdecode)
namedtuple)StringIO)BytesIO)izip)_fd_or_path_or_tempfiledb_to_floatratio_to_dbget_encoder_nameget_array_typeaudioop)TooManyMissingFramesInvalidDurationInvalidID3TagVersion
InvalidTagCouldntDecodeErrorCouldntEncodeErrorMissingAudioParameter)   r   c                   @   s0   e Zd Zd
ddZdddZdd Zdd	 ZdS )ClassPropertyDescriptorNc                 C   s   || _ || _d S N)fgetfset)selfr   r    r!   7/tmp/pip-unpacked-wheel-yhjes4t1/pydub/audio_segment.py__init__5   s    z ClassPropertyDescriptor.__init__c                 C   s    |d krt |}| j|| S r   )typer   __get__)r    objklassr!   r!   r"   r%   9   s    zClassPropertyDescriptor.__get__c                 C   s(   | j stdt|}| j |||S )Nzcan't set attribute)r   AttributeErrorr$   r%   )r    r&   valuetype_r!   r!   r"   __set__>   s    zClassPropertyDescriptor.__set__c                 C   s    t |ttfst|}|| _| S r   )
isinstanceclassmethodstaticmethodr   )r    funcr!   r!   r"   setterD   s    zClassPropertyDescriptor.setter)N)N)__name__
__module____qualname__r#   r%   r+   r0   r!   r!   r!   r"   r   3   s   

r   c                 C   s   t | ttfst| } t| S r   )r,   r-   r.   r   )r/   r!   r!   r"   classpropertyK   s    r4   mp4wav)Zm4awaveWavSubChunkidpositionsizeWavDataaudio_formatchannelssample_ratebits_per_sampleraw_datac                 C   s   d}g }|d t | kr~t |dk r~| ||d  }td| |d |d  d }|t||| |dkrpq~||d 7 }q|S )N      
      <Ir      data)lenstructunpack_fromappendr8   )dataposZ	subchunksZsubchunk_idZsubchunk_sizer!   r!   r"   extract_wav_headers\   s     rN   c           	   	   C   s   |st | }dd |D }|r,|d jdk r4td|d }|jd }td| ||d  d }|d	kr~|d
kr~td| td| |d |d  d }td| |d |d  d }td| |d |d  d }|d }|jdkrtd|jd }t||||| |||j  S )Nc                 S   s   g | ]}|j d kr|qS )s   fmt )r9   .0xr!   r!   r"   
<listcomp>p   s     
 z"read_wav_audio.<locals>.<listcomp>r      z$Couldn't find fmt header in wav datarC   z<H   r   i  z%Unknown audio format 0x%X in wav datarE   rF      rG   z%Couldn't find data header in wav data)rN   r;   r   r:   rI   rJ   r9   r<   )	rL   headersfmtrM   r=   r>   r?   r@   Zdata_hdrr!   r!   r"   read_wav_audiol   s,    
   


rY   c                 C   s   t | }|r|d jdkrd S t| dkr2tdtdt| d | dd< |d j}tdt| | d | |d |d < d S )NrV   rG   l        zUnable to process >4GB filesrF   rC   rE   )rN   r9   rH   r   rI   packr:   )rL   rW   rM   r!   r!   r"   fix_wav_headers   s    
r[   c                       sV  e Zd ZdZe Zedd Zejdd ZddiZ	dx fdd		Z
ed
d ZdyddZedd Zdd Zdd Zdd Zdd Zdd Zdd ZdzddZdd Zd d! Zd"d# Zd$d% Zi fd&d'Zed(d) Zd*d+ Zed,d- Zed{d0d1Zed2d3 Z ed|d4d5Z!ed}d6d7Z"ed~d8d9Z#edd:d;Z$edd<d=Z%edd>d?Z&ed@dA Z'edBdC Z(ddFdGZ)dHdI Z*ddJdKZ+dLdM Z,dNdO Z-dPdQ Z.dRdS Z/edTdU Z0edVdW Z1edXdY Z2edZd[ Z3ed\d] Z4ed^d_ Z5ddadbZ6ddcddZ7dedf Z8ddidjZ9ddldmZ:ddndoZ;dpdq Z<drds Z=dtdu Z>dvdw Z?  Z@S )AudioSegmentay  
    AudioSegments are *immutable* objects representing segments of audio
    that can be manipulated using python code.

    AudioSegments are slicable using milliseconds.
    for example:
        a = AudioSegment.from_mp3(mp3file)
        first_second = a[:1000] # get the first second of an mp3
        slice = a[5000:10000] # get a slice from 5 to 10 seconds of an mp3
    c                 C   s   | j S r   	converterclsr!   r!   r"   ffmpeg   s    zAudioSegment.ffmpegc                 C   s
   || _ d S r   r]   )r`   valr!   r!   r"   ra      s    oggZ	libvorbisNc                    s  | dd | _| dd | _| dd | _| j| j| jf}t|tjrhz| }W n   | }Y nX t|rd |krt	dnF| jd k	rt
|| j| j  dkrtd| j| j | _|| _n|ddr|| _| d D ]\}}t| || qnz t|ttfr|n| }W nD tk
rb   d	}|d
}|rZ||7 }|d
}q>|}Y nX t|}	|	sztd|	j| _|	jd | _|	j| _| j| j | _|	j| _| jdkrt| jdd| _| jdkrnt }
t| jd trdnd}t| j}ddd}t|||D ]8\}}}|
 ||dk  t!"||||}|
 | q|
# | _d| _| j| j | _t$t%| j&|| d S )Nsample_width
frame_rater>   z=Either all audio parameters or no parameter must be specifiedr   z=data length must be a multiple of '(sample_width * channels)'metadataF    z!Couldn't read wav audio from datarC   r   ir   ZBBBccc       )FT   rE   )'poprd   re   r>   r,   arraytobytestostringanyr   rH   
ValueErrorframe_width_datagetitemssetattr
basestringbytesreadOSErrorrY   r   r@   r?   rA   r   biasr   intiterr   writerI   rZ   getvaluesuperr\   r#   )r    rL   argskwargsZaudio_paramsattrrb   dreaderZwav_dataZbyte_bufferZpack_fmtipaddingZb0Zb1Zb2Z	old_bytes	__class__r!   r"   r#      sh    

 




zAudioSegment.__init__c                 C   s   | j S )zE
        public access to the raw audio data as a bytestring
        rt   r    r!   r!   r"   rA     s    zAudioSegment.raw_datac                 C   s   |dkr| j }t|| jS )z=
        returns the raw_data as an array of samples
        N)
array_typern   rt   )r    Zarray_type_overrider!   r!   r"   get_array_of_samples  s    z!AudioSegment.get_array_of_samplesc                 C   s   t | jd S )NrC   )r   rd   r   r!   r!   r"   r     s    zAudioSegment.array_typec                 C   s   t d|  | j  S )zJ
        returns the length of this audio segment in milliseconds
          )roundframe_countre   r   r!   r!   r"   __len__  s    zAudioSegment.__len__c                 C   s"   z| j |j kW S    Y dS X d S )NFr   r    otherr!   r!   r"   __eq__  s    zAudioSegment.__eq__c                 C   s    t tt | j| j| j| jfA S r   )hashr\   r>   re   rd   rt   r   r!   r!   r"   __hash__#  s    zAudioSegment.__hash__c                 C   s
   | |k S r   r!   r   r!   r!   r"   __ne__&  s    zAudioSegment.__ne__c                    s    fddt t D S )Nc                 3   s   | ]} | V  qd S r   r!   rP   r   r   r!   r"   	<genexpr>*  s     z(AudioSegment.__iter__.<locals>.<genexpr>)xrangerH   r   r!   r   r"   __iter__)  s    zAudioSegment.__iter__c                    s"  t  tr| jr2 fddt t D S  jd k	rB jnd} jd k	rV jnt}t|t}t|t}n } d }	|j
 }	|j
 }j|| }|| }|t| j
 }|r|jddkrtd| t|d j
 jd}||| 7 }|S )Nc                 3   s    | ]}|| j   V  qd S r   )stepr   millisecondr    r!   r"   r   /  s   z+AudioSegment.__getitem__.<locals>.<genexpr>r   r   rT   mszVYou should never be filling in    more than 2 ms with silence here, missing frames: %s)r,   slicer   r   indicesrH   startstopmin_parse_positionrs   rt   r   r   r   mulrd   _spawn)r    r   r   endrL   Zexpected_lengthZmissing_framesZsilencer!   r   r"   __getitem__,  s>    
 zAudioSegment.__getitem__c                    sP   t |    fdd}||d| j }|| | j }| j|| }| |S )z
        Get a section of the audio segment by sample index.

        NOTE: Negative indices do *not* address samples backword
        from the end of the audio segment like a python list.
        This is intentional.
        c                    s(   | d kr|S | dk rdS |  kr$ S | S )Nr   r!   )rb   defaultZmax_valr!   r"   bounded[  s    z.AudioSegment.get_sample_slice.<locals>.boundedr   )r}   r   rs   rt   r   )r    Zstart_sampleZ
end_sampler   Zstart_iZend_irL   r!   r   r"   get_sample_sliceQ  s    	zAudioSegment.get_sample_slicec                 C   s&   t |tr| j|ddS | |S d S )Nr   )	crossfade)r,   r\   rK   
apply_gainr    argr!   r!   r"   __add__j  s    
zAudioSegment.__add__c                 C   s   |dkr| S t ddS )zO
        Permit use of sum() builtin with an iterable of AudioSegments
        r   z6Gains must be the second addend after the AudioSegmentN)	TypeError)r    Zrargr!   r!   r"   __radd__p  s    zAudioSegment.__radd__c                 C   s$   t |trtdn| | S d S )Nz8AudioSegment objects can't be subtracted from each other)r,   r\   r   r   r   r!   r!   r"   __sub__y  s    

zAudioSegment.__sub__c                 C   s0   t |tr| j|dddS | j| j| dS dS )aH  
        If the argument is an AudioSegment, overlay the multiplied audio
        segment.

        If it's a number, just use the string multiply operation to repeat the
        audio.

        The following would return an AudioSegment that contains the
        audio of audio_seg eight times

        `audio_seg * 8`
        r   T)r:   looprL   N)r,   r\   overlayr   rt   r   r!   r!   r"   __mul__  s    
zAudioSegment.__mul__c                 C   s   t |trd|}t |tjrBz| }W n   | }Y nX t|drht|dr`|d | }| j	| j
| j| jd}|| | j||dS )a  
        Creates a new audio segment using the metadata from the current one
        and the data passed in. Should be used whenever an AudioSegment is
        being returned by an operation that would alters the current one,
        since AudioSegment objects are immutable.
        rg   rz   seekr   )rd   re   rs   r>   rL   rf   )r,   listjoinrn   ro   rp   hasattrr   rz   rd   re   rs   r>   updater   )r    rL   	overridesrf   r!   r!   r"   r     s$    





zAudioSegment._spawnc                    sP   t dd |D  t dd |D t dd |D t fdd|D S )Nc                 s   s   | ]}|j V  qd S r   )r>   rP   segr!   r!   r"   r     s     z%AudioSegment._sync.<locals>.<genexpr>c                 s   s   | ]}|j V  qd S r   )re   r   r!   r!   r"   r     s     c                 s   s   | ]}|j V  qd S r   rd   r   r!   r!   r"   r     s     c                 3   s$   | ]}|  V  qd S r   )set_channelsset_frame_rateset_sample_widthr   r>   re   rd   r!   r"   r     s   )maxtuple)r`   segsr!   r   r"   _sync  s    zAudioSegment._syncc                 C   sH   |dk rt | t| }|tdkr4| jt | dn
| j|d}t|S )Nr   infr   )rH   absfloatr   r}   )r    rb   r!   r!   r"   r     s    
zAudioSegment._parse_positionc                 C   s   | dddddddS )Nrg   r   r>   rd   re   rs   rf   r!   r_   r!   r!   r"   empty  s    zAudioSegment.emptyr   +  c                 C   s.   t ||d  }d| }| |dd|dddS )z
        Generate a silent audio segment.
        duration specified in milliseconds (default duration: 1000ms, default frame_rate: 11025).
             @@s     r   rT   r   r   )r}   )r`   durationre   framesrL   r!   r!   r"   silent  s    zAudioSegment.silentc           
      G   s   t |std| j| }|d jdkr0tdt |}|d j}|d j}tdd |D }t|d jd|| |  }t	|D ]\}}	|	
 ||d |< q| ||||dS )	Nz.At least one AudioSegment instance is requiredr   r   z[AudioSegment.from_mono_audiosegments requires all arguments are mono AudioSegment instancesc                 s   s   | ]}t | V  qd S r   )r}   r   r   r!   r!   r"   r     s     z7AudioSegment.from_mono_audiosegments.<locals>.<genexpr>rj   )r>   rd   re   )rH   rr   r   r>   rd   re   r   rn   r   	enumerater   )
r`   Zmono_segmentsr   r>   rd   re   r   rL   r   r   r!   r!   r"   from_mono_audiosegments  s.    


z$AudioSegment.from_mono_audiosegmentsc              	      s6  |t |ddd\}} r.   t    fdd}	|	drz| |}
|r\|  |d krr|d krr|
W S |d k	r|d kr|
|d d  W S |d kr|d k	r|
d |d  W S |
|d || d  W S W n   |d Y nX n|	d	s |	d
r|d }|d }|d }||||| d}| | |d}
|rH|  |d kr`|d kr`|
S |d k	r|d kr|
|d d  S |d kr|d k	r|
d |d  S |
|d || d  S tddd}z|	|  W n| t
k
rZ   |  |  tdddd}|r|  d}tddd}|d}|rV|	| |d}q8Y nX |  |rr|  tddd}| jdg} r|d g7 }|r|d|g7 }|d|jdddg7 }|d k	r|dt|g7 }|d k	r|dt|g7 }||jg7 }|d k	r|| t| ttjd}tj||tjtjd}W 5 Q R X | \}}t| t| z4|jdkrtd|j|jd d!| |}
W 5 |  |  t|j t|j X |d kr|d kr|
S |d k	r|d kr|
dd  S |d kr"|d k	r"|
d |d  S |
d|d  S d S )"NrbFtempfilec                    sZ   |   }  | krdS ttr2  d| S ttrV  d| dS dS )NT.{0}utf8F)lowerr,   rx   endswithformatry   encodefr   	orig_filer!   r"   	is_format  s    

z?AudioSegment.from_file_using_temporary_files.<locals>.is_formatr6   r   r   rawpcmrd   re   r>   rd   re   r>   rs   r   wbmodedeleterh   )r   r   	bufferingTi  )r   r   -y-f-acodec-i-vn-ss-tstdinstdoutstderrPDecoding failed. ffmpeg returned error code: {0}

Output from ffmpeg/avlib:

{1}ignoreerrors)r   r   AUDIO_FILE_EXT_ALIASESru   _from_safe_wavcloser   rz   r   r   r{   flushopenr^   namestrextendr   osdevnull
subprocessPopenPIPEcommunicater   unlink
returncoder   r   decode)r`   filer   codec
parametersstart_secondr   r   
close_filer   r&   rd   re   r>   rf   Z
input_filer   outputconversion_commandr	  pp_outp_errr!   r   r"   from_file_using_temporary_files  s    



  



  
z,AudioSegment.from_file_using_temporary_filesc                    s  |}zt | W n tk
r(   d  Y nX t|ddd\}}	rT t fdd}
|
drz|d kr|d kr| |W S |d k	r|d kr| ||d d  W S |d kr|d k	r| |d |d  W S | ||d || d  W S W n   |d Y nX n|
d	s*|
d
r|d }|d }|d }||||| d}|d krx|d krx| | |dS |d k	r|d kr| | |d|d d  S |d kr|d k	r| | |dd |d  S | | |d|d || d  S | j	dg}r|dg7 }|r*|d|g7 }|dd} rR|d g7 }d }d }n<| j	dkrt|dt
|ddg7 }n|ddg7 }tj}| }|rd }nt||d}|r dd |d D }|d d}|d dd kr|d!krd"}n|d d# }|d$krd%}nd&| }|d|g7 }|d'ddg7 }|d k	rH|d(t
|g7 }|d k	rb|d)t
|g7 }|dg7 }|d k	r|| t| tj||tjtjd*}|j|d+\}}|jdkst|dkr|	r|  td,|j|jd-d.t|}t| t|}| |}|	r|  |d kr6|d kr6|S |d k	rV|d krV|dd  S |d krz|d k	rz|d |d  S |d|d  S d S )/Nr   Fr   c                    s0   |   } | krdS  r,   d| S dS )NTr   F)r   r   r   r   filenamer   r!   r"   r     s    z)AudioSegment.from_file.<locals>.is_formatr6   r   r   r   r   rd   re   r>   r   r   r   r   r   read_ahead_limitrV   r   ra   z-read_ahead_limitzcache:pipe:0-)r  c                 S   s   g | ]}|d  dkr|qS )Z
codec_typeaudior!   rO   r!   r!   r"   rR     s    z*AudioSegment.from_file.<locals>.<listcomp>ZstreamsZ
codec_nameZ
sample_fmtZfltp)mp3r5   ZaacZwebmrc   rS   r@   rC   Zpcm_u8z	pcm_s%dler   r   r   r   )inputr   r   r   )r	   r   r   r   r   ru   r  r   rz   r^   r  r
  r  r   r  r   r  r  r  rH   r  r   r   r  	bytearrayr[   ry   )r`   r  r   r  r  r  r   r   r   r  r   rd   re   r>   rf   r  r  Zstdin_parameterZ
stdin_datainfoZaudio_streamsZaudio_codecr@   Zacodecr  r  r  r&   r!   r  r"   	from_file  s    


$$
 
 




  
zAudioSegment.from_filec                 C   s   | j |d|dS )Nr!  r  r%  r`   r  r  r!   r!   r"   from_mp3  s    zAudioSegment.from_mp3c                 C   s   | j |d|dS )NZflvr&  r'  r(  r!   r!   r"   from_flv  s    zAudioSegment.from_flvc                 C   s   | j |d|dS )Nrc   r&  r'  r(  r!   r!   r"   from_ogg"  s    zAudioSegment.from_oggc                 C   s   | j |d|dS )Nr6   r&  r'  r(  r!   r!   r"   from_wav&  s    zAudioSegment.from_wavc                 K   s    | j |d|d |d |d dS )Nr   rd   re   r>   )rd   re   r>   r'  )r`   r  r   r!   r!   r"   from_raw*  s    zAudioSegment.from_rawc                 C   s6   t |ddd\}}|d | |d}|r2|  |S )Nr   Fr   r   r   )r   r   r  )r`   r  r  r&   r!   r!   r"   r  /  s    

zAudioSegment._from_safe_wavr!  4c	              
   C   sR  ddg}	|dkr(|dk	s |dk	r(t dt|d\}}
|d |dkrb|| j |d |S |dkox|dkox|dk}|r|}ntd	d
d}| j}| jdkrt| jdd}t	
|d	}|| j || j || j |t|   || |  |r|d |S tdd
d}| jdddd|jg}|dkrP| j|d}|dk	r| dr|dkr|d|ddddddg nt d|dk	r|d|g |dk	r|d|g |dk	r|| |dk	rTt|tstdnX| D ] \}}|dd ||g q|dkrT||	krFt!d|	 |d |g t"j#d!krx|dkrx|d"dg |d||jg t$| t
t%j&d#}t'j(||t'j)t'j)d$}W 5 Q R X |* \}}t+| t+| |j,dkrt-d% |j,||j.d&d'|d ||/  |  |  t%0|j t%0|j |d |S )(aw  
        Export an AudioSegment to a file with given options

        out_f (string):
            Path to destination audio file. Also accepts os.PathLike objects on
            python >= 3.6

        format (string)
            Format for destination audio file.
            ('mp3', 'wav', 'raw', 'ogg' or other ffmpeg/avconv supported files)

        codec (string)
            Codec used to encode the destination file.

        bitrate (string)
            Bitrate used when encoding destination file. (64, 92, 128, 256, 312k...)
            Each codec accepts different bitrate arguments so take a look at the
            ffmpeg documentation for details (bitrate usually shown as -b, -ba or
            -a:b).

        parameters (list of strings)
            Aditional ffmpeg/avconv parameters

        tags (dict)
            Set metadata information to destination files
            usually used as tags. ({title='Song Title', artist='Song Artist'})

        id3v2_version (string)
            Set ID3v2 version for tags. (default: '4')

        cover (file)
            Set cover for audio file from image file. (png or jpg)
        3r.  r   NzCan not invoke ffmpeg when export format is "raw"; specify an ffmpeg raw format like format="s16le" instead or call export(format="raw") with no codec or parameterszwb+r   r6   r   Fr   r      zw+br   r   r   )z.pngz.jpgz.jpegz.bmpz.tifz.tiffr!  z-map01z-c:vZmjpegzxCurrently cover images are only supported by MP3 files. The allowed image formats are: .tif, .jpg, .bmp, .jpeg and .png.r   z-b:azTags must be a dictionary.z	-metadataz{0}={1}z/id3v2_version not allowed, allowed versions: %sz-id3v2_versiondarwinz-write_xingr   r   zcEncoding failed. ffmpeg/avlib returned error code: {0}

Command:{1}

Output from ffmpeg/avlib:

{2}r   r   )1r(   r   r   r   rt   r   rd   r   r|   r7   r  Zsetnchannelsr>   ZsetsampwidthZsetframeratere   Z
setnframesr}   r   Zwriteframesrawr  r^   r  DEFAULT_CODECSru   r   r   r  r,   dictr   rv   r   r   sysplatformr   r  r	  r
  r  r  r  r   r  r   r  rz   r  )r    Zout_fr   r  Zbitrater  tagsZid3v2_versionZcoverZid3v2_allowed_versions_Zeasy_wavrL   Zpcm_for_wavZ	wave_datar  r  keyr)   r	  r  r  r  r!   r!   r"   export8  s    #




   









      


zAudioSegment.exportc                 C   s"   || j  }|| j  }| j|| S r   )rs   rt   )r    indexZframe_startZ	frame_endr!   r!   r"   	get_frame  s    

zAudioSegment.get_framec                 C   s.   |dk	r|| j d  S tt| j| j S dS )z
        returns the number of frames for the given number of milliseconds, or
            if not specified, the number of frames in the whole AudioSegment
        Nr   )re   r   rH   rt   rs   )r    r   r!   r!   r"   r     s    zAudioSegment.frame_countc                 C   s:   || j kr| S | j| }| jt| j| j |||ddS )N)rd   rs   r   )rd   r>   r   r   Zlin2linrt   )r    rd   rs   r!   r!   r"   r     s    

zAudioSegment.set_sample_widthc                 C   sN   || j kr| S | jr6t| j| j| j| j |d \}}n| j}| j|d|idS )Nre   rL   r   )re   rt   r   Zratecvrd   r>   r   )r    re   	convertedr9  r!   r!   r"   r     s    
  
zAudioSegment.set_frame_ratec                    sN  | j kr S |dkrH j dkrHtj} jd }d}| j j||}n|dkr j dkrtj} jd }d}| j j||}n|dkrdd   D }t 	 }t

|d jd| j  }|D ],}t|D ]}	||	  ||	  j  7  < qqʈ j j  }n4 j dkr2 fddt|D }
tj|
 S td	 j|||d
dS )NrT   r   g      ?c                 S   s   g | ]}|  qS r!   )r   r   r!   r!   r"   rR     s     z-AudioSegment.set_channels.<locals>.<listcomp>r   rj   c                    s   g | ]} qS r!   r!   )rP   ZiChannelr   r!   r"   rR     s     zbAudioSegment.set_channels only supports mono-to-multi channel and multi-to-mono channel conversionr>   rs   r?  )r>   r   tostereors   rt   rd   tomonosplit_to_monor}   r   rn   typecoderanger\   r   rr   r   )r    r>   fnrs   Zfacr@  Zchannels_datar   Zraw_channel_datar   Zdup_channelsr!   r   r"   r     sD    




zAudioSegment.set_channelsc              	   C   s   | j dkr| gS |  }g }t| j D ]Z}||d | j  }z| }W n tk
rb   | }Y nX || j|d| jdd q&|S )Nr   rA  r>  )	r>   r   rF  ro   r(   rp   rK   r   rd   )r    ZsamplesZmono_channelsr   Zsamples_for_current_channelZ	mono_datar!   r!   r"   rD  '  s    
zAudioSegment.split_to_monoc                 C   s   t | j| jS r   )r   rmsrt   rd   r   r!   r!   r"   rH  <  s    zAudioSegment.rmsc                 C   s$   | j }|std S t| j | j S )NZinfinity)rH  r   r   max_possible_amplitude)r    rH  r!   r!   r"   dBFS@  s    
zAudioSegment.dBFSc                 C   s   t | j| jS r   )r   r   rt   rd   r   r!   r!   r"   r   G  s    zAudioSegment.maxc                 C   s   | j d }d| }|d S )NrC   rT   r   )r    bitsZmax_possible_valr!   r!   r"   rI  K  s    
z#AudioSegment.max_possible_amplitudec                 C   s   t | j| jS r   )r   r   rI  r   r!   r!   r"   max_dBFSS  s    zAudioSegment.max_dBFSc                 C   s   | j r|  | j  pdS )Ng        )re   r   r   r!   r!   r"   duration_secondsW  s    zAudioSegment.duration_secondsr   c                 C   sz   d|  krdksn t d| jdkr0| j}n2|dkrNt| j| jdd}nt| j| jdd}tt|| j| j S )z
        Returns a value between -1.0 and 1.0 representing the DC offset of a
        channel (1 for left, 2 for right).
        r   rT   z+channel value must be 1 (left) or 2 (right)r   )	rr   r>   rt   r   rC  rd   r   avgrI  )r    channelrL   r!   r!   r"   get_dc_offset[  s    
zAudioSegment.get_dc_offsetc                    s  |r"d|  krdks"n t d|rDd|  kr:dksDn t d|rZtt| j } fdd} jdkr j| j|d	S t j j	dd
}t j j	d
d}|r|dkr|||}|r|dkr|||}t
| j	dd
}t
| j	d
d} jt|| j	d	S )z
        Removes DC offset of given channel. Calculates offset if it's not given.
        Offset values must be in range -1.0 to 1.0. If channel is None, removes
        DC offset from all available channels.
        r   rT   z1channel value must be None, 1 (left) or 2 (right)g      g      ?z)offset value must be in range -1.0 to 1.0c                    s$   |st |  j}t |  j| S r   )r   rN  rd   r|   )rL   offr   r!   r"   remove_data_dc{  s    z5AudioSegment.remove_dc_offset.<locals>.remove_data_dcr   r   )rr   r}   r   rI  r>   r   rt   r   rC  rd   rB  add)r    rO  offsetrR  Zleft_channelZright_channelr!   r   r"   remove_dc_offsetl  s(    


zAudioSegment.remove_dc_offsetc                 C   s"   | j t| j| jtt|dS Nr   )r   r   r   rt   rd   r   r   )r    volume_changer!   r!   r"   r     s    
zAudioSegment.apply_gainr   Fc                 C   sJ  |r
d}n"|dkrd}n|dkr,|  | jS t }t| |\}}|j}	|j }
||d| j ||d j}|j}d}t|}t|}|r.td|| }||kr|d| }|}d}|r||||  }t	
|| jtt|}|t	|||	 n |t	||||  ||	 ||7 }|d8 }q|||d  |
|dS )a  
        Overlay the provided segment on to this segment starting at the
        specificed position and using the specfied looping beahvior.

        seg (AudioSegment):
            The audio segment to overlay on to this one.

        position (optional int):
            The position to start overlaying the provided segment in to this
            one.

        loop (optional bool):
            Loop seg as many times as necessary to match this segment's length.
            Overrides loops param.

        times (optional int):
            Loop seg the specified number of times or until it matches this
            segment's length. 1 means once, 2 means twice, ... 0 would make the
            call a no-op
        gain_during_overlay (optional int):
            Changes this segment's volume by the specified amount during the
            duration of time that seg is overlaid on top of it. When negative,
            this has the effect of 'ducking' the audio under the overlay.
        rV   Nr   r   r   )r   rt   r   r\   r   rd   r   rH   r   r   r   r   r   rS  )r    r   r:   r   timesZgain_during_overlayr  seg1seg2rd   spawnrM   Zseg1_lenZseg2_len	remainingZseg1_overlaidZseg1_adjusted_gainr!   r!   r"   r     sF    


zAudioSegment.overlayd   c                 C   s  t | |\}}|s&||j|j S |t| krHtd|t| n |t|krhtd|t||| d  jddtdd}||d | jddtdd9 }t	 }|
|d |  j |
|j |
||d  j |d |j|d}|  |S )	Nz@Crossfade is longer than the original AudioSegment ({}ms > {}ms)z@Crossfade is longer than the appended AudioSegment ({}ms > {}ms)r   r   )to_gainr   r   )	from_gainr   r   r   )r\   r   r   rt   rH   rr   r   fader   r   r   r   r  )r    r   r   rY  rZ  Zxfr  r&   r!   r!   r"   rK     s.       
zAudioSegment.appendc                 C   s6  d|||fkrt d|dkr*|dkr*| S |dk	r@tt| |nd}|dk	rZtt| |nd}|dk	rz|dk rz|t| 7 }|dk	r|dk r|t| 7 }|dk	r|dk rtd|r|dk	r|| }q|dk	r|| }n|| }t|}g }| d| j}|dkrt|| j|}|	| t|| }	|dkr|	| }
t
|D ]:}||
|  }| ||  }t|j| j|}|	| qBnt| j|d}| j|d}|| }|	| }
t
t|D ]>}||
|  }| t|| }t|| j|}|	| q| |d j}|dkr t|| jt|}|	| | j|dS )a  
        Fade the volume of this audio segment.

        to_gain (float):
            resulting volume_change in db

        start (int):
            default = beginning of the segment
            when in this segment to start fading in milliseconds

        end (int):
            default = end of the segment
            when in this segment to start fading in milliseconds

        duration (int):
            default = until the end of the audio segment
            the duration of the fade
        NzPOnly two of the three arguments, "start", "end", and "duration" may be specifiedr   z#duration must be a positive integerr]  r   r   )r   r   rH   r   r   rt   r   r   rd   rK   rF  r   r}   r=  r   )r    r_  r`  r   r   r   Z
from_powerr  Zbefore_fadeZ
gain_deltaZ
scale_stepr   rW  chunkZstart_frameZ	end_frameZfade_framessampleZ
after_fader!   r!   r"   ra    sn    






zAudioSegment.fadec                 C   s   | j d|tddS )Nr^  r   )r_  r   r   )ra  r   r    r   r!   r!   r"   fade_out`  s    zAudioSegment.fade_outc                 C   s   | j d|ddS )Nr^  r   )r`  r   r   )ra  rd  r!   r!   r"   fade_inc  s    zAudioSegment.fade_inc                 C   s   | j t| j| jdS rV  )r   r   reversert   rd   r   r!   r!   r"   rg  f  s    zAudioSegment.reversec                 C   s,   d}|   }t| d}|j|dS )Nz
                    <audio controls>
                        <source src="data:audio/mpeg;base64,{base64}" type="audio/mpeg"/>
                        Your browser does not support the audio element.
                    </audio>
                  ascii)base64)r;  ri  	b64encoderz   r  r   )r    srcfhrL   r!   r!   r"   _repr_html_k  s    zAudioSegment._repr_html_)N)N)NN)r   r   )NNNNN)NNNNN)N)N)N)N)Nr!  NNNNr.  N)N)r   )NN)r   FNN)r]  )r   r   NNN)Ar1   r2   r3   __doc__r   r^   r4   ra   r0   r4  r#   propertyrA   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r-   r   r   r   r   r   r  r%  r)  r*  r+  r,  r-  r  r;  r=  r   r   r   r   rD  rH  rJ  r   rI  rL  rM  rP  rU  r   r   rK   ra  re  rf  rg  rm  __classcell__r!   r!   r   r"   r\      s   


 Q


%
	 



  

  
 #

%







&
L
  
br\   )effects)N)9
__future__r   rn   r  r
  r   r   r   r7   r6  rI   Zlogging_utilsr   r   utilsr   r	   ri  collectionsr
   r   ior   	itertoolsr   zipr   r   r   r   r   r   
exceptionsr   r   r   r   r   r   r   version_infor  rx   rF  r   objectr   r4   r   r8   r<   rN   rY   r[   r\    rq  r!   r!   r!   r"   <module>   sd   
 $

 
         h