首页 > 其他分享 >Tensorflow 实现的sine函数,通过基频率构建激励信号

Tensorflow 实现的sine函数,通过基频率构建激励信号

时间:2022-09-22 14:45:46浏览次数:41  
标签:f0 rand values self 构建 tf Tensorflow sine

本篇博客主要是用tensorflow 来实现激励信号的构建,通过基础频率来构建

主要思路如下

  • 在有声音的部分, 激励信号是有 fundamental frequency (f0) 和 harmonics的具体值来构建
  • 在静音位置,通过高斯白噪声来构建

具体代码如下

import tensorflow as tf
import numpy as np

class TFSineGen(tf.keras.layers.Layer):
    def __init__(self, samp_rate, harmonic_num=0,
                 sine_amp=0.1, noise_std=0.003,
                 voiced_threshold=0,
                 flag_for_pulse=True, **kwargs):
        """ Definition of sine generator
            SineGen(samp_rate, harmonic_num = 0,
                    sine_amp = 0.1, noise_std = 0.003,
                    voiced_threshold = 0,
                    flag_for_pulse=False)

            samp_rate: sampling rate in Hz
            harmonic_num: number of harmonic overtones (default 0)
            sine_amp: amplitude of sine-wavefrom (default 0.1)
            noise_std: std of Gaussian noise (default 0.003)
            voiced_thoreshold: F0 threshold for U/V classification (default 0)
            flag_for_pulse: this SinGen is used inside PulseGen (default False)

            Note: when flag_for_pulse is True, the first time step of a voiced
                segment is always sin(np.pi) or cos(0)
            """
        super().__init__(**kwargs)
        self.sine_amp = sine_amp
        self.noise_std = noise_std
        self.harmonic_num = harmonic_num
        self.dim = self.harmonic_num + 1
        self.sampling_rate = samp_rate
        self.voiced_threshold = voiced_threshold
        self.flag_for_pulse = flag_for_pulse
        self.rad_values1 = None
        self.rand_ini1 = None
        self.cumsum_shift = None

    def _f02uv(self, f0):
        # generate uv signal
        uv = tf.ones_like(f0)
        uv = uv * tf.cast((f0 > self.voiced_threshold), dtype=tf.float32)
        return uv

    def _f02sine(self, f0_values):
        """ f0_values: (batchsize, length, dim)
            where dim indicates fundamental tone and overtones
        """
        # convert to F0 in rad. The interger part n can be ignored
        # because 2 * np.pi * n doesn't affect phase
        rad_values = (f0_values / self.sampling_rate) % 1
        # print(rad_values)
        # if self.rad_values1 is None:
        # self.rad_values1 = tf.Variable(rad_values, trainable=False, name = 'rad_values1')
        """
        rand_ini = torch.rand(f0_values.shape[0], f0_values.shape[2], \
                              device=f0_values.device)
        rand_ini[:, 0] = 0
        # print("rand_inirand_ini:", rand_ini)
        rad_values[:, 0, :] = rad_values[:, 0, :] + rand_ini
        """
        self.rad_values1 = rad_values
        # print("self.rad_values1:", self.rad_values1)
        f0_values_shape = shape_list(f0_values)
        # print("self.f0_values_shape:", f0_values_shape)
        rand_ini = tf.random.normal(shape=[f0_values_shape[0], f0_values_shape[2]], mean=0.0, stddev=1.0)
        # print("f0_values:", f0_values, rand_ini_)
        # if self.rand_ini1 is None:
        #     self.rand_ini1 = tf.Variable(rand_ini_, trainable=False, name='rand_ini1')
        # rand_ini_ = rand_ini_
        # rand_ini.assign(rand_ini_)

        # rand_ini[:, 0] = tf.zeros(f0_values_shape[0])
        # rand_ini = tf.unstack(rand_ini)
        rand_ini = tf.concat([tf.zeros([f0_values_shape[0], 1]), rand_ini[:, 1:]], axis=-1)
        rad_values = tf.concat([tf.expand_dims(rad_values[:, 0, :] + rand_ini, axis=1), rad_values[:, 1:, :]], axis=1)

        # To prevent torch.cumsum numerical overflow,
        # it is necessary to add -1 whenever \sum_k=1^n rad_value_k > 1.
        # Buffer tmp_over_one_idx indicates the time step to add -1.
        # This will not change F0 of sine because (x-1) * 2*pi = x *2*pi
        tmp_over_one = tf.cumsum(self.rad_values1, 1) % 1
        tmp_over_one_idx = (tmp_over_one[:, 1:, :] -
                            tmp_over_one[:, :-1, :]) < 0
        cumsum_shift = tf.zeros_like(self.rad_values1)
        cumsum_shift = tf.concat([cumsum_shift[:, 0:1, :], tf.cast(tmp_over_one_idx, dtype=tf.float32) * -1.0], axis=1)

        sines = tf.sin(tf.cumsum(rad_values + cumsum_shift, axis=1) * 2 * np.pi)
        return sines

    def call(self, f0):
        """ sine_tensor, uv = forward(f0)
        input F0: tensor(batchsize=1, length, dim=1)
                  f0 for unvoiced steps should be 0
        output sine_tensor: tensor(batchsize=1, length, dim)
        output uv: tensor(batchsize=1, length, 1)
        """
        f0_buf_1 = [f0[:, :, 0]]
        # f0_tmp = f0
        for idx in np.arange(self.harmonic_num):
            f0_tmp = f0[:, :, 0] * (idx + 2)
            f0_buf_1.append(f0_tmp)

        f0_buf = tf.stack(f0_buf_1, axis=-1)
        # generate sine waveforms
        sine_waves = self._f02sine(f0_buf) * self.sine_amp

        # generate uv signal
        uv = self._f02uv(f0)

        noise_amp = uv * self.noise_std + (1 - uv) * self.sine_amp / 3
        # print('noise_amp', noise_amp)
        noise = noise_amp * tf.random.normal(shape=tf.shape(sine_waves))  # tf.randn_like(sine_waves)

        # first: set the unvoiced part to 0 by uv
        # then: additive noise
        sine_waves = sine_waves * uv + noise
        return sine_waves, uv, noise, noise_amp

