- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
更新:我在 librosa 中重新实现了这个来进行比较,结果确实与 tensorflow 的结果有很大不同。 Librosa 给出了我期望的结果(但不是 tensorflow)。
我已将其发布为 issue在 tensorflow repo 上,但那里很安静,所以我在这里尝试。此外,我不确定这是不是 tensorflow 中的错误,还是代表我的用户错误。为了完整起见,我还将在此处包含完整的来源和结果。
A.) 当我使用汉恩窗口从具有 frame_length=1024
和 frame_step=256
的信号(即 25% 的跳跃大小,75% 的重叠)创建帧时(也尝试了汉明),然后我用 overlap_and_add
进行重构,我希望信号能够正确重构(因为 COLA 等)。但它恰好是振幅的两倍。我需要将生成的信号除以 2 才能正确。
B.) 如果我使用 STFT 创建一系列重叠的频谱图,然后使用逆 STFT 重建,再次使用 frame_length=1024
和 frame_step=256
,信号再次以双倍幅度重建。
我明白为什么会出现这种情况(汉恩在 50% 重叠时的单位增益,因此 75% 重叠将使信号加倍)。但是重构函数考虑到这个不是很正常吗?例如。 librosa istft 确实以正确的幅度返回信号,而 tensorflow 返回两倍。
C.)在任何其他 frame_step 中,都会进行严重的幅度调制。见下图。这似乎根本不对。
更新:如果我在 inverse_stft
中明确设置 window_fn=tf.contrib.signal.inverse_stft_window_fn(frame_step)
,则输出是正确的。所以似乎 inverse_stft
中的 frame_step
没有被传递到窗口函数中(这也是结果所暗示的)。
原始数据:
frames + overlap_and_add 的 tensorflow 输出:
stft+istft 的 tensorflow 输出:
stft+istft 的 librosa 输出:
tensorflow 代码:
from __future__ import print_function
from __future__ import division
import numpy as np
import scipy.io.wavfile
import math
import random
import matplotlib.pyplot as plt
import tensorflow as tf
out_prefix = 'tensorflow'
def plot(data, title, do_save=True):
plt.figure(figsize=(20,5))
plt.plot(data[:3*frame_length])
plt.ylim([-1, 1])
plt.title(title)
plt.grid()
if do_save: plt.savefig(title + '.png')
plt.show()
def reconstruct_from_frames(x, frame_length, frame_step):
name = 'frame'
frames_T = tf.contrib.signal.frame(x, frame_length=frame_length, frame_step=frame_step)
windowed_frames_T = frames_T * tf.contrib.signal.hann_window(frame_length, periodic=True)
output_T = tf.contrib.signal.overlap_and_add(windowed_frames_T, frame_step=frame_step)
return name, output_T
def reconstruct_from_stft(x, frame_length, frame_step):
name = 'stft'
spectrograms_T = tf.contrib.signal.stft(x, frame_length, frame_step)
output_T = tf.contrib.signal.inverse_stft(spectrograms_T, frame_length, frame_step)
return name, output_T
def test(fn, input_data):
print('-'*80)
tf.reset_default_graph()
input_T = tf.placeholder(tf.float32, [None])
name, output_T = fn(input_T, frame_length, frame_step)
title = "{}.{}.{}.l{}.s{}".format(out_prefix, sample_rate, name, frame_length, frame_step)
print(title)
with tf.Session():
output_data = output_T.eval({input_T:input_data})
# output_data /= frame_length/frame_step/2 # tensorflow needs this to normalise amp
plot(output_data, title)
scipy.io.wavfile.write(title+'.wav', sample_rate, output_data)
def generate_data(duration_secs, sample_rate, num_sin, min_freq=10, max_freq=500, rnd_seed=0, max_val=0):
'''generate signal from multiple random sin waves'''
if rnd_seed>0: random.seed(rnd_seed)
data = np.zeros([duration_secs*sample_rate], np.float32)
for i in range(num_sin):
w = np.float32(np.sin(np.linspace(0, math.pi*2*random.randrange(min_freq, max_freq), num=duration_secs*sample_rate)))
data += random.random() * w
if max_val>0:
data *= max_val / np.max(np.abs(data))
return data
frame_length = 1024
sample_rate = 22050
input_data = generate_data(duration_secs=1, sample_rate=sample_rate, num_sin=1, rnd_seed=2, max_val=0.5)
title = "{}.orig".format(sample_rate)
plot(input_data, title)
scipy.io.wavfile.write(title+'.wav', sample_rate, input_data)
for frame_step in [256, 512, 768, 1024]:
test(reconstruct_from_frames, input_data)
test(reconstruct_from_stft, input_data)
print('done.')
librosa 代码:
from __future__ import print_function
from __future__ import division
import numpy as np
import scipy.io.wavfile
import math
import random
import matplotlib.pyplot as plt
import librosa.core as lc
out_prefix = 'librosa'
def plot(data, title, do_save=True):
plt.figure(figsize=(20,5))
plt.plot(data[:3*frame_length])
plt.ylim([-1, 1])
plt.title(title)
plt.grid()
if do_save: plt.savefig(title + '.png')
plt.show()
def reconstruct_from_stft(x, frame_length, frame_step):
name = 'stft'
stft = lc.stft(x, n_fft=frame_length, hop_length=frame_step)
istft = lc.istft(stft, frame_step)
return name, istft
def test(fn, input_data):
print('-'*80)
name, output_data = fn(input_data, frame_length, frame_step)
title = "{}.{}.{}.l{}.s{}".format(out_prefix, sample_rate, name, frame_length, frame_step)
print(title)
# output_data /= frame_length/frame_step/2 # tensorflow needs this to normalise amp
plot(output_data, title)
scipy.io.wavfile.write(title+'.wav', sample_rate, output_data)
def generate_data(duration_secs, sample_rate, num_sin, min_freq=10, max_freq=500, rnd_seed=0, max_val=0):
'''generate signal from multiple random sin waves'''
if rnd_seed>0: random.seed(rnd_seed)
data = np.zeros([duration_secs*sample_rate], np.float32)
for i in range(num_sin):
w = np.float32(np.sin(np.linspace(0, math.pi*2*random.randrange(min_freq, max_freq), num=duration_secs*sample_rate)))
data += random.random() * w
if max_val>0:
data *= max_val / np.max(np.abs(data))
return data
frame_length = 1024
sample_rate = 22050
input_data = generate_data(duration_secs=1, sample_rate=sample_rate, num_sin=1, rnd_seed=2, max_val=0.5)
title = "{}.orig".format(sample_rate)
plot(input_data, title)
scipy.io.wavfile.write(title+'.wav', sample_rate, input_data)
for frame_step in [256, 512, 768, 1024]:
test(reconstruct_from_stft, input_data)
print('done.')
(刚刚尝试使用 TF1.5、Cuda9.0、cuDNN 7.0.5,结果相同)。
最佳答案
你应该使用tf.signal.inverse_stft_window_fn
window_fn=tf.signal.inverse_stft_window_fn(frame_step)
tf_istfts=tf.signal.inverse_stft(tf_stfts, frame_length=frame_length, frame_step=frame_step, fft_length=fft_length, window_fn=window_fn)}
查看更多信息 inverse_stft_window_fn
关于python - 使用 tensorflow.contrib.signal 重建信号会导致放大或调制(帧、overlap_and_add、stft 等),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48510229/
我想执行 BPSK 调制并用 Java 绘制调制信号。但我无法弄清楚。 我已经成功地对信号进行了编码,但是当我将载波和基带信号相乘然后绘制它时,我得到了一个尴尬的信号。 出于绘图目的,我使用了 JFr
我在 Octave 中使用以下代码来实现正弦消息和方波载波的频率调制。 %script to make a squarewave carrier modulated with a sinusoidal
我如何调制 Web Audio API 中的任何 AudioParams,例如使用低频振荡器的 GainNode 的增益值? 最佳答案 https://coderwall.com/p/h1jnmg v
我目前正在创建一个卫星地面站, future 几个月将用于控制我们的立方体卫星。使用的调制方案是 GFSK,波特率为 9600。在尝试通过直接连接流程图中的 tx 和 rx block 与卫星通信之前
我是一名优秀的程序员,十分优秀!