zoukankan      html  css  js  c++  java
  • 音频处理中交织与非交织数据转换的几种方法

    当音频的声道数多于一个时,音频数据的存放有两种格式,即交织的(interleave)和非交织的(non-interleave)。以最常见的双声道为例,交织和非交织的音频数据存放如下图:

     

    上图中L表示左声道数据,R表示右声道数据,整数1、2等表示第几个采样点,这样L1就表示左声道的第一个采样点数据。从上图看出,所谓交织的是指一个采样点的两个声道的数据依次放在一起,非交织的是指先放左声道的所有采样点的数据,再放右声道的所有采样点的数据。

    在音频处理时,有时需要交织的数据,而有时又需要非交织的数据,这样就存在两种数据格式之间的转换。本文就讲讲这两种数据格式转换的两种方法,第一种是常规的简单的方法,第二种是巧妙的省memory的方法。

    1,  常规方法

    1.1   interleave 转 non-interleave

    先动态申请一块memory(大小等于采样点数),把右声道的数据放在这块动态申请的memory上,同时把左声道的数据放在原buffer的前一半。然后再把动态memory上的右声道的数据放到原buffer的后一半,这样就完成了interleave到non-interleave的转换。C语言的实现代码如下:

    int interleave2noninterleave(short *buf, int count)
    {
        int i;
        short *temp;
    
        if(buf == NULL) {
            printf("input point buf is NULL 
    ");
            return -1;
        }
        
        temp = (short *)malloc(sizeof(short) * count);
        if(temp == NULL) {
            printf("memory alloc failed 
    ");
            return -1;
        }
    
        for(i = 0; i < count; i++)
        {
            temp[i] = buf[2 * i + 1];
            buf[i] = buf[2 * i];
        }
    
        for(i = 0; i < count; i++)
        {
            buf[count + i] = temp[i];
        }
    
        if(temp != NULL) {
            free(temp);
            temp = NULL;
        }
    
        return 0;
    }  

    1.2   non-interleave 转interleave

    同样先动态申请一块memory(大小等于采样点数),把原buffer前一半的(即左声道的)数据放在这块动态申请的memory上。然后再把动态memory上的左声道的数据放到原buffer的奇数位置上,把原buffer后一半的(即右声道的)数据放到原buffer的偶数位置上,这样就完成了non-interleave到interleave的转换。C语言的实现代码如下:

    int noninterleave2interleave(short *buf, int count)
    {
        int i;
        short *temp;
    
        if(buf == NULL) {
            printf("input point buf is NULL 
    ");
            return -1;
        }
        
        temp = (short *)malloc(sizeof(short) * count);
        if(temp == NULL) {
            printf("memory alloc failed 
    ");
            return -1;
        }
    
        for(i = 0; i < count; i++)
        {
            temp[i] = buf[i];
        }
    
        for(i = 0; i < count; i++)
        {
            buf[2 * i] = temp[i];
            buf[2 * i + 1] = buf[count + i];
    
        }
    
        if(temp != NULL) {
            free(temp);
            temp = NULL;
        }
    
        return 0;
    }

    由于常规方法比较简单,这里就不详述了。

    2, 省memory的巧妙方法

    2.1 interleave 转 non-interleave

    这里为了讲清楚,左右声道各有四个采样点,更多点也是一样处理。处理过程如下图:

     

    第一步,将L2放在临时变量里,R1向后移一位置,再将临时变量的值(即L2)放在原buffer第二位置上;第二步,将L3放在临时变量里,R1和R2向后移一位置,再将临时变量的值(即L3)放在原buffer第三位置上;将L4放在临时变量里,R1、R2和R3向后移一位置,再将临时变量的值(即L4)放在原buffer第四位置上。这样就完成了interleave到non-interleave的转换。C语言的实现代码如下:

    int interleave2noninterleave(short *buf, int count)
    {
        int i,j;
        short temp;
    
        if(buf == NULL) {
            printf("input point buf is NULL 
    ");
            return -1;
        }
        
        for(i = 1; i < count; i++)
        {
            temp = buf[2*i];
            for(j = 0; j < i; j++)
                buf[2*i - j] = buf[2*i - j -1];
            buf[i] = temp;
        }
    
        return 0;
    }

    2.2 non-interleave 转interleave

    这里为了讲清楚,同样左右声道各有四个采样点,更多点也是一样处理。处理过程如下图:

     

    第一步,将R1放在临时变量里,L2、L3和L4向后移一位置,再将临时变量的值(即R1)放在原buffer第二位置上;第二步,将R2放在临时变量里,L3和L4向后移一位置,再将临时变量的值(即R2)放在原buffer第四位置上;第三步,将R3放在临时变量里,L4向后移一位置,再将临时变量的值(即R3)放在原buffer第六位置上。这样就完成了non-interleave到interleave的转换。C语言的实现代码如下:

    int noninterleave2interleave(short *buf, int count)
    {
        int i,j;
        short temp;
    
        if(buf == NULL) {
            printf("input point buf is NULL 
    ");
            return -1;
        }
        
        for(i = 0; i < count; i++) {
            temp = buf[count + i];
            for(j = 0; j < count - 1 - i; j++)
                buf[count + i - j] = buf[count + i - j -1];
            buf[2 * i + 1] = temp;
        }
    
        return 0;
    }

    第二种方法相对第一种少用了一块memory,更简洁,尤其适用于memory资源紧张的硬件环境里,比如DSP上,但是不如第一种通俗易懂。到底用哪一种,就取决于硬件资源了。

  • 相关阅读:
    从零开始学Bootstrap
    CSS VS JS动画,哪个更快
    css定位(positon)
    json
    使用 CSS3 绘制 Hello Kitty
    后台找到repeater里面的div并添加客户端点击事件
    dropDownList之"请选择",同时设置默认选项
    asp.net 后台对话框,确认跳转
    后台生成textbox并设置多行属性,自动换行
    asp.net多图片上传同时保存对每张图片的描述
  • 原文地址:https://www.cnblogs.com/talkaudiodev/p/12988863.html
Copyright © 2011-2022 走看看