def _apply_fir(x, filt: Tensor, n_chans: int) -> Tensor:
        """
        Apply an FIR filter to the input tensor.

        Parameters
        ----------
        x : Tensor
            Input tensor of shape (batch_size, n_chans, n_times).
        filter : dict
            Dictionary containing IIR filter coefficients.
            - "b": Tensor of numerator coefficients.
        n_chans: int
            Number of channels

        Returns
        -------
        Tensor
            Filtered tensor of shape (batch_size, 1, n_chans, n_times).
        """
        # Expand filter coefficients to match the number of channels
        # Original 'b' shape: (filter_length,)
        # After unsqueeze and repeat: (n_chans, filter_length)
        # After final unsqueeze: (1, n_chans, filter_length)
        filt_expanded = filt.to(x.device).unsqueeze(0).repeat(n_chans, 1).unsqueeze(0)

        # Perform FFT-based convolution
        # Input x shape: (batch_size, n_chans, n_times)
        # filt_expanded shape: (1, n_chans, filter_length)
        # After convolution: (batch_size, n_chans, n_times)

        filtered = fftconvolve(
            x, filt_expanded, mode="same"
        )  # Shape: (batch_size, nchans, time_points)

        # Add a new dimension for the band
        # Shape after unsqueeze: (batch_size, 1, n_chans, n_times)
        filtered = filtered.unsqueeze(1)
        # returning the filtered
        return filtered

        Apply an FIR filter to the input tensor.

        Parameters
        ----------
        x : Tensor
            Input tensor of shape (batch_size, n_chans, n_times).
        filter : dict
            Dictionary containing IIR filter coefficients.
            - "b": Tensor of numerator coefficients.
        n_chans: int
            Number of channels

        Returns
        -------
        Tensor
            Filtered tensor of shape (batch_size, 1, n_chans, n_times).
        
braindecode/modules/filter.py