我正在尝试在Matlab中创建一些函数来记录音调然后半连续播放 . 例如,我希望用户能够吹哨2秒钟并将哨子拖出10秒钟 . 我想避免使用花哨的时间拉伸算法,但只是通过重复使用它 . 我知道这有问题但我正在做这个实验 .

要做到这一点,我需要交叉淡化声音的开头和结尾,使它看起来连续 . 我编写了一个交叉淡入淡出函数,它在它们之间需要两个信号和淡入淡出 .

我们的想法是使用sigmoid音量函数,对于旧声音从1到0,对于新声音从0到1 . 然后我将信号乘以此音量函数并添加结果 . 我对sigmoid函数的理解是得到的体积应该是两个输入信号的平均值,重量从输入信号a缓慢移动到输入信号b,输出幅度应该与输入信号相同 .

然而,当我尝试使用两个简单的正弦输入信号,并在低音和高音之间来回时,我会在从低到高的部分转换到的部分中得到一个小的“故障” . 从高到低的滑动部分 . 这来自哪里?我也不确定这是否只在我的扬声器上,我尝试在时域中观察绘制的波形,但在特定时间看不到任何奇怪的事情 .

第一部分的结尾和最后一部分的开头应该具有完全相同的频率成分,并且没有任何时间被移动,所以我不确定这个故障来自何处 .

示例代码:

(轻微警告:这会输出一些音调,其中一个是高音调,因此可能无法使用带有完整音量的耳机播放) .

function test()
Fs=44100;
x=1:1/Fs:2;
x=x'; %time vector
freq1 = 440; %low tone
freq2 = freq1*2^(7/12) % high tone (harmonic fifth)
Fs=44100;
x=1:1/Fs:2;
x=x'; %time vector
freq1 = 440; %low tone
freq2 = freq1*2^(7/12); % high tone (harmonic fifth)
y1 = sin(2*pi*x*freq1)
y2 = sin(2*pi*x*freq2)
res = stitchandrepeat(y1,y2, Fs);
end

function [out] = stitchandrepeat(in, in2, Fs)
lowtohigh = crossfade(in,in2,1);
hightolow = crossfade(in2,in,1);
out = [lowtohigh;hightolow];
out = [out;out];
out = [out;out];
out = [out;out];
end

function [out] = crossfade(a, b, sigmoid)
if not(size(a) == size(b))
    error('Different sizes');
end
index = (1:size(a,1))';
factor = index/size(a,1);
if(sigmoid)
    steepness = 5;
    factor = logsig((factor-0.5)*steepness*2);
end
plot(index, factor, 'o');
out = bsxfun(@times, a, 1-factor)+bsxfun(@times, b, factor);
end

我甚至尝试过第二次交叉渐变,我将第一个和第二个信号的结束和开始拼接在一起,但在过渡期间它仍然听起来有点奇怪 . 关于如何使过渡顺利进行的任何想法?

function [out] = stitchandrepeat2(in, in2, Fs)
lowtohigh = crossfade(in,in2,1);
hightolow = crossfade(in2,in,1);
secstofade = 0.1;
len = size(lowtohigh,1);
partsize = secstofade*Fs;
lthpart = lowtohigh((len-partsize+1):len,:);
htlpart = hightolow(1:partsize,:);
lthcropped = lowtohigh(1:len-partsize,:);
htlcropped = hightolow(partsize+1:len,:);

highfade = crossfade(htlpart, lthpart,1);
out = [lthcropped;highfade;htlcropped];
out = [out;out];
out = [out;out];
out = [out;out];
end

为什么我不能在声音的低音区听到这个小故障声? (两种不同的声波也在那里连接起来 . )