o
    iZs                     @  s  d dl mZ d dlZd dlZd dlZd dlZd dl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mZmZ G dd dejZG dd dejZG d	d
 d
ejZd=ddZG dd dejZG dd dejZG dd dejZG dd dejZG dd dejZG dd dejZd>ddZd?d!d"ZG d#d$ d$ejZG d%d& d&ejZ G d'd( d(ejZ!G d)d* d*ejZ"G d+d, d,ejZ#d-d. Z$G d/d0 d0ejZ%G d1d2 d2ejZ&G d3d4 d4ejZ'G d5d6 d6ejZ(G d7d8 d8ejZ)G d9d: d:eZ*d@d;d<Z+dS )A    )annotationsN)override)ComfyExtensionIOUIc                   @  *   e Zd Zedd ZedddZeZdS )	EmptyLatentAudioc                 C  sF   t jddddt jjddddd	d
t jjddddddgt j gdS )Nr   zEmpty Latent Audiolatent/audioAudiosecondsgG@      ?     @@皙?defaultminmaxstep
batch_size   i   z)The number of latent images in the batch.r   r   r   tooltip)node_iddisplay_namecategoryessentials_categoryinputsoutputs)r   SchemaFloatInputIntLatentOutputcls r&   6/mnt/c/Users/fbmor/ComfyUI/comfy_extras/nodes_audio.pydefine_schema   s   

zEmptyLatentAudio.define_schemareturnIO.NodeOutputc                 C  sB   t |d d d d }tj|d|gtj d}t|ddS )ND  i      @   )deviceaudio)samplestype)roundtorchzeroscomfymodel_managementintermediate_devicer   
NodeOutput)r%   r   r   lengthlatentr&   r&   r'   execute    s   zEmptyLatentAudio.executeNr)   r*   )__name__
__module____qualname__classmethodr(   r;   generater&   r&   r&   r'   r      s    
r   c                   @  r   )	ConditioningStableAudioc                 C  sf   t jddt jdt jdt jjdddddd	t jjd
ddddd	gt jjddt jjddgdS )NrB   conditioningpositivenegativeseconds_start        r   r   r   seconds_totalg     G@r   )r   r   r   r   )r   r   Conditioningr    r   r#   r$   r&   r&   r'   r(   *   s   

z%ConditioningStableAudio.define_schemar)   r*   c                 C  s0   t |||d}t |||d}t||S )N)rF   rH   )node_helpersconditioning_set_valuesr   r8   )r%   rD   rE   rF   rH   r&   r&   r'   r;   ;   s   zConditioningStableAudio.executeNr<   )r=   r>   r?   r@   r(   r;   appendr&   r&   r&   r'   rB   )   s    
rB   c                   @  r   )	VAEEncodeAudioc              	   C  4   t jddgddt jdt jdgt j gdS )NrN   zaudio to latentzVAE Encode Audior	   r/   vaer   search_aliasesr   r   r   r   )r   r   r
   r    Vaer"   r#   r$   r&   r&   r'   r(   E      


zVAEEncodeAudio.define_schemar)   r*   c                 C  sZ   |d }t |dd}||krtj|d ||}n|d }||dd}td|iS )Nsample_rateaudio_sample_rater+   waveformr   r0   )getattr
torchaudio
functionalresampleencodemovedimr   r8   )r%   rP   r/   rU   vae_sample_raterW   tr&   r&   r'   r;   S   s   zVAEEncodeAudio.executeNr<   )r=   r>   r?   r@   r(   r;   r]   r&   r&   r&   r'   rN   D   s    
rN   c                 C  s   |d ur| j |d |||ddd}n| |d dd}tj|ddgddd }d	||d	k < || }t| d
d}|d|vrD|dS |d dS )Nr0   )tile_xtile_yoverlaprX   r   r,   T)dimkeepdimg      @r   rV   r+   rU   rW   rU   )decode_tiledr^   decoder3   stdrY   )rP   r0   tilerc   r/   ri   r_   r&   r&   r'   vae_decode_audiob   s    rk   c                   @  r   )	VAEDecodeAudioc              	   C  rO   )Nrl   latent to audiozVAE Decode Audior	   r0   rP   rQ   )r   r   r"   r    rS   r
   r#   r$   r&   r&   r'   r(   p   rT   zVAEDecodeAudio.define_schemar)   r*   c                 C  s   t t||S Nr   r8   rk   )r%   rP   r0   r&   r&   r'   r;   ~   s   zVAEDecodeAudio.executeNr<   )r=   r>   r?   r@   r(   r;   rh   r&   r&   r&   r'   rl   o       
