o
    æS™i8Z  ã                   @   sð   d dl Z d dlZd dlmZ d dlmZ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mZmZmZ d dlZd dlZ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$m%Z%m&Z&m'Z'm(Z( eG dd„ deƒƒZ)dS )é    N)Ú	dataclass)ÚpartialÚreduce)Úgroupby)Úadd)ÚAnyÚCallableÚIterableÚListÚOptionalÚSequenceÚTupleÚUnion)Ú	Recording)ÚDataCut)ÚFeatures)ÚSupervisionSegment)	Úadd_durationsÚfastcopyÚhash_str_to_intÚis_equal_or_containsÚmerge_items_with_delimiterÚoverlapsÚrich_exception_infoÚto_listÚuuid4c                   @   sÆ  e Zd ZU dZee ed< edefdd„ƒZe		d-de
eeee f  de
ej fdd„ƒZe		d-de
eeee f  de
ej fd	d
„ƒZe			d.de
eeee f  dede
eeje
ej f  fdd„ƒZ							d/de
eeef  dedededee de
e de
e dd fdd„Z			d0dedede
eeee gef  dd fdd„Zd eee ef defd!d"„Zed#edd fd$d%„ƒZ d1d&eded'ed' f fd(d)„Z!ed*e"dd fd+d,„ƒZ#dS )2ÚMultiCutuE  
    :class:`~lhotse.cut.MultiCut` is a :class:`~lhotse.cut.Cut` that is analogous to the MonoCut.
    While MonoCut represents a single channel of a recording, MultiCut represents multi-channel
    recordings where supervisions may or may not be shared across channels.
    It is intended to be used to store, for example, segments of a microphone array recording.
    The following diagrams illustrate some examples for MultiCut usage:

    >>> 2-channel telephone recording with 2 supervisions, one for each channel (e.g., Switchboard):


                  â•”â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•  MultiCut  â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•—
                  â•‘ â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”                              â•‘
     Channel 1  â”€â”€â•¬â”€â”‚   Hello this is John.    â”‚â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•¬â”€â”€â”€â”€â”€â”€â”€â”€
                  â•‘ â””â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜                              â•‘
                  â•‘                               â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”â•‘
     Channel 2  â”€â”€â•¬â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”‚ Hey, John. How are you?  â”‚â• â”€â”€â”€â”€â”€â”€â”€â”€
                  â•‘                               â””â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜â•‘
                  â•šâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•

    >>> Multi-array multi-microphone recording with shared supervisions (e.g., CHiME-6),
    along with close-talk microphones (A and B are distant arrays, C is close-talk):

               â•”â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•—
               â•‘ â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”                         â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”       â•‘
       A-1   â”€â”€â•¬â”€â”¤                   â”œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”¤                   â”œâ”€â”€â”€â”€â”€â”€â”€â•¬â”€
               â•‘ â”‚ What did you do?  â”‚                         â”‚I cleaned my room. â”‚       â•‘
       A-2   â”€â”€â•¬â”€â”¤                   â”œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”¤                   â”œâ”€â”€â”€â”€â”€â”€â”€â•¬â”€
               â•‘ â””â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜  â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”  â””â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜       â•‘
       B-1   â”€â”€â•¬â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”¤Yeah, we were goingâ”œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•¬â”€
               â•‘                        â”‚   to the mall.    â”‚                              â•‘
       B-2   â”€â”€â•¬â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”¤                   â”œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•¬â”€
               â•‘                        â””â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜        â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â” â•‘
        C    â”€â”€â•¬â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”¤      Right.       â”œâ”€â•¬â”€
               â•‘                                                     â””â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜ â•‘
               â•šâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•  MultiCut  â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•

    By definition, a MultiCut has the same attributes as a MonoCut. The key difference is that
    the Recording object has multiple channels, and the Supervision objects may correspond to
    any of these channels. The channels that the MultiCut can be a subset of the Recording
    channels, but must be a superset of the Supervision channels.

    See also:

        - :class:`lhotse.cut.Cut`
        - :class:`lhotse.cut.MonoCut`
        - :class:`lhotse.cut.CutSet`
        - :class:`lhotse.cut.MixedCut`
    ÚchannelÚreturnc                 C   s   t t| jƒƒS ©N)Úlenr   r   )Úself© r"   úD/home/ubuntu/.local/lib/python3.10/site-packages/lhotse/cut/multi.pyÚnum_channelsR   s   zMultiCut.num_channelsNc                 C   sŽ   | j rE| jj| j| j|du r| jn|d}|jd | j dkr*|d| j…df }|S |jd | j dkrCtj	||dd…df fdd}|S dS )a˜  
        Load the features from the underlying storage and cut them to the relevant
        [begin, duration] region of the current MultiCut.

        :param channel: The channel to load the features for. If None, all channels will be loaded.
            This is useful for the case when we have features extracted for each channel of
            the multi-cut, and we want to selectively load them.
        N)ÚstartÚdurationÚ
