Ë
    îÿæi˜S  ã                   ób  — d Z ddlZg d¢ZddlmZ ddlmZ ddlmZ	  ed¬«      d6d„«       Z
 ed¬«      d6d„«       Z ed¬«      d6d	„«       Z ed¬«      d6d
„«       Ze
e
eeedœZ	 	 	 	 	 	 d7de	j                  ez  fd„Z	 	 	 	 	 	 d8d„Z ed¬«      	 	 	 	 d9dededededee   dee   dede	j                  fd„«       Z G d„ d«      Z	 d:de	j                  dedede	j                  fd„Zde	j                  de	j                  fd„Zd e	j                  de	j                  fd!„Zd"edefd#„Zd$e	j                  d%ed&ed'ede	j                  f
d(„Zd)ed*ed+ed,ed-edee	j                  e	j                  f   fd.„Z	 	 	 	 	 	 	 	 	 	 d;d$e	j                  ded/ed0ed1ed2ed3ed4ed'ed,ed-ede	j                  fd5„Zy)<z×Pure audio processing utilities - no TTS/STT imports.

This module contains only audio processing functions (window functions, STFT, mel filterbanks)
that can be imported without pulling in TTS or STT dependencies.
é    N)ÚhanningÚhammingÚblackmanÚbartlettÚSTR_TO_WINDOW_FNÚstftÚistftÚ
ISTFTCacheÚmel_filtersÚcompute_deltas_kaldiÚmel_scale_kaldiÚinverse_mel_scale_kaldiÚget_mel_banks_kaldiÚcompute_fbank_kaldi)Ú	lru_cache)ÚOptional)Úmaxsizec                 óÖ   — |r| n| dz
  }t        j                  t        | «      D �cg c]4  }ddt        j                  dt        j
                  z  |z  |z  «      z
  z  ‘Œ6 c}«      S c c}w )z‰Hanning (Hann) window.

    Args:
        size: Window length
        periodic: If True, use periodic window (for spectral analysis)
    é   ç      à?é   ©ÚmxÚarrayÚrangeÚmathÚcosÚpi©ÚsizeÚperiodicÚdenomÚns       úb/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/mlx_audio/dsp.pyr   r   !   s_   € ñ ‰D $¨¡(€EÜ�8‰8Ü@EÀdÄÓLÁ¸1ˆ�”D—H‘H˜Q¤§¡™[¨1™_¨uÑ4Ó5Ñ5Ó	6ÀÑLóð ùÚLó   ¦9A&c                 óÖ   — |r| n| dz
  }t        j                  t        | «      D �cg c]4  }ddt        j                  dt        j
                  z  |z  |z  «      z  z
  ‘Œ6 c}«      S c c}w )z‚Hamming window.

    Args:
        size: Window length
        periodic: If True, use periodic window (for spectral analysis)
    r   çHáz®Gá?çq=
×£pÝ?r   r   r   s       r$   r   r   /   s_   € ñ ‰D $¨¡(€EÜ�8‰8ÜBGÈÄ+ÓNÁ+¸Qˆ�”t—x‘x ¤D§G¡G¡¨a¡°%Ñ 7Ó8Ñ8Ó	8À+ÑNóð ùÚNr%   c                 ó6  — |r| n| dz
  }t        j                  t        | «      D �cg c]d  }ddt        j                  dt        j
                  z  |z  |z  «      z  z
  dt        j                  dt        j
                  z  |z  |z  «      z  z   ‘Œf c}«      S c c}w )zBlackman window.r   gáz®GáÚ?r   r   g{®Gáz´?é   r   r   s       r$   r   r   =   sš   € ñ ‰D $¨¡(€EÜ�8‰8ô
 ˜4”[ó		
ñ !�ð Ø”D—H‘H˜Q¤§¡™[¨1™_¨uÑ4Ó5Ñ5ñ6à”T—X‘X˜a¤$§'¡'™k¨A™o°Ñ5Ó6Ñ6ó7ð !ñ		
óð ùò	
s   ¦A)Bc                 ó¦   — |r| n| dz
  }t        j                  t        | «      D �cg c]  }ddt        ||dz  z
  «      z  |z  z
  ‘Œ c}«      S c c}w )zBartlett (triangular) window.r   r   )r   r   r   Úabsr   s       r$   r   r   K   sR   € ñ ‰D $¨¡(€EÜ�8‰8ÄÀtÄÓMÁ¸A�Q˜œS  U¨Q¡Y¡Ó/Ñ/°%Ñ7Ó7ÀÑMÓNÐNùÒMs   ¦!A)Úhannr   r   r   r   Úwindowc                 ó„  — |€|dz  }|€|}t        |t        «      r<t        j                  |j	                  «       «      }|€t        d|› �«      ‚ ||«      }n|}|j                  d   |k  r?||j                  d   z
  }	t        j                  |t        j                  |	f«      gd¬«      }dd„}
