Ë
    àAæj¦  ã                  óÈ   — d Z ddlmZ ddlZddlZddlZddlmZ ddlZ	ddl
mZ ddlmZmZmZ  ej                   d«      Zd	Zdd
„Zddd„Zddd„Z	 d	 	 	 	 	 	 	 dd„Zddd„Zy)a  Audio layer: background-bed integrity and delivery-energy mismatch.

Works on the raw mixes by default. If Demucs stems are available (`--separate`), vocals are used for
energy comparison and the accompaniment stems for the background check, which removes the speech bias.
é    )ÚannotationsN)ÚPath)Úfftconvolveé   )ÚSRÚloadÚmaskÚdubevalg{®Gáz„?c                ó$  — |dz  | j                   z  }|| j                   › d�z  || j                   › d�z  }}|j                  «       r|j                  «       s·|dz  j                  «       sMt        j                  t        j
                  dddddd	d
t        |«      dt        |«      t        | «      gdd¬«       |dz  |f|dz  |ffD ]F  \  }}t        j                  dddddt        |«      dddt        t        «      t        |«      gd¬«       ŒH ||fS )zPhtdemucs two-stem split on CPU; returns (vocals, no_vocals) as 16 kHz mono wavs.Úhtdemucsz.vocals.wavz.bed.wavz
vocals.wavz-mÚdemucsz-nz--two-stemsÚvocalsz-jz-oT)ÚcheckÚcapture_outputzno_vocals.wavÚffmpegz-vÚerrorz-yz-iz-acÚ1z-ar)r   )ÚstemÚexistsÚ
subprocessÚrunÚsysÚ
executableÚstrr   )Úwav44Úout_dirÚthreadsr   Úvocals16Úbed16ÚsrcÚdsts           ú1/root/repos/pocs/video-evals/src/dubeval/audio.pyÚseparater#      s  € à�ZÑ %§*¡*Ñ,€DØ 5§:¡: ,¨kÐ :Ñ:¸GÈÏÉÈÐT\ÐF]Ñ<]ˆe€HØ�O‰OÔ %§,¡,¤.Ø�|Ñ#×+Ñ+Ô-Ü�N‰NœCŸN™N¨D°(¸DÀ*ÈmÐ]eØ ¤# g£,°´c¸'³lÄCÈÃJðPØW[Ðlpõrà Ñ-¨xÐ8¸4À/Ñ;QÐSXÐ:YÐZò 	'‰HˆC�Ü�N‰N˜H d¨G°T¸4ÄÀSÃÈ5ÐRUÐW\Ô^aÔbdÓ^eÔgjÐknÓgoÐpØ!%ö'ð	'ð �Uˆ?Ðó    c                óR  — t        |t        z  «      t        t        t        z  «      }}t        | «      |z  }t	        j
                  | j                  t        j                  «      dz  t	        j                  |«      |z  d¬«      d||z  |…   }dt	        j                  |dz   «      z  S )z dBFS envelope at HOP resolution.é   Úsame©ÚmodeNé
   g»½×Ùß|Û=)
Úintr   ÚHOPÚlenÚnpÚconvolveÚastypeÚfloat64ÚonesÚlog10)ÚxÚwinÚnÚhÚframesÚsqs         r"   Úrms_dbr:   $   s�   € äˆs”R‰x‹=œ#œc¤B™h›-€q€AÜ�‹V�q‰[€FÜ	�‰�Q—X‘XœbŸj™jÓ)¨QÑ.´·±¸³
¸Q±ÀVÔ	LÈ_ÈvÐXYÉzÐ[\È_Ñ	]€BØ”—‘˜˜e™Ó$Ñ$Ð$r$   c                ó¶  — | | j                  «       z
  ||j                  «       z
  }}t        ||ddd…   d«      }t        |«      dz
  }t        |t        z  «      }|||z
  ||z   dz    }t        |j                  «       «      }	||	   t        j                  |dz  j                  «       |dz  j                  «       z  «      dz   z  }
|	|z
  t        z  t        |
«      fS )zULag (s) of b relative to a and normalised correlation peak, on downsampled envelopes.NéÿÿÿÿÚfullr   r&   g•Ö&è.>)
Úmeanr   r-   r+   r,   Úargmaxr.   ÚsqrtÚsumÚfloat)ÚaÚbÚ	max_shiftÚeaÚebÚrÚmidÚkr5   ÚiÚpeaks              r"   Úbest_offsetrM   ,   sÄ   € à�—‘“‰\˜1˜qŸv™v›x™<ˆ€BÜ�B˜™4˜R˜4™ &Ó)€AÜ
ˆb‹'�A‰+€CÜˆIœ‰OÓ€AØ
ˆC�!‰G�S˜1‘W˜q‘[Ð
!€CÜˆC�J‰J‹LÓ€AØˆq‰6”R—W‘W˜b A™gŸ]™]›_°°a±¯}©}«Ñ>Ó?À$ÑFÑG€DØ�‰E”S‰=œ% ›+Ð%Ð%r$   c                ó*  — t        | «      t        |«      }	}t        t        |«      t        |	«      «      }
|d|
 |	d|
 }	}t        |dt        |
