【CCS仿真系列教程】手把手教你纯软件仿真实现音频滤波
【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分钟,在命令行会输出当前进度。
示例项目下载
无法下载请私信或评论,看到马上修复
GitHub:https://github.com/highskyno1/CCS_music_filter
链接: 链接:https://pan.baidu.com/s/17BrjgPMYFzjJi7nc9IglKA?pwd=759l
提取码:759l
示例使用说明
首先用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_Filtetemp4 = 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 //滤波器的长度
/*** hello.c*///滤波器数据
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]; //音频缓冲器//循环保存数据时,取音频缓冲器的值
//为了减少时间复杂度,直接以新数据覆盖最旧的数据
//减少了移位的环节
/*** 循环保存数据时,取音频缓冲器的值* @param index 需要取得数据的相对索引* @param bias 索引偏置,即当前最新数据的直接索引* @return 取出的数据*/
int getValue(int index,int bias){int temp = bias + index;if(temp < N)return temp_Music[temp];elsereturn temp_Music[temp - N];
}//此函数用于计算滤波结果,每次输出一个值
//index为当前最新时域数据在音频缓冲器中的位置
/*** 实现单个数据的卷积并输出结果* @param index 最新的数据的直接索引* @return 卷积结果*/
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++; //输出结果的计数器+1if(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"); //滤波完成//关闭文件IOfclose(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);
教程结束,点个赞再走嘛!
【CCS仿真系列教程】手把手教你纯软件仿真实现音频滤波相关推荐
- 小白都能看懂的实战教程 手把手教你Python Web全栈开发(DAY 3)
小白都能看懂的实战教程 手把手教你Python Web全栈开发 Flask(Python Web)实战系列之在线论坛系统 第三讲 这是小白都能看懂的实战教程 手把手教你Python Web全栈开发 的 ...
- 小白都能看懂的实战教程 手把手教你Python Web全栈开发(DAY 1)
小白都能看懂的实战教程 手把手教你Python Web全栈开发 Flask(Python Web)实战系列之在线论坛系统 第一讲 博主博客文章内容导航(实时更新) 更多优质文章推荐: 收藏!最详细的P ...
- matlab 条形图误差线,数据可视化系列:手把手教你绘制带误差线的条形图
原标题:数据可视化系列:手把手教你绘制带误差线的条形图 条形图可以用于展示数据不同分类下的均值.中位数.标准差和置信区间等,Excel可以实现,但对于带误差线的条形图而言,还是比较麻烦的.R语言的基础 ...
- graphpad两组t检验_Graphpad 作图教程 | 手把手教你绘制森林图
森林图 (forest plots) 是以估计模型 (固定效应模型或是随机效应模型) 结果为基础绘制出的图型.它以一条垂直的直线 (横坐标刻度为 1 或 0) 为中心,用平行于横轴的多条线段描述了每个 ...
- 镜播无人直播带货教程,手把手教你如何搭建直播间
镜播无人直播带货新手教程,手把手教你如何搭建直播间 如果你一个人在家里面直播,没有直播中控来辅助你一个情况下怎么办?来教你一个什么叫做镜播.用镜子来做一个直播的辅助.在你的面前放一面镜子,下面是产品, ...
- linux下运行mcnp6安装教程,JBPM6教程-手把手教你安装JBPM
JBPM6教程-手把手教你安装JBPM 1. 安装JBPM的先决条件: (1)JDK 1.6+以上,没有安装的话,猛击这里. (2)Ant 1.7+以上,没有安装的话,看看这里. 2. 下载JBPM安 ...
- 【程序员面试系列】手把手教你如何面试,你要的我都有(工作项目篇)
作者:Dimple Solgan:当你的才华还无法撑起你的野心时候,那应该静下心来好好学习 前面两篇文章的总结,我们学会了面试前简历的准备.技术知识准备和算法题准备.不知道你是否看完了呢,如果没看完的 ...
- 网课答案公众号小白教程——手把手教你创建自己的大学查题公众号
网课答案公众号小白教程--手把手教你创建自己的大学查题公众号 1.很多新手想搭建属于自己的查题公众号! 所以我来写一个搜题公众号搭建教程,如果你想要做公众号方面的引流之类的,这个就非常不错! 废话不多 ...
- 2021win11最新最全MySQL下载安装教程——手把手教你安装MySQL
2021win11最新最全MySQL下载安装教程--手把手教你安装MySQL 最近重装了win11,给我MySQL整没了,故今天重新装一下. 第一步,进入官网 https://www.mysql.co ...
最新文章
- 怎样提高WebService的性能
- 【Java基础】对象拷贝
- 微信小程序的省市区三级地址mysql_微信小程序 实现三级联动-省市区
- Lucene知识小总结4:索引的反删除
- unity双面显示在哪_双面屏努比亚Z20售3499起 4800万三摄+855Plus+4K电池
- AI是计算机科学,人工智能计算机科学(79种)...
- 利用NABCD模型进行竞争性需求分析
- dubbo入门级梳理
- CMOS版图课程第七讲--可靠性设计,视频截图节选
- 《松本行弘的程序世界》精彩书摘
- 最详细的js获取当前url的方法
- java基本数据类型存放在哪?
- linux下重装显卡驱动
- c语言编程如何进行n次方运算,c语言n次方怎么输入?_后端开发
- 28岁,转行学 IT 靠谱吗?
- 解决nacos不停刷日志 ClientWorker get changedGroupKeys:[] 问题
- 道德经和译文_道德经全文和译文
- 关闭WIN7休眠功能
- (疯狂的石头)阿弥陀佛,上帝保佑铃声 (疯狂的石头)阿弥陀...
- navicat连接阿里云数据库
热门文章
- android shell du,Linux du 命令 command not found du 命令详解 du 命令未找到 du 命令安装 - CommandNotFound ⚡️ 坑否...
- sa结构组网方式_5G SA网络架构及组网规范
- C#中用RSA算法生成公钥和私钥
- 频谱、能谱、功率谱、倍频程谱、1/3 倍频程谱
- 【日常】SpringBoot缓存注解器及整合redis实现(附近期一些python零碎的内容)
- layui框架学习(4:导航)
- C# 读写Excel
- 数字图像处理与Python实现笔记之图像小波变换与多分辨率
- JAVA 的命令行运行
- 朋友入职中软一个月(外包华为)就离职了