|r |
| |dz  |«      } d| j                  d   |z
  |z  z   }|dk  r%t        d| j                  d   › d	|› d
|› d|› d�	«      ‚||f}|df}t        j                  | ||¬«      }t        j                  j                  ||z  «      S )Nr*   úUnknown window function: r   ©Úaxisc                 óÎ   — |dk(  rt        j                  | ||fg«      S |dk(  r5| d|dz    d d d…   }| |dz    d d d d…   }t        j                  || |g«      S t        d|› �«      ‚)NÚconstantÚreflectr   éÿÿÿÿzInvalid pad_mode )r   ÚpadÚconcatenateÚ
ValueError)ÚxÚpaddingÚpad_modeÚprefixÚsuffixs        r$   Ú_padzstft.<locals>._padv   sˆ   € Ø�zÒ!Ü—6‘6˜!˜w¨Ð0Ð1Ó2Ð2Ø˜Ò"Ø�q˜7 Q™;Ð'©¨"¨Ñ-ˆFØ˜ 1™�~¨Ð+©D¨b¨DÑ1ˆFÜ—>‘> 6¨1¨fÐ"5Ó6Ð6äÐ0°°
Ð;Ó<Ð<ó    r   r   zInput is too short (length=z) for n_fft=z with hop_length=z and center=Ú.©ÚshapeÚstrides)r5   )Ú
isinstanceÚstrr   ÚgetÚlowerr9   rC   r   r8   ÚzerosÚ
as_stridedÚfftÚrfft)r:   Ún_fftÚ
hop_lengthÚ
win_lengthr.   Úcenterr<   Ú	window_fnÚwÚpad_sizer?   Ú
num_framesrC   rD   Úframess                  r$   r   r   \   s_  € ð ÐØ˜a‘Zˆ
ØÐØˆ
ä�&œ#ÔÜ$×(Ñ(¨¯©«Ó8ˆ	ØÐÜÐ8¸¸ÐAÓBÐBÙ�jÓ!‰àˆà‡w�wˆq�z�EÒØ˜1Ÿ7™7 1™:Ñ%ˆÜ�N‰N˜AœrŸx™x¨¨Ó4Ð5¸AÔ>ˆó=ñ Ù��E˜Q‘J Ó)ˆà�a—g‘g˜a‘j 5Ñ(¨ZÑ7Ñ7€JØ�Q‚ÜØ)¨!¯'©'°!©*¨°\À%Àð IØ$˜ \°&°¸ð<ó
ð 	
ð
 ˜Ð€EØ˜1ˆo€GÜ�]‰]˜1 E°7Ô;€FÜ�6‰6�;‰;�v ‘zÓ"Ð"r@   c                 ób  — |€| j                   d   dz
  dz  }|€|dz  }t        |t        «      rBt        j	                  |j                  «       «      }|€t        d|› �«      ‚ ||dz   «      dd }n|}|j                   d   |k  r=t        j                  |t        j                  ||j                   d   z
  f«      gd¬«      }| j                   d   }	|	dz
  |z  |z   }
t        j                  |
«      }t        j                  |
«      }t        j                  j                  | d¬«      j                  dd«      }t        j                  |	«      |z  }|dd…df   t        j                  |«      z   }|j                  «       }||z  j                  «       }|r||z  n|}t        j                  ||	f«      j                  «       }|j                   |   j#                  |«      }|j                   |   j#                  |«      }t        j$                  |d	kD  ||z  |«      }|r|€||dz  | dz   }|�|d| }|S )
ak  Inverse Short-Time Fourier Transform.

    Args:
        x: Complex STFT output of shape (n_fft // 2 + 1, num_frames)
        hop_length: Hop length between frames (default: win_length // 4)
        win_length: Window length (default: (n_fft - 1) * 2)
        window: Window function name or array (default: "hann")
        center: If True, remove center padding (default: True)
        length: Target output length (default: None)
        normalized: If True, use window squared (COLA) normalization. If False, use simple window normalization (default: True)

    Returns:
        Reconstructed time-domain signal
    Nr   r   r*   r0   r6   r   r1   ç»½×Ùß|Û=)rC   rE   rF   r   rG   rH   r9   r   r8   rI   rK   ÚirfftÚ	transposeÚarangeÚflattenÚtileÚatÚaddÚwhere)r:   rN   rO   r.   rP   ÚlengthÚ