channel_idr   é   .éÿÿÿÿ)Úaxis)
Úhas_featuresÚfeaturesÚloadr%   r&   r   ÚshapeÚ
num_framesÚnpÚconcatenate)r!   r   Úfeatsr"   r"   r#   Úload_featuresV   s   ý	þzMultiCut.load_featuresc                 C   s.   | j r| jj|du r| jn|| j| jdS dS )au  
        Load the audio by locating the appropriate recording in the supplied Recording.
        The audio is trimmed to the [begin, end] range specified by the MultiCut.

        :param channel: optional int or list of int, the subset of channels to load (all by default).
        :return: a numpy ndarray with audio samples, with shape (C <channel>, N <samples>)
        N)ÚchannelsÚoffsetr&   )Úhas_recordingÚ	recordingÚ
load_audior   r%   r&   )r!   r   r"   r"   r#   r8   s   s   ýzMultiCut.load_audioTÚ
with_audioc                 C   s0   | j r| jj|du r| jn|| j| j|dS dS )að  
        Load the subset of video (and audio) from attached recording.
        The data is trimmed to the [begin, end] range specified by the MonoCut.

        :param channel: optional int or list of int, the subset of channels to load (all by default).
        :param with_audio: bool, whether to load and return audio alongside video. True by default.
        :return: a tuple of video tensor and optionally audio tensor (or ``None``),
            or ``None`` if this cut has no video.
        N)r4   r5   r&   r9   )Ú	has_videor7   Ú
load_videor   r%   r&   )r!   r   r9   r"   r"   r#   r;   †   s   üzMultiCut.load_videoF©r   Úrir_recordingÚnormalize_outputÚ
early_onlyÚaffix_idÚrir_channelsÚroom_rng_seedÚsource_rng_seedc           
   	      sÖ   | j sJ dƒ‚| jrt d¡ d| _ˆdu r4| jdksJ dƒ‚|du r-tttƒ ƒ| j	 ƒ}|du r3|}nt
‡fdd„|D ƒƒsCJ dƒ‚| jjˆ||ˆ |||d	}‡ fd
d„| jD ƒ}	t| ˆ rd| j	› dn| j	||	dS )aj  
        Return a new ``MultiCut`` that will convolve the audio with the provided impulse response.
        If the `rir_recording` is multi-channel, the `rir_channels` argument determines which channels
        will be used. This list must be of the same length as the number of channels in the `MultiCut`.

        If no ``rir_recording`` is provided, we will generate an impulse response using a fast random
        generator (https://arxiv.org/abs/2208.04101), only if the MultiCut has exactly one channel.
        At the moment we do not support simulation of multi-channel impulse responses.

        :param rir_recording: The impulse response to use for convolving.
        :param normalize_output: When true, output will be normalized to have energy as input.
        :param early_only: When true, only the early reflections (first 50 ms) will be used.
        :param affix_id: When true, we will modify the ``MonoCut.id`` field
            by affixing it with "_rvb".
        :param rir_channels: The channels of the impulse response to use. First channel is used by default.
            If multiple channels are specified, this will produce a MixedCut instead of a MonoCut.
        :param room_rng_seed: The seed for the room configuration.
        :param source_rng_seed: The seed for the source positions.
        :return: a modified copy of the current ``MonoCut``.
        z;Cannot apply reverberation on a MultiCut without Recording.z¥Attempting to reverberate a MultiCut that references pre-computed features. The feature manifest will be detached, as we do not support feature-domain reverberation.Nr(   zlWe do not support reverberation simulation for multi-channel recordings. Please provide an impulse response.c                 3   s    | ]}|ˆ j k V  qd S r   )r$   ©Ú.0Úc)r=   r"   r#   Ú	<genexpr>Ò   s   € 

