Ë
    žAæjù$  ã                  ó6  — d 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m	Z	 ddl
mZ ddlZddlmZ ddlmZmZ dd	lmZmZmZmZ dd
lmZmZmZ  ej8                  d«      ZdZdZe G d„ d«      «       Z dd„Z!ddd„Z"dd„Z#dd„Z$ddd„Z%d d„Z&d!d„Z'd"d„Z(d#d„Z)y)$až  Track discovery for m x n evaluation: which audio stream is the original, which streams are dubs,
and what language each one really is.

Container language tags are unreliable (the 3 Idiots original is tagged `eng` but is Hindi), so every
candidate stream gets Whisper language-ID on its speech. Streams that are a bit-for-bit copy of the
original audio (dub files often carry the source track along) are skipped.
é    )ÚannotationsN)Ú	dataclassÚfield)ÚPath)Úfftconvolveé   )ÚaudioÚspeech)ÚLangÚbase_ofÚresolveÚsame_language)ÚProbeÚextract_audioÚprobe_cachedÚdubevalç      à?gÍÌÌÌÌÌì?c                  ó  — e Zd ZU ded<   ded<   ded<   ded<   ded	<   ded
<   dZded<   dZded<    edd¬«      Zded<    edd¬«      Zded<    edd¬«      Z	ded<   e
dd„«       Ze
dd„«       Ze
d d„«       Zd!d„Zd"d„Zd#d„Zy)$ÚTrackÚstrÚroler   ÚpathÚintÚindexÚdictÚstreamÚdirÚlidNzLang | NoneÚlangÚdetectedÚlang_sourceF)ÚdefaultÚreprznp.ndarray | NoneÚ_xzdict | NoneÚ_asrztuple | NoneÚ_stemsc                ó.   — | j                   j                  S ©N)r   Úname©Úselfs    ú2/root/repos/pocs/video-evals/src/dubeval/tracks.pyÚslugz
Track.slug,   s   € à�x‰x�}‰}Ðó    c                ó    — | j                   dz  S )Núa16k.wav)r   r*   s    r,   Úwavz	Track.wav0   s   € à�x‰x˜*Ñ$Ð$r.   c                óz   — | j                   €$t        j                  | j                  «      | _         | j                   S r(   )r$   r
   Úloadr1   r*   s    r,   ÚxzTrack.x4   s(   € à�7‰7ˆ?Ü—k‘k $§(¡(Ó+ˆDŒGØ�w‰wˆr.   c           	     óð   — | j                   €_t        j                  | j                  | j                  | j
                  dz  |j                  |j                  |j                  |«      | _         | j                   S )Nzasr.json)	r%   r
   Ú
transcriber1   r   r   Úasr_cloud_modelÚasr_local_modelÚthreads)r+   ÚcfgÚwarningss      r,   Úasrz	Track.asr:   sZ   € Ø�9‰9ÐÜ×)Ñ)¨$¯(©(°D·I±I¸t¿x¹xÈ*Ñ?TÐVY×ViÑViØ*-×*=Ñ*=¸s¿{¹{ÈHóVˆDŒIà�y‰yÐr.   c                ó  — | j                   €³| j                  | j                  df| _         |r“	 t        | j                  | j                  | j
                  dz  d«      }t        j                  || j
                  dz  |«      \  }}t        j                  |«      t        j                  |«      df| _         | j                   S | j                   S # t        $ r6}|j                  d| j                  › d|› �«       Y d}~| j                   S d}~ww xY w)	zI(vocals, background, separated). Without separation both are the raw mix.NFza44k.waviD¬  ÚsepTzdemucs separation failed for z, using raw mix: )r&   r4   r   r   r   r   r	   Úseparater
   r3   Ú	ExceptionÚappendr-   )r+   Úenabledr9   r;   Úwav44ÚvÚbÚes           r,   ÚstemszTrack.stems@   sá   € à�;‰;ÐØŸ6™6 4§6¡6¨5Ð1ˆDŒKÙðeÜ)¨$¯)©)°T·Z±ZÀÇÁÈJÑAVÐX]Ó^�EÜ Ÿ>™>¨%°·±¸EÑ1AÀ7ÓK‘D�A�qÜ#)§;¡;¨q£>´6·;±;¸q³>À4Ð"H�D”Kð �{‰{Ðˆt�{‰{Ðøô !ò eØ—O‘OÐ&CÀDÇIÁIÀ;ÐN_Ð`aÐ_bÐ$c×dÐdØ�{‰{Ðûðeús   ®BC Ã	DÃ!DÄDc                óô   — t        | j                  «      | j                  | j                  j	                  d«      | j
                  | j                  €d n| j                  j                  «       | j                  dœS )Nr   )ÚfileÚaudio_indexÚcontainer_tagr    ÚlanguageÚlanguage_source)	r   r   r   r   Úgetr   r   Úto_dictr!   r*   s    r,   ÚdescribezTrack.describeM   s_   € Ü˜DŸI™I›°t·z±zÐTX×T_ÑT_×TcÑTcÐdjÓTkØ ŸH™H¸$¿)¹)Ð:K±$ÐQU×QZÑQZ×QbÑQbÓQdØ#'×#3Ñ#3ñ5ð 	5r.   )Úreturnr   )rQ   r   )rQ   ú
