Source code for diffsptk.core.frame

# ------------------------------------------------------------------------ #
# Copyright 2022 SPTK Working Group                                        #
#                                                                          #
# Licensed under the Apache License, Version 2.0 (the "License");          #
# you may not use this file except in compliance with the License.         #
# You may obtain a copy of the License at                                  #
#                                                                          #
#     http://www.apache.org/licenses/LICENSE-2.0                           #
#                                                                          #
# Unless required by applicable law or agreed to in writing, software      #
# distributed under the License is distributed on an "AS IS" BASIS,        #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and      #
# limitations under the License.                                           #
# ------------------------------------------------------------------------ #

import torch.nn as nn


[docs]class Frame(nn.Module): """See `this page <https://sp-nitech.github.io/sptk/latest/main/frame.html>`_ for details. Parameters ---------- frame_length : int >= 1 [scalar] Frame length, :math:`L`. frame_peirod : int >= 1 [scalar] Frame period, :math:`P`. center : bool [scalar] If True, assume that the center of data is the center of frame, otherwise assume that the center of data is the left edge of frame. zmean : bool [scalar] If True, perform mean subtraction on each frame. """ def __init__(self, frame_length, frame_period, center=True, zmean=False): super(Frame, self).__init__() self.frame_length = frame_length self.frame_period = frame_period self.zmean = zmean assert 1 <= self.frame_length assert 1 <= self.frame_period # Make padding module. if center: left_pad_width = self.frame_length // 2 right_pad_width = (self.frame_length - 1) // 2 else: left_pad_width = 0 right_pad_width = self.frame_length - 1 self.pad = nn.ConstantPad1d((left_pad_width, right_pad_width), 0)
[docs] def forward(self, x): """Apply framing to given waveform. Parameters ---------- x : Tensor [shape=(..., T)] Waveform. Returns ------- y : Tensor [shape=(..., T/P, L)] Framed waveform. Examples -------- >>> x = diffsptk.ramp(1, 9) >>> frame = diffsptk.Frame(5, 2) >>> y = frame(x) >>> y tensor([[0., 0., 1., 2., 3.], [1., 2., 3., 4., 5.], [3., 4., 5., 6., 7.], [5., 6., 7., 8., 9.], [7., 8., 9., 0., 0.]]) """ y = self.pad(x) y = y.unfold(-1, self.frame_length, self.frame_period) if self.zmean: y = y - y.mean(-1, keepdim=True) return y