我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android实现录音静音降噪

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android实现录音静音降噪

本文实例为大家分享了Android实现录音静音降噪的具体代码,供大家参考,具体内容如下

需求:

客户反馈产品的录音里面很多杂音(因为我们把Codec的录音增益调至最大,且电路上没有专用的音频处理芯片、CPU直接接MIC(有包地))。在外壳、硬件不能修改的情况下,软件得想想办法尝试解决问题。

首先想到的是双麦降噪,原理大概是:一个主麦克风用来做通话,另一个收集环境噪音,对音频波形分析和相位操作,叠加到主麦克风的采样波形上,形成相位抵消,就降噪了。缺点是,两个麦克风不能距离太近,并且两个麦克风距离说话人的距离不能太远,太远了角度就很小了,根本无法分辨出来,另外,根据产品使用情况,上下麦克风各自都有几率称为主麦克风。所以实验测试出来的结果并没有很好。

考虑到录音噪音在有“人声”的时候是分辨不出来的、或者说影响很小,而在静音时有明显的环境噪声,因此想使用静音降噪的方法来规避问题。

本文只是简单的静音降噪,原理如下:考虑到启动录音时,要等待一段时间(比如0.5s)才会有人声,可根据这0.5s时间来预测噪声的大小(阈值),然后以此为基础来检测“人声”的起始点。在人声到来前,把所有音频数据设置为0,也就是做静音处理,所以这里叫静音降噪。而人声到来时,返回实际的音频数据(包括里面的噪声数据)。计算阈值的方法只是简单的求和平均。

下面代码在RK平台上hardware/alsa_sound/AudioStreamInALSA.cpp实现。

#define MUTE_NOISE_REDUCTION
#ifdef MUTE_NOISE_REDUCTION
bool enable_reduction_noise = false;    //由属性sys.is.audiorecord.only控制

int threshold_def = 0x400;    //默认阈值
int threshold = 0;    //自适应噪声阈值
int threshold_count = 0;    //计数,超过THRESHOLD_COUNT则使用threshold来检测“人声”
#define THRESHOLD_COUNT 10

#define MUTE_DELAY_COUNT 15        //播放人声后保留的音频帧数、不静音

#define AUDIO_BUFFER_NUM 4        //缓存音频数据的帧数
#define AUDIO_BUFFER_SIZE 1024    //一帧的音频数据大小
char *audio_buffer[AUDIO_BUFFER_NUM];    //audio_buffer用于缓存音频数据
char *audio_buffer_temp;    //用于交互音频数据
int audio_buffer_pos=0;
#endif

#ifdef MUTE_NOISE_REDUCTION
    {
        unsigned int value = 0;
        int is_voice = 0;
        static int is_mute_delay_count;
        //ALOGE("in_begin_swip_num:%d in_begin_narrow_num=%d",in_begin_swip_num,in_begin_narrow_num);        

         if(enable_reduction_noise && bytes > AUDIO_BUFFER_SIZE){
            bytes = AUDIO_BUFFER_SIZE;
        }

        if(enable_reduction_noise){
            unsigned char * buffer_temp=(unsigned char *)buffer;
            unsigned int total = 0;
            unsigned int total_count=0;
            unsigned int total_temp = 0;
            short data16;
            int j = 0;
            for(j=0; j<bytes; j=j+2){
                value = buffer_temp[j+1];    //第二个字节为高位数据
                value = (value<<8)+buffer_temp[j];    //获得一个16bit的音频数据
                data16 = value&0xFFFF;
                if( (data16 & 0x8000) == 0){//正数
                    total +=data16;        //思考:会不会溢出
                    total_count++;        //计数
                }
            }

            total_temp = total/total_count;
            if(total_temp > threshold_def){
                is_voice++;        //检测到人声
            }else {    //is noise
                if(threshold_count == 0){
                    threshold = total_temp;
                }else{
                    threshold = (threshold+total_temp)/2;
                }
                threshold_count++;
                if(threshold_count >= THRESHOLD_COUNT){
                    threshold_def = threshold*2;    //更新阈值,这里的2要对产品实验来确定。
                    threshold_count = THRESHOLD_COUNT;    //此后一直用新阈值,直到停止录音
                }
            }

            //is_mute_delay_count的意义是,如果前面播放了人声,那再停止说话之后继续保留MUTE_DELAY_COUNT的音频数据,这样不会“戛然而止”。
            if( is_voice != 0 ){
                is_mute_delay_count=MUTE_DELAY_COUNT;
            }else{
                if(is_mute_delay_count != 0)
                    is_mute_delay_count--;
            }

            //audio_buffer的意义:检测到人声,要返回说话前的一小段音频数据,否则声音从静音到人声有个POP声的跳跃。
            //这里用audio_buffer来缓存AUDIO_BUFFER_NUM帧数据。
            if(is_mute_delay_count == 0){//Mute in order to remove noise
                memcpy(audio_buffer[audio_buffer_pos], (char *)buffer, bytes);    //缓存音频
                memset(buffer, 0, bytes);    //返回静音数据
            }else {
                memcpy(audio_buffer_temp, (char *)buffer, bytes);
                memcpy((char *)buffer, audio_buffer[audio_buffer_pos], bytes);    //返回旧的音频数据
                memcpy(audio_buffer[audio_buffer_pos], (char *)audio_buffer_temp, bytes);     //保存新的音频数据
            }
            audio_buffer_pos++;
            if(audio_buffer_pos>=AUDIO_BUFFER_NUM)
                audio_buffer_pos=0;
        }
    }