np.ndarray)r;   ú	list[str]rQ   r   )rB   Úboolr9   r   r;   rS   rQ   z#tuple[np.ndarray, np.ndarray, bool])rQ   r   )Ú__name__Ú
__module__Ú__qualname__Ú__annotations__r   r!   r   r$   r%   r&   Úpropertyr-   r1   r4   r<   rG   rP   © r.   r,   r   r      s±   … à
ƒIØ
ƒJØƒJØƒLØ	ƒIØ	ƒIØ€Dˆ+ÓØ!€K�Ó!Ù!¨$°UÔ;€BÐÓ;Ù d°Ô7€Dˆ+Ó7Ù ¨°EÔ:€FˆLÓ:àòó ðð ò%ó ð%ð òó ðó
óô5r.   r   c                óð   — t        j                  t        | j                  «       «      j	                  «       «      j                  «       d d }t        j                  dd| j                  «      d d › d|› d|› �S )Né   z[^A-Za-z0-9._-]+Ú_é0   ú-z.a)	ÚhashlibÚsha1r   r   ÚencodeÚ	hexdigestÚreÚsubÚstem)r   r   Úhs      r,   Ú_slugrh   S   se   € Ü�‰”S˜Ÿ™›Ó(×/Ñ/Ó1Ó2×<Ñ<Ó>¸rÀÐB€AÜ�f‰fÐ(¨#¨t¯y©yÓ9¸#¸2Ð>Ð?¸qÀÀÀ2ÀeÀWÐMÐMr.   c                ó   — t        j                  | «      }g d}}|D ]\  \  }}|j                  | t        |t         j                  z  «      t        |t         j                  z  «       «       |||z
  z  }||k\  sŒ\ n |dk  rddg dœS t        j
                  ||«      }	|	j                  t        j                  |«      d¬«      \  }
}}|
t        t        |«      d«      |dd D ��cg c]  \  }}|t        t        |«      d«      g‘Œ c}}dœS c c}}w )z^Whisper language-ID over the first `max_speech` seconds of VAD speech (music/silence removed).g        g      @N)r   ÚprobÚtopé   )r	   Úlanguage_detection_segmentsé   )r
   Úvad_segmentsrA   r   ÚSRÚwhisper_modelÚdetect_languageÚnpÚconcatenateÚroundÚfloat)r4   Úmodelr9   Ú
