Audio-音频降噪、回声消除处理

这篇具有很好参考价值的文章主要介绍了Audio-音频降噪、回声消除处理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        对音频数据进行处理时经常会对mic阵列的选择有很多特殊要求,当原始录取的音频阵列排布有问题时,会进行一些软件的处理,使阵列排布达到一定的要求。

1.回声消除对麦克阵列的特殊要求

Audio-音频降噪、回声消除处理

2.原始音频MIC阵列排布处理

         对于4ch音频数据而言,麦克阵列排列要求为mic1、mic2、ref1、ref2,但是通过tinycap采集的原始音频数据的阵列排布为ref1、null、mic1、mic2,俩路mic分别对应左右mic的音频摄入,需要对mic阵列进行一定处理。

Audio-音频降噪、回声消除处理

        check相关原始音频pcm文件,ref通道摄入的是喇叭对应的音频,收集到的是设备播放音乐的声音,同时mic通道也会摄入设备播放的音乐声音,需要通过回声消除处理对设备音进行一定的处理。

Audio-音频降噪、回声消除处理 

        针对麦克阵列排布不符合规定的代码端处理,调整排列架构符合要求。

struct pcm *pcm_open(unsigned int card, unsigned int device,
                     unsigned int flags, struct pcm_config *config)
{
    struct pcm *pcm;
    struct snd_pcm_info info;
    struct snd_pcm_hw_params params;
    struct snd_pcm_sw_params sparams;
    char fn[256];
    int rc;

    LOG("pcm_open card %d device %d channel %d period_size %d period_count %d format %d\n", card, device ,config->channels, config->period_size, config->period_count, config->format);

    ...
    ...

    if(card == 0 && device == 2 && config->rate == 64000){
        char *buffer;
        unsigned int ch1_first = 0, ch3_first = 0, i = 0;
        buffer = malloc(sizeof(char)*8);
        for(i = 0; i < 10 && ch1_first < 2 && ch3_first < 2; i++){
            pcm_mmap_read(pcm, buffer, 8);
            /* LOG("buffer[2] = 0x%x. buffer[3] = 0x%x buffer[6] = 0x%x. buffer[7] = 0x%x",
                *(buffer+2), *(buffer+i+3), *(buffer+6), *(buffer+7)); */
            if((*(buffer+2) == 0x00)&&(*(buffer+3) == 0x00))
                ch3_first++;
            if((*(buffer+6) == 0x00)&&(*(buffer+7) == 0x00))
                ch1_first++;
        }
        if(ch3_first > ch1_first){
            LOG("start channel ch3/4, do the conversion\n");
            printf("start channel ch3/4, do the conversion\n");
            pcm_mmap_read(pcm, buffer, 4);
        } else {
            LOG("start channel ch1/2 \n");
        }
        free(buffer);
    }

    LOG("pcm_open done pcm->fd = %d\n", pcm->fd);
    return pcm;
}

        相关代码执行log

Audio-音频降噪、回声消除处理

Audio-音频降噪、回声消除处理

        调整后的音频pcm文件

Audio-音频降噪、回声消除处理

 

 3.音频数据采样精度、回采通道复用处理

        原始录取出来的音频数据采样精度为16bit,采样频率为16khz,且ref2因为硬件设计为null。为满足麦克阵列的要求需对这样的音频数据进行应用层的处理,采样精度:16bit -> 32bit,第二路回采信号复用第一路回采信号。

        处理代码如下:

//2mic: 4c 16k 16bit -> 4c 16k 32bit(copy 3ch -> 4ch)
    public static byte[] addCnFor2MicN4(byte[] data) {
        byte[] cpy=new byte[data.length*2];
        int j=0;

        //mic1 mic2 ref ref
        while(j<data.length/8) {
            cpy[16*j]=00;
            cpy[16*j+1]=  00;
            cpy[16 * j + 2] = data[8 * j +0];
            cpy[16* j + 3] = data[8 * j +1];

            cpy[16*j+4]=00;
            cpy[16*j+5]=  00;
            cpy[16 * j + 6] = data[8 * j +2];
            cpy[16* j + 7] = data[8 * j +3];

            cpy[16*j+8]=00;
            cpy[16*j+9]=  00;
            cpy[16 * j + 10] = data[8 * j +4];
            cpy[16* j + 11] = data[8 * j +5];

            cpy[16*j+12]=00;
            cpy[16*j+13]=  00;
            cpy[16 * j + 14] = data[8 * j +4];
            cpy[16* j + 15] = data[8 * j +5];

            j++;
        }
        return cpy;
    }

