Нравится? Делимся информацией!

среда, 12 декабря 2012 г.

Create FIR filter C++ _ Создание КИХ фильтра на С++. Реализация класса, интерфейса класса.





Читаем гл 6,7,9, а так же с 460 и 820 Айфичера - это если совсем новичок и нет никаких наработок. У меня же есть модель в матлабе цифрового синхронного детектора ( а так же асинхронного, sqrt-детектора, разработанные мною). В этой модели я уже рассчитывал коэффициенты фильтра, поэтому осталось их оттуда вычленить и сгенерировать.

Т.к. в процессоре TMS320F28335 места не так много, то вместо динамического распределения памяти под коэффициенты будем использовать обычные массивы, причем массив с коэффициентами будет внешним, по отношению к классу фильтра (глобальный или локальный - неважно). А в класс фильтра при его создании будет передаваться указатель на массив и его размер. Пока данный вариант выглядит наиболее рационально, т.к. даже если динамически выделять память под коэффициенты фильтра, то как их инициализировать потом???? Внешним массивом с коэффициентами в заголовочном файле, сгенерированным матлабом ??? Опять же внешний массив - лишняя память. Зачем? Можно просто создать конструктор с передачей классу указателя на внешний массив и его размер!  (в отношении внутреннего буфера в классе фильтра - такое не применимо. придется использовать динамическое распределение, кучу и т.п...)

Работаю пока без применения шаблонов (templates), поэтому чтобы сделать класс фильтра независимым от типа данных используемых в его “недрах”, а так же в целях относительной легкости модификации этого типа при переходе на новую платформу и новые типы данных, решено прибегнуть к помощи typedef. Данный прием использовал и для создания модели виртуального АЦП (adcmodel.cpp, adcmodel.hpp здесь можно ознакомиться с кодом ) . Пример, небольшой кусок кода

class IFilter {
public:
   ///Standard types replacement for portability
 
   ///internal type of data
   typedef float       filterValueT;
   typedef filterValueT        filterOutputValueT;

public:
   inline        IFilter();
   virtual     ~IFilter();

   virtual filterOutputValueT     filtrate( const filterValueT& ) = 0;
};

class CFilter : publicIFilter {
public:
   inline        CFilter();
   virtual     ~CFilter();

   virtual filterOutputValueT      filtrate( const filterValueT& inSample );
};
//*********************************
//filter.cpp - Файл реализации
filterOutputValueT
CFilter::filtrate( const filterValueT& inSample ) {
/* filter algorithm*/
}

В данном виде код не компилится, т.к. для нормально работы тип filterOutputSampleT должен быть дополнительно объявлен глобально, помимо как внутри класса в public-секции. Это неудобно, т.к. в случае каких-либо изменений с типом обрабатываемых данных (например, с переходом с float на double или int) придется в двух местах производить правку.
Можно в одном месте, глобально, объявить  синонимы, замещающие используемые типы данных, но это идет в разрез с концепцией, что все должно быть внутри класса.
Поэтому вспоминая опыт работы с библиотекой openCV 2.4.2, выход функции лучше обозначить как void (ну, или возвращающий булевый результат удачного/неудачного завершения функции), а возвращаемые функцией данные организовать как аргумент функции, переданный по ссылке: 


class VideoCapture
{
public:
   
// the default constructor    VideoCapture();
 <...>
   
// reads the frame from the specified video stream
   // (non-zero channel is only valid for multi-head camera live streams)
   virtual bool retrieve( Mat& image, int channel=0 ); protected:
   <...>
};

Конечный вариант данной идеи, которая устраивает компилятор, выглядит следующим образом:

class IFilter {
public:
   ///Standard types replacement for portability
 
   ///internal type of data
   typedef float       filterValueT;
   typedef filterValueT        filterOutputValueT;

public:
   inline        IFilter();
   virtual     ~IFilter();

   virtual bool         filtrate( const filterValueT& ,
filterOutputValueT& ) = 0;
};

class CFilter : publicIFilter {
public:
   inline        CFilter();
   virtual     ~CFilter();

   virtual bool     filtrate( const filterValueT&  inSample,
filterOutputValueT&  outSample );
};
//filter.cpp - Файл реализации
bool
CFilter::filtrate( const filterValueT& inSample,
  filterOutputValueT&  outSample ) {
/* filter algorithm*/
}

4 комментария:

  1. Здравствуйте! а можно пожалуйста полностью код посмотреть. срочно надо....а нормальных кодов нет, самому писать мало...очень мало времени....

    ОтветитьУдалить
    Ответы
    1. ну так-то можно. надо либо Вам почту дать либо меня найти. Это не сложно

      Удалить
    2. zakirov_vm434@mail.ru это моя почта. Буду очень признателен вам. А на сколько код сложный?

      Удалить
  2. alexandvasilievby@yandex.ru могли бы тоже поделиться исходником?

    ОтветитьУдалить