o
    Vi                     @   s  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 d4ddZd	d
 Zd5ddZd5ddZd4ddZdd Zd6dededefddZdefddZdedejfddZdejdefd d!Z dede!fd"d#Z"d7d$ed%ee deejef fd&d'Z#d(ejd)ed*eddfd+d,Z$	d7d-ejd.ejd*ed/ee ddf
d0d1Z%d-ejd.ejdeeef fd2d3Z&dS )8z:
Utility functions for audio processing and watermarking.
    N)TupleOptionalDictAny)sqrt)modeTc              	   C   sl   | j d }g }td||D ]&}| |||  }|r.|j d |k r.t|t||j d  }|| q|S )Nr   )shaperangenpappendzeros)datawindow_lengthpad	n_samplesframesidxchunk r   ?/home/ubuntu/.local/lib/python3.10/site-packages/perth/utils.py_signal_to_frames   s   
r   c                 C   s
   t | S N)r   hstack)r   r   r   r   _frames_to_signal   s   
r      c                 C   sL   | j jdks
J d|d }d|  d| d }}| | ||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_maxr   r   r   audio_to_raw   s   r)   c                 C   sT   |d }d|  d| d }}d\}}|| | ||  ||    ddtjS )Nr   r   )g      g      ?r   )r!   r"   r   float32)r$   r%   r&   r'   r(   abr   r   r   raw_pcm16_tofloat$   s   ,r-   c                 C   s|   t | dksJ t| }t | | r|d t | |   }|r8t ||kr8tt|t || j}t|}|d | S )Nr   )lenr   arraysplitTflatten_watermark)watermark_listlengthwrap	watermarkr   r   r   formatted_watermark+   s   
r7   c                 C   s   t | ddj dS )Nr   )axisr   )r   squeeze)watermark_vectorr   r   r   r2   8      r2         @nkreturnc                 C   sH   | dkrdS dt d | }dt d | }t||  ||   t d S )Nr   r      )r   int)r=   r>   alphabetar   r   r   modified_binets_fibonnaci<   s   rD   r4   c                 C   s$   t j| f}t || kddS )Nr   r   )r   randomwheremean)r4   r6   r   r   r   generate_dummy_watermarkH   s   rH   r6   c                 C   s   t dd | D S )Nc                 S   s   g | ]}t |qS r   )rA   .0charr   r   r   
<listcomp>N       z*watermark_str_to_numpy.<locals>.<listcomp>)r   r/   r6   r   r   r   watermark_str_to_numpyM   r;   rO   c                 C   s   d dd | D S )N c                 s   s    | ]}t |V  qd S r   )strrI   r   r   r   	<genexpr>R   s    z)watermark_numpy_to_str.<locals>.<genexpr>)joinrN   r   r   r   watermark_numpy_to_strQ   r;   rT   c                 C   s   t dd | D S )Nc                 S   s   g | ]}|d vqS ))10r   rI   r   r   r   rL   V   rM   z-validate_string_watermark.<locals>.<listcomp>)anyrN   r   r   r   validate_string_watermarkU   s   rX   
audio_pathsrc              
   C   sJ   zt j| |d\}}||fW S  ty$ } z
td|  d| d}~w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)
    )rZ   zCould not load audio file z: N)librosaload	ExceptionIOError)rY   rZ   audiosample_rateer   r   r   
load_audioY   s   
rb   
audio_data	file_pathr`   c                 C   s4   t jt j|}t j|dd t|| | 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)rc   rd   r`   	directoryr   r   r   
save_audiok   s   	rn   originalwatermarkedoutput_pathc           	      C   sv  t jdddd\}}tt| | }|d j|| ddd |d j||dd	d |d d
 |d d |d d |d 	  ||  }|d || |d d |d d |d d t
jtt
|tjd}t
jj|dd||d d |d d |d d |d d |j|d jd |d dd t   |rt | t   dS t   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)rB   labelWatermarkedzWaveform ComparisonzTime (s)	Amplitudez#Difference (Watermarked - Original)
Difference)reftimelogr   )x_axisy_axisrZ   axzSpectrogram of DifferencezFrequency (Hz)z	%+2.0f dB)r   formatN)pltsubplotsr   aranger.   plot	set_title
set_xlabel
set_ylabellegendr[   amplitude_to_dbabsstftmaxdisplayspecshowcolorbarcollectionstight_layoutsavefigcloseshow)	ro   rp   r`   rq   figaxsr|   diffDr   r   r   plot_audio_comparisony   s4   
r   c                 C   s   t | t |krtdt| | d }t| d }|}|dkr+dt||  ntd}ttt| tt|}|dkrPdt|t|  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   rs   inf   )snrmsepsnr)	r.   
ValueErrorr   rG   log10floatr   r   r   )ro   rp   r   signal_powernoise_powerr   	max_valuer   r   r   r   calculate_audio_metrics   s   ""(r   )T)r   )r<   r   )'__doc__rf   numpyr   r[   	soundfilerk   matplotlib.pyplotpyplotr   typingr   r   r   r   mathr   scipy.statsr   r   r   r)   r-   r7   r2   rA   r   rD   rH   rQ   ndarrayrO   rT   boolrX   rb   rn   r   r   r   r   r   r   <module>   s>    



&
&/