ÿz&MultiCut.reverb_rir.<locals>.<genexpr>z(Invalid channel index in `rir_channels`.)r=   r>   r?   r@   rA   rB   rC   c                    s   g | ]}|j ˆ d ‘qS )©r@   )Ú
reverb_rir©rE   ÚsrH   r"   r#   Ú
<listcomp>à   s    ýÿÿz'MultiCut.reverb_rir.<locals>.<listcomp>Ú_rvb)Úidr7   Úsupervisions)r6   r+   ÚloggingÚwarningr,   r$   r   Ústrr   rN   Úallr7   rI   rO   r   )
r!   r=   r>   r?   r@   rA   rB   rC   Úrecording_rvbÚsupervisions_rvbr"   )r@   r=   r#   rI   ž   sR    ÿþÿÿ€
ÿþù

üüzMultiCut.reverb_rirÚ	delimiterÚmerge_policyÚmerge_channelsÚcustom_merge_fnc                    s  t td|dkd‰|dur|‰n‡fdd„‰t| jdd„ d}t|ƒd	kr'| S |rHtƒ }|D ]}tt|jƒƒ}| |¡ q.t|ƒ}t	|ƒ|i}nd
d„ t
t|dd„ ddd„ dD ƒ}g }	d}
| ¡ D ]š\}‰ ˆ d j}ˆ d j}t|| | jd}tdd„ ˆ D ƒƒ}tdd„ ˆ D ƒƒ}tdd„ tˆ ˆ d	d… ƒD ƒƒr³tdd„ ˆ D ƒƒr³|
s³t d| j› d¡ d}
|	 tˆdd„ ˆ D ƒƒˆ d j||t|ƒd dd„ ˆ D ƒ¡ˆdd„ ˆ D ƒƒˆdd„ ˆ D ƒƒˆdd„ ˆ D ƒƒ‡ ‡fdd„|D ƒ‡ fd d„|D ƒd!¡ qct| |	d"S )#a
  
        Return a copy of the cut that has all of its supervisions merged into
        a single segment. The ``channel`` attribute of all the segments in this case
        will be set to the union of all channels. If ``merge_channels`` is set to ``False``,
        the supervisions will be merged into a single segment per channel group. The
        ``channel`` attribute will not change in this case.

        The new start is the start of the earliest superivion, and the new duration
        is a minimum spanning duration for all the supervisions. The text fields of
        all segments are concatenated with a whitespace.

        :param merge_policy: one of "keep_first" or "delimiter". If "keep_first", we
            keep only the first segment's field value, otherwise all string fields
            (including IDs) are prefixed with "cat#" and concatenated with a hash symbol "#".
            This is also applied to ``custom`` fields. Fields with a ``None`` value are omitted.
        :param merge_channels: If true, we will merge all supervisions into a single segment.
            If false, we will merge supervisions per channel group. Default: True.
        :param custom_merge_fn: a function that will be called to merge custom fields values.
            We expect ``custom_merge_fn`` to handle all possible custom keys.
            When not provided, we will treat all custom values as strings.
            It will be called roughly like:
            ``custom_merge_fn(custom_key, [s.custom[custom_key] for s in sups])``
        ú#Ú
