问题
I'm trying to port over paulstretch's signal stretching over to matlab / octave. https://github.com/paulnasca/paulstretch_python
See workflow i'm following below
I can separate the signals into frequencies, amplitude and phase and join them back using the code below. I'm having issues porting over the windowing segments, overlapping, and extending the signals. Any ideas?
Example matlab / octave code:
freq=[0;0.534974;1.06995;1.60492;2.1399]
amp1=[3.94414e-19;1.20523e-05;5.08643e-06;4.22469e-05;3.04322e-05]
phase=[0;0.0546221;-1.11534;-2.4926;-2.55601]
a1=[freq,amp1,phase];
t_rebuilt=linspace(0,2*pi,8000);
sigcomb=zeros(1,length(t_rebuilt));
kk=0
for kk=1:1:length(freq) %rebuild signal from collected freq,amplitudes,and phases
sigcomb=sigcomb+a1(kk,2)*cos((a1(kk,1))*t_rebuilt+(a1(kk,3)));
end
normalize=(sigcomb/max(abs(sigcomb))*.8);
wavwrite([normalize'] ,8000,16,strcat('/tmp/test.wav'));
PS: This is just test data, to get an audio signal I would have to use many more data points which would make a mess of the question.
My thought's are to use a for loop to create chopped up 1 second wav files of the new signal no matter how long the file is stretched out for, as this will prevent array size memory issues with larger duration files. Then join them together using another program like sox which I've already figured out.
PS: I'm using octave 3.8.1 which is suppose to be compatible with matlab
回答1:
I've tried to build a version without loops and use the original.ogg from http://hypermammut.sourceforge.net/paulstretch/. I think it's a tradeoff between speed and memory size (the version below might use much memory if the input file is long)
[d, fs, bps] = wavread ("original.wav");
printf ("Input duration = %.2f s\n", rows (d)/fs);
stretch = 8;
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 ("Output duration = %.2f s\n", rows (left_stretched)/fs);
wavwrite (left_stretched, fs, bps, "streched.wav");
system("aplay streched.wav")
来源:https://stackoverflow.com/questions/27362525/time-stretching-signal-porting-python-code-to-matlab-octave