max_speechÚsegsÚchunksÚtotalÚsrF   ÚmÚcoderj   ÚallpÚcÚps                  r,   rr   rr   X   s
  € ä×Ñ˜qÓ!€DØ˜ˆE€FØò ‰ˆˆ1Ø�‰�aœ˜A¤§	¡	™MÓ*¬3¨q´6·9±9©}Ó+=Ð>Ô?Ø��Q‘‰ˆØ�JÓÙð	ð
 ˆs‚{Ø c°"Ñ5Ð5Ü×Ñ˜U GÓ,€AØ×(Ñ(¬r¯~©~¸fÓ/EÐcdÐ(ÓeÑ€Dˆ$�Ø¤%¬¨d«°QÓ"7ÐeiÐjlÐklÐem×@nÑ]aÐ]^Ð`aÀ!ÄUÌ5ÐQRË8ÐUVÓEWÒAXÓ@nÑoÐoùÓ@ns   Ã#!D

c                ó  — t        | «      }|dz  t        | |«      z  }|j                  dd¬«       t        | ||dz  t        j
                  «       |dz  }|j                  «       r$t        j                  |j                  «       «      }n[t        t	        j                  |dz  «      |j                  |j                  «      }|j                  t        j                  |«      «       t!        || ||j"                  |   ||«      S )NÚtracksT)ÚparentsÚexist_okr0   zlid.json)r   rh   Úmkdirr   r
   rp   ÚexistsÚjsonÚloadsÚ	read_textrr   r3   r8   r9   Ú
write_textÚdumpsr   r	   )	r   r   r   Úworkr:   r�   ÚdÚlid_filer   s	            r,   Ú_openr�   h   sÌ   € Ü�TÓ€AØˆx‰œ%  eÓ,Ñ,€AØ‡G�G�D 4€GÔ(Ü�$˜˜q :™~¬v¯y©yÔ9Ø�:‰~€HØ‡�ÔÜ�j‰j˜×+Ñ+Ó-Ó.‰äœfŸk™k¨!¨j©.Ó9¸3×;NÑ;NÐPS×P[ÑP[Ó\ˆØ×ÑœDŸJ™J s›OÔ,Ü��t˜U A§G¡G¨E¡N°A°sÓ;Ð;r.   c                óœ   — |j                  d«      r|j                  dd«      t        k\  r|d   S t        | «      xs |j                  d«      S )z^Language code we believe a stream is in: confident detection > container tag > weak detection.r   rj   r   )rN   ÚLID_MIN_PROBr   )Ú
stream_tagr   s     r,   Úeffective_langr”   v   sA   € à
‡w�wˆv„˜3Ÿ7™7 6¨1Ó-´Ò=Ø�6‰{ÐÜ�:ÓÒ1 #§'¡'¨&£/Ð1r.   c           
     óÂ  — t        t        | «      t        |«      «      }t        |t        j                  z  «      }||k  r|}t        d|dz  |dz  z
  «      }| |||z    j                  t        j                  «      ||||z    j                  t        j                  «      }}t        j                  |dz  j                  «       |dz  j                  «       z  «      }	|	dk  ryt        ||d d d…   d«      }
t        |t        j                  z  «      |dz
  }}t        t        j                  |
t        d||z
  «      ||z   dz    «      j                  «       |	z  «      t        k\  S )Nr   é   g•Ö&è.>FéÿÿÿÿÚfullr   )ÚminÚlenr   r
   rp   ÚmaxÚastypers   Úfloat64ÚsqrtÚsumr   rv   ÚabsÚPASSTHROUGH_CORR)ÚarE   ÚwindowÚmax_lagÚnÚwÚmidÚxaÚxbÚdenomÚrÚkr€   s                r,   Úis_passthroughr­   }   s+  € ÜŒC�‹F”C˜“FÓ€AÜˆF”V—Y‘YÑÓ€AØˆ1‚uØˆÜ
ˆa��a‘˜!˜q™&‘Ó
!€CØˆs�3˜‘7ˆ^×"Ñ"¤2§:¡:Ó.°°#°c¸A±g°×0EÑ0EÄbÇjÁjÓ0Qˆ€BÜ�G‰G�R˜1‘W—M‘M“O r¨Q¡w§m¡m£oÑ5Ó6€EØˆt‚|ØÜ�B˜™4˜R˜4™ &Ó)€AÜˆwœŸ™Ñ"Ó# Q¨¡U€q€AÜ”—‘˜œ#˜a  Q¡›-¨¨A©°©	Ð2Ó3×7Ñ7Ó9¸EÑAÓBÔFVÑVÐVr.   c                óª  ‡‡— | D �cg c]  }|d   sŒ	|d   ddœ‘Œ }}| D �cg c]
  }|d   rŒ	|‘Œ c}Št        ‰«      dk(  rnt        |«      dk(  r|d   nd}t        |«      dkD  r>t        ˆfd„|D «       «      s*|j                  ‰d   d   d	‰d   d
   › d|› �dœ«       g |fS ‰d   d   |fg|fS g }‰D ]�  Št        ‰d
   |«      r|j                  ‰d   d‰d
   › d�dœ«       Œ1|r5t        ˆfd„|D «       «      s!|j                  ‰d   d	‰d
   › d|› �dœ«       Œh|j                  ‰d   t	        ˆfd„|D «       d«      f«       Œ’ ||fS c c}w c c}w )a½  Pure selection rule. cands: [{"index", "lang", "passthrough"}]; wanted: requested base codes.

    Returns ([(index, declared base code or None)], [skipped {"index", "reason"}]).
    - passthrough copies of the original are never evaluated;
    - a lone remaining stream is always evaluated (even if it is in the wrong language: that is a defect);
    - otherwise streams in the source language are skipped and `wanted` filters by language.
    Úpassthroughr   zidentical to original audio)r   Úreasonr   r   Nc              3  óB   •K  — | ]  }t        ‰d    d   |«      –— Œ y­w)r   r   N©r   )Ú.0r¦   Úrests     €r,   ú	<genexpr>zchoose_dubs.<locals>.<genexpr>˜   s    øè ø€ Ò&YÈQ¤}°T¸!±W¸V±_Àa×'HÑ&Yùs   ƒz	language r   z not in zsame language as original (ú)c              3  ó<   •K  — | ]  }t        ‰d    |«      –— Œ y­w©r   Nr²   ©r³   r¦   r€   s     €r,   rµ   zchoose_dubs.<locals>.<genexpr>    s   øè ø€ ÒLÀ¤¨a°©i¸× ;ÑLùs   ƒc              3  óB   •K  — | ]  }t        ‰d    |«      sŒ|–— Œ y­wr¸   r²   r¹   s     €r,   rµ   zchoose_dubs.<locals>.<genexpr>£   s"   øè ø€ Ò,^°1Ä-ÐPQÐRXÑPYÐ[\ÕB]¬QÑ,^ùs   ƒ˜)rš   ÚanyrA   r   Únext)ÚcandsÚsrcÚwantedr€   ÚskippedÚdeclaredÚpickedr´   s      `   @r,   Úchoose_dubsrÃ   Œ   s—  ù€ ð X]ÖqÐRSÐ`aÐboÓ`p˜˜7™Ð/LÓMÐq€GÐqØÖ5�! A mÓ$4ŠAÒ5€DÜ
