o
    2wi                     @   s  d dl mZ d dlmZ d dlmZ d dlmZ d dlm	Z	m
Z
mZmZmZ d dlmZmZ d dlmZmZmZ d dlmZmZ d d	lmZmZ ed
eeeeeZedeeeeZdeee
e f defddZdedede	defddZde
e dee fddZ dS )    )ProcessPoolExecutor)reduce)chain)add)CallableIterableOptionalTypeVarUnion)	RecordingRecordingSet)CutSetMixedCutMonoCut)Features
FeatureSet)SupervisionSegmentSupervisionSetManifestItemManifest	manifestsreturnc                  G   s,   t | dkrt| ttfr| d } tt| S )a(  
    Combine multiple manifests of the same type into one.

    Examples:
        >>> # Pass several arguments
        >>> combine(recording_set1, recording_set2, recording_set3)
        >>> # Or pass a single list/tuple of manifests
        >>> combine([supervision_set1, supervision_set2])
       r   )len
isinstancetuplelistr   r   )r    r   P/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/lhotse/manipulation.pycombine   s   

r   num_jobsmanifestfnc                    sd   |j | d}t|  fdd|D }tdd |D }W d   |S 1 s+w   Y  |S )a)  
    Convenience wrapper that parallelizes the execution of functions
    that transform manifests. It splits the manifests into ``num_jobs``
    pieces, applies the function to each split, and then combines the splits.

    This function is used internally in Lhotse to implement some parallel ops.

    .. hint:
        This way of parallel execution is the most optimal when each item
        in the manifest is being processed with "simple" operations that take
        a short amount of time -- a ``ProcessPoolExecutor`` would have added
        a lot of overhead for sending individual items over IPC.

    Example::

        >>> from lhotse import CutSet, split_parallelize_combine
        >>> cuts = CutSet(...)
        >>> window_cuts = split_parallelize_combine(
        ...     16,
        ...     cuts,
        ...     CutSet.cut_into_windows,
        ...     duration=30.0
        ... )

    :param num_jobs: The number of parallel jobs.
    :param manifest: The manifest to be processed.
    :param fn: Function or method that transforms the manifest; the first parameter
        has to be ``manifest`` (for methods, they have to be methods on that manifests type,
        e.g. ``CutSet.cut_into_windows``.
    :param args: positional arguments to ``fn``.
    :param kwargs keyword arguments to ``fn``.
    )
num_splitsc                    s&   g | ]}j |g R i qS r   )submit).0subsetargsexr"   kwargsr   r   
<listcomp>F   s   & z-split_parallelize_combine.<locals>.<listcomp>c                 S   s   g | ]}|  qS r   )result)r%   fr   r   r   r+   G   s    N)splitr   r   )r    r!   r"   r(   r*   splitsfuturesr,   r   r'   r   split_parallelize_combine!   s   #

r1   itemsc                 C   s   t | } zt| }W n
 ty   Y dS w t|g| } t|tr%t| S t|tr/t	
| S t|ttfr;t| S t|trDtdtd| )z
    Take an iterable of data types in Lhotse such as Recording, SupervisonSegment or Cut, and create the manifest of the
    corresponding type. When the iterable is empty, returns None.
    NzFeatureSet generic construction from iterable is not possible, as the config information would have been lost. Call FeatureSet.from_features() directly instead.zUnknown type of manifest item: )iternextStopIterationr   r   r   r   from_recordingsr   r   from_segmentsr   r   r   	from_cutsr   
ValueError)r2   
first_itemr   r   r   to_manifestK   s$   





r;   N)!concurrent.futuresr   	functoolsr   	itertoolsr   operatorr   typingr   r   r   r	   r
   lhotse.audior   r   
lhotse.cutr   r   r   lhotse.featuresr   r   lhotse.supervisionr   r   r   r   r   intr1   r;   r   r   r   r   <module>   s0    
*