U
    &d*                     @   s   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 d dl	m
Z
 d dlmZmZ G dd deZeejd	e_G d
d deZG dd deZdd ZdS )    N)tqdm)ffmpeg_audiowrite)Clip)requires_duration)deprecated_version_ofextensions_dictc                
   @   sN   e Zd ZdZdddZedddZedd
dZdddZedddZ	dS )	AudioClipaN   Base class for audio clips.
    
    See ``AudioFileClip`` and ``CompositeSoundClip`` for usable classes.
    
    An AudioClip is a Clip with a ``make_frame``  attribute of
    the form `` t -> [ f_t ]`` for mono sound and
    ``t-> [ f1_t, f2_t ]`` for stereo sound (the arrays are Numpy arrays).
    The `f_t` are floats between -1 and 1. These bounds can be
    trespassed wihtout problems (the program will put the
    sound back into the bounds at conversion time, without much impact). 
    
    Parameters
    -----------
    
    make_frame
      A function `t-> frame at time t`. The frame does not mean much
      for a sound, it is just a float. What 'makes' the sound are
      the variations of that float in the time.
        
    nchannels
      Number of channels (one or two for mono or stereo).
    
    Examples
    ---------
    
    >>> # Plays the note A (a sine wave of frequency 440HZ)
    >>> import numpy as np
    >>> make_frame = lambda t: 2*[ np.sin(440 * 2 * np.pi * t) ]
    >>> clip = AudioClip(make_frame, duration=5)
    >>> clip.preview()
                     
    Nc                 C   sh   t |  |d k	r|| _|d k	rP|| _| d}t|drJtt|| _nd| _|d k	rd|| _	|| _
d S )Nr   __iter__   )r   __init__fps
make_frame	get_framehasattrlenlist	nchannelsdurationend)selfr   r   r   Zframe0 r   ;/tmp/pip-unpacked-wheel-0k2etfqj/moviepy/audio/AudioClip.pyr   /   s    


zAudioClip.__init__F   c                 c   s   |dkr| j }t|}|dk	r,t|| }t|| j }|| d }tjd||d dtd}	|jtt	|dD ]Z}
|	|
d  |	|
  }||kst
d| t|	|
 |	|
d   }| j|||||dV  qrdS )	zK Iterator that returns the whole sound array of the clip by chunks
        Nr
   r   T)ZendpointZdtype)chunk      ?)nbytesquantizer   
buffersize)r   proglogZdefault_bar_loggerintr   npZlinspaceZiter_barr   rangeAssertionErrorarangeto_soundarray)r   	chunksizeZchunk_durationr   r   r   loggerZ	totalsizeZnchunksZposposisizettr   r   r   iter_chunks@   s     
 
 zAudioClip.iter_chunksP  c           
      C   s   |dkr| j }| jdkrtjntj}d| | }|dkrl| j|krX|| j||d|dS td| jd| }| |}|rt	dt
d|}dd	d
d| }	dd| d  | |	}|S )a  
        Transforms the sound into an array that can be played by pygame
        or written in a wav file. See ``AudioClip.preview``.
        
        Parameters
        ------------
        
        fps
          Frame rate of the sound for the conversion.
          44100 for top quality.
        
        nbytes
          Number of bytes to encode the sound: 1 for 8bit sound,
          2 for 16bit, 4 for 32bit sound.
          
        Nr   r   )r   r   r   r%   r   gGzgGz?Zint8Zint16Zint32)r
   r         r
   )r   r   r    ZvstackZhstackr   r*   r#   r   maximumZminimumastype)
r   r)   r   r   r   r   ZstackerZmax_durationZ	snd_arrayZinttyper   r   r   r$   X   s"    

 
zAudioClip.to_soundarrayc                 C   sj   |o| j dk}|r tddgnd}| j||dD ]2}|rRt|t|jddnt|t| }q2|S )Nr   r   )r%   r&   )Zaxis)r   r    arrayr*   r.   absmax)r   Zstereor%   r&   Zmaxir   r   r   r   
max_volume   s
    0zAudioClip.max_volume  Tbarc                 C   s   |s| j sd}n| j }|dkrptjtj|\}}zt|dd  d d }W n tk
rn   tdY nX t| ||||||||	||
dS )a,   Writes an audio file from the AudioClip.


        Parameters
        -----------

        filename
          Name of the output file

        fps
          Frames per second. If not set, it will try default to self.fps if
          already set, otherwise it will default to 44100

        nbytes
          Sample width (set to 2 for 16-bit sound, 4 for 32-bit sound)

        codec
          Which audio codec should be used. If None provided, the codec is
          determined based on the extension of the filename. Choose
          'pcm_s16le' for 16-bit wav and 'pcm_s32le' for 32-bit wav.

        bitrate
          Audio bitrate, given as a string like '50k', '500k', '3000k'.
          Will determine the size and quality of the output file.
          Note that it mainly an indicative goal, the bitrate won't
          necessarily be the this in the output file.

        ffmpeg_params
          Any additional parameters you would like to pass, as a list
          of terms, like ['-option1', 'value1', '-option2', 'value2']

        write_logfile
          If true, produces a detailed logfile named filename + '.log'
          when writing the file

        verbose
          Boolean indicating whether to print infomation
          
        logger
          Either 'bar' or None or any Proglog logger

        iD  Nr
   codecr   zoMoviePy couldn't find the codec associated with the filename. Provide the 'codec' parameter in write_audiofile.)r6   bitratewrite_logfileverboseffmpeg_paramsr&   )	r   ospathsplitextbasenamer   KeyError
