硬件准备

ADSP-21489EVB:ADI 21489 DSP的开发板

产品链接:https://item.taobao.com/item.htm?spm=a1z10.5-c.w4002-5192690539.13.3cd16938GrbRa1&id=539694123232

在这里插入图片描述

AD-HP530ICE:ADI DSP通用仿真器

产品链接:https://item.taobao.com/item.htm?spm=a1z10.5-c.w4002-5192690539.11.27e0bfa3NS4TTS&id=38007242820

在这里插入图片描述

软件准备

Visual DSP++

算法功能

实现 Schroeder 提出的人工混响算法。

原理简介

下图为 Schroeder 人工混响算法的网络结构:

在这里插入图片描述

下图是其脉冲响应图:

在这里插入图片描述

在这里插入图片描述

资源占用(MIPS, Memory requirement)

在这里插入图片描述

相关函数

函数一:void InitReverbBuffers(float *DlyBufPtr[], int *BufIndex, int *BufSize );

1.函数说明:初始化函数,将延时线的数据置零。
2.输入参数:
DlyBufPtr 延时线指针数组
*DlyBufPtr 第一个梳状滤波器的延时线指针
*(DlyBufPtr + 1) 第二个梳状滤波器的延时线指针
*(DlyBufPtr + 2) 第三个梳状滤波器的延时线指针
*(DlyBufPtr + 3) 第四个梳状滤波器的延时线指针
*(DlyBufPtr + 4) 第一个全通滤波器的延时线指针
*(DlyBufPtr + 5) 第二个全通滤波器的延时线指针
BufIndex 对延时线进行数据操作的索引值
*BufIndex 第一个梳状滤波器延时线的索引值
*(BufIndex + 1)第二个梳状滤波器延时线的索引值
*(BufIndex + 2)第三个梳状滤波器延时线的索引值
*(BufIndex + 3)第四个梳状滤波器延时线的索引值
*(BufIndex + 4)第一个全通滤波器延时线的索引值
*(BufIndex + 5)第二个全通滤波器延时线的索引值
BufSize 延时线长度
*BufSize 第一个梳状滤波器延时线的长度
*(BufSize + 1)第二个梳状滤波器延时线的长度
*(BufSize + 1)第三个梳状滤波器延时线的长度
*(BufSize + 1)第四个梳状滤波器延时线的长度
*(BufSize + 1)第一个全通滤波器延时线的长度
*(BufSize + 1)第二个全通滤波器延时线的长度
3.输出参数:无
4.返回值:无。

函数二:int SchroedersReverberator(int *in, int *out, float *Gain,float *DlyBufPtr[], int *BufIndex, int *BufSize);

1.函数说明:对立体声的输入,进行梳状滤波处理。
2.输入参数:
in 输入数据指针。
*in 为左声道数据,本函数只对此声道的数据处理。 *(in+1)为右声道数据,本函数对其不作处理。
数据范围:int 类型表示的范围
Gain 增益系数
*Gain b1
*(Gain + 1) b2
*(Gain + 1) b3
*(Gain + 1) b4 *(Gain + 1) a1
*(Gain + 1) a2
*(Gain + 1) a3
*(Gain + 1) a4
*(Gain + 1) a5
*(Gain + 1) a6
数据范围: 0 ≤ ai < 1
DlyBufPtr 延时线指针数组
*DlyBufPtr 第一个梳状滤波器的延时线指针
*(DlyBufPtr + 1) 第二个梳状滤波器的延时线指针
*(DlyBufPtr + 2) 第三个梳状滤波器的延时线指针
*(DlyBufPtr + 3) 第四个梳状滤波器的延时线指针
*(DlyBufPtr + 4) 第一个全通滤波器的延时线指针
*(DlyBufPtr + 5) 第二个全通滤波器的延时线指针
BufIndex 对延时线进行数据操作的索引值
*BufIndex 第一个梳状滤波器延时线的索引值
*(BufIndex + 1)第二个梳状滤波器延时线的索引值
*(BufIndex + 2)第三个梳状滤波器延时线的索引值
*(BufIndex + 3)第四个梳状滤波器延时线的索引值
*(BufIndex + 4)第一个全通滤波器延时线的索引值
*(BufIndex + 5)第二个全通滤波器延时线的索引值
BufSize 延时线长度
*BufSize 第一个梳状滤波器延时线的长度
*(BufSize + 1)第二个梳状滤波器延时线的长度
*(BufSize + 1)第三个梳状滤波器延时线的长度
*(BufSize + 1)第四个梳状滤波器延时线的长度
*(BufSize + 1)第一个全通滤波器延时线的长度
*(BufSize + 1)第二个全通滤波器延时线的长度