ˆ4ƒy�A‚~Ü # F£¨qÒ 0�6˜!’9°dˆÜˆv‹;˜Š?¤3Ó&YÐRXÔ&YÔ#YØ�N‰N T¨!¡W¨WÑ%5À9ÈTÐRSÉWÐU[É_ÐL]Ð]eÐflÐemÐAnÑoÔpØ�w�;ÐØ�a‘˜Ñ! 8Ð,Ð-¨wÐ6Ð6Ø+-€FØò hˆÜ˜˜6™ CÔ(Ø�N‰N Q w¡ZÐ=XÐYZÐ[aÑYbÐXcÐcdÐ;eÑfÕgÙœCÓLÀVÔLÔLØ�N‰N Q w¡Z¸YÀqÈÁyÀkÐQYÐZ`ÐYaÐ;bÑcÕdà�M‰M˜1˜W™:¤tÓ,^¸Ô,^Ð`dÓ'eÐfÕgðhð �7ˆ?Ðùò! rùÚ5s   ‡
E’
E¢
E­Ec                óZ  — |rt        |«      dc| _        | _        | S t        | j                  j                  d«      | j                  «      }|€&t        d| j                  › d| j                  › d�«      ‚t        |«      | _        || j                  j                  d«      k(  rdnd| _        | S )NrÁ   r   zcannot determine language of z audio z; pass it explicitlyr    Útag)
r   r   r!   r”   r   rN   r   Ú
ValueErrorr   r   )ÚtrÁ   r~   s      r,   Ú_assignrÈ   §   s–   € ÙÜ '¨Ó 1°:ÐˆŒ�”ð €Hô ˜aŸh™hŸl™l¨6Ó2°A·E±EÓ:ˆØˆ<ÜÐ<¸Q¿V¹V¸HÀGÈAÏGÉGÈ9ÐThÐiÓjÐjÜ˜“ˆŒØ&*¨a¯e©e¯i©i¸Ó.?Ò&?™
ÀUˆŒØ€Hr.   c           	     ó  — t        | «      }|j                  st        | › d�«      ‚|j                  �|j                  }nŸt	        |j                  «      dk(  s|j
                  €d}nxd}|j                  D ]g  }t        | |d   d||«      }t        t        |j                  d«      |j                  «      t        |j
                  «      j                  «      sŒb|d   } n t        t        | |d||«      |j
                  «      S )Nz has no audio streamr   r   r   Úoriginalr   )r   r	   rÆ   Ú
orig_audiorš   Úsrc_langr�   r   r”   rN   r   r   ÚbaserÈ   )r   r:   r�   r�   Úidxr¢   rÇ   s          r,   Úoriginal_trackrÏ   ³   sÝ   € Ü˜DÓ!€AØ�7Š7Ü˜D˜6Ð!5Ð6Ó7Ð7Ø
‡~�~Ð!Ø�n‰n‰Ü	ˆQ�W‰W‹˜Ò	˜cŸl™lÐ2Ø‰àˆØ—‘ò 	ˆAÜ�d˜A˜g™J¨
°D¸#Ó>ˆAÜœ^¨A¯E©E°&«M¸1¿5¹5ÓAÄ7È3Ï<É<ÓCX×C]ÑC]Õ^Ø˜‘j�Ùð		ô
 ”5˜˜s J°°cÓ:¸C¿L¹LÓIÐIr.   c           
     ój  — t        | «      }|j                  D �cg c]  }t        |«      j                  ‘Œ }}|j                  D �ci c]+  }t        |«      j                  t        |«      j                  “Œ- }}|j
                  �;t        | |j
                  d||«      }t        |t        |«      dk(  r|d   nd «      gg fS i }	g }