Audio-音频降噪、回声消除处理

         以下是一些项目中用到的对音频数据进行处理的方法:

    //6mic 8ch 32bits
    private byte[] addCnForMutiMic(byte[] data) {
        int datasize=data.length;
        byte[] newdata=new byte[datasize*2];//double to 16bit -> 32bit
        int j=0;
        int k=0;
        int index= 0;
        int step = datasize/2;

        while(j<step) {
            for (int i=1; i<9;i++) {
                k = 4*j;
                index= 2*j;
                newdata[k]=00;
                newdata[k+1]=00;
                newdata[k+2]=data[index];
                newdata[k+3]=data[index+1];
                j++;
            }

        }
        data = null;
        return newdata;
    }

    //4mic 8ch->6ch
    private byte[] adapeter4Mic(byte[] data) {
        //  int size = ((data.length/8)*2)*6;
        int size = (data.length/8)*6;
        byte[] cpy=new byte[size];
        int j=0;

        while(j<data.length/16) {

            cpy[12 * j + 0] = data[16 * j +0];
            cpy[12* j + 1] = data[16 * j +1];

            cpy[12 * j + 2] = data[16 * j +2];
            cpy[12* j + 3] = data[16 * j +3];


            cpy[12 * j + 4] = data[16 * j +4];
            cpy[12* j + 5] = data[16 * j +5];


            cpy[12 * j + 6] = data[16 * j +6];
            cpy[12* j + 7] = data[16 * j +7];

            cpy[12 * j + 8] = data[16 * j +12];
            cpy[12* j + 9] = data[16 * j +13];

            cpy[12 * j + 10] = data[16 * j +14];
            cpy[12* j + 11] = data[16 * j +15];

            j++;
        }
        return cpy;
    }

    //4mic:8ch -> 6ch
    private byte[] adapeter4Mic32bit(byte[] data) {
        //  int size = ((data.length/8)*2)*6;
        int size = (data.length/8)*6*2;

        byte[] cpy=new byte[size];
        int j=0;

        while(j<data.length/16) {

            cpy[24 * j + 0] = 0x00;
            cpy[24* j + 1] = 0x01;
            cpy[24 * j + 2] = data[16 * j +0];
            cpy[24* j + 3] = data[16 * j +1];

            cpy[24 * j + 4] = 0x00;
            cpy[24* j + 5] = 0x02;
            cpy[24 * j + 6] = data[16 * j +2];
            cpy[24* j + 7] = data[16 * j +3];

            cpy[24 * j + 8] = 0x00;
            cpy[24* j + 9] = 0x03;
            cpy[24 * j + 10] = data[16 * j +4];
            cpy[24* j + 11] = data[16 * j +5];

            cpy[24 * j + 12] = 0x00;
            cpy[24* j + 13] = 0x04;
            cpy[24 * j + 14] = data[16 * j +6];
            cpy[24* j + 15] = data[16 * j +7];

            cpy[24 * j + 16] = 0x00;
            cpy[24* j + 17] = 0x05;
            cpy[24 * j + 18] = data[16 * j +12];
            cpy[24* j + 19] = data[16 * j +13];

            cpy[24 * j + 20] = 0x00;
            cpy[24* j + 21] = 0x06;
            cpy[24 * j + 22] = data[16 * j +14];
            cpy[24* j + 23] = data[16 * j +15];

            j++;
        }
        return cpy;
    }

    //6mic 16bit-> 2mic 32bit
    private byte[] addCnFor2Mic(byte[] data) {
        byte[] cpy=new byte[data.length];
        int j=0;

        //mic1 mic2 ref ref
        while(j<data.length/16) {
            cpy[16 * j] = 00;
            cpy[16 * j + 1] = (byte) 1;
            cpy[16 * j + 2] = data[16 * j + 0];
            cpy[16 * j + 3] = data[16 * j + 1];

            cpy[16 * j + 4] = 00;
            cpy[16 * j + 5] = (byte) 2;
            cpy[16 * j + 6] = data[16 * j + 2];
            cpy[16 * j + 7] = data[16 * j + 3];

            cpy[16 * j + 8] = 00;
            cpy[16 * j + 9] = (byte) 3;
            cpy[16 * j + 10] = data[16 * j + 12];
            cpy[16 * j + 11] = data[16 * j + 13];

            cpy[16 * j + 12] = 00;
            cpy[16 * j + 13] = (byte) 4;
            cpy[16 * j + 14] = data[16 * j + 14];
            cpy[16 * j + 15] = data[16 * j + 15];

            j++;
        }
        return cpy;
    }

4.回声消除效果

        经过回声消除之后输出的音频数据是16k、16bit、单声道数据,经过与之前的pcm文件对比可以看出数据的音乐声音被消除,基本只留下了之前mic声道里面说话的声音。

Audio-音频降噪、回声消除处理

 

总结

        回声消除和噪声抑制都是音频处理中必须要进行的一些过程,这篇只是对这些处理之前的音频数据进行转化的内容进行一下说明,回声消除与噪声抑制的具体处理涉及到算法的优化与解决,很难搞!文章来源地址https://www.toymoban.com/news/detail-403788.html