3.输出参数:
out 输出数据指针。
*out 为输出数据;
数据范围:int 类型表示的范围

4.返回值: 0 为正常;
1 反馈增益参数 ai 超范围

应用举例

首先将 SchroederReverb.dlb, SchroederReverb.h 两个文件拷贝到自己的工程目录下,然后将它们添加到工程中;然后在 LDF 文件中给数据段 SchroederReverb_dmda、程序段SchroederReverb_pmco 分配空间,接下来再写相关代码。

#include " SchroederReverb.h"
/******************************************************************************

  • 调用 SchroederReverb.dlb 库函数需定义的参数
    ******************************************************************************/
    // 定义增益系数
    #define b1 1.0
    #define b2 0.90
    #define b3 0.80
    #define b4 0.70
    #define a1 0.75
    #define a2 0.75
    #define a3 0.75
    #define a4 0.75
    #define a5 0.75
    #define a6 0.75
    // 定义延时线长度
    #define D1 2910
    #define D2 3770
    #define D3 4430
    #define D4 5020
    #define D5 2720
    #define D6 3100
    // 定义延时线缓冲区,分别用于 4 个梳状滤波器,2 个全通滤波器
    #pragma section (“SchroederReverb_dmda”)
    float w1[D1 + 1];
    #pragma section (“SchroederReverb_dmda”)
    float w2[D2 + 1];
    #pragma section (“SchroederReverb_dmda”)
    float w3[D3 + 1];
    #pragma section (“SchroederReverb_dmda”)
    float w4[D4 + 1];
    #pragma section (“SchroederReverb_dmda”)
    float w5[D5 + 1];
    #pragma section (“SchroederReverb_dmda”)
    float w6[D6 + 1];
    #pragma section (“SchroederReverb_dmda”)
    float *DelayBufPtr[6] = {w1,w2,w3,w4,w5,w6};

#pragma section (“SchroederReverb_dmda”)
float GainCoef[10] = {b1, b2, b3, b4, a1, a2, a3, a4, a5, a6} ;
#pragma section (“SchroederReverb_dmda”)
int BufSize[6] = {D1,D2,D3,D4,D5,D6};
#pragma section (“SchroederReverb_dmda”)
int DelayBufIndex[6]; // 往延时缓冲区存取数据的索引值
/************************************************************************/
// 第一次调用延时函数的标志
int FirstReverbFlag = 1;
// 输入输出数据的临时变量
int InputLR;
int OutputLR[2];
int InputData[2];
int OutputData[2];
if (FirstReverbFlag)
{
InitReverbBuffers(DelayBufPtr, DelayBufIndex,BufSize);
FirstReverbFlag = 0;
}
for (i=0; i<NUM_SAMPLES; i++)
{
//取左右声道数据
InputData[0] = (block_ptr+2i); // block_ptr 是 A/D D/A 收发数据的指针
InputData[1] = (block_ptr+2i + 1);
//对输入的左声道数据进行混响处理
SchroedersReverberator(InputData, OutputData,GainCoef, DelayBufPtr,
DelayBufIndex,BufSize);

//将处理后的输出数据传给 D/A
(block_ptr+2i) = OutputData[0];
(block_ptr+2i + 1) = OutputData[1];

}

更多推荐