
    wi                        d 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mZ ddlmZ ddlmZ d%dZd Zd&d
Zd&dZd%dZd Zd'dededefdZdefdZdedej        fdZdej        defdZ dede!fdZ"d(dedee         deej        ef         fdZ#dej        dededdfdZ$	 d(d ej        d!ej        ded"ee         ddf
d#Z%d ej        d!ej        deeef         fd$Z&dS ))z:
Utility functions for audio processing and watermarking.
    N)TupleOptionalDictAny)sqrt)modeTc           	          | j         d         }g }t          d||          D ]l}| |||z            }|rF|j         d         |k     r5t          j        |t          j        ||j         d         z
                      }|                    |           m|S )Nr   )shaperangenpappendzeros)datawindow_lengthpad	n_samplesframesidxchunks          [/root/.openclaw/workspace/chatterbox_venv_py311/lib/python3.11/site-packages/perth/utils.py_signal_to_framesr      s    
2IFQ	=11  S},,- 	R5;r?]22IeRX}u{2/N%P%PQQEeM    c                 *    t          j        |           S N)r   hstack)r   s    r   _frames_to_signalr      s    9Vr      c                     | j         j        dk    s
J d            |dz
  }d|z   d|z  dz
  }}| |z                      ||                              t          j                  S )Nfz)This function takes floating point arrays      )dtypekindclipastyper   int16)wav	bit_depthunsigned_bit_depth	range_min	range_maxs        r   audio_to_rawr-      sr    9>S   "M   "Q"455q=O7PST7TyI)O!!)Y77>>rxHHHr   c                     |dz
  }d|z   d|z  dz
  }}d\  }}|| |z
  ||z
  z  ||z
  z  z                        dd                              t          j                  S )Nr!   r"   )g      g      ?r
   )r%   r&   r   float32)r(   r)   r*   r+   r,   abs          r   raw_pcm16_tofloatr2   $   sx    "Q"455q<N7NQR7RyIDAq#	/a!e,Y1FGGMMbRSTT[[\^\fgggr   c                    t          |           dk    sJ t          j        |           }t          |           |z  r|d t          |           |z            }|r^t          |          |k    rKt          j        t          j        |t          |          |z                      j        }t          |          }|d |         S )Nr   )lenr   arraysplitTflatten_watermark)watermark_listlengthwrap	watermarks       r   formatted_watermarkr=   +   s    ~""""((I >V# @>^!4!4v!=>>?	 1I''HRXiY61IJJKKM	%i00	WfWr   c                 T    t          | d          j                             d          S )Nr!   )axisr
   )r   squeeze)watermark_vectors    r   r8   r8   8   s'     q))).66r:::r         @nkreturnc                     | dk    rdS dt          d          z   |z  }dt          d          z
  |z  }t          || z  || z  z
  t          d          z            S )Nr   r!      )r   int)rC   rD   alphabetas       r   modified_binets_fibonnacirK   <   s_     	Avvaaa[AEQK1D!	*d1gg5666r   r:   c                     t           j                            | f          }t          j        ||                                k    dd          S )Nr!   r   )r   randomwheremean)r:   r<   s     r   generate_dummy_watermarkrP   H   s<    	  &++I8I	 0 00!Q777r   r<   c                 >    t          j        d | D                       S )Nc                 ,    g | ]}t          |          S  )rH   .0chars     r   
