用C语言实现下列Matlab程序的功能
程序代码:tic;clc;clear;%close;
filedir=[]; % 设置路径
filename='sp_c2e2.wav'; % 设置文件名
fle=[filedir filename];
[x,fs]=wavread(fle); %读入数据文件
x=x(:,1); %取了所有的数据数据 因为数据是按列存储的,
%x=x(1:58000);
x=x/max(abs(x));
lx=length(x); %求数据长度
length_fft=1024; %fft的长度
lf=length_fft/2+1; %fft之后一半的有效数据
R=xcorr(x); % xcorr(A), when A is a vector, is the auto-correlation sequence. 求自相关序列 R的长度是数据长度的(2*lx-1)行1列
R=R(lx:end); %取从58000到结束的数据
a=find(R==max(R(round(fs/600):fix(fs/60))))-1; % round的作用是最近取整,四舍五入,复数的话把实部和虚部单独取整。fix 无论正负,像0最近取整(向下取整)
f0=fs/a; % a为最大峰值频率的点
n=2*ceil(1.5*a)+1; % length of one frame ceil(X) 是天花板函数。正向最近取整。 %% 取整数towards infinity.--无穷
win=hamming(n)/sum(hamming(n)); %归一化窗函数
[xa,tm]=subframe(x,win,0,fs); %分帧 xa为总的数据, tm为一帧的数据 窗长=帧长,且窗函数没有重叠
%% find peaks and frequency, amplitude, phase
% w=linspace(0,pi,lf);
% e=exp(-1i*(-(n-1)/2:(n-1)/2)'*w);
% fftx=e'*xa;
f=linspace(0,fs/2,lf); %给出513个采样频率等差数列
fftx=fft(xa,length_fft); %xa分帧完一帧数据的长度
fftx=fftx(1:513,:);
m=size(xa,2); % number of frames 获取帧数
DD=cell(3,m ); % cell(M,N) or cell([M,N]) is an M-by-N cell array of empty matrices--方阵.产生3行m列的空方阵
for k=1:m
X=fftx(:,k); %计算频谱,取出第k帧数据
% indmax=peak_selection(abs(X),f0,fs,'h');
indmax=peak_selection(abs(X),fs,'p'); %峰值搜索
Fre=f(indmax);
Am=abs(X(indmax));
Ph=angle(X(indmax));
DD{1,k}=Fre*2*pi; %给单元数组的内容赋值
DD{2,k}=Am;
DD{3,k}=Ph;
end
%% frequency matching
FM=cell(3,m-1);
delta=0.4*f0*2*pi; %频率间隔
for k=1:m-1
a1=DD{1,k};a2=DD{1,k+1}; %a1为第k帧的频率
b1=DD{2,k};b2=DD{2,k+1}; %b1为第k帧的幅度
c1=DD{3,k};c2=DD{3,k+1}; %c1为第k帧的相位
A1=[];A2=[];B1=[];B2=[];C1=[];C2=[]; %设置空矩阵
%上面为准备条件
for i=1:length(a1) %第k帧总频率的个数
e=abs(a1(i)-a2); %计算频差 第k帧的一个频率与第k+1帧的每个频率作差
if min(e)<delta
t=find(e==min(e)); %找到比设定小的频率间隔,把间隔赋值给t,t就是最小间隔
if length(t)~=1
t=t(1);
end
if i==length(a1)
A1=[A1,a1(i)];A2=[A2,a2(t)]; % k 帧中的最后一项
B1=[B1,b1(i)];B2=[B2,b2(t)];
C1=[C1,c1(i)];C2=[C2,c2(t)];
a2(t)=[];b2(t)=[];c2(t)=[]; %删除数组的数据
elseif e(t)<abs(a1(i+1)-a2(t)) % 比相邻的频率差小
A1=[A1,a1(i)];A2=[A2,a2(t)]; %把a1(i)放到A1的后面
B1=[B1,b1(i)];B2=[B2,b2(t)];
C1=[C1,c1(i)];C2=[C2,c2(t)];
a2(t)=[];b2(t)=[];c2(t)=[];
elseif t==1
A1=[A1,a1(i)];A2=[A2,a1(i)];% 比相邻的频率差大且k+1帧中没有m-1频率了,定义death
B1=[B1,b1(i)];B2=[B2,0];
C1=[C1,c1(i)];C2=[C2,c1(i)];
elseif abs(a1(i)-a2(t-1))<delta % 比相邻的频率差大且k+1帧中有 m-1频率
A1=[A1,a1(i)];A2=[A2,a2(t-1)];
B1=[B1,b1(i)];B2=[B2,b2(t-1)];
C1=[C1,c1(i)];C2=[C2,c2(t-1)];
a2(t-1)=[];b2(t)=[];c2(t)=[];
else
A1=[A1,a1(i)];A2=[A2,a1(i)]; % 以上情况都不满足 定义death
B1=[B1,b1(i)];B2=[B2,0];
C1=[C1,c1(i)];C2=[C2,c1(i)];
end
else
A1=[A1,a1(i)];A2=[A2,a1(i)]; % define death 死亡
B1=[B1,b1(i)];B2=[B2,0];
C1=[C1,c1(i)];C2=[C2,c1(i)];
end
end
%上面为第k帧的操作
%下面为第k+1帧的操作
%第m+1帧在第m帧出生
for i=1:length(a2)
t=find(A2<a2(i));
if isempty(t) %判断t是否为空
A1=[a2(i),A1];
A2=[a2(i),A2];
B1=[0,B1];
B2=[b2(i),B2];
C1=[c2(i)-a2(i)*length(A2)/fs,C1];
C2=[c2(i),C2];
else
A1=[A1(1:t(end)),a2(i),A1(t(end)+1:end)];
A2=[A2(1:t(end)),a2(i),A2(t(end)+1:end)];
B1=[B1(1:t(end)),0,B1(t(end)+1:end)];
B2=[B2(1:t(end)),b2(i),B2(t(end)+1:end)];
C1=[C1(1:t(end)),c2(i)-a2(i)*length(A2)/fs,C1(t(end)+1:end)];
C2=[C2(1:t(end)),c2(i),C2(t(end)+1:end)];
end
end
FM{1,k}=[A1;A2]; %A2放在A1的下面
FM{2,k}=[B1;B2];
FM{3,k}=[C1;C2];
end
%% interpolation of alimpulates
IM=cell(2,m); %产生2行m列的空矩阵
for i=1:m-1
e=FM{2,i};
p=size(e,2);
ai=zeros(p,n);
for k=1:p
ai(k,:)=e(1,k)+(e(2,k)-e(1,k))/n*(0:n-1);
end
IM{1,i}=ai;
end
%% interpolation of phase
T=n/fs;
ti=linspace(1/fs,n/fs,n);
for i=1:m-1
e=FM{1,i};t=FM{3,i};
p=size(e,2);c=zeros(p,n);
for k=1:p
q=((t(1,k)+e(1,k)*T-t(2,k))+(e(2,k)-e(1,k))*T/2)/2/pi;
M=round(q); %找到最近的整数
alfa=(t(2,k)-t(1,k)-e(1,k)*T+2*pi*M)*3/(T.^2)-(e(2,k)-e(1,k))/T;
beta=(t(2,k)-t(1,k)-e(1,k)*T+2*pi*M)*(-2)/(T.^3)+(e(2,k)-e(1,k))/(T.^2);
c(k,:)=t(1,k)+e(1,k)*ti+alfa*ti.^2+beta*ti.^3;
% d(k,:)=e(1,k)+2*alfa*ti+3*beta*ti.^2;
% g(k,:)=4*alfa+6*beta*ti;
end
IM{2,i}=c;
end
%% synthesis
s1=zeros(n,m);ns1=zeros(1,m*n);
for i=1:m
for k=0:n-1
s1(k+1,i)=DD{2,i}'*cos(k*(DD{1,i}')/fs+DD{3,i}); %求第i帧的第k+1个数据 /fs规一化频率
end
ns1((i-1)*n+1:n*i)=s1(:,i); %取得第i帧数据
end
soundsc(ns1,fs);
wavwrite(ns1/max(abs(ns1)),fs,'sp_c2e2_a.wav');
s=zeros(n,m);
for i=1:m-1
for k=1:n
s(k,i)=IM{1,i}(:,k)'*cos(IM{2,i}(:,k)); %
end
end
for k=0:n-1
s(k+1,m)=DD{2,m}'*cos(k*(DD{1,m}')/fs+DD{3,m});
end
ns=zeros(1,n*m);
for i=1:m
ns((i-1)*n+1:n*i)=s(:,i);
end
soundsc(ns,fs);
wavwrite(ns/max(abs(ns)),fs,'sp_c2e2_b.wav'); %正弦插值合成 可能是最终需要的合成
soundsc(x,fs);
wavwrite(x/max(abs(x)),fs,'sp_c2e2_c.wav'); %直接合成
toc;
%%
% [xa,tm]=subframe(x,rectwin(n),0,fs);
% w=linspace(0,pi,lf);
% f=linspace(0,fs/2,lf);
% e=exp(-1i*(-(n-1)/2:(n-1)/2)'*w);
% fftx=e'*xa;
% ffts=e'*s;
% figure;plot(unwrap(angle(fftx(:,1))))
% figure;plot(unwrap(angle(ffts(:,1))))






