class_docstr: Computes the context window.
  
  This class applies a context window by gathering multiple time steps
  in a single feature vector. The operation is performed with a
  convolutional layer based on a fixed kernel designed for that.
  
  Arguments
  ---------
  left_frames : int
       Number of left frames (i.e, past frames) to collect.
  right_frames : int
      Number of right frames (i.e, future frames) to collect.
  
  Example
  -------
  >>> import torch
  >>> compute_cw = ContextWindow(left_frames=5, right_frames=5)
  >>> inputs = torch.randn([10, 101, 20])
  >>> features = compute_cw(inputs)
  >>> features.shape
  torch.Size([10, 101, 220])
class_docstr_tok: ["Computes","the","context","window",".","This","class","applies","a","context","window","by","gathering","multiple","time","steps","in","a","single","feature","vector",".","The","operation","is","performed","with","a","convolutional","layer","based","on","a","fixed","kernel","designed","for","that",".","Arguments","--","--","--","--","-","left_frames",":","int","Number","of","left","frames","(","i.e",",","past","frames",")","to","collect",".","right_frames",":","int","Number","of","right","frames","(","i.e",",","future","frames",")","to","collect",".","Example","--","--","--","-",">",">",">","import","torch",">",">",">","compute_cw","=","ContextWindow","(","left_frames=5",",","right_frames=5",")",">",">",">","inputs","=","torch.randn","(","[","10",",","101",",","20","]",")",">",">",">","features","=","compute_cw","(","inputs",")",">",">",">","features.shape","torch.Size","(","[","10",",","101",",","220","]",")"]
docstr: Returns the tensor with the surrounding context.
  
  Arguments
  ---------
  x : tensor
      A batch of tensors.
docstr_tok: ["Returns","the","tensor","with","the","surrounding","context",".","Arguments","--","--","--","--","-","x",":","tensor","A","batch","of","tensors","."]
code: def forward(self, x):
      """Returns the tensor with the surrounding context.
  
      Arguments
      ---------
      x : tensor
          A batch of tensors.
      """
  
      x = x.transpose(1, 2)
  
      if self.first_call is True:
          self.first_call = False
          self.kernel = (
              self.kernel.repeat(x.shape[1], 1, 1)
              .view(
                  x.shape[1] * self.context_len,
                  self.kernel_len,
              )
              .unsqueeze(1)
          )
  
      # Managing multi-channel case
      or_shape = x.shape
      if len(or_shape) == 4:
          x = x.reshape(
              or_shape[0] * or_shape[2], or_shape[1], or_shape[3]
          )
  
      # Compute context (using the estimated convolutional kernel)
      cw_x = torch.nn.functional.conv1d(
          x,
          self.kernel.to(x.device),
          groups=x.shape[1],
          padding=max(self.left_frames, self.right_frames),
      )
  
      # Retrieving the original dimensionality (for multi-channel case)
      if len(or_shape) == 4:
          cw_x = cw_x.reshape(
              or_shape[0], cw_x.shape[1], or_shape[2], cw_x.shape[-1]
          )
  
      cw_x = cw_x.transpose(1, 2)
  
      return cw_x
  
imports: import math
  import torch
  import logging
  from speechbrain.utils.checkpoints import mark_as_saver, mark_as_loader, mark_as_transfer, register_checkpoint_hooks
  from speechbrain.dataio.dataio import length_to_mask
label_desc: Use image node_id 2 for calling the ContextWindow obj's underlying member method code with example usage: obj.forward(x) and returns: cw_x