normalizedrQ   rR   rT   ÚtÚreconstructedÚ
window_sumÚframes_timeÚframe_offsetsÚindicesÚindices_flatÚupdates_reconstructedÚwindow_normÚupdates_windows                       r$   r	   r	   �   s'  € ð. ÐØ—g‘g˜a‘j 1‘n¨Ñ)ˆ
ØÐØ 1‘_ˆ
ä�&œ#ÔÜ$×(Ñ(¨¯©«Ó8ˆ	ØÐÜÐ8¸¸ÐAÓBÐBÙ�j 1‘nÓ% c rÐ*‰àˆà‡w�wˆq�z�JÒÜ�N‰N˜AœrŸx™x¨°a·g±g¸a±jÑ)@Ð(BÓCÐDÈ1ÔMˆà—‘˜‘€JØ	�a‰˜:Ñ%¨
Ñ2€Aä—H‘H˜Q“K€MÜ—‘˜!“€Jô —&‘&—,‘,˜q q�,Ó)×3Ñ3°A°qÓ9€Kô —I‘I˜jÓ)¨JÑ6€MØšA˜t˜GÑ$¤r§y¡y°Ó'<Ñ<€GØ—?‘?Ó$€Là(¨1™_×5Ñ5Ó7Ðá'�1�q’5¨Q€KÜ—W‘W˜[¨:¨-Ó8×@Ñ@ÓB€Nð "×$Ñ$ \Ñ2×6Ñ6Ð7LÓM€MØ—‘˜|Ñ,×0Ñ0°Ó@€Jô —H‘HØ�UÑ˜M¨JÑ6¸ó€Mñ �&�.Ø% j°A¡o¸¸ÀqÑ8HÐIˆàÐØ% g vÐ.ˆàÐr@   Úsample_raterM   Ún_melsÚf_minÚf_maxÚnormÚ	mel_scaleÚreturnc                 óˆ  — d
d„}d
d„}|xs | dz  }|dz  dz   }	t        j                  d| dz  |	«      }
 |||«      } |||«      }t        j                  |||dz   «      } |||«      }|dd  |d d z
  }t        j                  |d«      t        j                  |
d«      z
  }|d d …d d…f    |d d z  }|d d …dd …f   |dd  z  }t        j                  t        j                  |«      t        j
                  ||«      «      }|dk(  r*d	|d|dz    |d | z
  z  }|t        j                  |d«      z  }|j                  dd«      }|S )Nc                 óð   — |dk(  rdt        j                  d| dz  z   «      z  S d\  }}| |z
  |z  }d}||z
  |z  }t        j                  d«      dz  }| |k\  r|t        j                  | |z  «      |z  z   }|S )	NÚhtkç     F¤@ç      ð?ç     à…@©ç        g«ªªªªªP@ç     @�@çš™™™™™@ç      ;@)r   Úlog10Úlog)Úfreqrq   rn   Úf_spÚmelsÚ
min_log_hzÚmin_log_melÚlogsteps           r$   Ú	hz_to_melzmel_filters.<locals>.hz_to_melé   s�   € Ø˜ÒØœDŸJ™J s¨T°E©\Ñ'9Ó:Ñ:Ð:ð %‰ˆˆtØ�u‘ Ñ$ˆØˆ
Ø! EÑ)¨TÑ1ˆÜ—(‘(˜3“- $Ñ&ˆØ�:ÒØ¤§¡¨$°Ñ*;Ó!<¸wÑ!FÑFˆDØˆr@   c           	      óö   — |dk(  rdd| dz  z  dz
  z  S d\  }}||| z  z   }d}||z
  |z  }t        j                  d«      d	z  }t        j                  | |k\  |t        j                  || |z
  z  «      z  |«      }|S )
Nru   rx   g      $@rv   rw   ry   r{   r|   r}   )r   r   r   r_   Úexp)r‚   rq   rn   r�   Úfreqsrƒ   r„   r…   s           r$   Ú	mel_to_hzzmel_filters.<locals>.mel_to_hz÷   s�   € Ø˜ÒØ˜D T¨F¡]Ñ3°cÑ9Ñ:Ð:ð %‰ˆˆtØ˜˜t™Ñ#ˆØˆ
Ø! EÑ)¨TÑ1ˆÜ—(‘(˜3“- $Ñ&ˆÜ—‘Ø�KÑØœŸ™ ¨4°+Ñ+=Ñ >Ó?Ñ?Øó
ˆð
 ˆr@   r   r   r   r6   éþÿÿÿÚslaneyç       @)ru   )r   ÚlinspaceÚexpand_dimsÚmaximumÚ