d«       |	dt        |
d«       «      \  }}|rt	        j
                  |
t        «      }n*t        ||t        «      d|
 t        ||t        «      d|
 z   }|dkD  }||z  ||	z
  |kD  z  }d}t	        j                  |j                  t        «      t	        j
                  |«      |z  d¬«      dkD  }g }t	        j                  t	        j                  dg|j                  t        j                  «      dgg«      «      }t        t	        j                   |d	k(  «      t	        j                   |d
k(  «      «      D ]í  \  }}||z
  t        z  |k  rŒ||| j#                  «       r*t        t	        j$                  ||	z
  || |||    «      «      n#t        t	        j$                  ||	z
  || «      «      }|j'                  dd|dkD  s||z
  t        z  dkD  rdnd|rdndt)        |t        z  d«      t)        |t        z  d«      d|d›d||z
  t        z  d›d�dt)        |d	«      |dœdœ	«       Œï ||dkD  rt)        |dz  d	«      fS dfS )a  Flag windows where the dub's non-speech bed is much quieter than the original's.

    Only frames where neither track has speech are compared, so speech loudness differences don't count
    (unless stems are used, in which case every frame is a fair comparison).
    Nip  iÎÿÿÿé2   r'   r(   ç      à?r   r   r<   ÚBACKGROUND_DROPOUTÚaudioé   é   ÚmajorÚminorgffffffæ?gš™™™™™á?r&   zBackground music/effects are ~z.0fz dB quieter in the dub for z.1fzs.zQRe-mix using the original background stem for this window (ducking or stem loss).)Úmedian_db_dropÚstems)	ÚcategoryÚsourceÚseverityÚ
confidenceÚstartÚendÚdescriptionÚfix_hintÚevidenceg333333Ó?iè  )r:   Úminr-   rM   r.   r2   Úboolr	   r,   r/   r0   rB   ÚdiffÚconcatenateÚint8ÚzipÚflatnonzeroÚanyÚmedianÚappendÚround)Úorig_bedÚdub_bedÚ	orig_segsÚdub_segsÚdurationÚusing_stemsÚmin_lenÚdrop_dbÚeoÚedr6   ÚoffsetrL   ÚvalidÚaudibleÚdroprJ   ÚissuesÚdrC   rD   Údeltas                         r"   Úbackground_checkr~   8   sˆ  € ô �HÓœv g›ˆ€BÜŒC�‹G”S˜“WÓ€AØ��ˆV�R˜˜�Vˆ€BÜ˜r .¤C¨¨4£LÐ1°2°n¼¸A¸t»Ð3EÓF�L€FˆDÙÜ—‘˜œ4Ó ‰ä�y (¬CÓ0°°!Ð4´t¸HÀhÔPSÓ7TÐUWÐVWÐ7XÑXÐYˆØ�3‰h€GØ�7‰?˜r B™w¨'Ñ1Ñ2€Dà
€AÜ�;‰;�t—{‘{¤5Ó)¬2¯7©7°1«:¸©>ÀÔGÈ#ÑM€DØ€FÜ
�‰”—‘   T§[¡[´·±Ó%9¸A¸3Ð?Ó@ÓA€AÜ”B—N‘N 1¨¡6Ó*¬B¯N©N¸1À¹7Ó,CÓDò ‰ˆˆ1Ø�‰E”S‰=˜7Ò"ØØ@EÀaÈÀ
ÇÁÔ@P””b—i‘i  b¡¨!¨A ¨u°Q°q¨zÑ :Ó;Ô<ÔV[Ô\^×\eÑ\eÐgiÐlnÑgnÐpqÐrsÐftÓ\uÓVvˆØ�‰Ø,¸Ø#(¨2¢:°!°a±%¼3±ÀÒ1B™ÈÙ!,™#°$ÄÀqÌ3ÁwÐPQÓARÔ[`ÐabÔehÑahÐjkÓ[lØ;¸EÀ#¸;ÐFaÐcdÐghÑchÔloÑboÐpsÐatÐtvÐwØkÜ+0°¸«?À[ÑQñ
õ 	ð	ð ¨d°Sªj”5˜ $™¨Ó*ÐBÐB¸dÐBÐBr$   c                ó  — t        |«      t        |«      }}d„ }| D �cg c]i  }|j                  r[|j                  dk\  rL|j                  dk\  r=| |||j                  |j
                  «       |||j                  |j                  «      f‘Œk }}t        |«      dk  rg S t        j                  |D �	cg c]  }	|	d   ‘Œ	 c}	«      }
