Плата DSP, которую я сейчас использую, это DSK6416 от Spectrum Digital, и я внедряю алгоритм свертки в C для свертывания входных выборок голоса с предварительно записанным массивом импульсных характеристик. Цель состоит в том, чтобы говорить в микрофон и выводить обработанный эффект, чтобы мы звучали так, как будто говорим в той среде, где получается массив импульсных характеристик.
Задача, с которой я сейчас сталкиваюсь, заключается в том, чтобы выполнить свертку вживую и поддерживать темп входной и выходной скорости функции прерывания на 8 кГц.
Вот моя идея мозгового штурма:
Моя текущая неэффективная реализация, которая не работает, выглядит следующим образом:
Прерывание остановит процесс свертки, выведет индекс и возобновит свертку на частоте 8 кГц или 1/8 кГц.
Однако полная итерация свертки выполняется намного медленнее, чем 1/8 кГц секунд. Поэтому, когда прерывание хочет вывести данные из выходного массива, данные еще не готовы.
Моя идеальная реализация алгоритма быстрой конвейерной свертки:
У нас будет много процессов свертки, работающих в фоновом режиме, при выводе завершенных с течением времени. Параллельно будет работать много труб.
Если я использую конвейерный подход, нам нужно иметь N = 10000 конвейерных процессов, работающих в фоновом режиме ...
Теперь у меня есть идея (по крайней мере, я думаю, что могу, я могу ошибаться), я понятия не имею, как реализовать это на плате DSK с использованием языка программирования C, потому что 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, чтобы мы могли одновременно выполнять несколько итераций свертки в фоновом режиме?
Я нарисовал несколько картинок, но я новичок в этой доске, поэтому не могу публиковать картинки.
Пожалуйста, дайте мне знать, если вам нужны мои изобразительные идеи, чтобы помочь вам помочь мне ~
Любая помощь по реализации этого кода очень ценится!