到了这里,关于Audio-音频降噪、回声消除处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 回声消除(AEC)原理、算法及实战——AEC背景介绍

    回声就是声音信号经过一系列反射之后,又听到了自己讲话的声音,这就是回声。 一些回声是必要的,比如剧院里的音乐回声以及延迟时间较短的房间回声;而大多数回声会造成负面影响,比如在有线或者无线通信时重复听到自己讲话的声音(回想那些年我们开黑打游戏时,

    2024年02月09日
    浏览(40)
  • 回声消除(AEC)原理、算法及实战——LMS(Least Mean Square)

    回声消除是语音通信前端处理中的一种重要技术,产生的原因是:在实时音视频通话中,扬声器播放的声音有再次录进了麦克风去。 在即时通讯应用中,需要进行双方,或是多方的实时语音交流,在要求较高的场合,通常都是采用外置音箱放音,这样必然会产生回音,即一方

    2024年02月04日
    浏览(52)
  • Android 9 Audio系统笔记:AudioFlinger音频流处理流程

    好久没写了,今天碰巧有个小伙伴问我关于音频流这一块的,久了还有点记不起来,我就顺便写一下,后面就不用又找一遍代码了,所谓好记性不如烂笔头。 所以,这里是关于如何从AudioTrack 写入数据到audioflinger,以及audioflinger如何写入到hal层的音频流处理流程,主要写一下

    2023年04月08日
    浏览(37)
  • chatgpt赋能python:Python音频降噪处理:使用Python减少噪音并提升声音质量

    在日常生活中,使用音频通信是非常普遍的。但是,由于各种原因,我们可能会遇到许多噪音干扰,从而降低语音质量并影响通信的效果。为了解决这个问题,我们可以使用Python来降噪音。 我们每天听到的声音都是由许多不同频率的声音波形组成的。噪音是指在声音中添加了

    2024年02月03日
    浏览(37)
  • 探索音频预处理的艺术:Audio-Preprocessing-Scripts

    项目地址:https://gitcode.com/innnky/audio-preprocessing-scripts 在数据科学和人工智能领域,尤其是语音识别和音乐分析中,高质量的音频预处理是成功的关键步骤。今天,我们要介绍的是一个名为 Audio-Preprocessing-Scripts 的开源项目,它提供了丰富的工具和脚本,旨在帮助开发者和研究人

    2024年04月27日
    浏览(34)
  • 音频处理:Audio DJ Studio for .NET-Crack

    Audio DJ Studio for .NET  is a .NET Windows Forms custom control developed by MultiMedia Soft that makes it easy to add sound playback and mixing capabilities to  Winform  and  WPF applications  written with  Microsoft Visual Studio ; thanks to the integration with DirectShow codecs and with the BASS library, both allowing decoding capabilities for the

    2024年01月23日
    浏览(36)
  • chatgpt赋能python:Python音频降噪:如何利用Python降噪音频?

    随着音频技术的不断发展,音频处理已经成为了我们生活中不可或缺的一部分。在音频处理的过程中,降噪技术是非常重要的一环。Python作为一种高级编程语言,已经成为了音频降噪领域的常用工具。在本篇文章中,我们将探讨如何利用Python降噪音频。 音频降噪是指在音频信

    2024年02月07日
    浏览(44)
  • 05|音频降噪概述(1)一传统降噪方法

    目录 一. 噪声的分类: 加性噪声和乘性噪声: 稳态噪声和非稳态噪声: 二. 如何降噪 1.线性滤波器: 2.谱减法 3.基于统计模型的实时降噪算法 3.1 核心思想: 3.2 基于两个假设:  3.3 维纳滤波 WebRTC原生降噪算法的三个特点: 3.4 改进方法OMLSA IMCRA 4.子空间算法 思想: 算法:

    2024年02月02日
    浏览(37)
  • 使用matlab进行回声处理(三重回声)-数字信号处理课设

    1.录制一段声音信号,作为原音频信号,生成频域与时域图形,观察与分析其时域 与频域图形。 2.对该音频信号进行时域处理,并且实现对该声音信号添加第一层回声。 3.对该音频信号再继续一次进行时域处理,实现对该声音信号添加第二层回声。 4.将三段音频信号进行合成

    2024年02月03日
    浏览(46)
  • 音频降噪模型汇总

    从事语音降噪增强算法开发多年了,上学期间和入行的前段都是做传统信号处理算法。19年以后基于深度学习的语音降噪模型凭借其优秀的处理效果,一时风头无两,似乎每个人都开始走上了模型降噪的路子。 特别是从2020年微软开始举办的Deep Noise Suppression Challenge – INTERSP

    2023年04月23日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包