rl   c                   @  &   e Zd Zedd ZedddZdS )	VAEDecodeAudioTiledc                 C  s\   t jddgddt jdt jdt jjddd	d
ddt jjddddddgt j gdS )Nrr   rm   zVAE Decode Audio (Tiled)r	   r0   rP   	tile_sizei       i       r   rc   r-   r   i   rQ   )r   r   r"   r    rS   r!   r
   r#   r$   r&   r&   r'   r(      s   


z!VAEDecodeAudioTiled.define_schemar)   r*   c                 C  s   t t||||S rn   ro   )r%   rP   r0   rs   rc   r&   r&   r'   r;      s   zVAEDecodeAudioTiled.executeNr<   r=   r>   r?   r@   r(   r;   r&   r&   r&   r'   rr      
    
rr   c                   @  s,   e Zd Zedd Zed
dddZeZd	S )	SaveAudioc                 C  s@   t jddgdddt jdt jjdddgt jjt jjgd	d
S )Nrx   zexport flaczSave Audio (FLAC)r/   r
   filename_prefixaudio/ComfyUIr   Tr   rR   r   r   r   r   hiddenis_output_node)r   r   r
   r    StringHiddenpromptextra_pnginfor$   r&   r&   r'   r(      s   
zSaveAudio.define_schemaComfyUIflacr)   r*   c                 C  s   t jtjj||| |ddS )N)ry   r%   formatuir   r8   r   AudioSaveHelperget_save_audio_ui)r%   r/   ry   r   r&   r&   r'   r;      s   zSaveAudio.executeN)r   r   r<   r=   r>   r?   r@   r(   r;   	save_flacr&   r&   r&   r'   rx      s    
rx   c                   @  ,   e Zd Zedd Zedddd	ZeZd
S )SaveAudioMP3c                 C  sT   t jddgdddt jdt jjdddt jjd	g d
ddgt jjt jjgddS )Nr   z
export mp3zSave Audio (MP3)r/   r
   ry   rz   r{   quality)V0128k320kr   optionsr   Tr|   	r   r   r
   r    r   Combor   r   r   r$   r&   r&   r'   r(      s   
zSaveAudioMP3.define_schemar   mp3r   r)   r*   c                 C     t jtjj||| ||ddS N)ry   r%   r   r   r   r   r%   r/   ry   r   r   r&   r&   r'   r;      
   
zSaveAudioMP3.executeN)r   r   r   r<   )r=   r>   r?   r@   r(   r;   save_mp3r&   r&   r&   r'   r      s    
r   c                   @  r   )SaveAudioOpusc                 C  sR   t jddgddt jdt jjdddt jjdg d	d
dgt jjt jjgddS )Nr   zexport opuszSave Audio (Opus)r/   ry   rz   r{   r   )64k96kr   192kr   r   r   Tr   rR   r   r   r   r}   r~   r   r$   r&   r&   r'   r(      s   
zSaveAudioOpus.define_schemar   opusV3r)   r*   c                 C  r   r   r   r   r&   r&   r'   r;      r   zSaveAudioOpus.executeN)r   r   r   r<   )r=   r>   r?   r@   r(   r;   	save_opusr&   r&   r&   r'   r      s    
r   c                   @  r   )	PreviewAudioc              	   C  s0   t jddgddt jdgt jjt jjgddS )Nr   z
play audiozPreview Audior/   Tr   )r   r   r
   r    r   r   r   r$   r&   r&   r'   r(      s   
zPreviewAudio.define_schemar)   r*   c                 C  s   t jtj|| ddS )Nr$   r   )r   r8   r   r   r%   r/   r&   r&   r'   r;      s   zPreviewAudio.executeNr<   r   r&   r&   r&   r'   r      rp   r   wavtorch.Tensorr)   c                 C  sL   | j jr| S | j tjkr|  d S | j tjkr|  d S td| j  )z*Convert audio to float 32 bits PCM format.i   l        zUnsupported wav dtype: )dtypeis_floating_pointr3   int16floatint32
ValueError)r   r&   r&   r'   f32_pcm  s   r   filepathstrtuple[torch.Tensor, int]c           
      C  s   t | b}|jjstd|jjd }|jj}|j}g }d}|j|j	dD ]$}t
