前提・実現したいこと
pythonを使ってタイムストレッチを再現したいと思い、調べていたところ下記のようなサイトを見つけました。
http://yukara-13.hatenablog.com/entry/2014/02/16/093556
このソースコードをそのまま実行してみたのですがうまくいきませんでした。
改善点を教えていただきたいです。
発生している問題・エラーメッセージ
Traceback (most recent call last):
File "time_sample", line 149, in <module>
test(input_wav)
File "time_sample", line 142, in test
new_data = timeStretch(data, fs, 2, cut_wid = 0.05, cross_wid = 0.03, fade_func = hamming)
File "time_sample", line 65, in timeStretch
new_sig = zeros(cut_num * (I + 1), dtype = float)
TypeError: 'float' object cannot be interpreted as an integer
該当のソースコード
-- coding: utf-8 --
"""
時間領域でのピッチシフト・タイムストレッチ
"""
from scipy import arange, array, around, ceil, fft, hamming, ifft, interp, linspace, sqrt, zeros
from scipy.io.wavfile import read, write
from matplotlib import pylab as pl
from stft import stft
def triangle(length):
h = int(ceil(length / 2.))
ret = zeros(length, dtype = float)
ret[: h] = (arange(h, dtype = float) / (h - 1))
if length % 2 == 0:
ret[- h :] = ret[h - 1 :: -1]
else:
ret[- h + 1 :] = ret[h - 1 :: -1]
return ret
def calc_dynamics(sig, fs, cut_wid = 0.01):
sig = array(sig, dtype = "float16") / max(sig)
cut_num = int(round(cut_wid * fs))
shift_num = cut_num / 4
N = (len(sig) - cut_num) / shift_num + 1 ret = zeros(N, dtype = float) for n in xrange(N): s = n * shift_num e = s + cut_num ret[n] = sqrt((sig[s : e] ** 2).sum() / float(cut_num)) return ret
"""
cut_wid : Width of cutting
cross_wid : Width of crossfade
"""
def timeStretch(sig, fs, scale, cut_wid = 0.06, cross_wid = 0.03, fade_func = None):
cut_num = int(round(cut_wid * fs)) cross_num = int(round(cross_wid * fs)) shift_num = int(round(cut_num / float(scale))) if fade_func == None: win = triangle(cross_num * 2) else: win = fade_func(cross_num * 2) L = len(sig) I = (L - (cut_num + cross_num)) / shift_num + 1 new_sig = zeros(cut_num * (I + 1), dtype = float) for i in xrange(I): s = i * shift_num e = s + cut_num + cross_num tmp_sig = sig[s : e].copy() if cross_num != 0: tmp_sig[-cross_num :] *= win[- cross_num :] if i != 0: tmp_sig[: cross_num] *= win[: cross_num] new_s = i * cut_num new_e = new_s + len(tmp_sig) new_sig[new_s : new_e] += tmp_sig new_sig = array(new_sig) dynamics = calc_dynamics(new_sig, fs) dynamics = interp(linspace(0, len(dynamics), num = len(new_sig)), arange(len(dynamics)), dynamics) noise_hz = 1. / cut_wid noise_ind = noise_hz * len(dynamics) / (fs / 2.) lowpass_hz = 7. lowpass_ind = lowpass_hz * len(dynamics) / (fs / 2.) fft_dyn = fft(dynamics) fft_dyn[lowpass_ind : - lowpass_ind] = 0 new_dynamics = ifft(fft_dyn).real new_dynamics[new_dynamics < 0] = 0 scale = zeros(len(new_sig), dtype = float) scale[dynamics < max(dynamics) / 30.] = 1. scale[new_dynamics == 0] = 1. scale[scale == 0] = new_dynamics[scale == 0] / dynamics[scale == 0] scaled_new_sig = new_sig * scale scaled_new_sig *= max(abs(sig)) / max(abs(scaled_new_sig)) x_up = 40000 fig = pl.figure() fig.patch.set_alpha(0.0) fig.add_subplot(311) pl.title("Time-stretched signal") pl.plot(new_sig) pl.xlim([0, x_up]) pl.ylim([-25000, 25000]) fig.add_subplot(312) pl.title("Volume dynamics") pl.plot(dynamics, label = "raw") pl.plot(new_dynamics, label = "low-pass", linewidth = 2) pl.legend(loc='upper right') pl.xlim([0, x_up]) fig.add_subplot(313) pl.title("Modified time-stretched signal") pl.plot(scaled_new_sig) pl.xlim([0, x_up]) pl.ylim([-25000, 25000]) pl.tight_layout() pl.show() return scaled_new_sig
def test(wav_file):
fs, data = read(wav_file)
new_data = timeStretch(data, fs, 2, cut_wid = 0.05, cross_wid = 0.03, fade_func = hamming)
new_data = array(around(new_data), dtype = "int16") write("a01_timestretch.wav", fs, new_data)
if name == "main":
input_wav = "a01.wav"
test(input_wav)
試したこと
line65のfloatが原因だと考え、intに変更してみたり、(int)をつけてみたりしたのですがエラーは直りませんでした。
補足情報(FW/ツールのバージョンなど)
python 3.7.3
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/06/11 16:11
2019/06/11 16:15
2019/06/11 16:32