code: def signal_framing(
      signal: Union[torch.Tensor, ComplexTensor],
      frame_length: int,
      frame_step: int,
      pad_value=0,
  ) -> Union[torch.Tensor, ComplexTensor]:
      """Expands signal into frames of frame_length.
  
      Args:
          signal : (B * F, D, T)
      Returns:
          torch.Tensor: (B * F, D, T, W)
      """
      if isinstance(signal, ComplexTensor):
          real = signal_framing(
              signal.real, frame_length, frame_step, pad_value
          )
          imag = signal_framing(
              signal.imag, frame_length, frame_step, pad_value
          )
          return ComplexTensor(real, imag)
      elif is_torch_1_9_plus and torch.is_complex(signal):
          real = signal_framing(
              signal.real, frame_length, frame_step, pad_value
          )
          imag = signal_framing(
              signal.imag, frame_length, frame_step, pad_value
          )
          return torch.complex(real, imag)
  
      signal = F.pad(
          signal, (0, frame_length - 1), "constant", pad_value
      )
      indices = sum(
          [
              list(range(i, i + frame_length))
              for i in range(
                  0, signal.size(-1) - frame_length + 1, frame_step
              )
          ],
          [],
      )
  
      signal = signal[..., indices].view(
          *signal.size()[:-1], -1, frame_length
      )
      return signal
  
file_path: espnet/espnet2/enh/layers/wpe.py
imports: from typing import Tuple, Union
  import torch
  import torch.nn.functional
  import torch_complex.functional
  from packaging.version import parse
  from torch_complex.tensor import ComplexTensor
  from espnet2.enh.layers.complex_utils import einsum, matmul, reverse
label_desc: Use image node_id 1 for calling a global function with example usage: signal_framing(signal, frame_length, frame_step, pad_value) and returns: signal, ComplexTensor, torch