def METHOD_NAME(
    self,
    phone: torch.Tensor,
    phone_lengths: torch.Tensor,
    midi_id: torch.Tensor,
    dur: torch.Tensor,
    slur: Optional[torch.Tensor] = None,
) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
    """Calculate forward propagation.
    Args:
        phone (Tensor): Input index tensor (B, T_text).
        phone_lengths (Tensor): Length tensor (B,).
        midi_id (Tensor): Input midi tensor (B, T_text).
        dur (Tensor): Input duration tensor (B, T_text).
    Returns:
        Tensor: Encoded hidden representation (B, attention_dim, T_text).
        Tensor: Mask tensor for padded part (B, 1, T_text).
        Tensor: Encoded hidden representation for duration
            (B, attention_dim, T_text).
        Tensor: Encoded hidden representation for pitch
            (B, attention_dim, T_text).
    """
    phone_end = self.emb_phone(phone) * math.sqrt(self.emb_phone_dim)
    pitch_end = self.emb_pitch(midi_id) * math.sqrt(self.emb_pitch_dim)
    if slur is not None:
        slur_end = self.emb_slur(slur) * math.sqrt(64)
    dur = dur.float()
    dur_end = self.emb_dur(dur.unsqueeze(-1))
    if slur is not None:
        x = torch.cat([phone_end, pitch_end, slur_end, dur_end], dim=-1)
    else:
        x = torch.cat([phone_end, pitch_end, dur_end], dim=-1)
    dur_input = self.pre_dur_net(x)
    dur_input = torch.transpose(dur_input, 1, -1)
    x = self.pre_net(x)
    # x = torch.transpose(x, 1, -1)  # [b, h, t]
    x_mask = (
        make_non_pad_mask(phone_lengths)
        .to(
            device=x.device,
            dtype=x.dtype,
        )
        .unsqueeze(1)
    )
    # encoder assume the channel last (B, T_text, attention_dim)
    # but mask shape shoud be (B, 1, T_text)
    x, _ = self.encoder(x, x_mask)
    # convert the channel first to (B, attention_dim, T_text)
    x = x.transpose(1, 2)
    x = self.proj(x) * x_mask
    pitch_info = self.proj_pitch(pitch_end.transpose(1, 2))
    return x, x_mask, dur_input, pitch_info