
    W|h6                         S r SSKrSSKrSSKrSSKrSSKJr  SSKJ	r	  SSK
Jr  SSKJrJr  SSKJr   " S S	\5      r " S
 S\5      r " S S\5      rS rg)zImplements AudioClip (base class for audio clips) and its main subclasses:

- Audio clips: AudioClip, AudioFileClip, AudioArrayClip
- Composition: CompositeAudioClip
    N)ffmpeg_audiowriteffplay_audiopreview)Clip)convert_path_to_stringrequires_duration)extensions_dictc                      ^  \ rS rSrSrSU 4S jjr\      SS j5       r\ SS j5       rSS jr	\\
" S5              SS j5       5       r\ SS	 j5       rU 4S
 jrSrU =r$ )	AudioClip   a  Base class for audio clips.

See ``AudioFileClip`` and ``CompositeAudioClip`` for usable classes.

An AudioClip is a Clip with a ``frame_function``  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 without problems (the program will put the
sound back into the bounds at conversion time, without much impact).

Parameters
----------

frame_function
  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.

duration
  Duration of the clip (in seconds). Some clips are infinite, in
  this case their duration will be ``None``.

nchannels
  Number of channels (one or two for mono or stereo).

Examples
--------

.. code:: python

    # Plays the note A in mono (a sine wave of frequency 440 Hz)
    import numpy as np
    frame_function = lambda t: np.sin(440 * 2 * np.pi * t)
    clip = AudioClip(frame_function, duration=5, fps=44100)
    clip.preview()

    # Plays the note A in stereo (two sine waves of frequencies 440 and 880 Hz)
    frame_function = lambda t: np.array([
        np.sin(440 * 2 * np.pi * t),
        np.sin(880 * 2 * np.pi * t)
    ]).T.copy(order="C")
    clip = AudioClip(frame_function, duration=3, fps=44100)
    clip.preview()