zeros_likeÚminimumÚmoveaxis)rl   rM   rm   rn   ro   rp   rq   r†   rŠ   Ún_freqsÚ	all_freqsÚm_minÚm_maxÚm_ptsÚf_ptsÚf_diffÚslopesÚdown_slopesÚ	up_slopesÚ
filterbankÚenorms                        r$   r   r   ß   sn  € óóð" Ò$�[ 1‘_€Eð �q‰j˜1‰n€GÜ—‘˜A˜{¨aÑ/°Ó9€Iñ �e˜YÓ'€EÙ�e˜YÓ'€EÜ�K‰K˜˜u f¨q¡jÓ1€EÙ�e˜YÓ'€Eð �1�2ˆY˜˜s ˜Ñ#€FÜ�^‰^˜E 1Ó%¬¯©°yÀ!Ó(DÑD€Fð š1˜c˜r˜c˜6‘N�? f¨S¨b kÑ1€KØ’q˜!™"�u‘  q r 
Ñ*€IÜ—‘Ü
�‰�kÓ"¤B§J¡J¨{¸IÓ$Fó€Jð ˆxÒØ�u˜Q ¨!¡Ð,¨u°W°f¨~Ñ=Ñ>ˆØ”b—n‘n U¨AÓ.Ñ.ˆ
à×$Ñ$ Q¨Ó*€JØÐr@   c                   óè   — e Zd ZdZd„ Zdededefd„Zdededed	ej                  def
d
„Z		 	 ddej                  dej                  dededed	ej                  de
dedej                  fd„Zd„ Zd„ Zy)r
   zä
    Advanced caching for iSTFT operations. Fully vectorized Overlap-Add for MLX.
    Handles multiple configurations efficiently.
    Automatically caches normalization buffers and position indices for maximum performance.
    c                 ó    — i | _         i | _        y )N)Únorm_buffer_cacheÚposition_cache©Úselfs    r$   Ú__init__zISTFTCache.__init__2  s   € Ø!#ˆÔØ ˆÕr@   rT   Úframe_lengthrN   c                 óú   — |||f}|| j                   vrZt        j                  |«      dd…df   |z  t        j                  |«      ddd…f   z   }|j                  d«      | j                   |<   | j                   |   S )z.Get cached position indices or create new onesNr6   )r£   r   rZ   Úreshape)r¥   rT   r§   rN   ÚkeyÚ	positionss         r$   Úget_positionszISTFTCache.get_positions6  sƒ   € à˜<¨Ð4ˆà�d×)Ñ)Ñ)ä—	‘	˜*Ó%¢a¨ gÑ.°Ñ;Ü—)‘)˜LÓ)¨$²¨'Ñ2ñ3ð ð (1×'8Ñ'8¸Ó'<ˆD×Ñ Ñ$à×"Ñ" 3Ñ'Ð'r@   rM   rO   r.   c                 óî  — t        t        |j                  «       «      «      }|||||f}|| j                  vr°|j                  d   }|dz
  |z  |z   }	| j                  |||«      }
|dz  }t        j                  |	t        j                  ¬«      }t        j                  ||«      }|j                  |
   j                  |«      }t        j                  |d«      }|| j                  |<   | j                  |   S )z1Get cached normalization buffer or create new oner   r   r   ©ÚdtyperW   )ÚhashÚtupleÚtolistr¢   rC   r¬   r   rI   Úfloat32r\   r]   r^   r�   )r¥   rM   rN   rO   r.   rT   Úwindow_hashrª   r§   Úola_lenÚpositions_flatÚwindow_squaredÚnorm_bufferÚwindow_sq_tileds                 r$   Úget_norm_bufferzISTFTCache.get_norm_bufferC  sâ   € ô œ5 §¡£Ó1Ó2ˆØ�j *¨k¸:ÐFˆà�d×,Ñ,Ñ,Ø!Ÿ<™<¨™?ˆLØ! A‘~¨Ñ3°lÑBˆGØ!×/Ñ/°
¸LÈ*ÓUˆNà# Q™YˆNÜŸ(™( 7´"·*±*Ô=ˆKÜ Ÿg™g n°jÓAˆOØ%Ÿ.™.¨Ñ8×<Ñ<¸_ÓMˆKÜŸ*™* [°%Ó8ˆKà*5ˆD×"Ñ" 3Ñ'à×%Ñ% cÑ*Ð*r@   NÚ	real_partÚ	imag_partrP   Úaudio_lengthrr   c	                 óZ  — |j                   d   |k  rI||j                   d   z
  }	t        j                  |t        j                  |	f|j                  ¬«      g«      }|d|z  z   }
t        j
                  j                  |
