o
    siS$                     @   sT   d dl mZ d dlZd dlZd dlZd dlZd dlZG dd dejj	j
Ze ZdS )    )PathNc                   @   s\   e Zd ZdZdZg dddddddddd	d
 dfddZdd Zdd Zdd Zdd Z	dS )MUSDB18Dataseta
  MUSDB18 music separation dataset

    The dataset consists of 150 full lengths music tracks (~10h duration) of
    different genres along with their isolated stems:
        `drums`, `bass`, `vocals` and `others`.

    Out-of-the-box, asteroid does only support MUSDB18-HQ which comes as
    uncompressed WAV files. To use the MUSDB18, please convert it to WAV first:

    - MUSDB18 HQ: https://zenodo.org/record/3338373
    - MUSDB18     https://zenodo.org/record/1117372

    .. note::
        The datasets are hosted on Zenodo and require that users
        request access, since the tracks can only be used for academic purposes.
        We manually check this requests.

    This dataset asssumes music tracks in (sub)folders where each folder
    has a fixed number of sources (defaults to 4). For each track, a list
    of `sources` and a common `suffix` can be specified.
    A linear mix is performed on the fly by summing up the sources

    Due to the fact that all tracks comprise the exact same set
    of sources, random track mixing can be used can be used,
    where sources from different tracks are mixed together.

    Folder Structure:
        >>> #train/1/vocals.wav ---------|
        >>> #train/1/drums.wav ----------+--> input (mix), output[target]
        >>> #train/1/bass.wav -----------|
        >>> #train/1/other.wav ---------/

    Args:
        root (str): Root path of dataset
        sources (:obj:`list` of :obj:`str`, optional): List of source names
            that composes the mixture.
            Defaults to MUSDB18 4 stem scenario: `vocals`, `drums`, `bass`, `other`.
        targets (list or None, optional): List of source names to be used as
            targets. If None, a dict with the 4 stems is returned.
             If e.g [`vocals`, `drums`], a tensor with stacked `vocals` and
             `drums` is returned instead of a dict. Defaults to None.
        suffix (str, optional): Filename suffix, defaults to `.wav`.
        split (str, optional): Dataset subfolder, defaults to `train`.
        subset (:obj:`list` of :obj:`str`, optional): Selects a specific of
            list of tracks to be loaded, defaults to `None` (loads all tracks).
        segment (float, optional): Duration of segments in seconds,
            defaults to ``None`` which loads the full-length audio tracks.
        samples_per_track (int, optional):
            Number of samples yielded from each track, can be used to increase
            dataset size, defaults to `1`.
        random_segments (boolean, optional): Enables random offset for track segments.
        random_track_mix boolean: enables mixing of random sources from
            different tracks to assemble mix.
        source_augmentations (:obj:`list` of :obj:`callable`): list of augmentation
            function names, defaults to no-op augmentations (input = output)
        sample_rate (int, optional): Samplerate of files in dataset.

    Attributes:
        root (str): Root path of dataset
        sources (:obj:`list` of :obj:`str`, optional): List of source names.
            Defaults to MUSDB18 4 stem scenario: `vocals`, `drums`, `bass`, `other`.
        suffix (str, optional): Filename suffix, defaults to `.wav`.
        split (str, optional): Dataset subfolder, defaults to `train`.
        subset (:obj:`list` of :obj:`str`, optional): Selects a specific of
            list of tracks to be loaded, defaults to `None` (loads all tracks).
        segment (float, optional): Duration of segments in seconds,
            defaults to ``None`` which loads the full-length audio tracks.
        samples_per_track (int, optional):
            Number of samples yielded from each track, can be used to increase
            dataset size, defaults to `1`.
        random_segments (boolean, optional): Enables random offset for track segments.
        random_track_mix boolean: enables mixing of random sources from
            different tracks to assemble mix.
        source_augmentations (:obj:`list` of :obj:`callable`): list of augmentation
            function names, defaults to no-op augmentations (input = output)
        sample_rate (int, optional): Samplerate of files in dataset.
        tracks (:obj:`list` of :obj:`Dict`): List of track metadata

    References
        "The 2018 Signal Separation Evaluation Campaign" Stoter et al. 2018.
    MUSDB18)vocalsbassdrumsotherNz.wavtrain   Fc                 C   s   | S N )audior   r   Q/home/ubuntu/.local/lib/python3.10/site-packages/asteroid/data/musdb18_dataset.py<lambda>j   s    zMUSDB18Dataset.<lambda>iD  c                 C   sp   t | | _|| _|| _|| _|
