OverlapAdd2函数的matlab实现

在做音频信号处理时发现,matlab高版本已经移除了OverlapAdd2函数,在之前的书籍里找到了该函数的实现。以下为matlab的原始实现思路,可以放心大胆使用。

function ReconstructedSignal=OverlapAdd2(XNEW,yphase,windowLen,ShiftLen);

%Y=OverlapAdd(X,A,W,S);
%Y is the signal reconstructed signal from its spectrogram. X is a matrix
%with each column being the fft of a segment of signal. A is the phase
%angle of the spectrum which should have the same dimension as X. if it is
%not given the phase angle of X is used which in the case of real values is
%zero (assuming that its the magnitude). W is the window length of time
%domain segments if not given the length is assumed to be twice as long as
%fft window length. S is the shift length of the segmentation process ( for
%example in the case of non overlapping signals it is equal to W and in the
%case of %50 overlap is equal to W/2. if not givven W/2 is used. Y is the
%reconstructed time domain signal.
%Sep-04
%Esfandiar Zavarehei

if nargin<2                                   % 如果没有带入yphase参数
    yphase=angle(XNEW);                       % 赋值
end
if nargin<3                                   % 如果没有带入windowLen参数
    windowLen=size(XNEW,1)*2;                 % 赋值
end
if nargin<4                                   % 如果没有带入ShiftLen参数
    ShiftLen=windowLen/2;                     % 赋值
end
if fix(ShiftLen)~=ShiftLen                    % 如果帧移带有小数
    ShiftLen=fix(ShiftLen);                   % 取整,并显示错误信息
    disp('The shift length have to be an integer as it is the number of samples.')
    disp(['shift length is fixed to ' num2str(ShiftLen)])
end

[FreqRes FrameNum]=size(XNEW);                % 取输入谱值的帧数和频谱谱线数

Spec=XNEW.*exp(j*yphase);                     % 求取复数谱值

if mod(windowLen,2)                           % 若windowLen是奇数
    Spec=[Spec;flipud(conj(Spec(2:end,:)))];  % 补上负频率部分  
else                                          % 若windowLen是偶数
    Spec=[Spec;flipud(conj(Spec(2:end-1,:)))];% 补上负频率部分
end
sig=zeros((FrameNum-1)*ShiftLen+windowLen,1); % 初始化sig
weight=sig;
for i=1:FrameNum                              % 按式(10-2-1)重叠相加法把数据叠接合成
    start=(i-1)*ShiftLen+1;                   % 计算i帧在sig中的起始位置  
    spec=Spec(:,i);                           % 取第i帧的频谱
    sig(start:start+windowLen-1)=sig(start:start+windowLen-1)...% 重叠相加
    +real(ifft(spec,windowLen));    
end
ReconstructedSignal=sig;                      % 把合成语音赋值于输出
  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
下面是一个简单的MATLAB代码实现男声变女声: ```matlab % 读取男声音频文件 [x,fs] = audioread('male_voice.wav'); % 分帧 frame_length = 256; frame_step = 128; frames = enframe(x, frame_length, frame_step); % 计算每帧的功率谱 nfft = 512; p = abs(fft(frames, nfft)).^2 / nfft; % 计算每帧的频率和幅度谱 freqs = linspace(0, fs/2, nfft/2+1); amp = 20*log10(sqrt(p(:,1:nfft/2+1))); % 对频率谱进行调整,使整个频谱向高频移动 freqs_new = freqs * 1.2; % 对幅度谱进行调整,使高频部分的振幅增大 amp_new = amp; amp_new(:,freqs>1000) = amp_new(:,freqs>1000) + 10; % 根据新的频率和幅度谱合成变声后的音频信号 p_new = 10.^(amp_new/20) .* exp(1j*2*pi*freqs_new'*frames'); y = overlapadd(real(p_new), frames, frame_step); % 将合成后的音频信号写入文件中 audiowrite('female_voice.wav', y, fs); ``` 在上面的代码中,我们使用 `audioread` 函数读取男声音频文件,并使用 `enframe` 将音频文件分帧。然后,我们计算了每一帧的功率谱,并使用 `linspace` 函数生成频率轴。接着,我们对频率和幅度谱进行了调整,将整个频谱向高频移动,并增大了高频部分的振幅。最后,我们使用 `overlapadd` 函数将合成后的音频信号进行重叠相加,得到女声音频信号,并使用 `audiowrite` 函数将其写入文件中。 需要注意的是,上面的代码只是一个简单的示例,实际的变声效果和代码实现可能需要进行更多的调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GodenEngineer

你的赞赏,是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值