j                  ddd«      |d¬«      }||z  }|j                   \  }}}|dz
  |z  |z   }| j                  |||||«      }| j                  |||«      }t        j                  |«      |z  }|ddd…f   |dd…df   z   }t        j                  ||z  t        j                  ¬«      }|j                  |j                  d«         j                  |j                  d«      «      }|j                  ||«      }||ddd…f   z  }|r|dz  }|dd…|d…f   }|�|dd…d|…f   }|S )	a  
        iSTFT with automatic caching and vectorized overlap-add.

        Args:
            real_part: Real part of STFT output (batch, freq, time)
            imag_part: Imaginary part of STFT output (batch, freq, time)
            n_fft: FFT size
            hop_length: Hop length
            win_length: Window length
            window: Window function
            center: If True, remove center padding
            audio_length: Target audio length

        Returns:
            Reconstructed audio (batch, samples)
        r   r®   y              ð?r   r   r6   ©r#   r2   N)rC   r   r8   rI   r¯   rK   rX   rY   rº   r¬   rZ   r³   r]   r©   r^   )r¥   r»   r¼   rM   rN   rO   r.   rP   r½   r7   Ústft_complexÚtime_framesÚwindowed_framesÚ
batch_sizerT   r§   rµ   r¸   r¶   Úbatch_offsetsÚglobal_indicesÚoutputÚ	start_cuts                          r$   r	   zISTFTCache.istft^  sÁ  € ð8 �<‰<˜‰?˜UÒ"Ø˜&Ÿ,™, q™/Ñ)ˆCÜ—^‘^ V¬R¯X©X°s°fÀFÇLÁLÔ-QÐ$RÓSˆFð ! 2¨	¡>Ñ1ˆÜ—f‘f—l‘l <×#9Ñ#9¸!¸QÀÓ#BÀeÐRT�lÓUˆð &¨Ñ.ˆà/>×/DÑ/DÑ,ˆ
�J Ø ‘> ZÑ/°,Ñ>ˆð ×*Ñ*Ø�:˜z¨6°:ó
ˆð ×+Ñ+¨J¸ÀjÓQˆô Ÿ	™	 *Ó-°Ñ7ˆØ'¨ªa¨Ñ0°=ÂÀDÀÑ3IÑIˆä—‘˜:¨Ñ/¼¿
¹
ÔCˆØ—‘˜>×1Ñ1°"Ó5Ñ6×:Ñ:¸?×;RÑ;RÐSUÓ;VÓWˆØ—‘ 
¨GÓ4ˆð ˜+ dªA gÑ.Ñ.ˆñ Ø ™
ˆIØšA˜y™z˜MÑ*ˆFàÐ#ØšA˜} ˜}Ð,Ñ-ˆFàˆr@   c                 ól   — | j                   j                  «        | j                  j                  «        y)z$Clear all cached data to free memoryN)r¢   Úclearr£   r¤   s    r$   Úclear_cachezISTFTCache.clear_cache£  s&   € à×Ñ×$Ñ$Ô&Ø×Ñ×!Ñ!Õ#r@   c                 ó¬   — t        | j                  «      t        | j                  «      t        | j                  «      t        | j                  «      z   dœS )z"Get information about cached items)Únorm_buffersÚposition_indicesÚtotal_cached_items)Úlenr¢   r£   r¤   s    r$   Ú
cache_infozISTFTCache.cache_info¨  sK   € ô   × 6Ñ 6Ó7Ü # D×$7Ñ$7Ó 8Ü"% d×&<Ñ&<Ó"=Ü�$×%Ñ%Ó&ñ#'ñ
ð 	
r@   )TN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r¦   Úintr¬   r   r   rº   Úboolr	   rÊ   rÐ   © r@   r$   r
   r
   +  sê   „ ñò!ð(¨ð (¸3ð (ÈCó (ð+àð+ð ð+ð ð	+ð
 —‘ð+ð ó+ðF Ø ñCà—8‘8ðCð —8‘8ðCð ð	Cð
 ðCð ðCð —‘ðCð ðCð ðCð 
�‰óCòJ$ó

r@   r
   ÚspecgramrO   Úmodec                 ó0  — |dk  rt        d|› �«      ‚| j                  }| j                  d|d   «      } | j                  d   }|dz
  dz  }t        ||dz   z  d|z  dz   z  «      dz  }|dk(  r]t	        j
                  | d	d	…dd…f   |d¬
«      }t	        j
                  | d	d	…dd	…f   |d¬
«      }t	        j                  || |gd¬
«      }	nt	        j                  | d||fg«      }	t	        j                  | |dz   |	j                  ¬«      }
|	j                  d   d|z  z
  }t	        j                  ||f|	j                  ¬«      }t        |«      D ]6  }|	d	d	…|||z   …f   }||
z  }t	        j                  |d¬
«      |z  |d	d	…|f<   Œ8 |j                  |«      S )aÇ  
    Compute delta coefficients of a spectrogram (Kaldi-compatible).

    The formula is:
    d_t = sum_{n=1}^{N} n * (c_{t+n} - c_{t-n}) / (2 * sum_{n=1}^{N} n^2)

    Args:
        specgram: MLX array of dimension (..., freq, time)
        win_length: The window length used for computing delta (default: 5)
        mode: Padding mode - "edge" or "constant" (default: "edge")

    Returns:
        MLX array of deltas of dimension (..., freq, time)
    é   zwin_length should be >= 3, got r6   r   r   r   g      @ÚedgeNr1   ©r   r   r®   )r9   rC   r©   Úfloatr   Úrepeatr8   r7   rZ   r¯   rI   r   Úsum)rØ   rO   rÙ   Úoriginal_shapeÚnum_featuresr#   r"   Úpad_leftÚ	pad_rightÚpaddedÚkernel_weightsÚ