| _|	| _|| _|| _	|| _
|| _|| _|| _t|  | _| js6tdd S )NzNo tracks found.)r   
expanduserrootsplitsample_ratesegmentrandom_track_mixrandom_segmentssource_augmentationssourcestargetssuffixsubsetsamples_per_tracklist
get_trackstracksRuntimeError)selfr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __init__^   s    zMUSDB18Dataset.__init__c                    sF  i }| j  } jrtd j| d  j }nd} jD ]a} jr>tt	t
 j} jr>td j| d  j }t| j } jrS|t j j  }nd }tjt j| d |  jd||d\}}	tj|jtjd} |}|||< qtt| d}
 jrtj fdd| D dd	}|
|fS )
Nr   min_durationpathT)	always_2dstartstop)dtypec                    s   g | ]\}}| j v r|qS r   )r   ).0srcwavr!   r   r   
<listcomp>   s    z.MUSDB18Dataset.__getitem__.<locals>.<listcomp>)dim)r   r   randomuniformr   r   r   r   choicerangelenintr   sfreadr   with_suffixr   torchtensorTfloatr   stackr   valuessumr   items)r!   indexaudio_sourcestrack_idr&   sourcestart_samplestop_sampler   _	audio_mixr   r,   r   __getitem__~   s:   




zMUSDB18Dataset.__getitem__c                 C   s   t | j| j S r   )r3   r   r   r,   r   r   r   __len__   s   zMUSDB18Dataset.__len__c                 #   s    t  j j}t| D ]c rr jrj jvrq fdd jD }t	dd |D s9t
d qtttj|}t	 fdd|D sRt
d q jdurltd	d |D }| jkrk|d
V  qdd
V  qdS )zLoads input and output tracksc                    s   g | ]	}| j   qS r   )r   )r)   sr!   
track_pathr   r   r-      s    z-MUSDB18Dataset.get_tracks.<locals>.<listcomp>c                 s   s    | ]}|  V  qd S r   )exists)r)   spr   r   r   	<genexpr>   s    z,MUSDB18Dataset.get_tracks.<locals>.<genexpr>z(Exclude track due to non-existing sourcec                 3   s    | ]	}|j  jkV  qd S r   )
samplerater   r)   ir,   r   r   rO      s    z+Exclude track due to different sample rate Nc                 s   s    | ]}|j V  qd S r   )durationrQ   r   r   r   rO      s    )r$   r#   )r   r   r   tqdmiterdiris_dirr   stemr   allprintr   mapr5   infor   min)r!   psource_pathsinfosr#   r   rK   r   r      s,   



zMUSDB18Dataset.get_tracksc                 C   s&   t  }| j|d< d|d< tg|d< |S )zGet dataset infos (for publishing models).

        Returns:
            dict, dataset infos with keys `dataset`, `task` and `licences`.
        datasetenhancementtasklicenses)dictdataset_namemusdb_license)r!   r_   r   r   r   	get_infos   s
   

zMUSDB18Dataset.get_infos)
__name__
__module____qualname____doc__re   r"   rH   rI   r   rg   r   r   r   r   r   	   s&    R
 3r   )pathlibr   torch.utils.datar8   r/   rT   	soundfiler5   utilsdataDatasetr   rd   rf   r   r   r   r   <module>   s     
U