2

我目前使用的 DSP 板是 Spectrum Digital 的 DSK6416,我正在用 C 语言实现卷积算法,以将输入语音样本与预先录制的脉冲响应阵列进行卷积。目标是对着麦克风讲话,并输出处理后的效果,使我们听起来像是在获得脉冲响应阵列的环境中讲话。

我现在面临的挑战是实时进行卷积,并保持 8 kHz 的中断函数的输入和输出速度。

这是我的头脑风暴想法:

我目前无效的低效实现如下:

中断将停止卷积过程,输出索引,并以 8 kHz 或 1/8 kHz 秒恢复卷积。

然而,卷积的完整迭代运行速度比 1/8kHz 秒慢得多。所以当中断要从输出数组中输出数据时,数据还没有准备好。

我对快速流水线卷积算法的理想实现:

随着时间的推移,我们将在后台运行许多卷积过程,同时输出完成的过程。将有许多管道并行运行。

如果我使用流水线方法,我们需要在后台运行 N = 10000 个流水线进程......

现在我有了这个想法(至少我认为我有,我可能错了),我不知道如何使用 C 编程语言在 DSK 板上实现它,因为 C 不支持面向对象。

以下是我们的 C 实现的伪代码:

#include <stdio.h>
#include "DSK6416_AIC23.h"
Uint32 fs=DSK6416_AIC23_FREQ_48KHZ;        //set sampling rate
#define DSK6416_AIC23_INPUT_MIC 0x0015
#define DSK6416_AIC23_INPUT_LINE 0x0011
Uint16 inputsource=DSK6416_AIC23_INPUT_MIC; // select input

//input & output parameters declaration
#define MAX_SIZE 10000
Uint32 curr_input;
Int16 curr_input2;
short input[1];
short impulse[MAX_SIZE ];
short output[MAX_SIZE ];
Int16 curr_output;

//counters declaration
Uint32 a, b, c, d;      //dip switch counters
int i, j, k;            //convolution iterations
int x;                  //counter for initializing output;                                     

interrupt void c_int11()         //interrupt running at 8 kHz
{
    //Reads Input
    //Start new pipe
    //Outputs output to speaker
}

void main()
{

//Read Impulse.txt into impulse array

    comm_intr();
    while(1)
    {

    if (DIP switch pressed)
    {
            //convolution here (our current inefficient convolution algorithm)
            //Need to run multiple of the same process in the background in parallel.

    for (int k = 0; k < MAX_SIZE; k++)
    {
        if (k==MAX_SIZE-1 && i == 0)  // special condition overwriting element at i = MAX_SIZE -1
        {
            output[k] = (impulse[k]*input[0]); 
        }
        else if (k+i < MAX_SIZE) // convolution from i to MAX_SIZE
        {
            output[k+i] += (impulse[k]*input[0]); 
        }

        else if (k+i-MAX_SIZE != i-1)  // convolution from 0 to i-2
        {
            output[k+i-MAX_SIZE] += (impulse[k]*input[0]); 
        }
        else   // overwrite element at i-1
        {
            output[i-1] = (impulse[k]*input[0]); 
        }
    }

    }

    else //if DIP switch is not pressed
    {
            DSK6416_LED_off(0);
            DSK6416_LED_off(1);
            DSK6416_LED_off(2);
            DSK6416_LED_off(3);
            j = 0; 
            curr_output = input[1];
            output_sample(curr_output);  //outputs unprocessed dry voice
    }
    } //end of while
    fclose(fp);
}

有没有办法在 C 代码中实现管道以在硬件 DSP 板上编译,以便我们可以同时在后台运行多个卷积迭代?

我画了一些图片,但我是这个板的新手,所以我不能发布图片。

如果您需要我的图片想法来帮助我,请告诉我~

非常感谢有关如何实现此代码的任何帮助!

4

2 回答 2

3

您可能需要处理一些 N 个样本的块中的数据。当一个块在 DAC/ADC 中断处理程序中被 I/O 时,另一个块正在 main() 中的某处处理。这里的主要内容是确保您处理一大块 N 个样本比接收/传输 N 个样本花费的时间更少。

以下是它在时间上的样子(每一步中的所有事情(除了第 1 步)都“并行”发生):

  1. buf1=buf3=零,buf2=任何东西
  2. ISR:DAC发送buf1,ADC接收buf2;main():处理 buf3
  3. ISR:DAC发送buf3,ADC接收buf1;main():处理 buf2
  4. ISR:DAC发送buf2,ADC接收buf3;main():处理 buf1

从第 2 步开始无限重复。

此外,您可能希望在汇编中实现卷积以提高速度。我会看一些 TI 应用笔记或不用于实现的东西。也许它也可以在某些图书馆中找到。

您也可以考虑通过Fast Fourier Transform.

于 2011-11-17T07:58:12.330 回答
0

您的 DSP 每秒只有这么多可用的 CPU 周期。您需要分析您的算法以确定平均处理每个样本需要多少 CPU 周期。这需要少于样本之间的 CPU 周期数。如果您没有一种算法可以在每个样本的平均循环数足够少的情况下完成,那么再多的流水线操作或面向对象将无济于事。

于 2011-11-19T16:56:36.633 回答