class_docstr: A ShoeBox Room Simulator. Simulates a cuboid of parametrized size and 
  average surface absorption coefficient. It also includes a source     and microphones in parametrized locations.
  
  Use it when you want a ton of synthetic room impulse responses of specific configurations
  characteristics or simply to quickly add reverb for augmentation purposes
  
  Some examples:
  
  > augment = RoomSimulator(use_ray_tracing=False)
  Quickly add reverberation without caring for accuracy.
  
  > augment = RoomSimulator(calculation_mode="rt60", min_target_rt60=0.06, max_target_rt60=0.06, min_size_x = ...)
  Augment with randomly selected room impulse responses that have an RT60 of 0.06.
  
  > augment = RoomSimulator(min_mic_radius=1.0, max_min_radius=1.0)
  Augment with a RIR captured by all positions of the microphone on a sphere, centred around the source at 1m
  
  > augment = RoomSimulator(min_mic_radius=1.0, max_min_radius=1.0, min_mic_elevation=0.0, max_mic_elevation=0.0)
  Augment with a RIR captured by all positions of the microphone on a circle, centred around the source at 1m    
code: def randomize_parameters(
      self, samples: NDArray[np.float32], sample_rate: int
  ):
      try:
          import pyroomacoustics as pra
      except ImportError:
          print(
              "Failed to import pyroomacoustics. Maybe it is not installed? "
              "To install the optional pyroomacoustics dependency of audiomentations,"
              " do `pip install audiomentations[extras]` or simply "
              " `pip install pyroomacoustics`",
              file=sys.stderr,
          )
          raise
  
      super().randomize_parameters(samples, sample_rate)
      self.parameters["size_x"] = random.uniform(
          self.min_size_x, self.max_size_x
      )
      self.parameters["size_y"] = random.uniform(
          self.min_size_y, self.max_size_y
      )
      self.parameters["size_z"] = random.uniform(
          self.min_size_z, self.max_size_z
      )
  
      room_dim = np.array(
          [
              self.parameters["size_x"],
              self.parameters["size_y"],
              self.parameters["size_z"],
          ]
      )
  
      self.parameters["max_order"] = self.max_order
  
      if self.calculation_mode == "rt60":
          target_rt60 = random.uniform(
              self.min_target_rt60, self.max_target_rt60
          )
          self.parameters["target_rt60"] = target_rt60
  
          # If we are in rt60 mode, estimate the absorption coefficient on a desired target
          # rt60 value.
          (
              self.parameters["absorption_coefficient"],
              max_order,
          ) = pra.inverse_sabine(
              self.parameters["target_rt60"], room_dim
          )
  
          # When `rt60` is specified, use max_order from sabine's formula
          self.parameters["max_order"] = min(max_order, self.max_order)
      else:
          self.parameters["absorption_coefficient"] = random.uniform(
              self.min_absorption_value, self.max_absorption_value
          )
  
      self.parameters["source_x"] = random.uniform(
          max(self.min_source_x, self.padding),
          min(
              self.max_source_x,
              self.parameters["size_x"] - self.padding,
          ),
      )
      self.parameters["source_y"] = random.uniform(
          max(self.min_source_y, self.padding),
          min(
              self.max_source_y,
              self.parameters["size_y"] - self.padding,
          ),
      )
      self.parameters["source_z"] = random.uniform(
          max(self.min_source_z, self.padding),
          min(
              self.max_source_z,
              self.parameters["size_z"] - self.padding,
          ),
      )
  
      self.parameters["mic_radius"] = random.uniform(
          self.min_mic_distance, self.max_mic_distance
      )
      self.parameters["mic_azimuth"] = random.uniform(
          self.min_mic_azimuth, self.max_mic_azimuth
      )
      self.parameters["mic_elevation"] = random.uniform(
          self.min_mic_elevation, self.max_mic_elevation
      )
  
      # Convert to cartesian coordinates according to ADM
      mic_x = self.parameters["source_x"] - self.parameters[
          "mic_radius"
      ] * np.cos(self.parameters["mic_elevation"]) * np.sin(
          self.parameters["mic_azimuth"]
      )
      mic_y = self.parameters["source_y"] + self.parameters[
          "mic_radius"
      ] * np.cos(self.parameters["mic_elevation"]) * np.cos(
          self.parameters["mic_azimuth"]
      )
      mic_z = self.parameters["source_z"] + self.parameters[
          "mic_radius"
      ] * np.sin(self.parameters["mic_elevation"])
  
      # Clamp between 0 and room dimensions
      self.parameters["mic_x"] = max(
          self.padding,
          min(self.parameters["size_x"] - self.padding, mic_x),
      )
      self.parameters["mic_y"] = max(
          self.padding,
          min(self.parameters["size_y"] - self.padding, mic_y),
      )
      self.parameters["mic_z"] = max(
          self.padding,
          min(self.parameters["size_z"] - self.padding, mic_z),
      )
  
      # Construct room
      self.room = pra.Room.from_corners(
          np.array(
              [
                  [0, 0],
                  [0, self.parameters["size_y"]],
                  [
                      self.parameters["size_x"],
                      self.parameters["size_y"],
                  ],
                  [self.parameters["size_x"], 0],
              ]
          ).T,
          fs=sample_rate,
          materials=pra.Material(
              self.parameters["absorption_coefficient"]
          ),
          ray_tracing=self.use_ray_tracing,
          air_absorption=True,
          max_order=self.parameters["max_order"],
      )
  
      if self.use_ray_tracing:
          # TODO: Somehow make those parameters
          self.room.set_ray_tracing(**self.ray_tracing_options)
  
      self.room.extrude(
          height=self.parameters["size_z"],
          materials=pra.Material(
              self.parameters["absorption_coefficient"]
          ),
      )
  
      # Add the point source
      self.room.add_source(
          np.array(
              [
                  self.parameters["source_x"],
                  self.parameters["source_y"],
                  self.parameters["source_z"],
              ]
          ),
          signal=samples,
      )
  
      # Add the microphone
      self.room.add_microphone_array(
          pra.MicrophoneArray(
              np.array(
                  [
                      [
                          self.parameters["mic_x"],
                          self.parameters["mic_y"],
                          self.parameters["mic_z"],
                      ]
                  ]
              ).T,
              self.room.fs,
          )
      )
      # Do the simulation
      self.room.compute_rir()
  
file_path: audiomentations/audiomentations/augmentations/room_simulator.py
imports: import random
  from typing import Optional, Dict
  import numpy
  import sys
  from numpy.typing import NDArray
  from scipy.signal import convolve
  from audiomentations.core.transforms_interface import BaseWaveformTransform
label_desc: Use image node_id 2 for calling the RoomSimulator obj's underlying member method code with example usage: obj.randomize_parameters(samples, sample_rate) without return types