o
    }oiL                     @   s   d dl Z d dlZd dlm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mZmZmZmZmZmZmZmZ zd dlZdZW n eyS   dZY nw G dd dZG dd	 d	ZG d
d dZdS )    N)SOUND_VELOCITY)calculate_sdr_numpyconvmtx_mc_numpycovariance_matrixdb2magestimated_coherence generate_approximate_noise_fieldget_segment_startmag2dbpow2dbrmstheoretical_coherencetoeplitzTFc                   @   s  e Zd Zejjejddgejddgejdddgejdd	d
gejddgdedededede	f
ddZ
ejjejddgejddgejdddgejdd	d
gejddg	ddedededede	defddZdS )!TestGenerateApproximateNoiseFieldnum_mics   mic_spacingg?
fft_lengthi   i   sample_ratei@  i>  field	sphericalc                 C   s$  d}|d d }dt j | t d| | }t |||f}	t|D ]@}
t|D ]9}|
|kr9d|	dd|
|f< q)|dkr[t|
| | }|| t }t |t j |	dd|
|f< q)td| d	q#t |d
f}|t | |dddf< t	|||dd}t 
t ||	 }||k sJ dS )z3Test calculation of a theoretical coherence matrix.g&.>      r   g      ?Nr   zField  not supported.   )r   r   r   )nppiarangezerosrangeabssound_velocitysincNotImplementedErrorr   max)selfr   r   r   r   r   max_diff_tolnum_subbandsangular_freqgolden_coherencepqdist_pqsinc_argmic_positionsuut_coherencemax_diff r1   b/home/ubuntu/.local/lib/python3.10/site-packages/tests/collections/audio/utils/test_audio_utils.py!test_theoretical_coherence_matrix2   s*    zCTestGenerateApproximateNoiseField.test_theoretical_coherence_matrixg?   Fsave_figuresc                 C   s  d}d}d|d  }	|| }
t j|
|}|t j|9 }t |df}|t | |dddf< t|||||d}t||||d}tj	|
 |d}|
d	d
d}t|}t |j| d
 }||	k sfJ t |jd
 }||	k stJ |rFtjd}tj|st| tj||d}|d }tjdd td	|D ]}t|d	 d
d
| d	  tj||ddd|f jdd tj||ddd|f jdd td|  td t  tjdd t|d	 d
d
|  tj|ddd|f jdd tj|ddd|f jdd td|  td t  tjdd qt  ttj |d| d| d| d| d	 t!  dS dS )zATest approximate noise field with white noise as the input noise.   i
   r   Nr   )r   r   r   )n_fftr   r   z~/_coherence)srr8   g     @@)   r7   )figsizegolden)label	estimatedzReal(coherence), p=0, q=zf / kHzzupper right)loczImag(coherence), p=0, q=	num_mics__sample_rate__fft_length__z.png)"r   randomrandrandnr   r   r   r   librosastft	transposer   meanrealimagospath
expanduserexistsmkdirfft_frequenciespltfigurer   subplotplottitlexlabelgridlegendtight_layoutsavefigjoinclose)r%   r   r   r   r   r   r5   duration_in_secrelative_mse_tol_dBrelative_mse_tolnum_samplesnoise_signalr.   noise_fieldr)   Nr/   relative_mse_realrelative_mse_imag
figure_dirfreqnr1   r1   r2   %test_generate_approximate_noise_field]   sf   

  

zGTestGenerateApproximateNoiseField.test_generate_approximate_noise_fieldN)F)__name__
__module____qualname__pytestmarkunitparametrizeintfloatstrr3   boolrk   r1   r1   r1   r2   r   1   sL    %r   c                
   @   s   e Zd Zejjdd Zejjdd Zejjdd Zejjdd Z	ejjd	d
 Z