t        j                  |D �	cg c]  }	|	d   ‘Œ	 c}	«      }|
t        j                  |
«      z
  t        j                  |
«      dz   z  }|t        j                  |«      z
  t        j                  |«      dz   z  }g }t        |||«      D ]œ  \  \  }}}}}||z
  d|z  k\  sŒ||k\  sŒ|j                  dd	d
dt        |j                  d«      t        |j
                  d«      |j                   d|d›d|d›d�dt        t#        |«      d«      t        t#        |«      d«      dœdœ
«       Œž |S c c}w c c}	w c c}	w )zcA line the original delivers loudly (relative to the actor track's norm) but the dub delivers flat.c                óî   — t        |t        z  «      t        t        j                  |t        z  «      «      }}| || }t	        |«      rt        t        j                  |d«      «      S t        j                  S )NéZ   )r+   r,   r.   Úceilr-   rB   Ú
percentileÚnan)ÚenvÚsÚerC   rD   Úsegs         r"   Úlevelzenergy_mismatch.<locals>.levela   sU   € Ü�1”s‘7‹|œS¤§¡¨¬S©Ó!1Ó2ˆ1ˆØ�!�AˆhˆÜ03°C´Œu”R—]‘] 3¨Ó+Ó,ÐD¼b¿f¹fÐDr$   gš™™™™™Ù?gš™™™™™é?é   r   r&   g�íµ ÷Æ°>ÚENERGY_MISMATCHrR   rV   rP   z%Original line is delivered loudly (z=z+.1fz) but the dub is flat (z=z).zLRegenerate with a higher-intensity/emotional voice style (shouting/excited).)Úorig_level_zÚdub_level_z)
rY   rZ   r[   r\   r]   r^   Ú
line_indexr_   r`   ra   )r:   ÚdubÚcoverageÚdurr]   r^   Ú	dub_startÚdub_endr-   r.   ÚarrayÚ	nanmedianÚnanstdrg   rk   rl   ÚindexrB   )ÚlinesÚorig_vocÚdub_vocÚzru   rv   r‰   ÚlnÚrowsrH   Úor|   ÚzoÚzdr{   Ú_rC   rD   s                     r"   Úenergy_mismatchr¢   ]   sæ  € ä�HÓœv g›ˆ€BòEð öPØ˜rŸvšv¨"¯+©+¸Ò*<ÀÇÁÈ3Âð ‘�r˜2Ÿ8™8 R§V¡VÓ,©e°B¸¿¹ÀbÇjÁjÓ.QÒRð P€Dð Pä
ˆ4ƒy�1‚}Øˆ	Ü
�‰ Ö%˜1�!�A“$Ò%Ó&€AÜ
�‰ Ö%˜1�!�A“$Ò%Ó&€AØ
Œb�l‰l˜1‹oÑ
¤"§)¡)¨A£,°Ñ"5Ñ	6€BØ
Œb�l‰l˜1‹oÑ
¤"§)¡)¨A£,°Ñ"5Ñ	6€BØ€FÜ  b¨"Ó-ò Ñ‰
ˆˆQ��A�qØˆq‰5�A˜‘E‹>˜a 1›fØ�M‰MØ-¸ÈgÐehÜ˜rŸx™x¨Ó+´E¸"¿&¹&À!Ó4DÐTV×T\ÑT\Ø!FÀqÈÀhÐNgÐhiÐjnÐgoÐoqÐrØjÜ-2´5¸³8¸QÓ-?ÔPUÔV[Ð\]ÓV^Ð`aÓPbÑcñõ ðð €Mùò%Pùò &ùÚ%s   žA.G<Â1HÃH)r   r   r   r   r   r+   Úreturnztuple[Path, Path])gš™™™™™©?)r4   ú
np.ndarrayr5   rB   r£   r¤   )g       @)rC   r¤   rD   r¤   rE   rB   r£   ztuple[float, float])g      ð?g      (@)rm   r¤   rn   r¤   rq   rB   rr   rc   rs   rB   rt   rB   r£   ztuple[list[dict], float | None])gÍÌÌÌÌÌô?)r™   r¤   rš   r¤   r›   rB   r£   z
list[dict])Ú__doc__Ú
__future__r   Úloggingr   r   Úpathlibr   Únumpyr.   Úscipy.signalr   Úspeechr   r   r	   Ú	getLoggerÚlogr,   r#   r:   rM   r~   r¢   © r$   r"   ú<module>r¯      s„   ðñõ
 #ã Û Û 
Ý ã Ý $ç "Ñ "à€g×Ñ˜	Ó"€Ø
€óô%ô	&ð PTð"CØ"&ð"CØ16ð"CØGLð"CØXwó"CõJr$   