class_docstr: A `scipy.signal.butter`-based generic filter class.
class_docstr_tok: ["A","`","scipy.signal.butter","`","-based","generic","filter","class","."]
code: def apply(
      self, samples: NDArray[np.float32], sample_rate: int = None
  ):
      assert samples.dtype == np.float32
  
      if (
          self.filter_type
          in BaseButterworthFilter.ALLOWED_ONE_SIDE_FILTER_TYPES
      ):
          cutoff_freq = self.parameters["cutoff_freq"]
          nyquist_freq = sample_rate // 2
          if cutoff_freq > nyquist_freq:
              # Ensure that the cutoff frequency does not exceed the nyquist
              # frequency to avoid an exception from scipy
              cutoff_freq = nyquist_freq * 0.9999
          sos = butter(
              self.parameters["rolloff"]
              // (12 if self.zero_phase else 6),
              cutoff_freq,
              btype=self.filter_type,
              analog=False,
              fs=sample_rate,
              output="sos",
          )
      elif (
          self.filter_type
          in BaseButterworthFilter.ALLOWED_TWO_SIDE_FILTER_TYPES
      ):
          low_freq = (
              self.parameters["center_freq"]
              - self.parameters["bandwidth"] / 2
          )
          high_freq = (
              self.parameters["center_freq"]
              + self.parameters["bandwidth"] / 2
          )
          nyquist_freq = sample_rate // 2
          if high_freq > nyquist_freq:
              # Ensure that the upper critical frequency does not exceed the nyquist
              # frequency to avoid an exception from scipy
              high_freq = nyquist_freq * 0.9999
          sos = butter(
              self.parameters["rolloff"]
              // (12 if self.zero_phase else 6),
              [low_freq, high_freq],
              btype=self.filter_type,
              analog=False,
              fs=sample_rate,
              output="sos",
          )
  
      # The actual processing takes place here
      if len(samples.shape) == 1:
          if self.zero_phase:
              processed_samples = sosfiltfilt(sos, samples)
          else:
              processed_samples, _ = sosfilt(
                  sos, samples, zi=sosfilt_zi(sos) * samples[0]
              )
          processed_samples = processed_samples.astype(np.float32)
      else:
          processed_samples = np.zeros_like(samples, dtype=np.float32)
          if self.zero_phase:
              for chn_idx in range(samples.shape[0]):
                  processed_samples[chn_idx, :] = sosfiltfilt(
                      sos, samples[chn_idx, :]
                  )
          else:
              zi = sosfilt_zi(sos)
              for chn_idx in range(samples.shape[0]):
                  processed_samples[chn_idx, :], _ = sosfilt(
                      sos,
                      samples[chn_idx, :],
                      zi=zi * samples[chn_idx, 0],
                  )
  
      return processed_samples
  
file_path: audiomentations/audiomentations/augmentations/base_butterword_filter.py
imports: import random
  import numpy
  from numpy.typing import NDArray
  from scipy.signal import butter, sosfilt, sosfiltfilt, sosfilt_zi
  from audiomentations.core.transforms_interface import BaseWaveformTransform
  from audiomentations.core.utils import convert_frequency_to_mel, convert_mel_to_frequency
label_desc: Use image node_id 5 for calling the BaseButterworthFilter obj's underlying member method code with example usage: obj.apply(samples, sample_rate) and returns: processed_samples