time_stepsrÆ   Úir.   Úweighteds                   r$   r   r   ·  s�  € ð" �A‚~ÜÐ:¸:¸,ÐGÓHÐHà—^‘^€NØ×Ñ  N°2Ñ$6Ó7€HØ—>‘> !Ñ$€Là	�a‰˜AÑ€AÜ�!�q˜1‘u‘+  Q¡¨¡Ñ+Ó,¨sÑ2€Eð ˆv‚~Ü—9‘9˜X¢a¨¨1¨ fÑ-¨q°qÔ9ˆÜ—I‘I˜h¢q¨"©# vÑ.°¸Ô:ˆ	Ü—‘ ¨8°YÐ ?ÀaÔH‰ä—‘˜ 6¨A¨q¨6Ð"2Ó3ˆä—Y‘Y ˜r 1 q¡5°·±Ô=€NØ—‘˜a‘ 1 q¡5Ñ(€JÜ�X‰X�| ZÐ0¸¿¹ÔE€Fä�:ÖˆØš˜1˜q :™~Ð-Ð-Ñ.ˆØ˜NÑ*ˆÜ—v‘v˜h¨QÔ/°%Ñ7ˆŠq�!ˆtŠð ð
 �>‰>˜.Ó)Ð)r@   r€   c                 ó>   — dt        j                  d| dz  z   «      z  S )z/Convert frequency to mel scale (Kaldi formula).ç     œ‘@rw   rx   )r   r   )r€   s    r$   r   r   æ  s   € à”B—F‘F˜3 ¨¡Ñ-Ó.Ñ.Ð.r@   Úmel_freqc                 ó>   — dt        j                  | dz  «      dz
  z  S )z/Convert mel scale to frequency (Kaldi formula).rx   rë   rw   )r   rˆ   )rì   s    r$   r   r   ë  s    € à”B—F‘F˜8 fÑ,Ó-°Ñ3Ñ4Ð4r@   r:   c                 ó<   — | dk(  rdS d| dz
  j                  «       z  S )z7Returns the smallest power of 2 that is greater than x.r   r   r   )Ú
bit_length)r:   s    r$   Ú_next_power_of_2rð   ð  s%   € à�Q’ˆ1Ð5˜A ! a¡%×!3Ñ!3Ó!5Ñ5Ð5r@   ÚwaveformÚwindow_sizeÚwindow_shiftÚ
snip_edgesc                 ó¤  — | j                   d   }|r&||k  rt        j                  d«      S d||z
  |z  z   }n~||dz  z   |z  }|dz  |dz  z
  }|dkD  r@| d|dz    ddd…   }|dkD  r| d| dz
  d…   n| ddd…   }t        j                  || |g«      } n#| ddd…   }t        j                  | | d |g«      } t        j                  | ||f|df¬«      S )zCExtract frames from waveform using strided windowing (Kaldi-style).r   rÝ   r   r   Nr6   rB   )rC   r   rI   r8   rJ   )	rñ   rò   ró   rô   Únum_samplesÚmr7   rã   rä   s	            r$   Ú_get_strided_kaldirø   õ  s  € ð —.‘. Ñ#€KáØ˜Ò$Ü—8‘8˜FÓ#Ð#Ø�˜{Ñ*¨|Ñ;Ñ;‰à˜L¨AÑ-Ñ.°<Ñ?ˆØ˜QÑ °Ñ!2Ñ2ˆà�Š7Ø  C¨!¡GÐ,©T¨r¨TÑ2ˆHØ8;¸aº˜  s d¨Q¡h°Ð!3Ò4ÀXÈbÐQRÐSUÈgÑEVˆIÜ—~‘~ x°¸9Ð&EÓF‰Hà ¡ 2 ™ˆIÜ—~‘~ x°°° ¸	Ð&BÓCˆHä�=‰=˜¨!¨[Ð)9ÀLÐRSÐCTÔUÐUr@   Únum_binsÚwindow_length_paddedÚsample_freqÚlow_freqÚ	high_freqc                 ó  — | dkD  sJ d«       ‚|dz  dk(  sJ ‚|dz  }d|z  }|dk  r||z  }d|cxk  r|k  rn J ‚d|cxk  r|k  sJ ‚ J ‚||z  }t        t        t        j                  |«      «      «      }t        t        t        j                  |«      «      «      }	|	|z
  | dz   z  }
