class_docstr: A dataset that accepts as argument multiple sub-datasets (usually from different languages, but that's not required) and then
  samples from them in order to create synthetic code-switched samples of up to N different sub-datasets
  Args:
      datasets (list): A list of datasets
      lang_probs (list): A list of probabilities (which must sum to 1) corresponding to the sampling probability for each dataset
      shuffle (bool): Whether to shuffle individual datasets. Only works with non-iterable datasets. 
          Defaults to True.
      min_duration (int): the minimum duration (secs) of each synthetic code-switched sample. Will draw randomly until this is hit.
          Defaults to 4
      max_duration (int): the maximum duration (secs) of each synthetic code-switched sample.
          Defaults to 20
      min_monolingual (float): this percentage of the dataset will be original monolingual samples
          Defaults to 0.3 - means 30%
      db_norm (float): will normalise the composite CS sample to this DB level
          Defaults to -25.0
      pause_start (int): inserts silence equal to this value (msecs) at the start of each CS sample
          Defaults to 0
      pause_join (int): inserts silence equal to this value (msecs) between all language changes in the CS sample
          Defaults to 0
      pause_end (int): terminates all CS samples with silence equal to this value (msecs)
          Defaults to 0
      sampling_scales (list or float): gives you the ability to upsample/downsample each individual dataset
      seed: Optional value to seed the numpy RNG.
      global_rank (int): Worker rank, used for partitioning map style datasets. Defaults to 0.
      world_size (int): Total number of processes, used for partitioning map style datasets. Defaults to 1.
      pure_random (bool): If true, then always draw random sample from lang_probs. If false, you only draw from those datasets
                          which you haven't sampled from yet for the composite sample
      force_monochannel (bool): If true, then all output audio will be mono-channel
      infinity_mode (bool): If true, then the dataset iterable will generate an infinite amount of samples
      sample_rate (int): the sample rate of all audio being sent to this Dataset
      augmentor (AudioAugmentor): The any perturbations you wish to have applied on the CS samples
code: def __init__(
      self,
      datasets: List[Any],
      lang_probs: Optional[List[float]] = None,
      shuffle: bool = True,
      min_duration: int = 4,
      max_duration: int = 20,
      min_monolingual: float = 0.3,
      db_norm: float = -25.0,
      pause_start: int = 0,
      pause_join: int = 0,
      pause_end: int = 0,
      sampling_scales: Optional[Union[float, List[float]]] = None,
      seed: Optional[int] = None,
      global_rank: int = 0,
      world_size: int = 1,
      pure_random: bool = False,
      force_monochannel: bool = True,
      infinity_mode: bool = False,
      sample_rate: int = 16000,
      augmentor: Optional["AudioAugmentor"] = None,
  ):
      super().__init__()
  
      if len(datasets) == 0:
          raise ValueError(
              "CodeSwitchedDataset must receive a non-zero length datasets dict object"
          )
  
      self.datasets = datasets
      self.langs = list(range(len(datasets)))
      self.langs_set = set(self.langs)
      self.lang_iterables = {k: None for k in self.langs}
      self.lang_kind = {k: None for k in self.langs}
      self.shuffle = shuffle
      self.min_duration = min_duration
      self.max_duration = max_duration
      self.min_monolingual = min_monolingual
      self.db_norm = db_norm
      self.pause_start = pause_start
      self.pause_join = pause_join
      self.pause_end = pause_end
      self.pure_random = pure_random
      self.force_monochannel = force_monochannel
      self.infinity_mode = infinity_mode
      self.global_rank = global_rank
      self.world_size = world_size
      self.augmentor = augmentor
      self.sample_rate = sample_rate
      self.length = 0
      if lang_probs is None:
          self.prob_dict = {
              l: 1.0 / len(self.langs) for l in self.langs
          }
      else:
          assert len(self.langs) == len(
              lang_probs
          ), "Size mismatch between languages and respective probs in CodeSwitchedDataset"
          self.prob_dict = {l: lang_probs[l] for l in self.langs}
      self.lang_probs = np.array(list(self.prob_dict.values()))
      if sampling_scales is not None and not isinstance(
          sampling_scales, list
      ):
          self.sampling_scales = {
              k: sampling_scales for k in self.langs
          }
      elif (
          sampling_scales is not None
          and isinstance(sampling_scales, list)
          and len(sampling_scales) == len(self.langs)
      ):
          self.sampling_scales = {
              k: v for k, v in zip(self.langs, sampling_scales)
          }
      else:
          self.sampling_scales = {k: 1 for k in self.langs}
  
      for lang, dataset in enumerate(self.datasets):
          isiterable = isinstance(dataset, IterableDataset)
  
          if isiterable:
              self.lang_kind[lang] = "iterable"
              self.length += int(
                  len(dataset) * self.sampling_scales[lang]
              )
          else:
              self.lang_kind[lang] = "map"
              self.length += int(
                  (len(dataset) // world_size)
                  * self.sampling_scales[lang]
              )
  
      if seed is not None:
          np.random.seed(seed)
  
      # set this to ensure compatibility with models searching for the collate_fn
      # since this class stores datasets as a dict, not list
      # self.collate_fn = self.datasets[self.langs[0]].collate_fn
      if hasattr(self.datasets[self.langs[0]], "collate_fn"):
          self.collate_fn = self.datasets[self.langs[0]].collate_fn
      elif (
          hasattr(self.datasets[self.langs[0]], "datasets")
          and isinstance(self.datasets[self.langs[0]].datasets, list)
          and len(self.datasets[self.langs[0]].datasets) > 0
          and hasattr(
              self.datasets[self.langs[0]].datasets[0], "collate_fn"
          )
      ):
          # support datasets that are lists of entries
          self.collate_fn = (
              self.datasets[self.langs[0]].datasets[0].collate_fn
          )
      elif (
          hasattr(self.datasets[self.langs[0]], "datasets")
          and isinstance(self.datasets[self.langs[0]].datasets, list)
          and len(self.datasets[self.langs[0]].datasets) > 0
          and hasattr(
              self.datasets[self.langs[0]].datasets[0], "datasets"
          )
          and isinstance(
              self.datasets[self.langs[0]].datasets[0].datasets, list
          )
          and len(self.datasets[self.langs[0]].datasets[0].datasets) > 0
          and hasattr(
              self.datasets[self.langs[0]].datasets[0].datasets[0],
              "collate_fn",
          )
      ):
          # support datasets that are lists of lists
          self.collate_fn = (
              self.datasets[self.langs[0]]
              .datasets[0]
              .datasets[0]
              .collate_fn
          )
      else:
          raise RuntimeError(
              "CodeSwitchedDataset could not locate a valid dataset collate_fn to bind to"
          )
  
imports: import io
  import logging
  from typing import Any, List, Optional, Tuple, Union
  import numpy
  import torch
  import torch.utils.data
  from torch.utils.data import Dataset, IterableDataset
label_desc: Use image node_id 1 to create a new CodeSwitchedDataset object from inherited base classes: IterableDataset with example: obj = CodeSwitchedDataset(datasets, lang_probs, shuffle, min_duration, max_duration, min_monolingual, db_norm, pause_start, pause_join, pause_end, sampling_scales, seed, global_rank, world_size, pure_random, force_monochannel, infinity_mode, sample_rate, augmentor)