code: def build(
      self,
      csv_path: str,
      batch_size: int = 8,
      shuffle: bool = True,
      convert_to_uint: bool = True,
      random_data_augmentation: bool = False,
      random_time_crop: bool = True,
      infinite_generator: bool = True,
      cache_directory: Optional[str] = None,
      wait_for_cache: bool = False,
      num_parallel_calls: int = 4,
      n_chunks_per_song: int = 2,
  ) -> Any:
      dataset = dataset_from_csv(csv_path)
      dataset = self.compute_segments(dataset, n_chunks_per_song)
      # Shuffle data
      if shuffle:
          dataset = dataset.shuffle(
              buffer_size=200000,
              seed=self._random_seed,
              # useless since it is cached :
              reshuffle_each_iteration=True,
          )
      # Expand audio path.
      dataset = dataset.map(self.expand_path)
      # Load waveform, compute spectrogram, and filtering error,
      # K bins frequencies, and waveform.
      N = num_parallel_calls
      for instrument in self.instruments:
          dataset = (
              dataset.map(
                  instrument.load_waveform, num_parallel_calls=N
              )
              .filter(self.filter_error)
              .map(instrument.compute_spectrogram, num_parallel_calls=N)
              .map(instrument.filter_frequencies)
          )
      dataset = dataset.map(self.filter_waveform)
      # Convert to uint before caching in order to save space.
      if convert_to_uint:
          for instrument in self.instruments:
              dataset = dataset.map(instrument.convert_to_uint)
      dataset = self.cache(dataset, cache_directory, wait_for_cache)
      # Check for INFINITY (should not happen)
      for instrument in self.instruments:
          dataset = dataset.filter(instrument.filter_infinity)
      # Repeat indefinitly
      if infinite_generator:
          dataset = dataset.repeat(count=-1)
      # Ensure same size for vocals and mix spectrograms.
      # NOTE: could be done before caching ?
      dataset = dataset.map(self.harmonize_spectrogram)
      # Filter out too short segment.
      # NOTE: could be done before caching ?
      dataset = dataset.filter(self.filter_short_segments)
      # Random time crop of 11.88s
      if random_time_crop:
          dataset = dataset.map(
              self.random_time_crop, num_parallel_calls=N
          )
      else:
          # frame_duration = 11.88/T
          # take central segment (for validation)
          for instrument in self.instruments:
              dataset = dataset.map(instrument.time_crop)
      # Post cache shuffling. Done where the data are the lightest:
      # after croping but before converting back to float.
      if shuffle:
          dataset = dataset.shuffle(
              buffer_size=256,
              seed=self._random_seed,
              reshuffle_each_iteration=True,
          )
      # Convert back to float32
      if convert_to_uint:
          for instrument in self.instruments:
              dataset = dataset.map(
                  instrument.convert_to_float32, num_parallel_calls=N
              )
      M = 8  # Parallel call post caching.
      # Must be applied with the same factor on mix and vocals.
      if random_data_augmentation:
          dataset = dataset.map(
              self.random_time_stretch, num_parallel_calls=M
          ).map(self.random_pitch_shift, num_parallel_calls=M)
      # Filter by shape (remove badly shaped tensors).
      for instrument in self.instruments:
          dataset = dataset.filter(instrument.filter_shape).map(
              instrument.reshape_spectrogram
          )
      # Select features and annotation.
      dataset = dataset.map(self.map_features)
      # Make batch (done after selection to avoid
      # error due to unprocessed instrument spectrogram batching).
      dataset = dataset.batch(batch_size)
      return dataset
  
imports: import os
  import time
  from os.path import exists
  from os.path import sep
  from typing import Any, Dict, List, Optional, Tuple
  import tensorflow
  from .audio.adapter import AudioAdapter
  from .audio.convertor import db_uint_spectrogram_to_gain, spectrogram_to_db_uint
  from .audio.spectrogram import compute_spectrogram_tf, random_pitch_shift, random_time_stretch
  from .utils.logging import logger
  from .utils.tensor import check_tensor_shape, dataset_from_csv, set_tensor_shape, sync_apply
label_desc: Use image node_id 15 for calling the DatasetBuilder obj's underlying member method code with example usage: obj.build(csv_path, batch_size, shuffle, convert_to_uint, random_data_augmentation, random_time_crop, infinite_generator, cache_directory, wait_for_cache, num_parallel_calls, n_chunks_per_song) and returns: dataset