keep_first)rV   Úreturn_firstNc                    s   ˆ t t|ƒƒS r   )ÚmaprR   )ÚkÚvs)Úmerge_func_r"   r#   Ú<lambda>  s    z-MultiCut.merge_supervisions.<locals>.<lambda>c                 S   ó   | j S r   )r%   ©rK   r"   r"   r#   ra     ó    ©Úkeyr(   c                 S   s   i | ]\}}t |ƒt|ƒ“qS r"   )ÚtupleÚlist)rE   rF   Úcsupsr"   r"   r#   Ú
<dictcomp>(  s    ÿÿz/MultiCut.merge_supervisions.<locals>.<dictcomp>c                 S   rb   r   ©r   rc   r"   r"   r#   ra   +  rd   Fr   r)   )Úsampling_ratec                 s   ó.    | ]}|j d ur|j  ¡ D ]}|V  qqd S r   )ÚcustomÚkeys©rE   rK   r^   r"   r"   r#   rG   6  ó   € $ÿz.MultiCut.merge_supervisions.<locals>.<genexpr>c                 s   rm   r   )Ú	alignmentro   rp   r"   r"   r#   rG   9  rq   c                 s   s    | ]
\}}t ||ƒV  qd S r   )r   )rE   Ús1Ús2r"   r"   r#   rG   >  s   € c                 s   s    | ]}|j d uV  qd S r   ©ÚtextrJ   r"   r"   r#   rG   ?  ó   € z¦You are merging overlapping supervisions that have text transcripts. The result is likely to be unusable if you are going to train speech recognition models (cut id: z).Tc                 s   ó    | ]}|j V  qd S r   )rN   rJ   r"   r"   r#   rG   K  ó   € ú c                 s   ó    | ]	}|j r|j V  qd S r   ru   rJ   r"   r"   r#   rG   P  ó   € c                 s   r{   r   )ÚspeakerrJ   r"   r"   r#   rG   Q  r|   c                 s   r{   r   )ÚlanguagerJ   r"   r"   r#   rG   R  r|   c                 s   r{   r   )ÚgenderrJ   r"   r"   r#   rG   S  r|   c                    s&   i | ]‰ ˆ ˆˆ ‡ fd d„ˆD ƒƒ“qS )c                 3   ó.    | ]}|j d urˆ |j v r|j ˆ  V  qd S r   )rn   rJ   ©r^   r"   r#   rG   W  ó   € þýú9MultiCut.merge_supervisions.<locals>.<dictcomp>.<genexpr>r"   ©rE   )ri   Úmerge_customr   r#   rj   T  s    	ø
þþÿc                    s&   i | ]‰ ˆ t t‡ fd d„ˆD ƒƒ“qS )c                 3   r€   r   )rr   rJ   r   r"   r#   rG   c  r‚   rƒ   )r   r   r„   )ri   r   r#   rj   _  s    
ø
þþþ)rN   Úrecording_idr%   r&   r   rv   r}   r~   r   rn   rr   ©rO   )r   r   ÚsortedrO   r    Úsetr   r   Úupdaterg   r   Úitemsr%   Úendr   rl   ÚanyÚzipÚwarningsÚwarnrN   Úappendr   r†   rh   Újoinr   )r!   rW   rX   rY   ÚsupsÚall_channelsrK   rF   Úsups_by_channelÚmsupsÚtext_overlap_warningr   ÚmstartÚmendÚ	mdurationÚcustom_keysÚalignment_keysr"   )ri   r…   r`   r#   Úmerge_supervisionsî   s†   ýÿþ

ÿÿÿþýþÿ	÷

öëÿ%zMultiCut.merge_supervisionsr4   c              	      s²   t ˆ tƒ}t|rˆ gnˆ ƒ t| jjƒ¡s!J dˆ ›d| jj›ƒ‚|p(tˆ ƒdk}|rSddlm} |s6ˆ \‰ || j	› dˆ › | j| j
| jˆ ‡ fdd„| jD ƒ| jdS t| ˆ d	S )
a-  
        Select specified channels from this cut.
        Supports extending to other channels available in the underlying :class:`Recording`.
        If a single channel is provided, we'll return a :class:`~lhotse.cut.MonoCut`,
        otherwise we'll return a :class:`~lhotse.cut.MultiCut`.
        zCannot select channels=z= because they are not a subset of self.recording.channel_ids=r(   ©ÚMonoCutú-c                    ó$   g | ]}t |jˆ ƒrt|ˆ d ‘qS ©rk   ©r   r   r   rJ   ©r4   r"   r#   rL   ˆ  ó    
ý
ÿz*MultiCut.with_channels.<locals>.<listcomp>©rN   r7   r%   r&   r   rO   rn   rk   )Ú
isinstanceÚintr‰   Úissubsetr7   Úchannel_idsr    ÚmonorŸ   rN   r%   r&   rO   rn   r   )r!   r4   Úchannel_is_intr«   rŸ   r"   r¤   r#   Úwith_channelsp  s.   

ÿþ
þõzMultiCut.with_channelsÚcutsc                     sÄ   ddl m‰  t‡ fdd„| D ƒƒsJ dƒ‚tdd„ t| dd„ d	D ƒƒdks*J d
ƒ‚ttdd„ | D ƒƒƒt| ƒks=J dƒ‚| d  ¡ }| d¡ t	di i |¥t
dd„ | D ƒƒdd„ | D ƒdœ¥¤ŽS )a  
        Convert one or more MonoCut to a MultiCut. If multiple mono cuts are provided, they
        must match in all fields except the channel. Each cut must have a distinct channel.

        :param cuts: the input cut(s).
        :return: a MultiCut with a single track.
        r(   rž   c                 3   s    | ]}t |ˆ ƒV  qd S r   )r§   rD   rž   r"   r#   rG     rw   z%MultiCut.from_mono.<locals>.<genexpr>zAll cuts must be MonoCutsc                 s   s    | ]}d V  qdS )r(   Nr"   )rE   Ú_r"   r"   r#   rG   Ÿ  s   € 
