Matlab 由于内存限制,将向量循环转换为for循环

Matlab 由于内存限制,将向量循环转换为for循环,matlab,octave,sox,Matlab,Octave,Sox,我有一段Octave/Matlab代码,我从Andy和团队那里得到了很多帮助。我现在遇到的问题是没有足够的内存来产生持续时间更长的信号 我的计划是: 1) 将向量循环转换为for循环。(这里有问题) 2) 让for循环将循环的每个段导出为wav文件,而不是像矢量代码那样附加它。(这里有问题) 3) 使用sox连接每个wave文件段 大多数在线示例都是从for循环到矢量化循环,而不是相反,有什么想法吗?我也愿意接受其他建议来解决我的记忆问题。注意:我在rasberry pi 2上使用1G的ram,

我有一段Octave/Matlab代码,我从Andy和团队那里得到了很多帮助。我现在遇到的问题是没有足够的内存来产生持续时间更长的信号

我的计划是:

1) 将向量循环转换为for循环。(这里有问题)
2) 让for循环将循环的每个段导出为wav文件,而不是像矢量代码那样附加它。(这里有问题)
3) 使用sox连接每个wave文件段

大多数在线示例都是从for循环到矢量化循环,而不是相反,有什么想法吗?我也愿意接受其他建议来解决我的记忆问题。注意:我在rasberry pi 2上使用1G的ram,它工作正常,速度非常快,我只是想获得持续时间更长的信号,导出每个段应该考虑到这一点

我使用的是与Matlab兼容的倍频程

请参阅下面的工作矢量化代码: 它基于Paul Nasca的拉伸算法

我试图通过在关键点上显示(“线”)来追踪问题。它看起来像一条线

left_stretched = sparse (ind2(:), repmat(1:columns (ind2), rows(ind2), 1)(:), real(ifft_left(:)), ind2(end, end), cols_ind);

上面这行似乎只有在内存用完时才有问题。它说错误下标索引必须是正整数或逻辑数。请注意,只有当我试图通过设置dur=60*1800来使用长持续时间时内存不足时,才会发生这种情况。如果我设置dur=60*10,一切正常。

你还记得我吗?我是您发布的初始代码的作者。下面的代码为for循环。我已经用800秒的输出透镜测试过了

## based on http://hypermammut.sourceforge.net/paulstretch/
## https://github.com/paulnasca/paulstretch_python/blob/master/paulstretch_steps.png

more off
inputfn = "original.wav"
[d, fs, bps] = wavread (inputfn);
inputlen=rows  (d)/fs;

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

target_duration = 60; # in seconds
stretch = target_duration/inputlen;
# 1/4 s window len
windowsize = round (0.25 * fs);

# stepwidth between windows
step = round ((windowsize/2)/stretch);
numsteps = floor((rows(d)-windowsize)/step);

## restore the windowed segments with half windowsize shift
restore_step = floor (windowsize / 2);

## stetched duration
stretched_len = (numsteps*restore_step+windowsize)/fs;
printf ("Stretched duration of file in seconds = %.2f s\n", stretched_len);
stretched = zeros (numsteps*restore_step+windowsize, 1);
if (!exist ("out", "dir"))
  mkdir ("out");
endif

## Matrix which holds the freq of the maximum amplitude and the max. amplitude
chunks_stats = zeros (numsteps, 2);

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

## loop over all windows
for k = 1:numsteps
  if (! mod(k, 50))
    printf ("Calculating chunk %i of %i...\n", k, numsteps);
    fflush (stdout);
  endif

  ## Only use left channel
  s_ind = (k - 1) * step + 1;
  e_ind = s_ind + windowsize - 1;
  tmp = win' .* d(s_ind:e_ind, 1);

  ## FFT, overwrite phases with random phases and IFFT
  tmp = fft(tmp);
  [m, ind] = max (abs(tmp(1:numel(tmp)/2)));
  # Frequency in Hz
  chunks_stats(k, 1) = (ind-1)/windowsize*fs;
  # max Amplitude
  chunks_stats(k, 2) = m;
  printf ("Freq =  %.2f Hz, max = %.2f\n", chunks_stats(k, :));
  tmp = ifft (tmp .* exp(i*2*pi*rand(size(tmp))));

  ## window again
  tmp = win' .* real (tmp);
  fn = sprintf ("out/out_%04i.wav", k);
  wavwrite (tmp, fs, bps, fn);
  s_ind = (k - 1) * restore_step + 1;
  e_ind = s_ind + windowsize - 1;
  stretched (s_ind:e_ind) += tmp;