t        j                  | «      j                  dd«      }|||
z  z   }||d	z   |
z  z   }||d
z   |
z  z   }t        |«      }t        |t        j                  |«      z  «      j                  dd«      }||z
  ||z
  z  }||z
  ||z
  z  }t        j                  t        j                  d«      t        j                  ||«      «      }||j                  «       fS )a¡  
    Create Kaldi-compatible mel filterbank matrix.

    Args:
        num_bins: Number of mel bins
        window_length_padded: Padded window length (FFT size)
        sample_freq: Sample frequency in Hz
        low_freq: Low frequency cutoff
        high_freq: High frequency cutoff (0 or negative = relative to Nyquist)

    Returns:
        (bins, center_freqs): Mel filterbank matrix and center frequencies
    rÛ   zMust have at least 3 mel binsr   r   r   rz   r   r6   rw   r�   )rÞ   r   r   r   rZ   r©   r   r�   rI   r’   Úsqueeze)rù   rú   rû   rü   rý   Únum_fft_binsÚnyquistÚfft_bin_widthÚmel_low_freqÚmel_high_freqÚmel_freq_deltaÚbin_idxÚleft_melÚ
center_melÚ	right_melÚcenter_freqsÚmelÚup_slopeÚ
down_slopeÚbinss                       r$   r   r     s§  € ð( �aŠ<Ð8Ð8Ó8ˆ<Ø !Ñ# qÒ(Ð(Ð(à'¨1Ñ,€LØ�KÑ€Gà�CÒØ�WÑˆ	à�8Ô%˜gÔ%ÐGÐG¨C°)Ô,F¸wÒ,FÐGÐGÐ,FÐGÐGàÐ"6Ñ6€MÜœ¬¯©°(Ó);Ó<Ó=€LÜœ/¬"¯(©(°9Ó*=Ó>Ó?€MØ# lÑ2°xÀ!±|ÑD€Nä�i‰i˜Ó!×)Ñ)¨"¨aÓ0€GØ˜g¨Ñ6Ñ6€HØ ¨3¡°.Ñ @Ñ@€JØ ¨#¡°Ñ?Ñ?€Iä*¨:Ó6€LÜ
˜-¬"¯)©)°LÓ*AÑAÓ
B×
JÑ
JÈ1ÈbÓ
Q€Cà�h‘ :°Ñ#8Ñ9€HØ˜c‘/ i°*Ñ&<Ñ=€JÜ�:‰:”b—h‘h˜q“k¤2§:¡:¨h¸
Ó#CÓD€Dà�×%Ñ%Ó'Ð'Ð'r@   Úwin_lenÚwin_incÚnum_melsÚwin_typeÚpreemphasisÚditherc                 ó6  — | j                   dk(  r| d   } ||z  dz  }||z  dz  }t        ||z  dz  «      }t        ||z  dz  «      }t        |«      }t        | |||«      }|j                  d   dk(  rt        j                  d|f«      S |dk7  r1t
        j                  j                  |j                  «      |z  }||z   }t        j                  |dd¬«      }||z
  }|dk7  r>|d	d	…dd…f   }|d	d	…dd	…f   ||d	d	…d	d
…f   z  z
  }t        j                  ||gd¬«      }|dk(  rKt        j                  |«      }ddt        j                  dt
        j                  z  |z  |dz
  z  «      z  z
  }nË|dk(  rKt        j                  |«      }ddt        j                  dt
        j                  z  |z  |dz
  z  «      z  z
  }n{|dk(  rat        j                  |«      }ddt        j                  dt
        j                  z  |z  |dz
  z  «      z  z
  }t        j                  |d«      }nt        j                  |«      }||z  }||k7  r||z
  }t        j                   |dd|fg«      }t
        j"                  j%                  ||d¬«      }t        j&                  |«      dz  }t)        ||t+        |«      |	|
«      \  }}t        j                   |ddg«      }t        j,                  ||j.                  «      }t        j0                  t        j2                  |d«      «      }|S )aš  
    Compute Kaldi-compatible log mel-filterbank features.

    Args:
        waveform: Input audio (1D array)
        sample_rate: Sample rate in Hz
        win_len: Window length in samples
        win_inc: Window shift in samples
        num_mels: Number of mel bins
        win_type: Window type ("hamming", "hanning", "povey", "rectangular")
        preemphasis: Preemphasis coefficient
        dither: Dither amount (0 to disable)
        snip_edges: If True, discard incomplete frames at edges
        low_freq: Low frequency cutoff
        high_freq: High frequency cutoff (0 = Nyquist)

    Returns:
        Log mel-filterbank features (time, num_mels)
    r   r   iè  gü©ñÒMbP?rz   r   T)r2   ÚkeepdimsNr6   r1   r   r'   r(   r   r   Úpoveyg333333ë?rÝ   r¿   r�   )r   r   g:Œ0âŽyE>)ÚndimrÕ   rð   rø   rC   r   rI   ÚrandomÚnormalÚmeanr8   rZ   r   r   ÚpowerÚonesr7   rK   rL   r,   r   rÞ   ÚmatmulÚTr   r�   )rñ   rl   r  r  r  r  r  r  rô   rü   rý   Úframe_length_msÚframe_shift_msÚwindow_shift_samplesrò   Úpadded_window_sizeÚstrided_inputÚ
