code: def phase_vocoder(
      complex_specgrams: Tensor, rate: float, phase_advance: Tensor
  ) -> Tensor:
      r"""Given a STFT tensor, speed up in time without modifying pitch by a factor of ``rate``.
  
      .. devices:: CPU CUDA
  
      .. properties:: Autograd TorchScript
  
      Args:
          complex_specgrams (Tensor):
              A tensor of dimension `(..., freq, num_frame)` with complex dtype.
          rate (float): Speed-up factor
          phase_advance (Tensor): Expected phase advance in each bin. Dimension of `(freq, 1)`
  
      Returns:
          Tensor:
              Stretched spectrogram. The resulting tensor is of the same dtype as the input
              spectrogram, but the number of frames is changed to ``ceil(num_frame / rate)``.
  
      Example
          >>> freq, hop_length = 1025, 512
          >>> # (channel, freq, time)
          >>> complex_specgrams = torch.randn(2, freq, 300, dtype=torch.cfloat)
          >>> rate = 1.3 # Speed up by 30%
          >>> phase_advance = torch.linspace(
          >>>    0, math.pi * hop_length, freq)[..., None]
          >>> x = phase_vocoder(complex_specgrams, rate, phase_advance)
          >>> x.shape # with 231 == ceil(300 / 1.3)
          torch.Size([2, 1025, 231])
      """
      if rate == 1.0:
          return complex_specgrams
  
      # pack batch
      shape = complex_specgrams.size()
      complex_specgrams = complex_specgrams.reshape(
          [-1] + list(shape[-2:])
      )
  
      # Figures out the corresponding real dtype, i.e. complex128 -> float64, complex64 -> float32
      # Note torch.real is a view so it does not incur any memory copy.
      real_dtype = torch.real(complex_specgrams).dtype
      time_steps = torch.arange(
          0,
          complex_specgrams.size(-1),
          rate,
          device=complex_specgrams.device,
          dtype=real_dtype,
      )
  
      alphas = time_steps % 1.0
      phase_0 = complex_specgrams[..., :1].angle()
  
      # Time Padding
      complex_specgrams = torch.nn.functional.pad(
          complex_specgrams, [0, 2]
      )
  
      # (new_bins, freq, 2)
      complex_specgrams_0 = complex_specgrams.index_select(
          -1, time_steps.long()
      )
      complex_specgrams_1 = complex_specgrams.index_select(
          -1, (time_steps + 1).long()
      )
  
      angle_0 = complex_specgrams_0.angle()
      angle_1 = complex_specgrams_1.angle()
  
      norm_0 = complex_specgrams_0.abs()
      norm_1 = complex_specgrams_1.abs()
  
      phase = angle_1 - angle_0 - phase_advance
      phase = phase - 2 * math.pi * torch.round(phase / (2 * math.pi))
  
      # Compute Phase Accum
      phase = phase + phase_advance
      phase = torch.cat([phase_0, phase[..., :-1]], dim=-1)
      phase_acc = torch.cumsum(phase, -1)
  
      mag = alphas * norm_1 + (1 - alphas) * norm_0
  
      complex_specgrams_stretch = torch.polar(mag, phase_acc)
  
      # unpack batch
      complex_specgrams_stretch = complex_specgrams_stretch.reshape(
          shape[:-2] + complex_specgrams_stretch.shape[1:]
      )
      return complex_specgrams_stretch
  
imports: import math
  import tempfile
  import warnings
  from collections.abc import Sequence
  from typing import List, Optional, Tuple, Union
  import torch
  import torchaudio
  from torch import Tensor
  from torchaudio._internal.module_utils import deprecated
  from .filtering import highpass_biquad, treble_biquad
label_desc: Use image node_id 16 for calling a global function with example usage: phase_vocoder(complex_specgrams, rate, phase_advance) and returns: complex_specgrams_stretch, complex_specgrams