数字音频滤波器的简单使用。

音视频处理都是比较复杂的,本章主要讲解javacv转码视频的时候,如果使得音频仅保留人声段,去除不必要的声音,其实很简单,不需要其他peak滤波器,只需要一组低通、高通滤波器即可(lowpass、highpass),接着往下看


图我手绘的有点丑,大概意思就是这样吧,lowpass只通过1000hz以内,highpass只通过800以上,一旦这两家伙合体,就进化成了黑色阴影部分,也就是声音只有800-1000hz,其他频率全部被抛弃了。

接下来直接看代码

这是其中的两个数字音频滤波算法,自由组合,可以用来切除声音

/*** 双二次滤波器之低通、高通* * @author ZJ**/
public class AudioFilter {double b0, b1, b2, a0, a1, a2;double x1, x2, y, y1, y2;/*** 采样率*/private float sample_rate = 44100f;/*** 中心频率*/private double center_freq = 0;/*** Q值*/private double Q = 1;public AudioFilter(float sample_rate, double center_freq) {super();this.sample_rate = sample_rate;this.center_freq = center_freq;}public AudioFilter(float sample_rate, double center_freq, double q) {super();this.sample_rate = sample_rate;this.center_freq = center_freq;Q = q;}/*** 低通滤波*/public void initLowpass() {Q = (Q == 0) ? 1e-9 : Q;double ov = 2 * Math.PI * center_freq / sample_rate;double sn = Math.sin(ov);double cs = Math.cos(ov);double alpha = sn / (2 * Q);b0 = (1 - cs) / 2;b1 = 1 - cs;b2 = (1 - cs) / 2;a0 = 1 + alpha;a1 = -2 * cs;a2 = 1 - alpha;gcompute();}/*** 高通滤波*/public void initHighpass() {Q = (Q == 0) ? 1e-9 : Q;double ov = 2 * Math.PI * center_freq / sample_rate;double sn = Math.sin(ov);double cs = Math.cos(ov);double alpha = sn / (2 * Q);b0 = (1 + cs) / 2;b1 = -(1 + cs);b2 = (1 + cs) / 2;a0 = 1 + alpha;a1 = -2 * cs;a2 = 1 - alpha;gcompute();}/*** 计算*/private void gcompute() {// a0归一化为1b0 /= a0;b1 /= a0;b2 /= a0;a1 /= a0;a2 /= a0;}/*** 过滤* * @param x* @return*/public double filter(double x) {y = b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2;x2 = x1;x1 = x;y2 = y1;y1 = y;return y;}

在javacv中使用filter过滤

/*** java视频转码之音频滤波实现* * @author ZJ**/
public class JavacvStreamAudioFilter {static int sampleFormat;static int sampleRate;static int audioChannels;public static void start() throws IOException, ExecutionException, LineUnavailableException {FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("d:/flv/file.mp4");grabber.start();FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("d:/flv/out.flv", grabber.getImageWidth(), grabber.getImageHeight(), grabber.getAudioChannels());// 设置flv格式recorder.setFormat("flv");recorder.setFrameRate(25);// 设置帧率recorder.setGopSize(25);// 设置goprecorder.setVideoQuality(1);recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);// 这种方式也可以recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);// 设置音频编码recorder.start();CanvasFrame canvas = new CanvasFrame("视频预览");// 新建一个窗口canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);Frame frame = null;sampleFormat = grabber.getSampleFormat();sampleRate = grabber.getSampleRate();audioChannels = grabber.getAudioChannels();// 初始化扬声器final AudioFormat audioFormat = new AudioFormat(grabber.getSampleRate(), 16, grabber.getAudioChannels(), true,true);final DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);final SourceDataLine soundLine = (SourceDataLine) AudioSystem.getLine(info);soundLine.open(audioFormat);soundLine.start();//线程池ExecutorService executor = Executors.newSingleThreadExecutor();// 低通滤波AudioFilter lowpass = new AudioFilter(sampleRate, 1000);lowpass.initLowpass();// 高通AudioFilter highpass = new AudioFilter(sampleRate, 800);highpass.initHighpass();// 只抓取图像画面for (; (frame = grabber.grab()) != null;) {// 判断是否是音频帧if (frame.samples != null) {// 一般音频都是16位非平面型左右声道在一个buffer中,如果不是得自己解析ShortBuffer channelSamples = (ShortBuffer) frame.samples[0];// 扬声器采样数据channelSamples.rewind();ByteBuffer bufferToSourceDataLine = ByteBuffer.allocate(channelSamples.capacity() * 2);// recorder采样数据channelSamples.rewind();ShortBuffer bufferToRecorder = ShortBuffer.allocate(channelSamples.capacity());for (int i = 0; i < channelSamples.capacity(); i++) {short val = channelSamples.get(i);/*** 滤波计算 可能是javacv的缘故,重新编码声音貌似有bug,偶尔会有噪音,我直接用java自己解析就不会,算法是没有问题的*/val = (short) lowpass.filter(val);val = (short) highpass.filter(val);bufferToSourceDataLine.putShort(val);bufferToRecorder.put(val);}/*** 写入到扬声器 并准备下一次读取*/try {executor.submit(new Runnable() {public void run() {soundLine.write(bufferToSourceDataLine.array(), 0, bufferToSourceDataLine.capacity());bufferToSourceDataLine.clear();}}).get();} catch (InterruptedException interruptedException) {Thread.currentThread().interrupt();}bufferToRecorder.rewind();recorder.recordSamples(sampleRate, audioChannels, bufferToRecorder);bufferToRecorder.clear();} else {// 画面帧直接录制/推流recorder.record(frame);// 显示画面canvas.showImage(frame);}}recorder.close();// close包含stop和release方法。录制文件必须保证最后执行stop()方法,才能保证文件头写入完整,否则文件损坏。grabber.close();// close包含stop和release方法canvas.dispose();soundLine.close();System.exit(0);}public static void main(String[] args) throws IOException, ExecutionException, LineUnavailableException {start();}

gitee地址

至此简单的音频滤波器功能实现了。

如果觉得可以,请随手点赞,Thanks♪(・ω・)ノ

java数字音频最强教程之lowpass、highpass的应用(保留人声)相关推荐