rand_gaussÚ	row_meansÚ	first_colÚ
other_colsr#   r.   r-   r;   Ú
fft_resultÚspectrumÚmel_energiesÚ_Úmel_featuress                                 r$   r   r   A  s  € ð@ ‡}�}˜ÒØ˜A‘;ˆà Ñ+¨dÑ2€OØ˜{Ñ*¨TÑ1€NÜ˜{¨^Ñ;¸eÑCÓDÐÜ�k OÑ3°eÑ;Ó<€KÜ)¨+Ó6Ðô 'Ø�+Ð3°Zó€Mð ×Ñ˜1Ñ Ò"Ü�x‰x˜˜H˜Ó&Ð&ð �‚}Ü—Y‘Y×%Ñ% m×&9Ñ&9Ó:¸VÑCˆ
Ø%¨
Ñ2ˆô —‘˜¨A¸Ô=€IØ! IÑ-€Mð �cÒØ!¢! Q q S &Ñ)ˆ	Ø"¢1 a¡b 5Ñ)¨K¸-ÊÈ3ÈBÈ3ÈÑ:OÑ,OÑOˆ
ÜŸ™¨	°:Ð'>ÀQÔGˆð �9ÒÜ�I‰I�kÓ"ˆØ˜œrŸv™v a¬"¯%©%¡i°!¡m°{ÀQ±Ñ&GÓHÑHÑH‰Ø	�YÒ	Ü�I‰I�kÓ"ˆØ�sœRŸV™V A¬¯©¡I°¡M°[À1±_Ñ$EÓFÑFÑF‰Ø	�WÒ	Ü�I‰I�kÓ"ˆØ�Sœ2Ÿ6™6 !¤b§e¡e¡)¨a¡-°;À±?Ñ"CÓDÑDÑDˆÜ—‘˜$ Ó%‰ä—‘˜Ó%ˆà! FÑ*€Mð ˜[Ò(Ø$ {Ñ2ˆÜŸ™˜}¨v¸¸7°|Ð.DÓEˆô —‘—‘˜]Ð.@Àq�ÓI€JÜ�v‰v�jÓ! SÑ(€Hô *ØÐ$¤e¨KÓ&8¸(ÀIó�O€L�!ô —6‘6˜,¨°Ð(8Ó9€Lô —9‘9˜X |§~¡~Ó6€LÜ—6‘6œ"Ÿ*™* \°4Ó8Ó9€LàÐr@   )F)i   NNr-   Tr5   )NNr-   TNF)r   NNru   )é   rÜ   )
i€»  i€  i€  é<   r   g
×£p=
ï?rw   Tg      4@rz   ) rÔ   r   Ú__all__Ú	functoolsr   Útypingr   Úmlx.coreÚcorer   r   r   r   r   r   r   rF   r   r	   rÕ   rÞ   r   r
   r   r   r   rð   rÖ   rø   r±   r   r   r×   r@   r$   Ú<module>r5     s4  ðñó ò€õ"  Ý å ñ �4Ôò
ó ð
ñ �4Ôò
ó ð
ñ �4Ôò
ó ð
ñ �4ÔòOó ðOð ØØØØñÐ ð ØØØ#ØØñ1#ð
 �H‰H�s‰Nó1#ðl ØØØØØóIñ^ �4Ôð
 Ø!ØØñHØðHàðHð ðHð ð	Hð
 �E‰?ðHð �3‰-ðHð ðHð ‡X�XòHó ðH÷VD
ñ D
ðZ :@ñ,*Ø�h‰hð,*Ø$'ð,*Ø36ð,*à‡X�Xó,*ð^/˜"Ÿ(™(ð / r§x¡xó /ð
5 b§h¡hð 5°2·8±8ó 5ð
6˜ð 6 ó 6ð
VØ�h‰hðVØ%(ðVØ8;ðVØIMðVà‡X�XóVð20(Øð0(àð0(ð ð0(ð ð	0(ð
 ð0(ð ˆ2�8‰8�R—X‘XÐÑó0(ðj ØØØØØØØØØñcØ�h‰hðcàðcð ðcð ð	cð
 ðcð ðcð ðcð ðcð ðcð ðcð ðcð ‡X�Xôcr@   