<listcomp>z*watermark_str_to_numpy.<locals>.<listcomp>N   s    5554SYY555r   )r   r5   r<   s    r   watermark_str_to_numpyrY   M   s!    8559555666r   c                 @    d                     d | D                       S )N c              3   4   K   | ]}t          |          V  d S r   )strrT   s     r   	<genexpr>z)watermark_numpy_to_str.<locals>.<genexpr>R   s(      333t99333333r   )joinrX   s    r   watermark_numpy_to_strr`   Q   s#    7733333333r   c                 4    t          d | D                       S )Nc                     g | ]}|d vS ))10rS   rT   s     r   rW   z-validate_string_watermark.<locals>.<listcomp>V   s    ===4J&===r   )anyrX   s    r   validate_string_watermarkrf   U   s    ==9===>>>r   
audio_pathsrc                     	 t          j        | |          \  }}||fS # t          $ r}t          d|  d|           d}~ww xY w)z
    Load an audio file using librosa.
    
    Args:
        audio_path: Path to the audio file
        sr: Target sample rate. If None, the native sample rate is used.
        
    Returns:
        Tuple of (audio_data, sample_rate)
    )rh   zCould not load audio file z: N)librosaload	ExceptionIOError)rg   rh   audiosample_ratees        r   
load_audiorq   Y   sn    F$\*<<<{k!! F F FD:DDDDEEEFs    
A>A
audio_data	file_pathro   c                     t           j                            t           j                            |                    }t          j        |d           t          j        || |           dS )z
    Save audio data to a file.
    
    Args:
        audio_data: Audio data as a numpy array
        file_path: Output file path
        sample_rate: Sample rate for the audio file
    T)exist_okN)ospathdirnameabspathmakedirssfwrite)rr   rs   ro   	directorys       r   
save_audior~   k   sT     	 : :;;IK	D))))HY
K00000r   originalwatermarkedoutput_pathc                 6   t          j        ddd          \  }}t          j        t	          |                     |z  }|d                             || dd           |d                             ||dd	           |d                             d
           |d                             d           |d                             d           |d         	                                 || z
  }|d                             ||           |d                             d           |d                             d           |d                             d           t          j        t          j        t          j        |                    t          j                  }t          j                            |dd||d                    |d                             d           |d                             d           |d                             d           |                    |d         j        d         |d         d           t          j                     |r)t          j        |           t          j                     dS t          j                     dS )a$  
    Plot a comparison between original and watermarked audio.
    
    Args:
        original: Original audio data
        watermarked: Watermarked audio data
        sample_rate: Sample rate of the audio
        output_path: Path to save the plot. If None, plot is shown interactively.
       r!   )
      )figsizer   gffffff?Original)rI   labelWatermarkedzWaveform ComparisonzTime (s)	Amplitudez#Difference (Watermarked - Original)
Difference)reftimelogr"   )x_axisy_axisrh   axzSpectrogram of DifferencezFrequency (Hz)z	%+2.0f dB)r   formatN)pltsubplotsr   aranger4   plot	set_title
set_xlabel
set_ylabellegendrj   amplitude_to_dbabsstftmaxdisplayspecshowcolorbarcollectionstight_layoutsavefigcloseshow)	r   r   ro   r   figaxsr   diffDs	            r   plot_audio_comparisonr   y   sR    |Aq(333HC 9S]]##k1DFKKhcK<<<FKKkMKBBBF*+++Fj!!!Fk"""FMMOOO !DFKKdF:;;;Fj!!!Fl### 	
w|D!!""	 	 	A OQvePSTUPVWWWF0111Fj!!!F&'''LLQ#A&3q6+LFFF K   	




r   c                 b   t          |           t          |          k    rt          d          t          j        | |z
  dz            }t          j        | dz            }|}|dk    rdt          j        ||z            z  nt          d          }t          t          j        t          j        |                     t          j        t          j        |                              }|dk    r,dt          j        |t          j        |          z            z  nt          d          }|||dS )ak  
    Calculate audio quality metrics between original and watermarked audio.
    
    Args:
        original: Original audio data
        watermarked: Watermarked audio data
        
    Returns:
        Dictionary of quality metrics:
        - snr: Signal-to-Noise Ratio (dB)
        - mse: Mean Squared Error
        - psnr: Peak Signal-to-Noise Ratio (dB)
    z8Original and watermarked audio must have the same lengthr"   r   r   inf   )snrmsepsnr)	r4   
ValueErrorr   rO   log10floatr   r   r   )r   r   r   signal_powernoise_powerr   	max_valuer   s           r   calculate_audio_metricsr      s    8}}K((((STTT '8k)a/
0
0C 78q=))LK7BQ"rx{233
3
3ERWLLC BF26(++,,bfRVK5H5H.I.IJJI69Agg2RWS\\122225<<D   r   )T)r   )rB   r   )'__doc__rv   numpyr   rj   	soundfiler{   matplotlib.pyplotpyplotr   typingr   r   r   r   mathr   scipy.statsr   r   r   r-   r2   r=   r8   rH   r   rK   rP   r]   ndarrayrY   r`   boolrf   rq   r~   r   r   rS   r   r   <module>r      s    
			                - - - - - - - - - - - -                 I I I Ih h h h
 
 
 
; ; ;	7 	7 	7 	7 	7 	7 	7 	78S 8 8 8 8
7c 7bj 7 7 7 74bj 4S 4 4 4 4? ? ? ? ? ?F F3 FHSM FU2:s?=S F F F F$12: 1# 1C 1D 1 1 1 1 IM, ,BJ ,RZ ,&),8@,QU, , , ,^!bj !rz !dSVX]S]N^ ! ! ! ! ! !r   