| }|jd |kr>|d| }|| ||jd 7 }q&|sQtdt
j|dd}	t|	}	|	|fW  d    S 1 sjw   Y  d S )Nz"No audio stream found in the file.r   )streamsrX   r   zNo audio frames decoded.rd   )avopenr   r/   r   codec_contextrU   channelsrh   indexr3   
from_numpy
to_ndarrayshapeviewr`   rM   catr   )
r   afstreamsr
n_channelsframesr9   framebufr   r&   r&   r'   load  s(   
$r   c                   @  sB   e Zd Zedd ZedddZedd Zed	d
 ZeZdS )	LoadAudioc                 C  sZ   t  }t t|ddg}tjdg ddddtjjdtj	j
t|dgtj gdS )	Nr/   videor   )zimport audioz
open audioz
audio filez
Load Audior
   )uploadr   )r   rR   r   r   r   r   r   )folder_pathsget_input_directoryfilter_files_content_typesoslistdirr   r   r   r    
UploadTyper/   sortedr
   r#   )r%   	input_dirfilesr&   r&   r'   r(   )  s   
zLoadAudio.define_schemar)   r*   c                 C  0   t |}t|\}}|d|d}t|S Nr   rf   r   get_annotated_filepathr   	unsqueezer   r8   r%   r/   
audio_pathrW   rU   r&   r&   r'   r;   9  s   

zLoadAudio.executec                 C  sV   t |}t }t|d}||  W d    n1 s w   Y  |  S )Nrb)	r   r   hashlibsha256r   updatereaddigesthex)r%   r/   
image_pathmfr&   r&   r'   fingerprint_inputs@  s   
zLoadAudio.fingerprint_inputsc                 C  s   t |s
d|S dS )NzInvalid audio file: {}T)r   exists_annotated_filepathr   r   r&   r&   r'   validate_inputsH  s   

zLoadAudio.validate_inputsNr<   )	r=   r>   r?   r@   r(   r;   r   r   r   r&   r&   r&   r'   r   (  s    


r   c                   @  r   )	RecordAudioc                 C  s0   t jdg dddt ddgt j gdS )Nr   )zmicrophone inputzaudio capturezvoice inputzRecord Audior/   AUDIO_RECORDrQ   )r   r   Customr    r
   r#   r$   r&   r&   r'   r(   R  s   
zRecordAudio.define_schemar)   r*   c                 C  r   r   r   r   r&   r&   r'   r;   _  s   

zRecordAudio.executeNr<   )r=   r>   r?   r@   r(   r;   r   r&   r&   r&   r'   r   Q  s    
r   c                   @  r   )	TrimAudioDurationc                 C  sX   t jdg ddddt jdt jjdddd	d
ddt jjdddd
ddgt j gdS )Nr   )z	cut audioz
audio clipzshorten audiozTrim Audio Durationz)Trim audio tensor into chosen time range.r/   start_indexrG   l     {Gz?zTStart time in seconds, can be negative to count from the end (supports sub-seconds).r   r   r   r   r   duration      N@zDuration in seconds)r   r   r   r   r   rR   r   descriptionr   r   r   )r   r   r
   r    r   r#   r$   r&   r&   r'   r(   k  s2   

zTrimAudioDuration.define_schemar)   r*   c           	      C  s   |d }|d }|j d }|dk r|tt||  }ntt|| }tdt||d }|tt||  }tdt||}||krHtdt|d||f |dS )	NrW   rU   rX   r   r   zPAudioTrim: Start time must be less than end time and be within the audio length..rf   )r   intr2   r   r   r   r   r8   )	r%   r/   r   r   rW   rU   audio_lengthstart_frame	end_framer&   r&   r'   r;     s   
zTrimAudioDuration.executeNr<   )r=   r>   r?   r@   r(   r;   trimr&   r&   r&   r'   r   j  s    
r   c                   @  r   )	SplitAudioChannelsc                 C  s<   t jddgdddt jdgt jjddt jjddgd	S )
Nr   zstereo to monozSplit Audio Channelsz1Separates the audio into left and right channels.r/   leftrI   rightr   r   r   r
   r    r#   r$   r&   r&   r'   r(     s   
z SplitAudioChannels.define_schemar)   r*   c                 C  sj   |d }|d }|j d dkrtd|dddd d f }|dddd d f }t||d||dS )	NrW   rU   r   r,   z-AudioSplit: Input audio has only one channel..r   rf   )r   r   r   r8   )r%   r/   rW   rU   left_channelright_channelr&   r&   r'   r;     s   zSplitAudioChannels.executeNr<   )r=   r>   r?   r@   r(   r;   separater&   r&   r&   r'   r     s    
r   c                   @  rq   )	JoinAudioChannelsc              	   C  s6   t jddddt jdt jdgt jjddgdS )	Nr   zJoin Audio Channelsz=Joins left and right mono audio channels into a stereo audio.r/   
audio_leftaudio_rightrI   )r   r   r   r   r   r   r   r$   r&   r&   r'   r(     s   

zJoinAudioChannels.define_schemar)   r*   c                 C  s,  |d }|d }|d }|d }|j d dks|j d dkr"tdt||||\}}}|j d }|j d }	||	krot||	}
||
krWtd| d|
 d |d	d |
f }|	|
krotd
|	 d|
 d |d	d |
f }|d	ddd d f }|d	ddd d f }tj||gdd}t	||dS )NrW   rU   r   z*AudioJoin: Both input audios must be mono.rX   z.JoinAudioChannels: Trimming left channel from  to z	 samples..z/JoinAudioChannels: Trimming right channel from r   r   rf   )
r   r   match_audio_sample_ratesr   logginginfor3   r   r   r8   )r%   r   r  waveform_leftsample_rate_leftwaveform_rightsample_rate_rightoutput_sample_ratelength_leftlength_right
min_lengthr   r   stereo_waveformr&   r&   r'   r;     s.   



zJoinAudioChannels.executeNr<   rv   r&   r&   r&   r'   r     rw   r   c                 C  sz   ||kr6||krt j|||}|}td| d| d nt j| ||} |}td| d| d n|}| ||fS )NzResampling audio2 from zHz to zHz for merging.zResampling audio1 from )rZ   r[   r\   r  r  )
waveform_1sample_rate_1
waveform_2sample_rate_2r
  r&   r&   r'   r    s   
r  c                   @  r   )	AudioConcatc                 C  sN   t jdg ddddt jdt jdt jjdd	d
gd	ddgt j gdS )Nr  )z
join audiozcombine audiozappend audiozAudio Concatz=Concatenates the audio1 to audio2 in the specified direction.r/   audio1audio2	directionafterbeforez0Whether to append audio2 after or before audio1.)r   r   r   r   r   r   r
   r    r   r#   r$   r&   r&   r'   r(     s"   



zAudioConcat.define_schemar)   r*   c           
      C  s   |d }|d }|d }|d }|j d dkr#|ddd}td |j d dkr6|ddd}td t||||\}}}|dkrNtj||fdd}	n|d	kr[tj||fdd}	t|	|d
S )NrW   rU   r   r,   zHAudioConcat: Converted mono audio1 to stereo by duplicating the channel.zHAudioConcat: Converted mono audio2 to stereo by duplicating the channel.r  r   r  rf   )	r   repeatr  r  r  r3   r   r   r8   )
r%   r  r  r  r  r  r  r  r
  concatenated_audior&   r&   r'   r;     s    

zAudioConcat.executeNr<   )r=   r>   r?   r@   r(   r;   concatr&   r&   r&   r'   r    s    
r  c                   @  r   )	
AudioMergec                 C  sL   t jdg ddddt jdt jdt jjdg d	d
dgt j gdS )Nr  )z	mix audiozoverlay audiozlayer audiozAudio Mergez7Combine two audio tracks by overlaying their waveforms.r/   r  r  merge_method)addmeansubtractmultiplyz/The method used to combine the audio waveforms.)r   r   r   r  r$   r&   r&   r'   r(   5  s    


	zAudioMerge.define_schemar)   r*   c                 C  sL  |d }|d }|d }|d }t ||||\}}}|jd }	|jd }
|
|	kr=td|
 d|	 d |dd |	f }n.|
|	k rktd|
 d|	 d t|j}|	|
 |d< tj||j|jd	}tj	||fdd
}|dkrt|| }n|dkr}|| }n|dkr|| }n
|dkr|| d }|
  }|dkr|| }t||dS )NrW   rU   rX   z!AudioMerge: Trimming audio2 from r  z  samples to match audio1 length..z AudioMerge: Padding audio2 from )r   r.   r   r  r!  r"  r   r,   r   rf   )r  r   r  r  listr3   r4   r   r.   r   absr   r   r8   )r%   r  r  r  r  r  r  r  r
  length_1length_2	pad_shape
pad_tensorrW   max_valr&   r&   r'   r;   I  s8   





zAudioMerge.executeNr<   )r=   r>   r?   r@   r(   r;   merger&   r&   r&   r'   r  4  s    
$r  c                   @  r   )	AudioAdjustVolumec                 C  s@   t jdg dddt jdt jjddddd	d
gt j gdS )Nr+  )z
audio gainloudnesszaudio levelzAudio Adjust Volumer/   volumer   id   zNVolume adjustment in decibels (dB). 0 = no change, +6 = double, -6 = half, etcr   rQ   )r   r   r
   r    r!   r#   r$   r&   r&   r'   r(   r  s    


zAudioAdjustVolume.define_schemar)   r*   c                 C  sF   |dkr	t |S |d }|d }d|d  }|| }t ||dS )Nr   rW   rU   
      rf   )r   r8   )r%   r/   r-  rW   rU   gainr&   r&   r'   r;     s   
zAudioAdjustVolume.executeNr<   )r=   r>   r?   r@   r(   r;   adjust_volumer&   r&   r&   r'   r+  q  s    
r+  c                   @  r   )	
EmptyAudioc                 C  sb   t jddgddt jjddddd	d
dt jjdddddddt jjdddddddgt j gdS )Nr3  zblank audiozEmpty Audior/   r   r   rG   r   r   z+Duration of the empty audio clip in secondsr   rU   r+   z$Sample rate of the empty audio clip.r   i  T)r   r   r   r   advancedr   r,   z4Number of audio channels (1 for mono, 2 for stereo).)r   r   r   r   r4  rQ   )r   r   r   r    r!   r
   r#   r$   r&   r&   r'   r(     s@   
zEmptyAudio.define_schemar)   r*   c                 C  s6   t t|| }tjd||ftjd}t||dS )Nr   )r   rf   )r   r2   r3   r4   float32r   r8   )r%   r   rU   r   num_samplesrW   r&   r&   r'   r;     s   zEmptyAudio.executeNr<   )r=   r>   r?   r@   r(   r;   create_empty_audior&   r&   r&   r'   r3    s    
#r3  c                   @  rq   )	AudioEqualizer3Bandc                 C  s   t jdg ddddt jdt jjdddd	d
ddt jjddddddt jjdddd	d
ddt jjddddddt jjddd
dd
ddt jjdddd	d
ddt jjd d!dd"d#dgt j gd$S )%Nr8  )eqz
bass boostztreble boost	equalizerzAudio Equalizer (3-Band)r/   Tlow_gain_dBrG   g      8g      8@r   zGain for Low frequencies (Bass)r   low_freqr.  r0  i  zCutoff frequency for Low shelfr   mid_gain_dBzGain for Mid frequenciesmid_freqi     i  zCenter frequency for Midsmid_q9v?g      $@zQ factor (bandwidth) for Midshigh_gain_dBz"Gain for High frequencies (Treble)	high_freqi  i:  zCutoff frequency for High shelf)r   rR   r   r   is_experimentalr   r   )r   r   r
   r    r   r!   r#   r$   r&   r&   r'   r(     s"   


z!AudioEqualizer3Band.define_schemar)   r*   c	                 C  s   |d }	|d }
|	  }|dkrtjj||
|t|dd}|dkr.tjj||
t|||d}|dkr?tjj||
|t|dd}t||
dS )NrW   rU   r   rA  )r1  central_freqQ)center_freqr1  rF  rf   )	clonerZ   r[   bass_biquadr   equalizer_biquadtreble_biquadr   r8   )r%   r/   r;  r<  r=  r>  r@  rB  rC  rW   rU   eq_waveformr&   r&   r'   r;     s8   		zAudioEqualizer3Band.executeNr<   rv   r&   r&   r&   r'   r8    s
    
r8  c                   @  s   e Zd ZedddZdS )AudioExtensionr)   list[type[IO.ComfyNode]]c                   s,   t ttttttttt	t
ttttttttgS rn   )r   rN   rl   rr   rx   r   r   r   r   rB   r   r   r   r   r  r  r+  r3  r8  )selfr&   r&   r'   get_node_list  s*   zAudioExtension.get_node_listN)r)   rN  )r=   r>   r?   r   rP  r&   r&   r&   r'   rM     s    rM  c                     s   t  S rn   )rM  r&   r&   r&   r'   comfy_entrypoint  s   rQ  )NN)r   r   r)   r   )r   r   r)   r   )r)   rM  ),
__future__r   r   rZ   r3   comfy.model_managementr5   r   r   r   rK   r  typing_extensionsr   comfy_api.latestr   r   r   	ComfyNoder   rB   rN   rk   rl   rr   rx   r   r   r   r   r   r   r   r   r   r   r  r  r  r+  r3  r8  rM  rQ  r&   r&   r&   r'   <module>   sJ    



)5!50=$.=