o
    Si\                     @   s@  d Z ddl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mZmZmZ ddlZddlmZmZmZ ddlmZmZ ddlmZ d	Zd
d Zdd Zd$ddZ	d%dedefddZ		d&dededee dee dee ee ef f f
ddZ!de dededee fdd Z"d!e#dedee fd"d#Z$dS )'ak  
LibriSpeechMix dataset preparation for Lhotse.

This recipe processes LibriSpeechMix metadata to create multi-speaker mixtures
from LibriSpeech recordings. LibriSpeechMix provides predefined
speaker combinations and timing information for creating consistent mixtures.

For more details, see:
- GitHub repository: https://github.com/NaoyukiKanda/LibriSpeechMix/
    N)ThreadPoolExecutoras_completed)Path)DictListOptional)CutSetMonoCutmix)manifests_existread_manifests_if_cached)Pathlikei>  c                 C   sN   t jj| ddid}t j|}t|W  d    S 1 s w   Y  d S Nz
User-Agentzpython-urllib)headers)urllibrequestRequesturlopenjsonloadurlreqresp r   Q/home/ubuntu/.local/lib/python3.10/site-packages/lhotse/recipes/librispeechmix.py_fetch_json   s   $r   c                 C   sL   t jj| ddid}t j|}| W  d    S 1 sw   Y  d S r   )r   r   r   r   readr   r   r   r   _fetch_bytes#   s   $r   main.c           
   	   C   s   d|  d| d| d| }t |}tj|dd |D ]@}tj||d }|d d	krKt|d
}	|	t|d  W d    n1 sEw   Y  q|d dkr[t| ||d || qd S )Nzhttps://api.github.com/repos//z
/contents/z?ref=T)exist_oknametypefilewbdownload_urldirpath)	r   osmakedirsr)   joinopenwriter   download_github_dir)
userrepor)   branchsave_dirapi_urlfilesr%   	file_pathfr   r   r   r/   )   s   r/   
target_dirreturnc                 C   sr   t | } | jddd | d }|d }| r"td| d |S td| d td	d
dd| |  |S )z!Download LibriSpeechMix metadata.Tparentsr"   listz
.completedzSkipping download because z exists.zMDownloading https://github.com/NaoyukiKanda/LibriSpeechMix/tree/main/list to ...NaoyukiKandaLibriSpeechMixr   )r   mkdiris_filelogginginfor/   touch)r8   metadata_dircompleted_detectorr   r   r   download_librispeechmix8   s   
rG      librispeech_root_pathlibrispeechmix_metadata_path
output_dirnum_jobsc                 C   s.  |durt |}|jddd i }t| d}dd |D }|dur,t||ddd	}|D ]f}t |j}t||ddd
rGtd| d q.td| d t | dd|	ddd  d }	t
|	}
dd }|
| }
t||
|}t
|}|dur||d| d  d|i||< q.|S )a  
    Prepare LibriSpeechMix manifests for multi-speaker mixtures.

    Args:
        librispeech_root_path: Path to LibriSpeech manifests
        librispeechmix_metadata_path: Path to LibriSpeechMix metadata JSONL files
        output_dir: Directory to save manifests
        num_jobs: Number of parallel threads used for processing (default: 1)

    Returns:
        Dict with keys for each split containing CutSets
    NTr:   z/*.jsonlc                 S   s   g | ]}t |jqS r   )r   stem).0r7   r   r   r   
<listcomp>i   s    z*prepare_librispeechmix.<locals>.<listcomp>librispeechmix)cutset)dataset_partsrK   prefixtypes)partrK   rS   rT   zLibriSpeechMix subset: z already prepared - skipping.Processing r=   librispeech_cutset_-z	.jsonl.gzc                 S   s   | j | _| S )N)recording_idid)cutr   r   r   use_recording_id   s   z0prepare_librispeechmix.<locals>.use_recording_idlibrispeechmix_cutset_rQ   )r   r@   globr   rM   r   rB   rC   r,   splitr   	from_filemapto_eager _process_librispeechmix_metadata	from_cutsto_file)rI   rJ   rK   rL   	manifestsmetadata_filesrR   metadata_file	part_namelibrispeech_cutset_pathlibrispeech_cutsetr]   cutsrQ   r   r   r   prepare_librispeechmixM   sT   




rn   ri   rl   c           	         s   g }t | d}|D ]}|t|  q
W d   n1 s!w   Y  g }tdt| d|  d t|d.  fdd|D }t	j	t
|t|d	D ]}| }|dur`|| qQW d   |S 1 slw   Y  |S )
z-Process a LibriSpeechMix metadata JSONL file.rNrV   z entries from r=   )max_workersc                    s   g | ]	}  t|qS r   )submit_process_metadata_entry)rN   entryexrl   r   r   rO      s    z4_process_librispeechmix_metadata.<locals>.<listcomp>)total)r-   appendr   loadsstriprB   rC   lenr   tqdmr   result)	ri   rl   rL   metadata_entriesr7   linerm   futuresr|   r   rt   r   rd      s,   



rd   rs   c                 C   s   | d  dd }| d }| d }g }t|D ],\}}t|j}|| }	|t|k r.|| nd}
|
dkr>|	j|
|	j dd	}	||	 qt|t|krPtd
|d }|dd D ]	}t	||dd}qZ||_
|S )z4Process a single metadata entry from LibriSpeechMix.r[   r!   rY   wavsdelaysg        r   left)	directionzNot all mono cuts collectedrH   N)preserve_id)r`   	enumerater   rM   rz   paddurationrw   
ValueErrorr
   r[   )rs   rl   
mixture_idr   r   source_cutsiwav_pathcut_idr\   delay	mixed_cut
source_cutr   r   r   rr      s$   
rr   )r   r    )r    )NrH   )%__doc__r_   r   rB   r*   urllib.requestr   concurrent.futuresr   r   pathlibr   typingr   r   r   r{   lhotse.cut.setr   r	   r
   lhotse.recipes.utilsr   r   lhotse.utilsr   RATEr   r   r/   rG   intstrrn   rd   dictrr   r   r   r   r   <module>   sh    



U
