【问题标题】:Formula for adjusting the length of an array / audio file in matlab / octavematlab/octave中调整数组/音频文件长度的公式
【发布时间】:2015-01-02 15:36:26
【问题描述】:

这是来自以下问题的后续问题: Time stretching signal / porting python code to matlab / octave

我试图通过更改变量 dur 在几秒钟内将文件拉伸一定量。

输出文件 (stretch.wav) 文件的长度应与 dur 变量相同 但它不匹配。它取决于文件的样本大小。

我试图通过调整变量 dur 和变量 中的公式来找出一种方法来计算变量 stretch 应该是的正确数字>拉伸

注意:我试图不改变这两个变量(dur 和 stretch)下面的其他代码,因为它会影响信号的创建方式。

我得到的答案如下,你可以看到它们在假设接近 1800 秒时变化很大:

inputfn = 1sec8000.wav
Original duration of file in seconds = 1.00 s
converted 1sec8000.wav =1.00(s) file to stretched.wav = 750.25(s)

inputfn = 1sec44100.wav
Original duration of file in seconds = 1.00 s
converted 1sec44100.wav =1.00(s) file to stretched.wav = 1378.25(s)

inputfn = 3sec8000.wav
Original duration of file in seconds = 3.00 s
converted 3sec8000.wav =3.00(s) file to stretched.wav = 1375.25(s)

inputfn = 3sec44100.wav
Original duration of file in seconds = 3.00 s
converted 3sec44100.wav =3.00(s) file to stretched.wav = 1684.47(s)

PS:我使用的是 octave 3.8.1,它适用于 matlab。

请参阅下面的示例工作测试代码:

urlwrite('http://www.onewithall.net/rttmpfiles/1sec8000.wav','1sec8000.wav'); %test files I used online
urlwrite('http://www.onewithall.net/rttmpfiles/1sec44100.wav','1sec44100.wav'); %test files I used online
urlwrite('http://www.onewithall.net/rttmpfiles/3sec8000.wav','3sec8000.wav'); %test files I used online
urlwrite('http://www.onewithall.net/rttmpfiles/3sec44100.wav','3sec44100.wav'); %test files I used online
inputfn='1sec8000.wav' %change this to test another file
[d, fs, bps]=wavread(inputfn);
inputlen=rows (d)/fs;

printf ("Original duration of file in seconds = %.2f s\n", rows (d)/fs);

dur=1800; %duration / length you want the file to be in seconds
stretch = dur/rows(d)*fs; %how much I need to stretch the file to get it to be the duration I want
windowsize = round (0.25 * fs);

step = round ((windowsize/2)/stretch);

## original window
fwin = @(x) (1-x.^2).^1.25;
win = fwin (linspace (-1, 1, windowsize));

#win = hanning (windowsize)';

## build index
ind = (bsxfun (@plus, 1:windowsize, (0:step:(rows(d)-windowsize))'))';
cols_ind = columns(ind);

## Only use left channel
left_seg = d(:,1)(ind);
clear d ind;

## Apply window
left_seg = bsxfun (@times, left_seg, win');

## FFT
fft_left_seg = fft (left_seg);
clear left_seg

#keyboard

## overwrite phases with random phases
fft_rand_phase_left = fft_left_seg.*exp(i*2*pi*rand(size(fft_left_seg)));
clear fft_left_seg;

ifft_left = ifft (fft_rand_phase_left);
clear fft_rand_phase_left;

## window again
ifft_left = bsxfun (@times, real(ifft_left), win');

## restore the windowed segments with half windowsize shift
restore_step = floor(windowsize/2);
ind2 = (bsxfun (@plus, 1:windowsize, (0:restore_step:(restore_step*(cols_ind-1)))'))';
left_stretched = sparse (ind2(:), repmat(1:columns (ind2), rows(ind2), 1)(:), real(ifft_left(:)), ind2(end, end), cols_ind);
clear ind2 ifft_left win;

left_stretched = full (sum (left_stretched, 2));

## normalize
left_stretched = 0.8 * left_stretched./max(left_stretched);
printf ("converted %s =%.2f(s) file to stretched.wav = %.2f(s)\n", inputfn, inputlen, rows (left_stretched)/fs);
wavwrite (left_stretched, fs, bps, "streched.wav");
%system("aplay streched.wav")

【问题讨论】:

标签: matlab math octave


【解决方案1】:

线

windowsize = round (0.25 * fs);

表示 FFT 块的窗口大小为 0.25 秒。如果您的输入文件只有 1s 长,这意味着

step = round ((windowsize/2)/stretch);

变得非常大,因为我的代码使用全窗口进行重建。如果你想要一个精确的长度,我建议添加一个额外的重建窗口并将输出裁剪到你想要的长度。

顺便说一句,您的 1s 输入文件仅包含一个窦性周期。由于混叠效应,此代码无法拉伸。

【讨论】:

  • 添加另一个“重构窗口”是什么意思?
猜你喜欢
  • 1970-01-01
  • 2016-06-19
  • 1970-01-01
  • 2014-12-02
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多