ejjejdddgejddgejdddgdededefddZejjejdddgejddgejdddgdededefddZdS )TestAudioUtilsElementsc           	      C   s   t j }d}d}d}t ddt j |}|t dt j | |  }t|}|t d }t || |k sDJ d| d| d| d	S )
zTest RMS calculationd   i  g-C6?r   r   zRMS not matching for A=z, omega=z
, n_point=N)	r   rD   rE   linspacer   cosr   sqrtr    )	r%   Aomegan_pointsrms_thresholdtxx_rms
golden_rmsr1   r1   r2   test_rms   s   
zTestAudioUtilsElements.test_rmsc                 C   s   d}d}t j|}t|}tt |d|d   |k sJ tt t|d|d   |k s2J tt t|d | |k sCJ dS )z Test conversions to and from dB.r7   ư>r6   r   N)r   rD   rE   r
   allr    r   r   )r%   num_examplesabs_thresholdmagmag_dbr1   r1   r2   test_db_conversion   s   "&&z)TestAudioUtilsElements.test_db_conversionc              	   C   s   d}d}d}t jj|d}t|D ]6}|j|d}|jd|d d}|j||d}||| }	t||	d	}
|
|ksGJ d
| d|
 d| dqd S )N*   2     seedsizer   r   lowhigh)signalsegmentExample z: estimated start (z!) not matching the actual start ())r   rD   default_rngr   normalintegersr	   )r%   random_seedr   rb   _rngrj   r   startendr   estimated_startr1   r1   r2   test_get_segment_start   s   
z-TestAudioUtilsElements.test_get_segment_startc              	   C   s   d}d}d}d}t jj|d}t|D ]f}|j|d}|jddd	}|d
d| d    }	t|	|dd}
t j|
||dsJJ d| d|
 d| d||jddd	7 }|	|jddd	7 }	t|	|dd}
t j|
||dsyJ d| d|
 d| dqd S )Nr   r   r   r   r   r   ir7   r   r   r6   F)estimatetargetremove_meanatolr   : estimated (!) not matching the actual value (r   T)	r   rD   r   r   r   r   r   iscloseuniform)r%   r   r   r   rb   r   rj   r   
golden_sdrr   estimated_sdrr1   r1   r2   test_calculate_sdr_numpy   s0   z/TestAudioUtilsElements.test_calculate_sdr_numpyc              	   C   s   d}d}d}d}t jj|d}t|D ]Q}|j|d}||jddd	|j|jd  }|t j|d
  }	t 	||	 |	 }	t
||	ddd}
t
||ddd}t j||
|dsdJ d| d| d|
 dqd S )Nr   r   r   r   r   r   g{Gz?r   r   gؗҜ<F)r   r   scale_invariantr   Tr   r   r   r   r   )r   rD   r   r   r   r   r   linalgnormsumr   r   )r%   r   r   r   rb   r   rj   r   r   target_scaledr   r   r1   r1   r2   (test_calculate_sdr_numpy_scale_invariant  s,    z?TestAudioUtilsElements.test_calculate_sdr_numpy_scale_invariantnum_channelsr   r   filter_lengthr7   delayr   r   c                 C   s   d}d}d}d}t jj|d}t|D ]g}	|j||fd}
|j||fd}t|
||d}|| dd	 }|d	}d
}t|D ](}t 	t 
||
dd|f g}|t j||dd|f dddt|
 7 }qAt j|||dszJ d|	 dqdS )zTest convmtx against convolve and sum.
        Multiplication of convmtx_mc of input with a vectorized multi-channel filter
        should match the sum of convolution of each input channel with the corresponding
        filter.
        r   r   r7   r   r   r   )r   r   r   r   r   Nfull)moder   r   !: UUT not matching the reference.)r   rD   r   r   r   r   rI   reshapesqueezehstackr   convolvelenallclose)r%   r   r   r   r   r   r   rb   r   rj   r   fCMuut
golden_refmx_m_delayedr1   r1   r2   test_convmtx_mc2  s"   

 ."z&TestAudioUtilsElements.test_convmtx_mcrb   rx   c                 C   s   d}d}d}d}t jj|d}t|D ]K}	|j|||fd}
tt|
d}t|D ]3}t|D ],}tj	|
||df }t j
|||df   ||d	s\J d
|	 d| d| dq0q*qdS )z:Test construction of a Toeplitz matrix for a given signal.r   r   r7      r   r   r   .r   r   z$: not matching the reference for (b=z, m=z), .N)r   rD   r   r   r   r   torchtensorscipyr   r   cpunumpy)r%   r   r   rb   r   r   num_batches
batch_sizer   rj   r   Txbr   T_refr1   r1   r2   test_toeplitzU  s&   z$TestAudioUtilsElements.test_toeplitzN)rl   rm   rn   ro   rp   rq   r   r   r   r   r   rr   rs   r   r   r1   r1   r1   r2   rw      s*    



