o
    is8                     @   sx   d Z ddlZddlZddlZddlZddlmZmZmZm	Z	 ddl
mZ ddlmZmZmZmZmZ G dd deZdS )	a  
IndicMFA Validator
==================

Montreal Forced Aligner (MFA) with AI4Bharat Indic acoustic models.
https://github.com/AI4Bharat/IndicMFA

Requirements:
- MFA must be installed via conda: `conda install -c conda-forge montreal-forced-aligner`
- Or use the fallback CTC segmentation method

Features:
- Precise word and phone level alignments
- Language-specific acoustic models for Indian languages
- TextGrid output with timing information
    N)OptionalListDictAny)Path   )BaseValidatorValidationResultWordAlignmentValidatorStatusnormalize_language_codec                	       s&  e Zd ZdZdZdZddddddddddddd	d	dd
ZdddddddZ			d.dede	def fddZ
defddZdefddZdefddZde	de	d e	dee fd!d"Zd#edee fd$d%Zde	de	d e	defd&d'Z	(	)d/de	dee	 d e	defd*d+Zd,d- Z  ZS )0IndicMFAValidatorz
    Validator using Montreal Forced Aligner with Indic models.
    
    Provides precise word-level alignments using forced alignment.
    Requires reference text for alignment.
    indicmfaz<Montreal Forced Aligner with AI4Bharat Indic acoustic models
telugu_mfa)acoustic
dictionary	hindi_mfa	tamil_mfabengali_mfaenglish_mfa)tehitabnenzVhttps://github.com/AI4Bharat/IndicMFA/releases/download/v1.0/telugu_acoustic_model.zipzRhttps://github.com/AI4Bharat/IndicMFA/releases/download/v1.0/telugu_dictionary.txtzUhttps://github.com/AI4Bharat/IndicMFA/releases/download/v1.0/hindi_acoustic_model.zipzQhttps://github.com/AI4Bharat/IndicMFA/releases/download/v1.0/hindi_dictionary.txt)r   r   T./models/indicmfaenabled
models_diruse_ctc_fallbackc                    s<   t  jdd|i| t|| _|| _d| _d| _d| _dS )z
        Initialize IndicMFA validator.
        
        Args:
            enabled: Whether validator is active
            models_dir: Directory for MFA models
            use_ctc_fallback: Use CTC segmentation if MFA unavailable
        r   N )super__init__r   r   r   _mfa_available
_ctc_model_ctc_processor)selfr   r   r   kwargs	__class__r   B/home/ubuntu/maya3_transcribe/src/validators/indicmfa_validator.pyr!   A   s   

zIndicMFAValidator.__init__returnc              	   C   s   | j dur| j S z*tjddgdddd}|jdk| _ | j r/td| j d	|j   W | j S W | j S  tjt	fyC   d
| _ Y | j S w )z(Check if MFA is installed and available.NmfaversionT
   capture_outputtexttimeoutr   [z] MFA version: F)
r"   
subprocessrun
returncodeprintnamestdoutstripTimeoutExpiredFileNotFoundError)r%   resultr   r   r)   _check_mfa_availableW   s&   
z&IndicMFAValidator._check_mfa_availablec                 C   sx   t d| j d |  rt d| j d dS | jr(t d| j d |  S t d| j d t d| j d dS )	zSetup MFA or CTC fallback.r2   z] Checking MFA availability...z] MFA is availableTz,] MFA not available, setting up CTC fallbackz+] MFA not available and no fallback enabledzC] Install MFA: conda install -c conda-forge montreal-forced-alignerF)r6   r7   r=   r   _setup_ctc_fallback)r%   r   r   r)   setupk   s   zIndicMFAValidator.setupc              
   C   s   zHddl }ddlm}m} td| j d d}||| _||| _|j	
 r+dnd}| j| | j  || _td| j d	|  W d
S  tyn } ztd| j d|  ddl}|  W Y d}~dS d}~ww )z&Setup CTC-based alignment as fallback.r   N)Wav2Vec2ForCTCWav2Vec2Processorr2   z*] Loading Wav2Vec2 for CTC segmentation...z(anuragshas/wav2vec2-large-xlsr-53-telugucudacpuz] CTC fallback ready on Tz] CTC fallback setup failed: F)torchtransformersr@   rA   r6   r7   from_pretrainedr$   r#   rB   is_availabletoeval_device	Exception	traceback	print_exc)r%   rD   r@   rA   
model_namedeviceerL   r   r   r)   r>   {   s(   
z%IndicMFAValidator._setup_ctc_fallback
audio_pathreference_textlanguagec                 C   s  t |}t }t|}t|j}ddl}|| d }	ddl}
|
|\}}|
|	|| || d }|	| |d }|
  | j|| jd}ddt||d	 |d
 t|dg}z>tj|dddd}|jdkrtd| j d|j  g W W  d   S || d }| r| |W W  d   S W n/ tjy   td| j d Y n% ty } ztd| j d|  W Y d}~nd}~ww W d   g S W d   g S W d   g S 1 sw   Y  g S )z#Perform forced alignment using MFA.r   Nz.wavz.txtalignedr   r+   alignr   r   z--cleanTi,  r.   r2   z] MFA error: z	.TextGridz] MFA timeout)r   tempfileTemporaryDirectoryr   stemshutil	soundfilereadwrite