ÿc                 S   s   | j | j| jfS r   )r†   r%   rŒ   )rF   r"   r"   r#   ra      s    z$MultiCut.from_mono.<locals>.<lambda>re   z,Cuts must match in all fields except channelc                 s   rx   r   rk   rD   r"   r"   r#   rG   ¤  ry   z%All cuts must have a distinct channelr   Útypec                 S   s   g | ]}|j ‘qS r"   rk   rD   r"   r"   r#   rL   ®  s    z&MultiCut.from_mono.<locals>.<listcomp>c                 S   s   g | ]
}|j D ]}|‘qqS r"   r‡   )rE   rF   rK   r"   r"   r#   rL   ¯  s    )r   rO   Nr"   )r«   rŸ   rS   Úsumr   r    r‰   Úto_dictÚpopr   rˆ   )r®   Údatar"   rž   r#   Ú	from_mono’  s0   	ÿýüÿþ
ÿýÿzMultiCut.from_monoÚmono_downmixr   c                    sb   ddl m}m‰  ddlm‰ ‡‡fdd„tˆjƒD ƒ}|s|S |ˆj‡ fdd„|D ƒd}| ¡ S )ar  
        Convert a MultiCut to either a list of MonoCuts (one per channel) or a single
        MonoCut obtained by downmixing all channels.

        :param mono_downmix: If true, we will downmix all channels into a single MonoCut.
            If false, we will return a list of MonoCuts, one per channel.
        :return: a list of MonoCuts or a single MonoCut.
        r(   )ÚMixedCutÚMixTrackrž   c                    sF   g | ]‰ ˆˆj › d ˆ › ˆjˆjˆjˆ ‡ fdd„ˆjD ƒˆjd‘qS )r    c                    r¡   r¢   r£   rJ   rk   r"   r#   rL   Æ  r¥   z/MultiCut.to_mono.<locals>.<listcomp>.<listcomp>r¦   )rN   r7   r%   r&   rO   rn   r„   )rŸ   r!   rk   r#   rL   ¿  s    ó
þõÿz$MultiCut.to_mono.<locals>.<listcomp>c                    s   g | ]	}ˆ |d dd‘qS )g        N)Úcutr5   Úsnrr"   )rE   Úmono_cut)r¸   r"   r#   rL   Õ  s    ÿ)rN   Útracks)	Úmixedr·   r¸   r«   rŸ   r   r   rN   Úto_mono)r!   r¶   r·   Ú	mono_cutsÚ	mixed_cutr"   )r¸   rŸ   r!   r#   r¾   ³  s   	ò
ÿþzMultiCut.to_monor´   c                 C   s°   ddl m} |  dd ¡ d| v rt |  d¡¡nd }d| v r&t |  d¡¡nd }d| v r1|  d¡ng }d| v r=|| d ƒ d| v rF|  d¡ tdi | ¤||dd	„ |D ƒd
œ¤ŽS )Nr   )Údeserialize_custom_fieldr°   r,   r7   rO   rn   c                 S   s   g | ]}t  |¡‘qS r"   )r   Ú	from_dictrJ   r"   r"   r#   rL   ô  s    z&MultiCut.from_dict.<locals>.<listcomp>)r,   r7   rO   r"   )Úlhotse.serializationrÁ   r³   r   rÂ   r   r   )r´   rÁ   r,   r7   Úsupervision_infosr"   r"   r#   rÂ   Û  s$   ÿÿ
ÿ
üzMultiCut.from_dictr   )NT)NTFTr<   NN)rV   TN)F)$Ú__name__Ú
__module__Ú__qualname__Ú__doc__r
   r¨   Ú__annotations__Úpropertyr$   r   r   r   r0   Úndarrayr3   r8   Úboolr   ÚtorchÚTensorr;   r   r   r   rI   rR   r   r	   r   r   r­   Ústaticmethodrµ   r¾   ÚdictrÂ   r"   r"   r"   r#   r      s   
 1ÿÿþÿÿþýþýüøþýüûúùø	
÷Rüþýü
û "  (r   )*rP   r   Údataclassesr   Ú	functoolsr   r   Ú	itertoolsr   Úoperatorr   Útypingr   r   r	   r
   r   r   r   r   Únumpyr0   rÍ   Úlhotse.audior   Úlhotse.cut.datar   Úlhotse.featuresr   Úlhotse.supervisionr   Úlhotse.utilsr   r   r   r   r   r   r   r   r   r   r"   r"   r"   r#   Ú<module>   s     (,