"
"rw   c                   @   s\  e Zd Zejjejje ddejdddgejdddgejd	d
dgejdd
dgejdg dde	de	d	e
de
def
ddZejjejdddgejdddgejd	d
dgejdd
dgejdg dde	de	d	e
de
def
ddZejjejdddgejdddgde	de	fddZdS )TestCovarianceMatrixz'Modules in this test require torchaudio)reasonr   r   r   num_freq   !   use_maskTFnormalize_mask	mask_type)rK   complexrv   c              	   C   s.  d}d}t  }|| d}	d\}
}tjjd|dd}t|	D ]t}t j|
|||t j|d}|d	kr>t j	|
||t j
|d}n+|d
krNt j	|
||t j|d}n|dkrat jdd|
||ft j|d}ntd| dt||ro|nd|d}|||rz|ndd}|s|| }t j|||dsJ d| dq dS )z4Test against reference calculation using torchaudio.h㈵>r   r7   r   rx   F:0yE>)
multi_mask	normalizeepsdtype	generatorrK   r   rv   r   r   
Mask type r   Nr   maskr   )specgramr   r   r   r   )r   	Generatormanual_seed
torchaudio
transformsPSDr   rF   cfloatrE   rt   randintrv   
ValueErrorr   r   )r%   r   r   r   r   r   r   r   rngr   r   	num_stepspsd_refrj   inputr   r   refr1   r1   r2   'test_calculate_covariance_matrix_vs_psds  s,   
"z<TestCovarianceMatrix.test_calculate_covariance_matrix_vs_psdr7   c                 C   s  d}d}t  }|| d}	d\}
}t|	D ]}t j|
|||t j|d}|dkr5t j|
||t j|d}n+|dkrEt j|
||t j|d}n|dkrXt jd	d
|
||ft j	|d}nt
d| dt||rf|nd|d}t j|
||||t jd}t|
D ]3}t|D ],}t|D ]%}t ||dd||f ||dd||f  |||dddd|f< qqq{|r|r||jdddd  }||dddddf  }|jdd}n|jdd}t j|||dsJ d| dqdS )z*Test against simple reference calculation.r   r   r7   )r   r7   r   rK   r   rv   r   r   r   r   Nr   r   r   T)dimkeepdimr   .)r   r   r   r   )r   r   r   r   rF   r   rE   rt   r   rv   r   r   r   outerconjr   rJ   r   )r%   r   r   r   r   r   r   r   r   r   r   r   rj   r   r   r   r   r   r   r   r1   r1   r2    test_calculate_covariance_matrix  s>   
H"z5TestCovarianceMatrix.test_calculate_covariance_matrixc                 C   s4  d\}}t j||||t jd}t j|||t jd}tt t|d d W d   n1 s0w   Y  tt t||d d W d   n1 sMw   Y  tt t||ddd	f d W d   n1 snw   Y  tt t||ddd	ddf d W d   dS 1 sw   Y  dS )
zrTest that the covariance matrix is not calculated if the mask has a different number of dimensions than the input.r   r   )r   r   .r   N)r   .)r   r   .r   )	r   rF   r   rE   rt   ro   raisesr   r   )r%   r   r   r   r   r   r   r1   r1   r2   test_mismatch_dimensions  s    "z-TestCovarianceMatrix.test_mismatch_dimensionsN)rl   rm   rn   ro   rp   rq   skipifHAVE_TORCHAUDIOrr   rs   rv   ru   r   r   r  r1   r1   r1   r2   r   r  sP    +:r   )rM   rG   matplotlib.pyplotpyplotrS   r   r   ro   r   r   (nemo.collections.audio.parts.utils.audior   r!   r   r   r   r   r   r   r	   r
   r   r   r   r   r   r  ModuleNotFoundErrorr   rw   r   r1   r1   r1   r2   <module>   s(   8  =