Source code for diffsptk.signals

# ------------------------------------------------------------------------ #
# 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


[docs] def impulse(order: int, **kwargs) -> torch.Tensor: """Generate impulse sequence. See `impulse <https://sp-nitech.github.io/sptk/latest/main/impulse.html>`_ for details. Parameters ---------- order : int >= 0 The order of the sequence, :math:`M`. **kwargs : additional keyword arguments See `torch.eye <https://pytorch.org/docs/stable/generated/torch.eye.html>`_. Returns ------- out : Tensor [shape=(M+1,)] The impulse sequence. Examples -------- >>> x = diffsptk.impulse(4) >>> x tensor([1., 0., 0., 0., 0.]) """ x = torch.eye(n=1, m=order + 1, **kwargs).squeeze(0) return x
[docs] def step(order: int, value: float = 1, **kwargs) -> torch.Tensor: """Generate step sequence. See `step <https://sp-nitech.github.io/sptk/latest/main/step.html>`_ for details. Parameters ---------- order : int >= 0 The order of the sequence, :math:`M`. value : float Step value. **kwargs : additional keyword arguments See `torch.full <https://pytorch.org/docs/stable/generated/torch.full.html>`_. Returns ------- out : Tensor [shape=(M+1,)] The step sequence. Examples -------- >>> x = diffsptk.step(4, 2) >>> x tensor([2., 2., 2., 2., 2.]) """ x = torch.full((order + 1,), float(value), **kwargs) return x
[docs] def ramp( arg: float, end: float | None = None, step: float = 1, eps: float = 1e-8, **kwargs ) -> torch.Tensor: """Generate ramp sequence. See `ramp <https://sp-nitech.github.io/sptk/latest/main/ramp.html>`_ for details. Parameters ---------- arg : float If `end` is `None`, this is the end value otherwise start value. end : float or None The end value. step : float != 0 The slope. eps : float A correction value. **kwargs : additional keyword arguments See `torch.arange <https://pytorch.org/docs/stable/generated/torch.arange.html>`_. Returns ------- out : Tensor [shape=(?,)] The ramp sequence. Examples -------- >>> x = diffsptk.ramp(4) >>> x tensor([0., 1., 2., 3., 4.]) """ if end is None: start = 0 end = arg else: start = arg if 0 < step: end += eps elif step < 0: end -= eps else: raise ValueError("step must be non-zero") x = torch.arange(start, end, step, **kwargs) return x
[docs] def sin( order: int, period: float | None = None, magnitude: float = 1, **kwargs ) -> torch.Tensor: """Generate sinusoidal sequence. See `sin <https://sp-nitech.github.io/sptk/latest/main/sin.html>`_ for details. Parameters ---------- order : int >= 0 The order of the sequence, :math:`M`. period : float > 0 The period. magnitude : float The magnitude. **kwargs : additional keyword arguments See `torch.arange <https://pytorch.org/docs/stable/generated/torch.arange.html>`_. Returns ------- out : Tensor [shape=(M+1,)] The sinusoidal sequence. Examples -------- >>> x = diffsptk.sin(4) >>> x tensor([ 0.0000, 0.9511, 0.5878, -0.5878, -0.9511]) """ if period is None: period = order + 1 if period <= 0: raise ValueError("period must be positive.") x = torch.arange(order + 1, **kwargs) x = torch.sin(x * (2 * torch.pi / period)) * magnitude return x
[docs] def train( order: int, frame_period: float, norm: str | int = "power", **kwargs ) -> torch.Tensor: """Generate pulse sequence. See `train <https://sp-nitech.github.io/sptk/latest/main/train.html>`_ for details. Parameters ---------- order : int >= 0 The order of the sequence, :math:`M`. frame_period : float >= 1 The frame period. norm : ['none', 'power', 'magnitude'] The normalization type. **kwargs : additional keyword arguments See `torch.zeros <https://pytorch.org/docs/stable/generated/torch.zeros.html>`_. Returns ------- out : Tensor [shape=(M+1,)] The pulse sequence. Examples -------- >>> x = diffsptk.train(5, 2.3) >>> x tensor([1.5166, 0.0000, 0.0000, 1.5166, 0.0000, 1.5166]) """ if frame_period < 1: raise ValueError("frame_period must be greater than or equal to 1.") if norm in (0, "none"): pulse = 1 elif norm in (1, "power"): pulse = frame_period**0.5 elif norm in (2, "magnitude"): pulse = frame_period else: raise ValueError(f"norm {norm} is not supported.") frequency = 1 / frame_period v = torch.full((order + 2,), frequency) v[0] *= -1 v = torch.floor(torch.cumsum(v, dim=0)) index = torch.ge(torch.diff(v), 1) x = torch.zeros(order + 1, **kwargs) x[index] = pulse return x
[docs] def nrand( *order: int, mean: float = 0, stdv: float = 1, var: float | None = None, **kwargs ) -> torch.Tensor: """Generate random number sequence. See `nrand <https://sp-nitech.github.io/sptk/latest/main/nrand.html>`_ for details. Parameters ---------- order : int >= 0 The order of the sequence, :math:`M`. mean : float The mean. stdv : float >= 0 The standard deviation. var : float >= 0 The variance. This overrides `stdv`. **kwargs : additional keyword arguments See `torch.randn <https://pytorch.org/docs/stable/generated/torch.randn.html>`_. Returns ------- out : Tensor [shape=(M+1,)] The random value sequence. Examples -------- >>> x = diffsptk.nrand(4) >>> x tensor([-0.8603, 0.6743, -0.9178, 1.5382, -0.2574]) >>> x = diffsptk.nrand(2, 4) >>> x tensor([[-0.2385, -0.0778, -0.0418, -1.6217, 0.1560], [ 1.6646, 0.8429, 0.9357, -0.5123, 0.9571]]) """ if var is not None: stdv = var**0.5 if stdv < 0: raise ValueError("stdv must be non-negative.") if any(isinstance(item, (list, tuple)) for item in order): order = list(*order) else: order = list(order) order[-1] += 1 x = torch.randn(*order, **kwargs) x = x * stdv + mean return x