
    (HJj                     v    d Z ddlZddlZddlZddlZd Zd Zd Zd Z	d Z
d Zd	 Zd
 Zd Zd Zd Zd Zd Zy)zTests for mlx_audio.dsp module.    Nc                      d} t        j                  t        j                  d| gdd      }|j                  dk(  sJ d|j
                          y)zrVerify dsp.py doesn't import TTS/STT modules.

    Runs in subprocess to avoid interference with other tests.
    z
import sys
from mlx_audio.dsp import stft
assert "mlx_audio.tts" not in sys.modules, "TTS was imported"
assert "mlx_audio.stt" not in sys.modules, "STT was imported"
print("OK")
-cTcapture_outputtextr   zImport isolation failed: N
subprocessrunsys
executable
returncodestderrcoderesults     b/Users/ahmed/devFolder/claude-voice/.venv/lib/python3.12/site-packages/mlx_audio/tests/test_dsp.pytest_dsp_import_isolationr   
   sT    
D ^^	t$F
 !N%>v}}o#NN!    c                      ddl m} m}m}m} t        |      sJ t        |      sJ t        |      sJ t        |       sJ y)z<Verify backward compatible imports from utils.py still work.r   hanningistftmel_filtersstftN)mlx_audio.utilsr   r   r   r   callabler   s       r   test_dsp_backward_compatr      s<    AAD>>E??K   Gr   c                  R    ddl m}  g d}|D ]  }t        | |      rJ d|         y)z&Verify __all__ exports work correctly.r   )dsp)r   hammingblackmanbartlettSTR_TO_WINDOW_FNr   r   r   integrated_loudnessnormalize_loudnessnormalize_peakzMissing export: N)	mlx_audior   hasattr)r   expectednames      r   test_dsp_all_exportsr+   (   s5    H sD!<%5dV#<<! r   c                  h   ddl m}  t        j                  g dt        j                        } | ddgdg|      }t        j
                  j                  |g d       t        j                  g dt        j                        } | dgddg|      }t        j
                  j                  |g d	       y
)z<Verify the local lfilter recurrence for FIR and IIR filters.r   )lfilter)      ?g       @g      @dtyper.         )r.   g      ?g      @)r.           r2   r2   )r.         ?g      ?g      ?N)mlx_audio.dspr-   nparrayfloat32testingassert_allclose)r-   xfirimpulseiirs        r   test_lfilter_fir_and_iirr>   >   s    %


3A
3+ua
(CJJsO4hh+2::>G
3%#tg
.CJJs$;<r   c                      d} t        j                  t        j                  d| gdd      }|j                  dk(  sJ d|j
                          y)zwVerify utils.py uses lazy imports for TTS/STT/STS.

    Runs in subprocess to avoid interference with other tests.
    a  
import sys
from mlx_audio.utils import stft
assert "mlx_audio.tts.utils" not in sys.modules, "TTS utils was imported"
assert "mlx_audio.stt.utils" not in sys.modules, "STT utils was imported"
assert "mlx_audio.sts.utils" not in sys.modules, "STS utils was imported"
print("OK")
r   Tr   r   zLazy import failed: Nr   r   s     r   test_utils_lazy_importsr@   K   sT    
D ^^	t$F
 !I%9&--#II!r   c                     ddl m}  t        j                  j	                  d      }|j                  d      dz  j                  t        j                        }|j                  d      dz  j                  t        j                        } | |d      t        j                  dd	      k(  sJ  | |d      t        j                  d
