Calculates a spectrogram over one waveform using the Short-Time Fourier Transform. This function can create the following kinds of spectrograms: - amplitude spectrogram (`power = 1.0`) - power spectrogram (`power = 2.0`) - complex-valued spectrogram (`power = None`)
(
waveform: np.ndarray,
window: np.ndarray,
frame_length: int,
hop_length: int,
fft_length: Optional[int] = None,
power: Optional[float] = 1.0,
center: bool = True,
pad_mode: str = "reflect",
onesided: bool = True,
preemphasis: Optional[float] = None,
mel_filters: Optional[np.ndarray] = None,
mel_floor: float = 1e-10,
log_mel: Optional[str] = None,
reference: float = 1.0,
min_value: float = 1e-10,
db_range: Optional[float] = None,
remove_dc_offset: Optional[bool] = None,
dtype: np.dtype = np.float32,
)
| 381 | |
| 382 | # TODO This method does not support batching yet as we are mainly focused on inference. |
| 383 | def spectrogram( |
| 384 | waveform: np.ndarray, |
| 385 | window: np.ndarray, |
| 386 | frame_length: int, |
| 387 | hop_length: int, |
| 388 | fft_length: Optional[int] = None, |
| 389 | power: Optional[float] = 1.0, |
| 390 | center: bool = True, |
| 391 | pad_mode: str = "reflect", |
| 392 | onesided: bool = True, |
| 393 | preemphasis: Optional[float] = None, |
| 394 | mel_filters: Optional[np.ndarray] = None, |
| 395 | mel_floor: float = 1e-10, |
| 396 | log_mel: Optional[str] = None, |
| 397 | reference: float = 1.0, |
| 398 | min_value: float = 1e-10, |
| 399 | db_range: Optional[float] = None, |
| 400 | remove_dc_offset: Optional[bool] = None, |
| 401 | dtype: np.dtype = np.float32, |
| 402 | ) -> np.ndarray: |
| 403 | """ |
| 404 | Calculates a spectrogram over one waveform using the Short-Time Fourier Transform. |
| 405 | |
| 406 | This function can create the following kinds of spectrograms: |
| 407 | |
| 408 | - amplitude spectrogram (`power = 1.0`) |
| 409 | - power spectrogram (`power = 2.0`) |
| 410 | - complex-valued spectrogram (`power = None`) |
| 411 | - log spectrogram (use `log_mel` argument) |
| 412 | - mel spectrogram (provide `mel_filters`) |
| 413 | - log-mel spectrogram (provide `mel_filters` and `log_mel`) |
| 414 | |
| 415 | How this works: |
| 416 | |
| 417 | 1. The input waveform is split into frames of size `frame_length` that are partially overlapping by `frame_length |
| 418 | - hop_length` samples. |
| 419 | 2. Each frame is multiplied by the window and placed into a buffer of size `fft_length`. |
| 420 | 3. The DFT is taken of each windowed frame. |
| 421 | 4. The results are stacked into a spectrogram. |
| 422 | |
| 423 | We make a distinction between the following "blocks" of sample data, each of which may have a different lengths: |
| 424 | |
| 425 | - The analysis frame. This is the size of the time slices that the input waveform is split into. |
| 426 | - The window. Each analysis frame is multiplied by the window to avoid spectral leakage. |
| 427 | - The FFT input buffer. The length of this determines how many frequency bins are in the spectrogram. |
| 428 | |
| 429 | In this implementation, the window is assumed to be zero-padded to have the same size as the analysis frame. A |
| 430 | padded window can be obtained from `window_function()`. The FFT input buffer may be larger than the analysis frame, |
| 431 | typically the next power of two. |
| 432 | |
| 433 | Note: This function is not optimized for speed yet. It should be mostly compatible with `librosa.stft` and |
| 434 | `torchaudio.functional.transforms.Spectrogram`, although it is more flexible due to the different ways spectrograms |
| 435 | can be constructed. |
| 436 | |
| 437 | Args: |
| 438 | waveform (`np.ndarray` of shape `(length,)`): |
| 439 | The input waveform. This must be a single real-valued, mono waveform. |
| 440 | window (`np.ndarray` of shape `(frame_length,)`): |