标签:f0,rand,values,self,构建,tf,Tensorflow,sine
From: https://www.cnblogs.com/wuzhitj/p/16719190.html

相关文章

  • Process finished with exit code -1073740791 (0xC0000409) tensorflow显存不足
    显存问题:1、这种情况需要去官网下载zlib的文件,http://www.winimage.com/zLibDll/zlib123dllx64.zip这是下载地址。2、在解压后的文件夹dll_x64中找到zlibwapi.dll文......
  • 美团数据库运维自动化系统构建之路
    文章链接 美团数据库运维自动化系统构建之路-美团技术团队(meituan.com)本文整理自美团点评技术沙龙第10期:数据库技术架构与实践。美团点评技术沙龙由美团点评技术团......
  • 通过Jenkins构建CI/CD实现全链路灰度
    简介: 本文介绍通过Jenkins构建流水线的方式实现全链路灰度功能。作者:卜比 本文介绍通过Jenkins构建流水线的方式实现全链路灰度功能。 在发布过程中,......
  • 上传了ipa但iTunes Connect没有构建版本问题
    AU上传ipa出现下图红框提示说明成功上传,如果AppStore后台没有出现构建版本,请登录apple账号对应的邮箱查看反馈,特别留意垃圾邮箱,无论成功还是失败,apple都会发邮件一、首......
  • 基于Apache Hudi构建企业级数据湖
                         ......
  • Typer 构建命令行应用
    Typer构建命令行应用1.摘要Typer是一个构建命令行程序的python包,它具有一下几个优点:设计简单,学习成本低,花费更少的时间debug用户使用便捷,自动构建帮助文档并......
  • vite+svelte项目构建篇
    描述学习博文[https://juejin.cn/post/7121759118070644772#heading-21]1、项目构建步骤:#1、新建文件夹study-vite-svelte#2、下载模板的命令npminitvite@late......
  • 如何使用 Prefect 中的任务、流和子流构建模块化数据流
    如何使用Prefect中的任务、流和子流构建模块化数据流以及如何在Prefect数据管道中定义状态和数据依赖关系磷反射是一个协调平面对于不断发展的数据世界。使用长......
  • 构建更好的标签云
    发表于2018年2月1日  下载该项目的源代码和二进制文件可在https://github.com/BradSmith1985/TagClouds典型的标签云标签云是一种显示主题/类别列表及其相......
  • 阿里云张新涛:连接产业上下游,构建XR协作生态
    简介: 用交互技术辅以澎湃的算力带给大家最真实的“沉浸式体验”2022年9月2日,在世界人工智能大会“区块新生数字宇宙——元宇宙技术与生态合作”分论坛上,阿里云......