d	      k(  sJ y)z8Verify BS.1770 loudness matches fixed reference outputs.r   r$   ]  {Gz?)rC      gQ?gQVf%?-q=absg>[>N)
r4   r$   r5   randomdefault_rngstandard_normalastypefloat64pytestapprox)r$   rngmonostereos       r   1test_integrated_loudness_matches_reference_valuesrS   `   s    1
))


"C&-55bjjAD!!*-5==bjjIFtU+v}}0    vu-2   r   c                     ddl m} m} t        j                  j                  d      }|j                  d      dz  j                  t        j                        } | |dd      } |||d      }t        j                  t        j                  |            t        j                  dd	
      k(  sJ t        j                  j                  |dd t        j                  g d      d	d       y)z>Verify loudness normalization matches fixed reference outputs.r   )r$   r%   rC   rD   g?)
block_sizeg      2gߩ"?rF   rG   N   )g2de?gBgϵ|˭?g0y?g.먿r2   atolrtol)r4   r$   r%   r5   rI   rJ   rK   rL   rM   maxrH   rN   rO   r8   r9   r6   )r$   r%   rP   rQ   measured
normalizeds         r   0test_normalize_loudness_matches_reference_valuesr]   p   s    E
))


"C&-55bjjAD"43?H#D(E:J66"&&$%7Iu)UUUUJJ2A
	
   r   c                  j   ddl m}  t        j                  dddt        j                        } | |d      }t        j
                  t        j                  |            t        j                  dd	
      k(  sJ t        j                  j                  |dd t        j                  g d      d	d       y)z:Verify peak normalization matches fixed reference outputs.r   )r&   r1   r3       r/         gK
 ?rF   rG   NrV   )gK
 g
Rgkg, g=8(r2   rW   )r4   r&   r5   linspacerM   rZ   rH   rN   rO   r8   r9   r6   )r&   datar\   s      r   ,test_normalize_peak_matches_reference_valuesrc      s    ,;;tS"BJJ7Dd+J66"&&$%7Iu)UUUUJJ2A
	
   r   c            	         ddl m}  d\  }}t        j                  d|z        |z  }t        j                  dt        j
                  z  dz  |z        j                  t        j                        }t        j                   | |||            }t        t        j                  t        j                  |dd dz                    }|dk  sJ y	)
zA tone just above the new Nyquist must be band-limited away, not aliased
    back into the signal. The previous Kaiser(5.0) default left a large residual
    in the top bins here (#24).r   resample_audiorC   >  rE   g     @  pg{Gz?Nr   rf   r5   arangesinpirL   r7   asarrayfloatsqrtmean)rf   origtargetttoneoutrmss          r   1test_resample_rejects_energy_above_target_nyquistry      s     /LD&
		!d(d"A66!bee)f$q()00<D
**^D$7
8C
C 234
5C::r   c            
         ddl m}  d\  }}t        j                  d|z        |z  }dD ]  }t        j                  dt        j
                  z  |z  |z        j                  t        j                        }t        j                   | |||            }t        t        j                  t        j                  |dd dz                    }d|cxk  rd	k  rJ  J  y
)zIn-band tones pass with ~unit gain, including near the Nyquist edge where
    the old filter drooped (full-scale sine RMS == 1/sqrt(2) ~= 0.7071).r   re   rg   rE   )g     @@g     X@ri   rj   gffffff?g
ףp=
?Nrk   )rf   rs   rt   ru   freqrv   rw   rx   s           r    test_resample_preserves_passbandr|      s     /LD&
		!d(d"A vva"%%i$&*+222::>jjdF;<BGGBGGCDMQ$6789c D     	 !r   c                  L   ddl m}  ddlm} t	        j
                  dt        j                        } ||dd      }t        |t        j                        sJ t        t        |      dz
        dk  sJ  || j                  |      dd      }t        || j                        sJ y)zFOutput length tracks the rate ratio and the return type matches input.r   Nre   rC   r/   rh      )mlx.corecorer   rf   r5   zerosr7   
isinstancendarrayrH   lenr6   )mxrf   r:   rw   out_mxs        r   test_resample_length_and_typer      s    .
bjj)A
E5
)Cc2::&&&s3x% A%%%BHHQK6Ffbhh'''r   c                      ddl m}  t        j                  dddt        j                        } | |dd      }t        j
                  j                  t        j                  |      |       y )Nr   re   r`   r.   d   r/   rh   )r   rf   r5   ra   r7   r8   assert_array_equalro   )rf   r:   rw   s      r   #test_resample_noop_when_rates_equalr      sG    .
D#s"**5A
E5
)CJJ!!"**S/15r   c                     ddl m}  t        j                  t        d      5   | t        j                  dt
        j                        d       ddd       t        j                  t        d	      5   | t        j                  d
t
        j                        d       ddd       y# 1 sw Y   ZxY w# 1 sw Y   yxY w)z<Verify the public helper keeps the old validation semantics.r   rB   zData must be floating point.)match
   r/   rC   Nz3Audio must have length greater than the block size.r   )
r4   r$   rN   raises
ValueErrorr5   rl   int16r   rM   rB   s    r   =test_integrated_loudness_validation_matches_previous_behaviorr      s    1	z)G	HBIIb95A 
I 
O
 	BHHS

;UC
 
 
I	H
 
s   -B(2-B4(B14B=)__doc__r	   r   numpyr5   rN   r   r   r+   r>   r@   rS   r]   rc   ry   r|   r   r   r    r   r   <module>r      sX    %  
  O(=,
=J* 60!(6
Dr   