【CCS仿真系列教程】手把手教你纯软件仿真实现音频滤波
事先说明示例项目下载示例使用说明首先用Matlab生成加了噪声的音频将我的项目弄你的CCS的WorkSpace中把Matlab生成后的_input文件拷贝到CCS仿真的工程目录中的Debug文件中把Matlab生成的滤波器数据加载到DSP运行CCS仿真Matlab播放DSP滤波结果
如果你的CCS还没有配置仿真条件,不能纯软件仿真打印出HelloWorld,请先看这篇文章【致CCS仿真失败的你】CCS(Code Composer)V6.0以上版本仿真教程
事先说明
在CCS纯软件仿真时,可以使用C语言的文件系统,读取Debug目录下的文件,或把数据保存到文件中。此时,CCS不支持以浮点型或者长整型的方式读取文件中的数据或者存储数据到文件。正是由于CCS的简化版文件系统只能对整型数据进行读写,所以使用Matlab把音频数据从双精度浮点型转换为整形,在DSP仿真处理结束后,把处理结果读进Matlab中,重新处理为双精度浮点型后,用sound函数播放。因为本例子中要处理的音频数据比较长,所以先把音频存到文件中,在程序运行时,动态加载该文件。为了减少时间复杂度,本例中音频缓冲方式是直接以新数据覆盖旧数据,没有使用数组移位来加载新数据。CCS仿真时,printf到命令行的东西需要加回车符\n,遇到\n后才会一次性显示到命令行。由于F28335性能比较低下,而仿真软件在仿真的时候真实度过高,仿真了F28335的低处理速度,所以程序运行有点慢,大约需要20分钟,在命令行会输出当前进度。
示例项目下载
链接: https://pan.baidu.com/s/1ZkdQIct70ivgXZqJMyva6g 密码: uu1b
示例使用说明
首先用Matlab生成加了噪声的音频
注意把被调戏音乐放到F盘,或修改audioread的参数,改为被调戏音乐的地址。运行下载下来的音频滤波项目文件中的Matlab部分的Filter.m。代码运行后,会在Matlab安装目录的bin文件夹中生成_input文件,这个文件是加了噪声后,根据设定的采样率生成的经过处理的整形音频数据文件,把它拷贝到CCS仿真的工程目录中的Debug文件中。代码运行后,会显示加噪声后以及滤波后的频谱,用于做可行性检验,以确定滤波器设计正确,同时,还会显示滤波器的幅频特征曲线图以及相频特征曲线。代码运行后,会通过电脑音频播放滤波后的音乐。 代码如下
Frequency_in
= 1000; %需要引入的干扰正弦波的频率
size_cut
= 100000; %截断到多少点
is_Filte
= 1; %为零时播放假如干扰后的音频,为一时播放滤波后的音频
[data
,fs
] = audioread('C:\Users\high_sky\Desktop\音频滤波项目\样品2.wav'); %要调戏的音频,改成你自己的路径
result_Fs
= 8000; %结果的采样率
%[size_raw
,~] = size(data
);
%注意,如果是两个或者以上声道的音频数据,以下代码只取读进来的第一个声道
temp
= data(1:size_cut
,1); %由于DSP处理速度过低,可能要压缩数据
temp2
= resample(temp
,result_Fs
,fs
); %对原音频的再次采样
[size_data
,~] = size(temp2
); %求取音频长度
%给音频人为地添加干扰,干扰的频率由Frequency_in给定
noise
= sin(2*pi
*Frequency_in
*size_data
/result_Fs
*linspace(0,1,size_data
));
temp2
= temp2
+ noise'
; %加入噪声
temp3
= int32(temp2
*10^4); %把数据处理成整形,方便DSP读入
temp4
= double(temp3
)/10^4; %尝试把整形数据恢复成浮点型数据
Hn
= getFilter(result_Fs
); %获取滤波器的时域数据
if is_Filte
temp4
= conv(temp4
,Hn
); %对加入了干扰的音频数据进行滤波
end
sound(temp4
,result_Fs
); %播放处理结果
%把加了噪声并且做了整形转换的结果写入到文件,方便DSP分析
fp
= fopen('_input','w');
for i
= 1:size(temp3
)
fprintf(fp
,'%d ',temp3(i
));
end
fclose(fp
);
%画出加干扰后的频谱图
figure(1);
plot(abs(fft(temp2
)));
%画出滤波后的频谱图
figure(2);
plot(abs(fft(temp4
)));
%画出滤波器的分析图
figure(3);
freqz(Hn
);
%格式化输出滤波器数据,方便写入DSP
fprintf("{");
for i
= 1:length(Hn
)
fprintf("%e,",Hn(i
));
end
fprintf("};\n");
%获得滤波器的方法
function result
= getFilter(result_Fs
)
fcuts
= [200 900 1100 2000]; %定义通带和阻带的频率
mags
= [1 0 1]; %定义通带和阻带
devs
= [0.1 0.01 0.1]; %定义通带或阻带的纹波系数
[n
,Wn
,beta
,ftype
] = kaiserord(fcuts
,mags
,devs
,result_Fs
); %计算出凯塞窗N,beta的值
result
= fir1(n
,Wn
,ftype
,kaiser(n
+1,beta
),'noscale'); %生成滤波器
end
将我的项目弄你的CCS的WorkSpace中
解压下载的文件点击CCS中的Import 选择Import类型为CCS Projects,然后选择Next 开始导入,按下Brows,选择项目解压的目录,点击确定,然后点击Finish,注意勾上Copy projects into WorkSpace的选项
把Matlab生成后的_input文件拷贝到CCS仿真的工程目录中的Debug文件中
我的CCS工程已经放好,如果你使用自己的音频文件,就需要这一步。
把Matlab生成的滤波器数据加载到DSP
把Matlab生成的滤波器数据复制到CCS代码中 更改滤波器长度标志
运行CCS仿真
代码运行需要比较长,请耐心等待,命令行中会显示进度。仿真结束后,在项目Debug文件夹下会有一个_output文件,这个文件就是仿真的对输入音频滤波后的输出,该文件需要使用Matlab播放。运行请使用Debug方式运行,操作方法如下图所示: 进入Debug界面后,等待程序编译完成,点击Resume按钮,开始程序的运行: 仿真代码如下
#include <stdio.h>
#include <stdlib.h>
#define N 27
const static double filter
[] = {-1.817133e-03,-1.030943e-02,-1.486092e-02,-6.554923e-03,5.310618e-03,-3.484461e-17,-1.961028e-02,-1.277302e-02,5.264802e-02,1.370936e-01,1.426501e-01,1.707388e-02,-1.639884e-01,7.500000e-01,-1.639884e-01,1.707388e-02,1.426501e-01,1.370936e-01,5.264802e-02,-1.277302e-02,-1.961028e-02,-3.484461e-17,5.310618e-03,-6.554923e-03,-1.486092e-02,-1.030943e-02,-1.817133e-03,};
int temp_Music
[N
];
int getValue(int index
,int bias
){
int temp
= bias
+ index
;
if(temp
< N
)
return temp_Music
[temp
];
else
return temp_Music
[temp
- N
];
}
int output(int index
){
int i
;
double sum
= 0;
for(i
= 0;i
< N
;i
++)
sum
+= getValue(N
-i
-1,index
) * filter
[i
];
return (int)sum
;
}
int main(void)
{
int i
;
int out_Count
= 0;
unsigned long Conter
= 0;
int index_new
= 0;
int out_temp
;
long input_length
;
double input_size
= 0;
char temp
;
printf("Hello World!\n");
FILE
*fp_input
,*fp_output
;
if((fp_input
= fopen("_input","r")) == NULL){
printf("The file can not be opened\n");
return 1;
}
printf("OK0!\n");
if((fp_output
= fopen("_output","w")) == NULL){
printf("The file can not be created\n");
return 2;
}
printf("OK1!\n");
while((temp
= fgetc(fp_input
)) != EOF){
if(temp
== ' ')
input_size
++;
}
input_length
= (long)(input_size
/1000);
fseek(fp_input
,0L,SEEK_SET);
for(i
= 0;i
< N
;i
++){
fscanf(fp_input
,"%d",&out_temp
);
temp_Music
[i
] = out_temp
;
}
printf("OK2!\n");
fprintf(fp_output
,"%d ",output(index_new
));
printf("OK3!\n");
while(fscanf(fp_input
,"%d",&out_temp
) != EOF){
temp_Music
[index_new
] = out_temp
;
index_new
++;
if(index_new
>= N
)
index_new
= 0;
fflush(fp_output
);
fprintf(fp_output
,"%d ",output(index_new
));
Conter
++;
if(Conter
% input_length
== 0){
printf("%d/1000 \0",(int)(Conter
/input_length
));
out_Count
++;
if(out_Count
>= 15){
printf("\n");
out_Count
= 0;
}
}
}
printf("OK4!\n");
fclose(fp_input
);
fclose(fp_output
);
return 0;
}
Matlab播放DSP滤波结果
Matlab运行OpenOutput_Filter.m,注意把fopen的参数改为你的CCS项目的Debug下的_output的路径。播放时,切记把sound的第二个参数设置成音频文件生成的采样率,也就是Filter.m文件中的result_Fs的值。戴上耳机,聆听滤波后的结果,享受成功的喜悦。
播放代码
Id
= fopen('E:\CCS_prj_new\MyFilter\Debug\_output','r');
data
= fscanf(Id
,'%d ');
data
= data
/10^4;
sound(data
,8000); %播放时,注意采样率需要与生成时一致
fclose(Id
);
教程结束,点个赞再走嘛!