def __call__(self, x: np.ndarray, y: np.ndarray | None = None) -> tuple[np.ndarray, np.ndarray | None]:
        """
        Augment the sample `(x, y)` with Gaussian noise. The result is either an extended dataset containing the
        original sample, as well as the newly created noisy samples (augmentation=True) or just the noisy counterparts
        to the original samples.

        :param x: Sample to augment with shape `(batch_size, width, height, depth)`.
        :param y: Labels for the sample. If this argument is provided, it will be augmented with the corresponded
                  original labels of each sample point.
        :return: The augmented dataset and (if provided) corresponding labels.
        """
        logger.info("Original dataset size: %d", x.shape[0])

        # Select indices to augment
        if self.augmentation:
            size = int(x.shape[0] * self.ratio)
            indices = np.random.randint(0, x.shape[0], size=size)

            # Generate noisy samples
            x_aug = np.random.normal(x[indices], scale=self.sigma, size=(size,) + x.shape[1:]).astype(ART_NUMPY_DTYPE)
            x_aug = np.vstack((x, x_aug))
            if y is not None:
                y_aug = np.concatenate((y, y[indices]))
            else:
                y_aug = y
            logger.info("Augmented dataset size: %d", x_aug.shape[0])
        else:
            x_aug = np.random.normal(x, scale=self.sigma, size=x.shape).astype(ART_NUMPY_DTYPE)
            y_aug = y
            logger.info("Created %i samples with Gaussian noise.")

        if self.clip_values is not None:
            x_aug = np.clip(x_aug, self.clip_values[0], self.clip_values[1])

        return x_aug, y_aug

        Augment the sample `(x, y)` with Gaussian noise. The result is either an extended dataset containing the
        original sample, as well as the newly created noisy samples (augmentation=True) or just the noisy counterparts
        to the original samples.

        :param x: Sample to augment with shape `(batch_size, width, height, depth)`.
        :param y: Labels for the sample. If this argument is provided, it will be augmented with the corresponded
                  original labels of each sample point.
        :return: The augmented dataset and (if provided) corresponding labels.
        
art/defences/preprocessor/gaussian_augmentation.py