write_textmkdir
MFA_MODELSgetstrr3   r4   r5   r6   r7   stderrexists_parse_textgridr:   rK   )r%   rQ   rR   rS   	lang_codetemp_dir	temp_path
audio_namerY   
audio_destsfdatasrtranscript_path
output_dirmodelscmdr<   textgrid_pathrP   r   r   r)   _align_with_mfa   sl   


	
/
0"
8
8
88z!IndicMFAValidator._align_with_mfarq   c           	   
   C   s   zBddl m} |jt|dd}g }dD ]+}||jv r?||}|jD ]}|j r:|	t
|j |j|jdd q# |W S q|W S  tyV   td| j d	 g  Y S  tyt } ztd| j d
|  g W  Y d}~S d}~ww )z/Parse TextGrid file to extract word alignments.r   )textgridF)includeEmptyIntervals)wordswordWords      ?rv   
start_timeend_time
confidencer2   z:] praatio not installed, install with: pip install praatioz] TextGrid parse error: N)praatiors   openTextgridra   	tierNamesgetTierentrieslabelr9   appendr
   startendImportErrorr6   r7   rK   )	r%   rq   rs   tg
alignments	tier_nametierintervalrP   r   r   r)   rd      s8   



z!IndicMFAValidator._parse_textgridc              	   C   s~  ddl }ddl}ddl}||\}}|dkr8ddl}	|| d}
|	j	|d}||
}
|

  }d}t|| }t| dd}| j||ddd}|j|}|  | |}|j }W d   n1 slw   Y  | }g }|rtd	d
 |D }d}|D ]!}|dkrt|| | nd}|t|||| dd ||7 }q|j|dd}|jddj  }|||fS )z)Perform alignment using CTC segmentation.r   Ni>  rJ   rC   ptT)sampling_ratereturn_tensorspaddingc                 s   s    | ]}t |V  qd S )N)len).0wr   r   r)   	<genexpr>'  s    z4IndicMFAValidator._align_with_ctc.<locals>.<genexpr>g        g?ry   )dim)rD   rZ   numpyr[   
torchaudio
from_numpyfloat	unsqueeze
transformsResamplesqueezer   getattrr$   input_valuesrH   no_gradr#   logitsrC   splitsumr   r
   softmaxmaxvaluesmeanitem)r%   rQ   rR   rS   rD   rj   nprk   rl   r   waveform	resamplerdurationrO   inputsr   outputsr   ru   r   total_charscurrent_timerv   word_durationprobsr|   r   r   r)   _align_with_ctc   sR   



z!IndicMFAValidator._align_with_ctcNr   c                 C   sH  | j st| j|dddS |st| j|dddS |  s$t| j|dddS t }t|}zM|  rN| |||}d}d}dd	l}	|		|\}
}t
|
| }n| |||\}}}d
}t | }t| j|t
|dk||||||||t
|dd
W S  ty } zdd	l}|  t| j|dt|t | dW  Y d	}~S d	}~ww )a5  
        Align audio with reference text.
        
        Args:
            audio_path: Path to audio file
            reference_text: Reference transcription (REQUIRED for alignment)
            language: Language code
            
        Returns:
            ValidationResult with word alignments
        FzValidator disabled)validator_namerQ   successerror_messagez,Reference text required for forced alignmentzMFA/CTC not availabler+   rx   r   Nctc_fallback)rS   method
word_count)
r   rQ   r   transcriptionword_alignmentsoverall_confidencealignment_scoreprocessing_time_secaudio_duration_sec
raw_output)r   rQ   r   r   r   )r   r	   r7   ensure_setuptimer   r=   rr   rZ   r[   r   r   rK   rL   rM   ra   )r%   rQ   rR   rS   rz   re   r   r   r|   rj   rk   rl   r   processing_timerP   rL   r   r   r)   validate:  s~   


zIndicMFAValidator.validatec                 C   sL   | j dur
| ` d| _ | jdur| `d| _ddl}|j r$|j  dS dS )zRelease resources.Nr   )r#   r$   rD   rB   rG   empty_cache)r%   rD   r   r   r)   cleanup  s   


zIndicMFAValidator.cleanup)Tr   T)Nr   )__name__
__module____qualname____doc__r7   descriptionr_   INDICMFA_URLSboolra   r!   r=   r?   r>   r   r
   rr   r   rd   tupler   r   r	   r   r   __classcell__r   r   r'   r)   r   !   sz    
D 
B
\r   )r   osr   rV   r3   typingr   r   r   r   pathlibr   baser   r	   r
   r   r   r   r   r   r   r)   <module>   s    	