2016-05-12 12 views
2

Я пытаюсь реализовать фильтр нижних частот в OpenCL, и теория, лежащая в основе всего этого, меня немного смутила. Я приложил свой код внизу после моего объяснения сценария.Фильтр нижних частот в OpenCL

Прежде всего, позвольте мне попытаться объяснить весь сценарий в виде точки.

  • Для ввода мы имеем сигнал cos с размером выборки, частотой (образец частоты, полученный путем умножения размера выборки с частотой) и размером шага.
  • Значение каждого размера шага хранится в массиве с частотой и размером шага, умноженным на функцию
  • Этот массив затем передается в ядро, которое затем выполняет функцию фильтра нижних частот.
  • Kernel возвращает выходной массив с новыми отфильтрованными значениями.

Функция cos всегда возвращает значение от (-1,1), единственным изменением этого значения является частота. Таким образом, он может повторяться быстрее или медленнее в зависимости от частоты, но он всегда находится между (-1,1).

Здесь я смущен, я не уверен, как применить фильтр нижних частот к этим значениям. Скажем, отсечка была 100 Гц для фильтра. Я не могу просто сказать:

if(array[i] > 100) { //delete or ignore this value. Else store in a array } 

Причина этого не будет работать потому, что значение массива [I] варьирует от (-1,1). Итак, как же применить этот фильтр? Какие ценности я буду сравнивать?

С физической точки зрения, я вижу, как это работает, конденсатор и резистор для вычисления частоты отсечки и отправки входного сигнала через схему. Но программно, я не вижу, как я могу это реализовать. Я видел много реализаций этого он-лайн, но код не был достаточно документирован, чтобы получить хорошее представление о том, что происходит.

Вот код на моей стороне хоста:

//Array to hold the information of signal 
float *Array; 

//Number of sampling points 
int sampleSize = 100; 
float h = 0; 

//Signal Frequency in Hz 
float signalFreq = 10; 

//Number of points between 0 and max val (T_Sample) 
float freqSample = sampleSize*signalFreq; 

//Step = max value or T_Sample 
float stepSize = 1.0/freqSample; 

//Allocate enough memory for the array 
Array = (float*)malloc(sampleSize*sizeof(float)); 

//Populate the array with modified cosine 
for (int i = 0; i < sampleSize; i++) { 
    Array[0] = cos(2*CL_M_PI*signalFreq*h); 
    h = h + stepSize; 
    printf("Value of current sample for cos is: %f \n", Array[0]); 
} 

Мое ядро ​​только следующим образом: (Очевидно, это не код для фильтра, это где я запутался).

__kernel void lowpass(__global int *Array, __local float *cutOffValue, __global int *Output) { 
    int idx = get_global_id(0); 
    Output[idx] = Array[idx]; 
}; 

Я нашел этот PDF-файл, который реализует множество фильтров. В конце документа вы можете найти float-реализацию фильтра низких частот.

http://scholar.uwindsor.ca/cgi/viewcontent.cgi?article=6242&context=etd

В реализации фильтра в этом формате PDF, то сравнение данных [J] к значению. Также я не знаю, что такое numItems или workItems.

Если кто-то может дать некоторое представление об этом, это было бы здорово. Я искал много других примеров в фильтрах нижних частот, но я просто не могу обернуть голову вокруг реализации. Надеюсь, я ясно сформулировал этот вопрос. Опять же, я знаю, как/что делает фильтр нижних частот. Я просто не знаю, какие значения мне нужно сравнить, чтобы фильтрация имела место.

Найдено этот вопрос как хорошо:

Low Pass filter in C

+0

Что вы имеете в виду «с частотой и размером шага, умноженным на функцию»? –

+0

cos (2 * CL_M_PI * signalFreq * h); Я просто умножаю частоту сигнала на функцию косинуса. Значение h увеличивается при изменении размера шага каждый раз, когда я увеличиваю массив. Так как размер шага равен 1/(Частотный пример), h в значительной степени h = h + 1/(Frequency Sample). Надеюсь, это правильный способ изменения косинусоидальной волны с заданной частотой. Oh и Frequency Sample - просто образцы * signalFrequency – VedhaR

ответ

1

У меня есть возможное решение. То, что я пытаюсь, будет скользящей средней пихтой (которая, как мне сказали, является самой легкой формой фильтра нижних частот, которую можно реализовать).

Что требуется:

  • FIFO-буфер
  • значения коэффициентов (я сгенерировал и получил мое от MATLAB для определенной частоты среза)
  • Входные и выходные массивы для программы

Я не реализовал этот код, но понимаю, как его использовать на теоретическом уровне. Для того, чтобы попытаться объяснить процесс, я создал диаграмму ниже.

enter image description here

По существу, из другого входного значения массива будут переданы в буфер FIFO по одному за раз. Каждый раз, когда передается значение, ядро ​​будет выполнять умножение в буфере FIFO с «n» кранами. Каждый кран имеет связанное с ним значение коэффициента. Таким образом, ввод в конкретном элементе умножается на значение коэффициента, и все значения затем накапливаются и сохраняются в одном элементе выходного буфера.

Обратите внимание, что коэффициенты были сгенерированы в Matlab. Я не знал, как еще взять эти ценности. Сначала я собирался использовать коэффициент 1/n, но я уверен, что это просто искажает значения сигнала.

И это должно сделать трюк, я собираюсь реализовать это в коде сейчас, но если что-то не так с этой теорией, не стесняйтесь ее исправить.

+0

Я собираюсь принять свой собственный ответ, поскольку это все, что есть на данный момент. – VedhaR