2

私が現在使用している DSP ボードは、Spectrum Digital の DSK6416 です。C 言語で畳み込みアルゴリズムを実装して、事前に録音されたインパルス応答アレイを使用して入力音声サンプルを畳み込みます。目的は、マイクに向かって話し、処理された効果を出力して、インパルス応答配列が得られる環境で話しているように聞こえるようにすることです。

私が今直面している課題は、畳み込みをライブで行い、割り込み関数の入出力速度を 8 kHz で維持することです。

これが私のブレインストーミングのアイデアです:

動作しない私の現在の非効率的な実装は次のとおりです。

割り込みは、畳み込みプロセスを停止し、インデックスを出力し、8 kHz または 1/8 kHz 秒で畳み込みを再開します。

ただし、畳み込みの完全な反復は、1/8kHz 秒よりもはるかに遅く実行されます。したがって、割り込みが出力配列からデータを出力したい場合、データはまだ準備ができていません。

高速パイプライン畳み込みアルゴリズムの私の理想的な実装:

時間の経過とともに完了したものを出力しながら、多くの畳み込みプロセスをバックグラウンドで実行します。多くのパイプが並行して実行されます。

パイプライン アプローチを使用する場合、N = 10000 のパイプライン プロセスをバックグラウンドで実行する必要があります...

C言語はオブジェクト指向をサポートしていないため、Cプログラミング言語を使用してこれをDSKボードに実装する方法がわかりません。

以下は、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);
}

ハードウェア DSP ボードでコンパイルする C コードにパイプラインを実装して、複数の畳み込み反復をバックグラウンドで同時に実行する方法はありますか?

絵は描いたのですが、この掲示板は初心者なので投稿できません。

私を助けるために私の絵のアイデアが必要な場合はお知らせください〜

このコードを実装する方法についてのヘルプは大歓迎です!!

4

2 に答える 2

3

おそらく、N個のサンプルのチャンクでデータを処理する必要があります。1つのチャンクが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には、1秒あたりに使用できるCPUサイクルが非常に多くあります。アルゴリズムを分析して、各サンプルの平均処理に必要なCPUサイクル数を決定する必要があります。これは、サンプル間のCPUサイクル数よりも少ない必要があります。平均してサンプルあたりのサイクル数が十分に少ないアルゴリズムがない場合は、パイプライン処理やオブジェクト指向の量は役に立ちません。

于 2011-11-19T16:56:36.633 に答える