c                    > [         TU ]  5         Ub  X0l        UbI  Xl        U R	                  S5      n[        US5      (       a  [        [        U5      5      U l        OSU l        Ub  X l	        X l
        g g )Nr   __iter__   )super__init__fpsframe_function	get_framehasattrlenlist	nchannelsdurationend)selfr   r   r   frame0	__class__s        Q/home/james-whalen/.local/lib/python3.13/site-packages/moviepy/audio/AudioClip.pyr   AudioClip.__init__D   sk    ?H%"0^^A&Fvz**!$T&\!2!"$MH      c           	   #     #    Uc  U R                   n[        R                  " U5      nUb  [        X#-  5      n[        X0R                  -  5      nXq-  S-   n[
        R                  " SXxS-   S[        S9n	UR                  [        [        U5      5      S9 HM  n
XS-      X   -
  nX::  d   eSU-  [
        R                  " X   XS-      5      -  nU R                  XXCUS9v   MO     g7f)	zAIterator that returns the whole sound array of the clip by chunksNr   r   T)endpointdtype)chunk      ?)nbytesquantizer   
buffersize)r   proglogdefault_bar_loggerintr   nplinspaceiter_barr   rangearangeto_soundarray)r   	chunksizechunk_durationr   r'   r&   logger
total_sizenchunks	positionsisizetimingss                r   iter_chunksAudioClip.iter_chunksU   s      ;((C++F3%N01I}},-
)A-KK:{TQTU	tE'N';<AU#il2D$$$SyBIIilI!e<L$MMG$$y %  	 =s   C%C'c                    Uc  Uc  U R                   nSU-  U-  nU R                  U:  aP  U R                  S:X  a  [        R                  O[        R
                  nU" [        U R                  X#SUS95      5      $ [        R                  " SU R                  SU-  5      n U R                  U5      nU(       aR  [        R                  " S[        R                  " SU5      5      nSS	S
S.U   n	SSU-  S-
  -  U-  R                  U	5      nU$ )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.

r      )r   r'   r&   r2   r   r%   gGzgGz?int8int16int32)r   r>         )r   r   r   r,   vstackhstacktupler;   r0   r   maximumminimumastype)
r   ttr   r'   r&   r(   max_durationstacker	snd_arrayinttypes
             r   r1   AudioClip.to_soundarrayt   s   ( :{hhz>C/L}}|+'+~~':"))		(( #qJ )   YYq$--s;	 NN2&	

5"**T9*EFI W9&AGq6zA~.:BB7KIr    c                    U=(       a    U R                   S:  n[        R                  " U R                   5      nU R                  X#S9 H0  n[        R                  " U[        U5      R                  SS95      nM2     U(       a  U$ US   $ )z-Returns the maximum volume level of the clip.r   )r2   r4   r   )axis)r   r,   zerosr;   rG   absmax)r   stereor2   r4   maxir$   s         r   
max_volumeAudioClip.max_volume   sv     .DNNQ. xx'%%	%IE::dCJNNN$:;D J t*47*r    filenamec
                 N   U(       d   [        U S5      (       a  U R                  nOSnUcQ  [        R                  R	                  [        R                  R                  U5      5      u  p [        USS    S   S   n[        U UUUUUUUUU	S9
$ ! [         a    [        S5      ef = f)	a+  Writes an audio file from the AudioClip.


Parameters
----------

filename
  Name of the output file, as a string or a path-like object.

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)

buffersize
  The sound is not generated all at once, but rather made by bunches
  of frames (chunks). ``buffersize`` is the size of such a chunk.
  Try varying it if you meet audio problems (but you shouldn't
  have to). Default to 2000

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

logger
  Either ``"bar"`` for progress bar or ``None`` or any Proglog logger.

r   iD  Nr   codecr   zoMoviePy couldn't find the codec associated with the filename. Provide the 'codec' parameter in write_audiofile.)r[   bitratewrite_logfileffmpeg_paramsr4   )
r   r   ospathsplitextbasenamer	   KeyError
ValueErrorr   )r   rY   r   r&   r(   r[   r\   r^   r]   r4   nameexts               r   write_audiofileAudioClip.write_audiofile   s    v tU##hh=(()9)9()CDID'AB09!< !''
 	
   4 s   *B B$c           	           [        U UUUUUS9  g)a%  
Preview an AudioClip using ffplay

Parameters
----------

fps
    Frame rate of the sound. 44100 gives top quality, but may cause
    problems if your computer is not fast enough and your clip is
    complicated. If the sound jumps during the preview, lower it
    (11025 is still fine, 5000 is tolerable).

buffersize
    The sound is not generated all at once, but rather made by bunches
    of frames (chunks). ``buffersize`` is the size of such a chunk.
    Try varying it if you meet audio problems (but you shouldn't
    have to).

nbytes:
    Number of bytes to encode the sound: 1 for 8bit sound, 2 for
    16bit, 4 for 32bit sound. 2 bytes is fine.

audio_flag, video_flag:
    Instances of class threading events that are used to synchronize
    video and audio during ``VideoClip.preview()``.
)clipr   r(   r&   
audio_flag
video_flagNr   )r   r   r(   r&   rk   rl   s         r   audiopreviewAudioClip.audiopreview  s    < 	!!!	
r    c                 l   > [        U[        5      (       a  [        X/5      $ [        [        U ]  U5      $ N)
isinstancer   concatenate_audioclipsr   __add__)r   otherr   s     r   rs   AudioClip.__add__6  s/    eY'')4-88Y-e44r    )r   r   r   r   r   )NNN)NNNFr>   N)NNFr>   P  )Frv   N)Nr>     NNNFbar)Nrw   r>   NN)__name__
__module____qualname____firstlineno____doc__r   r   r;   r1   rW   r   rg   rm   rs   __static_attributes____classcell__r   s   @r   r   r      s    -^ "   < FK2 2h+ J' U
 ( U
n OS$
 $
L5 5r    r   c                       \ rS rSrSrS rSrg)AudioArrayClipi<  z

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                    ^  [         R                  " T 5        UT l        UT l        S[	        U5      -  U-  T l        U 4S jnUT l        [	        [        T R                  S5      5      5      T l	        g )Nr%   c                   > [        U [        R                  5      (       a  [        R                  " TR                  U -  5      R                  [        5      nUS:  U[        TR                  5      :  -  n[        R                  " [        U 5      S45      nTR                  X      X2'   U$ [        TR                  U -  5      nUS:  d  U[        TR                  5      :  a  STR                  S   -  $ TR                  U   $ )zWComplicated, but must be able to handle the case where t
is a list of the form sin(t).
r   r>   )
rq   r,   ndarrayroundr   rI   r+   r   arrayrR   )t
array_indsin_arrayresultr8   r   s        r   r   /AudioArrayClip.__init__.<locals>.frame_functionT  s     !RZZ((XXdhhl3::3?
&!O
S_0LM3q61+.#'::j.B#C 1%q5ATZZ0tzz!},,::a=(r    r   )
r   r   r   r   r   r   r   r   r   r   )r   r   r   r   s   `   r   r   AudioArrayClip.__init__N  s[    d
c%j(3.	)" -T$.."345r    )r   r   r   r   r   N)ry   rz   r{   r|   r}   r   r~    r    r   r   r   <  s    "6r    r   c                   R   ^  \ rS rSrSrU 4S jr\S 5       r\S 5       rS r	Sr
U =r$ )CompositeAudioClipii  an  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, depends on their ``start`` attributes. If all have their
  ``duration`` attribute set, the duration of the composite clip is
  computed automatically.
c                   > Xl         [        S U R                    5       5      U l        S nU R                   H  nUc    O[        X2=(       d    S5      nM     S nU R                    H`  n[	        US5      (       d  M  [        UR                  [        R                  5      (       d  MA  [        UR                  U=(       d    S5      nMb     [        TU ])  X$S9  g )Nc              3   8   #    U  H  oR                   v   M     g 7frp   )r   .0rj   s     r   	<genexpr>.CompositeAudioClip.__init__.<locals>.<genexpr>z  s     C
^^
   r   r   )r   r   )clipsrT   r   endsr   rq   r   numbersNumberr   r   )r   r   r   r   r   rj   r   s         r   r   CompositeAudioClip.__init__x  s    
C

CC 99C{3A.H  JJDtU##
488W^^(L(L$((CH1-  	(4r    c                 (    S U R                    5       $ )z8Returns starting times for all clips in the composition.c              3   8   #    U  H  oR                   v   M     g 7frp   )startr   s     r   r   ,CompositeAudioClip.starts.<locals>.<genexpr>  s     2zt

zr   r   r   s    r   startsCompositeAudioClip.starts  s     3tzz22r    c                 (    S U R                    5       $ )z6Returns ending times for all clips in the composition.c              3   8   #    U  H  oR                   v   M     g 7frp   )r   r   s     r   r   *CompositeAudioClip.ends.<locals>.<genexpr>  s     0ZTZr   r   r   s    r   r   CompositeAudioClip.ends  s     1TZZ00r    c                 :   U R                    Vs/ s H  o"R                  U5      PM     nn[        U R                   U5       VVs/ s HK  u  p$USLd  M  UR                  XR                  -
  5      [
        R                  " U/5      R                  -  PMM     nnn[        U[
        R                  5      (       a,  [
        R                  " [        U5      U R                  45      nO [
        R                  " U R                  5      nU[        U5      -   $ s  snf s  snnf )z7Renders a frame for the composition for the time ``t``.F)r   
is_playingzipr   r   r,   r   Trq   r   rR   r   r   sum)r   r   rj   played_partspartsoundszeros          r   r   !CompositeAudioClip.frame_function  s    7;zzBzt*zB "$**l;
;
E! @DNN1zz>*RXXtf-=-?-??; 	 
 a$$88SVT^^45D88DNN+Dc&k!! C
s   DDAD)r   r   )ry   rz   r{   r|   r}   r   propertyr   r   r   r~   r   r   s   @r   r   r   i  s?    5& 3 3 1 1" "r    r   c                    [         R                  " S/U  Vs/ s H  oR                  PM     snQ5      n[        XSS 5       VVs/ s H  u  pUR	                  U5      PM     nnn[        U5      R                  US   5      $ s  snf s  snnf )zConcatenates one AudioClip after another, in the order that are passed
to ``clips`` parameter.

Parameters
----------

clips
  List of audio clips, which will be played one after other.
r   N)r,   cumsumr   r   
with_startr   with_duration)r   rj   
starts_endr   newclipss        r   rr   rr     sz     AB5 A545 ABCJ25e_2MN2Mwt"2MHNh'55jnEE !BNs   B
B)r}   r   r_   numpyr,   r)   #moviepy.audio.io.ffmpeg_audiowriterr   &moviepy.audio.io.ffplay_audiopreviewerr   moviepy.Clipr   moviepy.decoratorsr   r   moviepy.toolsr	   r   r   r   rr   r   r    r   <module>r      sV     	   A F  H )e5 e5P	*6Y *6Z;" ;"|Fr    