Цитата
Так и обрабатывать. В цикле проверять не дошел ли текущий указатель до конца массива, если да, то сдвигаем его в начало массива
Недавно решал такую же проблему, только "заворот" указателя при использовании данных был недопустимым по потерям производительности.
В результате родился такой код с двойным размером буфера и дублированием данных - где всегда есть непрерывная область отсчётов.
Оптимизатор современных версий GCC очень качественно разворачивает такие конструкции.
Код
static float32_t filter_fir_rx_AUDIO(float32_t NewSample, int_fast8_t reset)
{
enum { Ntap = Ntap_rx_AUDIO, NtapHalf = Ntap / 2 };
float32_t v = 0.0f; //output sample
// буфер с сохраненными значениями сэмплов
static float32_t x [Ntap * 2] = { 0.0f, }; // заставить расположить буфер в CCM
static uint_fast16_t fir_stage = 0;
if (reset != 0)
{
fir_stage = 0;
memset(x, 0, sizeof x);
return NewSample;
}
//shift the old samples
fir_stage = (fir_stage == 0) ? (Ntap - 1) : (fir_stage - 1);
//Calculate the new output
x [fir_stage] = NewSample;
x [fir_stage + Ntap] = NewSample;
uint_fast16_t bh = fir_stage; // Начало обрабатываемой части буфера
uint_fast16_t bt = fir_stage + Ntap; // Позиция за концом обрабатываемого буфера
uint_fast16_t n = 0;
while (n < NtapHalf)
{
v += FIRCoef_rx_AUDIO [n ++] * (x [bh ++] + x [-- bt]);
}
// Выборка в середине буфера
v += FIRCoef_rx_AUDIO [n] * x [bh];
// Обеспечиваем масштабирование к ранее расчитанному усилению фильтра (1.0)
return v * FIRScale_rx_AUDIO;
}
Сообщение отредактировал Genadi Zawidowski - Jun 12 2014, 20:43