ValueErrorr   )r   filenamer   r   r   r6   r7   r:   r8   r9   r&   nameextr   r   r   write_audiofile   s$    .  zAudioClip.write_audiofile)NNN)NNNFr   N)NNFr   r+   )Fr+   N)	Nr   r4   NNNFTr5   )
__name__
__module____qualname____doc__r   r   r*   r$   r3   rD   r   r   r   r   r      s(   !
      /
	           r   to_audiofilec                   @   s   e Zd ZdZdd ZdS )AudioArrayClipa(  
    
    An audio clip made from a sound array.
    
    Parameters
    -----------
    
    array
      A Numpy array representing the sound, of size Nx1 for mono,
      Nx2 for stereo.
       
    fps
      Frames per second : speed at which the sound is supposed to be
      played.
    
    c                    sR   t   | _| _dt| |  _ fdd}| _tt d _	d S )Nr   c                    s   t | tjrZ j|  t}|dk|t jk @ }tt| df} j||  ||< |S t j|  }|dk s~|t jkrd jd  S  j| S dS )zc complicated, but must be able to handle the case where t
            is a list of the form sin(t) r   r   N)	
isinstancer    ndarrayr   r/   r   r   r0   zeros)tZ
array_indsZin_arrayresultr'   r   r   r   r      s    z+AudioArrayClip.__init__.<locals>.make_framer   )
r   r   r0   r   r   r   r   r   r   r   )r   r0   r   r   r   rP   r   r      s    
zAudioArrayClip.__init__NrE   rF   rG   rH   r   r   r   r   r   rJ      s   rJ   c                   @   s   e Zd ZdZdd ZdS )CompositeAudioClipay   Clip made by composing several AudioClips.
    
    An audio clip made by putting together several audio clips.
    
    Parameters
    ------------
    
    clips
      List of audio clips, which may start playing at different times or
      together. If all have their ``duration`` attribute set, the
      duration of the composite clip is computed automatically.
    
    c                    sr   t   | _dd  jD }tdd  jD  _tdd |D s\t| _t| _ fdd}| _d S )Nc                 S   s   g | ]
}|j qS r   )r   .0cr   r   r   
<listcomp>  s     z/CompositeAudioClip.__init__.<locals>.<listcomp>c                 S   s   g | ]
}|j qS r   )r   rS   r   r   r   rV     s     c                 S   s   g | ]}|d kqS )Nr   )rT   er   r   r   rV      s     c                    sh    fddj D } fddtj |D }t tjrPtt jf}ntj}|t| S )Nc                    s   g | ]}|  qS r   )Z
is_playingrS   rN   r   r   rV   &  s     zCCompositeAudioClip.__init__.<locals>.make_frame.<locals>.<listcomp>c                    s6   g | ].\}}|d k	r|  |j t|gj qS )F)r   startr    r0   T)rT   rU   partrX   r   r   rV   (  s   )	clipsziprK   r    rL   rM   r   r   sum)rN   Zplayed_partsZsoundsZzerorP   rX   r   r   $  s    

z/CompositeAudioClip.__init__.<locals>.make_frame)	r   r   r\   r2   r   anyr   r   r   )r   r\   Zendsr   r   rP   r   r     s    


zCompositeAudioClip.__init__NrQ   r   r   r   r   rR   	  s   rR   c                 C   sh   dd | D }t dg| }dd t| |D }t||d }dd | D }|r^t|nd|_|S )zK
    The clip with the highest FPS will be the FPS of the result clip.
    c                 S   s   g | ]
}|j qS r   )r   rS   r   r   r   rV   ;  s     z*concatenate_audioclips.<locals>.<listcomp>r   c                 S   s   g | ]\}}| |qS r   )Z	set_start)rT   rU   rN   r   r   r   rV   =  s     c                 S   s   g | ]}t |d dr|jqS )r   N)getattrr   rS   r   r   r   rV   A  s      N)r    Zcumsumr]   rR   Zset_durationr2   r   )r\   Z	durationsr)   ZnewclipsrO   Zfpssr   r   r   concatenate_audioclips7  s    rb   )r;   Znumpyr    r   r   Z#moviepy.audio.io.ffmpeg_audiowriterr   Zmoviepy.Clipr   Zmoviepy.decoratorsr   Zmoviepy.toolsr   r   r   rD   rI   rJ   rR   rb   r   r   r   r   <module>   s    J..