|j                  D ]u  }t        | |d   d||«      }||	|d   <   |
j                  |d   t        |j                  d«      |j                  «      t        |j                  |j                  «      dœ«       Œw t!        |
|j"                  j                  |j                  D �cg c]  }t        |«      j                  ‘Œ c}«      \  }}|D ]N  }|j%                  t'        | «      |	|d      j                  |j                  |d      j                  d«      ¬«       ŒP |D ��cg c]'  \  }}t        |	|   |r|j                  |«      nd «      ‘Œ) c}}|fS c c}w c c}w c c}w c c}}w )NÚdubr   r   r   r   )r   r   r¯   )rI   r    rK   )r   Ú	tgt_langsr   rÅ   rÍ   Ú	dub_audior�   rÈ   rš   r	   rA   r”   rN   r   r­   r4   rÃ   r   Úupdater   )r   r¾   r:   r�   r�   r¦   r¿   Úby_tagrÇ   rƒ   r½   r¢   rÂ   rÀ   r|   ÚirŽ   s                    r,   Ú
dub_tracksr×   Å   sô  € Ü�TÓ€AØ&)§m¡mÖ4 Œg�a‹j�n‹nÐ4€FÐ4Ø7:·}±}ÖE°!Œg�a‹j�o‰oœw q›zŸ~™~Ñ-ÐE€FÐEØ
‡}�}Ð Ü�$˜Ÿ™ u¨d°CÓ8ˆÜ˜¬¨F«°qÒ(8˜6 !š9¸dÓCÐDÀbÐHÐHØ!€FØ€EØ�W‰Wò BˆÜ�$˜˜'™
 E¨4°Ó5ˆØˆˆq�‰zÑØ�‰˜q ™z´>À!Ç%Á%ÈÃ-ÐQR×QVÑQVÓ3WÜ%3°C·E±E¸1¿3¹3Ó%?ñAõ 	BðBô
 " %¨¯©¯©ÐRU×R_ÑR_Ö8`ÈQ¼À»¿»Ò8`Óa�O€FˆGØò qˆØ	�‰”c˜$“i¨&°°7±Ñ*<×*@Ñ*@ÐPQ×PWÑPWÐXYÐZaÑXbÑPc×PgÑPgÐhnÓPoˆÕpðqàIO×PÁÀÀAŒG�F˜1‘I±˜vŸz™z¨!œ}°tÕ<ÓPÐRYÐYÐYùò 5ùÚEùò 9aùó Qs   šH Á0H%Å0H*Ç.,H/)r   r   r   r   rQ   r   )g      ^@)
r4   rR   rw   r   r9   r   rx   rv   rQ   r   )
r   r   r   r   r   r   r�   r   rQ   r   )r“   ú
str | Noner   r   rQ   rØ   )g      4@r   )
r¢   rR   rE   rR   r£   rv   r¤   rv   rQ   rT   )r½   z
list[dict]r¾   rØ   r¿   rS   rQ   z/tuple[list[tuple[int, str | None]], list[dict]])rÇ   r   rÁ   rØ   rQ   r   )r   r   r�   r   rQ   r   )r   r   r¾   r   r�   r   rQ   ztuple[list[Track], list[dict]])*Ú__doc__Ú
__future__r   r`   rˆ   Úloggingrd   Údataclassesr   r   Úpathlibr   Únumpyrs   Úscipy.signalr   Ú r	   r
   r   r   r   r   r   Úmediar   r   r   Ú	getLoggerÚlogr’   r¡   r   rh   rr   r�   r”   r­   rÃ   rÈ   rÏ   r×   rZ   r.   r,   ú<module>rä      sŸ   ðñõ #ã Û Û Û 	ß (Ý ã Ý $ç ß 7Ó 7ß 5Ñ 5à€g×Ñ˜	Ó"€à€ØÐ ð ÷15ð 15ó ð15óhNô
pó <ó2ôWóó6	óJô$Zr.   