#endif

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android实现录音静音降噪

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android实现录音静音降噪

这篇文章主要为大家详细介绍了Android实现录音静音降噪,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
2022-11-13

Golang与FFmpeg: 如何实现音频降噪和音量调节

要实现音频降噪和音量调节,可以通过调用FFmpeg库来处理音频文件。在Golang中,可以使用CGO来调用C语言的FFmpeg库。首先,确保已经安装了FFmpeg,并且在系统环境变量中配置了FFmpeg的路径。然后,可以使用CGO来调用FF
2023-10-08

Ubuntu怎么开启隐藏录音降噪功能

这篇“Ubuntu怎么开启隐藏录音降噪功能”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Ubuntu怎么开启隐藏录音降噪功能
2023-07-04

Golang与FFmpeg: 如何实现音频降噪和增益

要在Golang中实现音频降噪和增益,您可以使用FFmpeg库来处理音频文件。首先,您需要安装FFmpeg并确保它在您的系统上可用。然后,您可以使用Golang的os/exec包来调用FFmpeg命令行工具。下面是一个示例代码,演示如何使用
2023-10-10

利用Golang和FFmpeg实现音频降噪的技巧

要利用Golang和FFmpeg实现音频降噪,可以按照以下步骤进行:1. 安装Golang和FFmpeg:首先,确保已经在计算机上安装了Golang和FFmpeg。可以在官方网站上下载并安装它们。2. 导入所需的Golang模块:在Go代码
2023-10-08

Ubuntu 20.04 开启隐藏录音降噪功能(推荐)

参考 最近在使用 Ubuntu 20.04 的kazam进行录音的时候,发现了一个问题: 使用系统默认的配置进行录音,录制出来的音频会有明显的噪音,我记得在 WIndow 系统里面,有一个麦克风降噪的选项可以选,但在 Ubuntu 上始终都
2022-06-04

Android实现音频录音与播放

这篇文章主要为大家详细介绍了Android实现音频录音与播放,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
2022-11-13

降噪耳机性价比之王 静享音乐必备神器

现在的生活越来越离不开无线耳机了,随着主动降噪技术被逐步攻克,近年来诞生了不少内置降噪性能的耳机产品。大家肯定也和我一样十分好奇,在这么多降噪耳机中究竟哪款才是性价比之王?其实就这个问题我也纠结了好久,只能“听个响”的蓝牙耳机已经不能满足我的需求了,早就想换一
降噪耳机性价比之王 静享音乐必备神器
2014-05-31

Golang与FFmpeg: 如何实现音频格式转换和降噪

要实现音频格式转换和降噪,可以使用Golang与FFmpeg结合的方式。首先,确保已经安装了FFmpeg并且将其添加到系统的环境变量中。然后,使用Golang的os/exec包来执行FFmpeg命令。下面是一个示例代码,演示了如何使用Gol
2023-10-20

Android实现录音声波图

这篇文章主要为大家详细介绍了Android实现录音声波图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
2022-11-13

Android实现多媒体录音笔

记事本涉及到的仅仅是对string 的存储,而且在读取上并不存在什么难点,直接用textview显示便可以了。需要做的主要是使用SQLite对数据进行一个整理。 而录音笔需要考虑的就相对较多了:比如录音时中断,录音时用户点击播放按钮;未录音
2022-06-06

Android如何实现录音功能

这篇文章给大家分享的是有关Android如何实现录音功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。本文介绍了Android实现录音的实例代码(MediaRecorder),分享给大家,具体如下:Android
2023-05-30

Android实现定时自动静音小助手

定时静音助手的实现方法,供大家参考,具体内容如下背景突发奇想,刚好这学期刚上安卓课程,想设计一个时间助手。工作、学习中经常会被突如其来的电话所打扰,在上班,上课时这突如其来的铃声会惹来别人的反感,而只靠人们的记性是很难在准确的时间记得静音。
2023-05-31

Android音频录制MediaRecorder之简易的录音软件实现代码

使用MediaRecorder的步骤:1、创建MediaRecorder对象2、调用MediRecorder对象的setAudioSource()方法设置声音的来源,一般传入MediaRecorder.MIC3、调用MediaRecorde
2022-06-06

Android使用AudioRecord实现录音功能

这篇文章主要为大家详细介绍了Android使用AudioRecord实现录音功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
2022-11-13

Android使用Flutter实现录音插件

这篇文章主要介绍了基于flutter实现录音功能,介绍了如何录音,如何把文件存放到本地,这些都是我们平常使用这个功能会遇到的问题。在使用的过程中遇到的问题也有列出,需要的朋友可以参考下
2022-11-13

android MediaRecorder实现录屏时带录音功能

下面说说android的事把 最近是不是也会遇到需求中需要用到录屏录音的功能,最近也是遇到的 现在整理完记录一下 首先呢,录音录屏需要权限 先贴一个动态权限类public class TalAllow {/*** RECORD_AUDIO
2022-06-07

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录