  1. java数字音频最强教程之3D音乐技术知识翻译

    何为HRTF Head-related transfer function(HRTF)也被称为解剖学传递函数(ATF)[引证需要],是表征的响应如何的耳接收来自空间点的声音.当声音击中听者时,头部.耳 ...

  2. java数字音频最强教程之如何检测一段音频中是否有声音

    声音检测 随着人工智能的发展,机器视觉,机器可视化也变的越来越完善,但是声音这块分析资料却比较少,有时候需要去检测一段视频或者音频中是否有声音.在某些场景中需要判断有声音则抓拍录制,当然这里只是先初步 ...

  3. java数字音频最强教程之音频的王者之路(音频发烧友篇)

    讲一下音频,其实是一门"玄学",有的人喜欢听震撼低音,有的喜欢通透人声,想要做出一款牛逼的"发烧"音乐播放器不仅需要程序员,还要程序员懂音频.从我慢慢接触音响后 ...

  4. java数字音频最强教程之去除人声

    怎么去除人声,先来谈谈原理,在这个直播火热的时代,扬声器依旧常用的立体声双声道,再外加一个麦克风录音,一个麦克风录入的声音会均匀的分散在两个声道中,举个例子,现在有一串立体声双声道的pcm数据,那么假 ...

  5. java的继承实例_java教程之java继承示例详解

    这篇文章主要介绍了java继承示例详解,需要的朋友可以参考下 什么是继承(extends)? 继承是:新定义的类是从已有的类中获取属性和方法的现象. 这个已有的类叫做父类, 从这个父类获取属性和方法的 ...

  6. c# java base64编码解码_C#教程之Base64编码解码原理及C#编程实例

    一. Base64编码由来 为什么会有Base64编码呢?因为有些网络传送渠道并不支持所有的字节,例如传统的邮件只支持可见字符的传送,像ASCII码的控制字符就不能通过邮件传送.这样用途就受到了很大的 ...

  7. java+mysql性能优化_Java培训实战教程之mysql优化

    Java培训实战教程之mysql优化 更新时间:2015年12月29日13时30分 来源:传智播客Java培训学院 浏览次数: 1.   mysql引擎 1.1.  引擎类型 MySQL常用的存储引擎 ...

  8. java jdbc 教程_java JDBC系列教程之JDBC类的简析与JDBC的基础操作

    什么是JDBC? 概念:JAVA Database Connectivity Javas数据库连接,Java语言操作数据库接口,然后由各个数据库厂商去实现这个接口,提供数据库驱动java包,我们可以使 ...

  9. 学java教程之this关键字

    学编程吧学java教程之this关键字发布了,欢迎通过xuebiancheng8.com来访问 java中的this关键字是一个非常重要的关键词.java中的this关键词主要有两种用法,先看第一种 ...

最新文章

  1. 多传感器融合:自动驾驶(上)
  2. 手机直播系统源码搭建说明
  3. set-matrix-zeroes当元素为0则设矩阵内行与列均为0
  4. 南方日报专访 | 网易云信沈青松: 企业上云正热,PaaS将迎来爆发
  5. how debug option is handled - handle_debug
  6. 火焰传感器感应有火亮灯代码_智能无线感应灯火了,光感人感2种传感器感应,做照明品牌的几光...
  7. html5学习新的知识总结(一)
  8. C++11 后置返回类型
  9. Word修改标题样式缩进不起作用原因
  10. 大数据影响下的专题地图编制
  11. bzoj 4987 Tree
  12. SigFox与LoRa技术原理、应用场景和商业模式上的比较
  13. 以您想要的方式进行EE-使用书签
  14. 山东科技大学计算机学院奖学金,山东科技大学:一份特殊“奖学金”
  15. mysql查询今年过去的天数
  16. C语言execvp实现简易Shell的两种方法
  17. axios 请求拦截器响应拦截器
  18. 《上海市优质中小企业梯度培育管理实施细则》的通知
  19. x265 码率控制算法(一)CQP
  20. 火车头怎么采集头条规则写法

热门文章

  1. mysql.cj.jdbc_com.mysql.jdbc.Driver和com.mysql.cj.jdbc.Driver的区别
  2. 怎么看伦敦银实时行情走势图?
  3. 计算机C语言代码实例:统计0~9出现的次数
  4. 编码质量评估-编码视频效果测试场景归纳
  5. TCP 连接的建立 断开
  6. 纯FLASH网站SEO方案
  7. kitti_object_vis
  8. 调用手机在线API获取手机号码归属地信息
  9. 相对论-再看电动力学
  10. 练习(三)——乳腺肿瘤(良、恶性)数据分类