docstr: Forward.
  
  Args:
      input (torch.Tensor or ComplexTensor): Encoded feature [B, T, F]
      ilens (torch.Tensor): input lengths [Batch]
      additional (Dict or None): other data included in model
          NOTE: not used in this model
  
  Returns:
      masked (List[Union(torch.Tensor, ComplexTensor)]): [(B, T, F), ...]
      ilens (torch.Tensor): (B,)
      others predicted data, e.g. masks: OrderedDict[
          'mask_spk1': torch.Tensor(Batch, Frames, Freq),
          'mask_spk2': torch.Tensor(Batch, Frames, Freq),
          ...
          'mask_spkn': torch.Tensor(Batch, Frames, Freq),
      ]
docstr_tok: ["Forward",".","Args",":","input","(","torch.Tensor","or","ComplexTensor",")",":","Encoded","feature","[","B",",","T",",","F","]","ilens","(","torch.Tensor",")",":","input","lengths","[","Batch","]","additional","(","Dict","or","None",")",":","other","data","included","in","model","NOTE",":","not","used","in","this","model","Returns",":","masked","(","List","[","Union","(","torch.Tensor",",","ComplexTensor",")","]",")",":","[","(","B",",","T",",","F",")",",","...","]","ilens","(","torch.Tensor",")",":","(","B",",",")","others","predicted","data",",","e.g",".","masks",":","OrderedDict","[","'mask_spk1","'",":","torch.Tensor","(","Batch",",","Frames",",","Freq",")",",","'mask_spk2","'",":","torch.Tensor","(","Batch",",","Frames",",","Freq",")",",","...","'mask_spkn","'",":","torch.Tensor","(","Batch",",","Frames",",","Freq",")",",","]"]
code: def forward(
      self,
      input: Union[torch.Tensor, ComplexTensor],
      ilens: torch.Tensor,
      additional: Optional[Dict] = None,
  ) -> Tuple[
      List[Union[torch.Tensor, ComplexTensor]],
      torch.Tensor,
      OrderedDict,
  ]:
      """Forward.
  
      Args:
          input (torch.Tensor or ComplexTensor): Encoded feature [B, T, F]
          ilens (torch.Tensor): input lengths [Batch]
          additional (Dict or None): other data included in model
              NOTE: not used in this model
  
      Returns:
          masked (List[Union(torch.Tensor, ComplexTensor)]): [(B, T, F), ...]
          ilens (torch.Tensor): (B,)
          others predicted data, e.g. masks: OrderedDict[
              'mask_spk1': torch.Tensor(Batch, Frames, Freq),
              'mask_spk2': torch.Tensor(Batch, Frames, Freq),
              ...
              'mask_spkn': torch.Tensor(Batch, Frames, Freq),
          ]
      """
      # shape (B, T, F) --> (B, F, T)
      specs = input.permute(0, 2, 1)
      real, imag = specs.real, specs.imag
  
      # # shape (B, F, T)
      # spec_mags = torch.sqrt(real**2 + imag**2 + 1e-8)
      # # shape (B, F, T)
      # spec_phase = torch.atan2(imag, real)
      # shape (B, 2, F, T)
      cspecs = torch.stack([real, imag], 1)
      # shape (B, 2, F-1, T)
      cspecs = cspecs[:, :, 1:]
  
      out = cspecs
      encoder_out = []
  
      for idx, layer in enumerate(self.encoder):
          out = layer(out)
          encoder_out.append(out)
      # shape (B, C, F, T)
      batch_size, channels, dims, lengths = out.size()
      # shape (T, B, C, F)
      out = out.permute(3, 0, 1, 2)
      if self.use_clstm:
          # shape (T, B, C // 2, F)
          r_rnn_in = out[:, :, : channels // 2]
          # shape (T, B, C // 2, F)
          i_rnn_in = out[:, :, channels // 2 :]
          # shape (T, B, C // 2 * F)
          r_rnn_in = torch.reshape(
              r_rnn_in, [lengths, batch_size, channels // 2 * dims]
          )
          # shape (T, B, C // 2 * F)
          i_rnn_in = torch.reshape(
              i_rnn_in, [lengths, batch_size, channels // 2 * dims]
          )
          r_rnn_in, i_rnn_in = self.enhance([r_rnn_in, i_rnn_in])
          # shape (T, B, C // 2, F)
          r_rnn_in = torch.reshape(
              r_rnn_in, [lengths, batch_size, channels // 2, dims]
          )
          # shape (T, B, C // 2, F)
          i_rnn_in = torch.reshape(
              i_rnn_in, [lengths, batch_size, channels // 2, dims]
          )
          # shape (T, B, C, F)
          out = torch.cat([r_rnn_in, i_rnn_in], 2)
  
      else:
          # shape (T, B, C*F)
          out = torch.reshape(
              out, [lengths, batch_size, channels * dims]
          )
          out, _ = self.enhance(out)
          out = self.tranform(out)
          # shape (T, B, C, F)
          out = torch.reshape(
              out, [lengths, batch_size, channels, dims]
          )
      # shape (B, C, F, T)
      out = out.permute(1, 2, 3, 0)
  
      for idx in range(len(self.decoder)):
          # skip connection
          out = complex_cat([out, encoder_out[-1 - idx]], 1)
          out = self.decoder[idx](out)
          out = out[..., 1:]
      # out shape = (B, 2*num_spk, F-1, T) if self.use_noise_mask == False
      # else (B, 2*(num_spk+1), F-1, T)
  
      masks = self.create_masks(out)
      masked = self.apply_masks(masks, real, imag)
      others = OrderedDict(
          zip(
              ["mask_spk{}".format(i + 1) for i in range(self.num_spk)],
              masks,
          )
      )
  
      if self.use_noise_mask:
          others["mask_noise1"] = masks[-1]
          others["noise1"] = masked.pop(-1)
  
      return (masked, ilens, others)
  
file_path: espnet/espnet2/enh/separator/dccrn_separator.py
imports: from collections import OrderedDict
  from typing import Dict, List, Optional, Tuple, Union
  import torch
  import torch.nn
  import torch.nn.functional
  from packaging.version import parse
  from torch_complex.tensor import ComplexTensor
  from espnet2.enh.layers.complexnn import ComplexBatchNorm, ComplexConv2d, ComplexConvTranspose2d, NavieComplexLSTM, complex_cat
  from espnet2.enh.separator.abs_separator import AbsSeparator
label_desc: Use image node_id 2 for calling the DCCRNSeparator obj's underlying member method code with example usage: obj.forward(input, ilens, additional) and returns: masked,  ilens,  others