endfor

## normalize
stretched = 0.8 * stretched./max(stretched);
wavwrite (stretched, fs, bps, "stretched.wav");
如果您想在以后编写多个WAV来连接它们,这会有点困难,因为重叠的窗口。但我认为这段代码可以在BeagleBoneBlack上正常运行


编辑:将块保存到单独的文件中,并将每个块的最大振幅和频率收集到块统计数据中。

内存中的故障在哪里<代码>bsxfun<代码>快速傅立叶变换?一个简单的工作示例就好了。@bla上面的代码是一个工作示例,它甚至可以从网站中提取音频文件进行测试。我更新了问题并添加了问题开始的那一行。是的,安迪,我记得你和你给我的精彩代码。我会试试你的答案,看看我是否能步履蹒跚地找到一种方法,将每个数组部分导出为一个wave文件。再次感谢您为什么要将块导出为wav,然后将它们连接起来?我需要使用fft分析每个wav文件/块,以获得其频率、振幅和相位(我已经有了这个函数)。我将所有文件的频率、振幅和相位数据放在一个数组中,并根据我选择的频率、振幅和/或相位,使用sox连接选定的文件。@RickT:老实说,我怀疑你是否理解我的代码或“paulstretch”算法。例如,“获取阶段”是没有意义的,因为它被设置为随机值。另一点:如果你想分析每个块并“将频率…放入一个数组”,你又有了同样的内存限制。如果你能解释一下你的最终目标是什么,我可以帮你做得更好,但在这一点上,我真的很沮丧,因为帮助那些可能是错误的小步骤direction@RickT如果编辑了上面的代码,将块写入单独的文件,并收集最大振幅和匹配频率。
## based on http://hypermammut.sourceforge.net/paulstretch/
## https://github.com/paulnasca/paulstretch_python/blob/master/paulstretch_steps.png

more off
inputfn = "original.wav"
[d, fs, bps] = wavread (inputfn);
inputlen=rows  (d)/fs;

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

target_duration = 60; # in seconds
stretch = target_duration/inputlen;
# 1/4 s window len
windowsize = round (0.25 * fs);

# stepwidth between windows
step = round ((windowsize/2)/stretch);
numsteps = floor((rows(d)-windowsize)/step);

## restore the windowed segments with half windowsize shift
restore_step = floor (windowsize / 2);

## stetched duration
stretched_len = (numsteps*restore_step+windowsize)/fs;
printf ("Stretched duration of file in seconds = %.2f s\n", stretched_len);
stretched = zeros (numsteps*restore_step+windowsize, 1);
if (!exist ("out", "dir"))
  mkdir ("out");
endif

## Matrix which holds the freq of the maximum amplitude and the max. amplitude
chunks_stats = zeros (numsteps, 2);

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

## loop over all windows
for k = 1:numsteps
  if (! mod(k, 50))
    printf ("Calculating chunk %i of %i...\n", k, numsteps);
    fflush (stdout);
  endif

  ## Only use left channel
  s_ind = (k - 1) * step + 1;
  e_ind = s_ind + windowsize - 1;
  tmp = win' .* d(s_ind:e_ind, 1);

  ## FFT, overwrite phases with random phases and IFFT
  tmp = fft(tmp);
  [m, ind] = max (abs(tmp(1:numel(tmp)/2)));
  # Frequency in Hz
  chunks_stats(k, 1) = (ind-1)/windowsize*fs;
  # max Amplitude
  chunks_stats(k, 2) = m;
  printf ("Freq =  %.2f Hz, max = %.2f\n", chunks_stats(k, :));
  tmp = ifft (tmp .* exp(i*2*pi*rand(size(tmp))));

  ## window again
  tmp = win' .* real (tmp);
  fn = sprintf ("out/out_%04i.wav", k);
  wavwrite (tmp, fs, bps, fn);
  s_ind = (k - 1) * restore_step + 1;
  e_ind = s_ind + windowsize - 1;
  stretched (s_ind:e_ind) += tmp;
endfor

## normalize
stretched = 0.8 * stretched./max(stretched);
wavwrite (stretched, fs, bps, "stretched.wav");