Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: FFT на асм для ARM7TDMI (AT91SAM7xx)
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Страницы: 1, 2
hd44780
На Си нашёл, вставил в программу - тормозит оно. Конечно, гораздо лучше, чем на AVR, но всё равно не айс.
Надо сделать аудио-анализатор. Сделать-сделал, осциллограммы рисует великолепно, рендер быстрый для дисплея написал, а с FFT проблемы.
А если ещё и стерео запустить - вообще ступор почти будет...

Нет ли у кого реализации на асме, типа как Чен для AVR-ов?
Сам я ейный ассемблер практически не знаю sad.gif .
Спасибо.
_Pasha
Цитата(hd44780 @ Nov 15 2012, 11:05) *
На Си нашёл, вставил в программу - тормозит оно.
Спасибо.

Небось, в плавучке?sm.gif
Тем более, что смотря какой анализатор - набор согласованных фильтров по фиксированной сетке частот может оказаться лучше.
hd44780
Нет, не на плавучке lol.gif
Выдрал у Геннадия - http://www.cqham.ru/forum/showthread.php?t=9688 100% целочисленная арифметика.
Даже слегка пооптимизировал его sm.gif .
Там есть макросы
#define FFT_POWER 8
#define FFT_N (1 << FFT_POWER) // 256

У него величина FFT_POWER в доп. цикле определялась. Зачем - непонятно, ведь она уже есть ...

А где почитать про "набор согласованных фильтров по фиксированной сетке частот"? Или что-нибудь "для подражания" sm.gif
Я в этих делах - почти ноль sad.gif Это типа набора фильтров на определённые частоты?

Вот, нашёл сие - http://www.renan.org/ARM/doc/Apps16pdf.pdf
но, похоже, только общие слова sad.gif
Xenia
Цитата(hd44780 @ Nov 15 2012, 14:52) *
Выдрал у Геннадия - http://www.cqham.ru/forum/showthread.php?t=9688 100% целочисленная арифметика.


Уточните, откуда вы его там выдрали? А то я в упор не вижу в той ссылке чего-либо про FFT.
hd44780
В конце есть архив исходниками разными - TC1-Oct-30-2012.zip‎ Там есть файлы fft.c и прочее.
Окна Хэмминга и Ханнинга в комплекте sm.gif .
Добро обнаружил, в общем-то случайно, когда с дисплеем на ILI9320 разбирался.

Я вложил сюда, чтобы там не шарить.

Даже для какого-то ARM9 нашёл на асме - http://www.elsevierdirect.com/v2/companion...N=9781558608740 biggrin.gif

Вот бабочка для ARM7TDMI - http://www.platan.ru/shem/pdf/bpf.pdf
Остальное обещает на http://www.platan.ru/shem/ , но там Error 404 sad.gif
_Pasha
Цитата(hd44780 @ Nov 15 2012, 13:52) *
Нет, не на плавучке lol.gif

А где почитать про "набор согласованных фильтров по фиксированной сетке частот"? Или что-нибудь "для подражания" sm.gif
Я в этих делах - почти ноль sad.gif Это типа набора фильтров на определённые частоты?


Вот, с кортехом-м4 уже не шутошное действо, эта плавучка.
Книжка:
затертых годов... чётта с разбегу не нахожу. Страница 67-74
Да, и поделитесь размером окна FFT, чтоли ...sm.gif
hd44780
Спасибо, почитаю.
Размер окна сейчас - 256 байт. Хоть осциллограмма красивее на 8кБ biggrin.gif

Как я выше приводил:
#define FFT_POWER 8
#define FFT_N (1 << FFT_POWER) // 256
Genadi Zawidowski
Я затащил к себе в проект (на будущее использование) это из конкурсной работы AR1731 одного программиста на приз журнала Circuit Cellar.
Оригинальные файлы здесь. Там не в реальном времени, просто демонстрация принципа работы.
_Pasha
А заинлайнить BitShift() и Butterfly() слабо? sm.gif
hd44780
Genadi Zawidowski, я так и подумал, т.к. оно у Вас фактически нигде не используются. Даже пытался искать по AR1731 - не нашёл. Спасибо.
_Pasha, попробую вечером дома. потом отпишусь.
Там ещё входной разъём почти отвалился, запаять надо.
hd44780
Разъём припаял, inline вставил.
Закрутился чуть быстрее, но всё равно тормоза.
Но даже не это суть. Там полосок 10 вначале прыгают, дальше тишина .... Остальные - редко-редко ... На входе обычная песня (попса biggrin.gif ) с компа, частот там валом всяких.
Наверное там сам алгоритм "неправильный" sad.gif .
ViKo
A. N. Sloss ... ARM System Developer's Guide - лежит в закромах.
Начиная со стр 303.
_Pasha
Цитата(hd44780 @ Nov 15 2012, 21:11) *
Наверное там сам алгоритм "неправильный" sad.gif .

Дык можно ж свипом 0-20кГц пощщупать..
hd44780
Viko, нашёл, скачал...

_Pasha, видимо придётся... А не знаете какую-нибудь прогу для генерации частот? Где-то натыкался, не помню ...
Genadi Zawidowski
Цитата(hd44780 @ Nov 15 2012, 23:13) *
прогу для генерации частот? Где-то натыкался, не помню ...


В том же моём проекте встроена генерация многочастотного сигнала - я с её помощью и проверял алгоритм (то как я его переносил к себе).

Получение очередного семпла с АЦП - GetADCVoltage() - самое начало файла hardware.c - там я даже шум пытался замешать.
ReAl
Цитата(_Pasha @ Nov 15 2012, 14:28) *
А заинлайнить BitShift() и Butterfly() слабо? sm.gif
Когда там запилят уже fixed point в gcc? В С11 уже ж вроде попало. Или в 4.8 уже есть?
Сюда
Код
typedef int _Complex cmplx_t;

//cmplx_t a = 2 + 3I;
//cmplx_t b = -1 + 2I;

void foo(cmplx_t *px, cmplx_t *py, cmplx_t w, int len)
{
    while(len--) {
        cmplx_t temp = *px + *py * w;
        *py = *px - *py * w;
        *px = temp;
        ++px;
        ++py;
    }
}
arm-none-eabi-gcc -Os -S -mcpu=cortex-m3 -mthumb cmplx-int.c
CODE
foo:
push {r4, r5, r6, r7, r8, lr}
ldr r4, [sp, #24]
b .L2
.L3:
ldmdb r1, {r5, r8}
mul r7, r2, r5
mls r7, r3, r8, r7
mul r8, r2, r8
mla r5, r3, r5, r8
ldr ip, [r0, #-8]
ldr r6, [r0, #-4]
rsb r8, r7, ip
str r8, [r1, #-8]
add r7, ip, r7
rsb r8, r5, r6
adds r5, r6, r5
str r8, [r1, #-4]
str r7, [r0, #-8]
str r5, [r0, #-4]
.L2:
subs r4, r4, #1
adds r0, r0, #8
adds r1, r1, #8
cmp r4, #-1
bne .L3
pop {r4, r5, r6, r7, r8, pc}
ещё fixed point встроенный, так и вообще хорошо.
(правда это Cortex-M3, тут ещё mla/mls хорошо пошли)



Закат солнца вручную тоже нормально выглядит:
Код
#define FIXED_FACTOR (1<<12)

typedef int _Complex cmplx_t;

void foo(cmplx_t *px, cmplx_t *py, cmplx_t w, int len)
{
    while(len--) {
        cmplx_t temp = *py * w / FIXED_FACTOR;
        *px = *px + temp;
        *py = *px - temp;
        ++px;
        ++py;
    }
}
CODE

foo:
push {r4, r5, r6, r7, r8, lr}
ldr r4, [sp, #24]
b .L2
.L5:
ldmdb r1, {r5, r8}
mul r6, r2, r5
mls r6, r3, r8, r6
mul r8, r2, r8
mla r5, r3, r5, r8
cmp r6, #0
itt lt
addlt r6, r6, #4064
addlt r6, r6, #31
cmp r5, #0
ldr ip, [r0, #-8]
ldr r7, [r0, #-4]
itt lt
addlt r5, r5, #4064
addlt r5, r5, #31
add r6, ip, r6, asr #12
add r5, r7, r5, asr #12
str r6, [r0, #-8]
str r5, [r0, #-4]
str ip, [r1, #-8]
str r7, [r1, #-4]
.L2:
subs r4, r4, #1
adds r0, r0, #8
adds r1, r1, #8
cmp r4, #-1
bne .L5
pop {r4, r5, r6, r7, r8, pc}


(ой, ну по нормальному там не ++px; ++py; а раскрыв крыльев бабочки передавать надо)
_Pasha
Вроде ж давно есть fixed...

Да, пока не забыл - бит реверс по приснопамятному красивому трюку
Здесь
Т.е. вместо тяжеленького BitShift пишем хард-кодед вариант
Код
b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;


Где там ошибка - сходу вроде нету. Мож, в представлении Q11 косяк? Не вникал, короче.
hd44780
По-моему, BitShift это мелочи sm.gif , я сейчас пытаюсь основной цикл перекрутить ...

Код
  // Main FFT loop
  for ( stc = 0; stc < NumOfStages; stc ++ )
  {
    NumOfButterflys = (1<<stc);
    NumOfBlocks = FFT_N>>(stc+1);

    for ( blc=0; blc < NumOfBlocks; blc ++ )
    {
     base = (1<<(stc+1))*blc;
     for ( bfc=0; bfc < NumOfButterflys; bfc ++ )
     {
      Butterfly ( X+base+bfc, X+base+bfc+NumOfButterflys, NumOfBlocks*bfc );
     } // for
    } // for
  } // for


Butterfly - самая тяжёлая вещь ...

http://www.embeddedsignals.com/ARM.htm - есть всё, но Cortex-M3 sad.gif
_Pasha
Цитата(hd44780 @ Nov 16 2012, 20:56) *
Butterfly - самая тяжёлая вещь ...

Глянул - точно. Надо избавиться от complex.c - сразу инлайнами сделать операции над комплексными числами. Потом - сделать unroll для хотя бы внутреннего цикла. Оптимизация -О2 или -О3
hd44780
inline сделал, слегка видоизменил структуру вызовов кода - пошустрей пошёл, но недостаточно - сильно заметен рендеринг, хотя тот же рендер на осциллограмме летает.

_Pasha, с unroll непонятно - как я могу его сделать, ведь число оборотов циклов заранее неизвестно?
Возможно я не понял, что Вы имели в виду sad.gif . Поясните пожалуйста.
_Pasha
Цитата(hd44780 @ Nov 18 2012, 12:09) *
_Pasha, с unroll непонятно - как я могу его сделать, ведь число оборотов циклов заранее неизвестно?
Возможно я не понял, что Вы имели в виду sad.gif . Поясните пожалуйста.

Вы про unroll loops? Это - можно -O2 сделать - оно автоматом включится, там где выгоднее.
Про перестановку бит - я тут более артист разговорного жанра... надо еще посчитать, что лучше. Но может лучше - табличкой, для 256 отсчетов-то?
hd44780
Цитата(_Pasha @ Nov 18 2012, 12:57) *
Вы про unroll loops? Это - можно -O2 сделать - оно автоматом включится, там где выгоднее.

Спасибо, попробую.

Цитата(_Pasha @ Nov 18 2012, 12:57) *
может лучше - табличкой, для 256 отсчетов-то?

с этим вообще пока не разбирался почти. Гляну ещё.

Вот, сделал замеры времени одного прохода FFT через DBGU и COM-порт:

---> DoFFT start
Create complex data: 1 ms
Window function 0: 0 ms
FFT: 9 ms
Determine spektrum: 0 ms
--> DoFFT end

Window function 0 - прямоугольное окно, т.е. вообще там ничего нет.
FFT - скачет 8-9 ms.
Determine spektrum - всегда 0 - значит, меньше 1 ms.

Эти цифры вообще нормальные? Может там собака в другом месте зарыта ..
У меня сейчас отображает всё вместе - осциллограмму, FFT, ещё уровень рисует - просто максимум по каждому блоку данных АЦП. Еще и часиси рисует sm.gif.
Щас выкину всё, оставлю только FFT.
hd44780
_Pasha, спасибо.

Со скоростью вроде управился, работает довольно быстро.
Осталось, в общем-то главное - работает он как-то ненормально, рисует что-то странное..
Видимо, придётся перебирать разные реализации FFT sad.gif
Genadi Zawidowski
Там очень проблемно с переполнением - я у себя переделал оригинальный проект (с потерей скорости - на 64 бит арифметику) для простоты.
hd44780
Спасибо.
Вечерком проверю вариант с заменой int на long.
Геннадий, а вы не копались, в каком месте алгоритма эти переполнения лезут? Главный цикл, последуэщий расчёт спектра, ещё что?
hd44780
Проверил. Особых тормозов от long int не заметил.
Полосок заметно больше стало, но всё равно WinAmp круче.

Сейчас другие реализации алгоритма буду пробовать ...
esaulenka
А какой должна быть разница от замены int на long в случае ARM-а ? :-)
hd44780
Медленнее. То же самое как на 8-битном проце складывать-вычитать 16-битные числа.
Ну и т.д. т.п.
adnega
Цитата(hd44780 @ Nov 19 2012, 20:18) *
Полосок заметно больше стало, но всё равно WinAmp круче.

Может, он в децибелах кажет?!
DRUID3
Цитата(hd44780 @ Nov 15 2012, 10:05) *
На Си нашёл, вставил в программу - тормозит оно. Конечно, гораздо лучше, чем на AVR, но всё равно не айс.
Надо сделать аудио-анализатор. Сделать-сделал, осциллограммы рисует великолепно, рендер быстрый для дисплея написал, а с FFT проблемы.

Вам нужен RealFFT и аппроксимация формулы для нахождения магнитуды (Р.Лайонс страница 475). По-поводу asm я где-то статью когда-то чью-то бросал сюда на форум. По поводу мегаоптимизаций - откажитесь от битреверса, примените RADIX4 и на асме вручную разверните внутренние циклы (не каскады бабочек). Вряд ли есть куда двигаться дальше в этом вопросе...

кстати раз уж пошли аппроксимации то набор IIR + блочное суммирование под частоту обновления экрана вполне претендует на спасение отца русской демократии. Ну а если уж совсем упростить - полосовые фильтры можно строить на основе фильтров скользящего среднего (можно ведь и в дифференцирующем включении их реализовать). Но результат будет... ммм... ну главное что он таки будет.
hd44780
Цитата(adnega @ Nov 19 2012, 19:43) *
Может, он в децибелах кажет?!


хрен его знает... Вообще вряд ли.
Я где-то год назад родственный анализатор на C#, .NET 2.0 (VS.NET 2005) написал.
Алгоритм откуда-то выдрал готовый. Как вы понимаете, всё в лоб, плавающая точка в любых количествах и всё прочее sm.gif . Логарифмов вроде нету. Результат визуально близок к винампу.
Могу выложить, если кого интересует.

Кстати, как децибелы по таблице просчитать, я уже придумал, осталось реализовать и проверить sm.gif .

DRUID3, я RealFFT для 80x86 только нашёл - неактуально rolleyes.gif .

Асма я этого не знаю. Учить потихоньку начал, но когда это будет ....
Нашёл реализацию FFT на нём - вложение. Для какого проца - не знаю, это с сидюка к какой-то буржуйской книжке. К какой - не знаю. На форумах англоязычных нашёл.
Сам определить я пока не способен. Если кто ориентируется - гляньте плиз.
Меня смущают имена функций типа fft_16_arm9m ....

Сейчас курю это - http://code.google.com/p/falab/
Ещё лежит kissFFt, руки пока не дошли ....

Спасибо.
esaulenka
Цитата(hd44780 @ Nov 19 2012, 21:39) *
Медленнее. То же самое как на 8-битном проце складывать-вычитать 16-битные числа.
Ну и т.д. т.п.

Задам вопрос по-другому.
Какой разрядности у Вас int и long ?

И компилятор какой?
hd44780
Компилятор - IAR
int - 32 (вроде бы). Для 64 написал long long.

Вообще у IAR help какой-то тупой, даже размер типов данных я там не нашёл sad.gif .
Хотя в том же CvAVR и прочих это с пол-пинка находится .....
_Артём_
Цитата(hd44780 @ Nov 20 2012, 13:16) *
Вообще у IAR help какой-то тупой, даже размер типов данных я там не нашёл sad.gif .
Хотя в том же CvAVR и прочих это с пол-пинка находится .....

Смотрите EWARM_DevelopmentGuide.ENU.pdf
Part 2. Reference information
Data representation
Basic data types
hd44780
Цитата(_Артём_ @ Nov 20 2012, 13:48) *
Смотрите EWARM_DevelopmentGuide.ENU.pdf


спасибо. Так и есть,long long - 64 бита.
Вечером ещё разок проверю на железе ..
Рассобачился я на этих __int32 и __int64 в VS.NET sm.gif . Зато как удобно ...
esaulenka
Цитата(hd44780 @ Nov 20 2012, 15:54) *
Рассобачился я на этих __int32 и __int64 в VS.NET sm.gif . Зато как удобно ...

Что, и stdint.h нет?


Хех, а я уж решил, что свершилось чудо, и поведение int и long (ещё вчера упоминался long int, не long long) на 32-битниках как-то различается :-)
hd44780
long long поставил.
Объём кода подскочил где-то с 33кил до 38 кил sm.gif
Полосок больше стало, но все равно редкие какие-то ...
DRUID3
Цитата(hd44780 @ Nov 20 2012, 09:49) *
DRUID3, я RealFFT для 80x86 только нашёл - неактуально rolleyes.gif .

hd44780
DRUID3, спасибо, буду смотреть. Попытаюсь к иару прикрутить.

Кста. Вот тут - http://electronix.ru/forum/index.php?showt...ost&p=57271 вчера поздно вечером что-то нарыл, добавил тупо в иаровский проект - ругается, синтаксис на такой.
DRUID3
Цитата(hd44780 @ Nov 21 2012, 09:26) *
DRUID3, спасибо, буду смотреть. Попытаюсь к иару прикрутить.

...там это... для "реал" они во флоат, но никто не мешает принять синус равным 32768 на время военного конфликта в том числе и в тригонометрических формулах. Но вообще Вам сподручнее будет не само realFFT брать, а функцию 2-а реал за одно комплексное двойной длинны(есть там и такая). Кстати, а сколько у Вас точек? Для правильного масштабирования бабочек я там еще свое intFFT приложил. fixed 0.15 не применял, и так хорошо. С asm не спешите заморачиваться. Вы как вычисляете логарифм магнитуды(или просто магнитуду)бинов в частотной области? Там эти вычисления отъедят намного больше MIPS чем FFT на C.
hd44780
Точек сейчас - 512.
Про логарифм магнетуды, извините не понял. Наверное терию вопроса плохо знаю sad.gif . Поясните пожалуйста.

Ваш код (целочисленный) сейчас читаю.

Как я понял, у Вас там 2 функции - int fn_aT_ditNbrRadix2FFT_int и fn_aT_ditNbrRadix2ReFFT_int - где какой (имею в виду "за одно комплексное двойной длины")?

Спасибо.
DRUID3
Цитата(hd44780 @ Nov 21 2012, 12:21) *
Про логарифм магнетуды, извините не понял. Наверное терию вопроса плохо знаю sad.gif . Поясните пожалуйста.

Ну вот Вы график потом отрисовываете. Это график чего? У Вас после 512 точек действительной последовательности будет 512 точоек комплексного спектра. Но рисуете то Вы физический а не комплексный спектр. Т.е. длину вектора образованного каждым комплексным бином - корень из квадрата реал плюс квадрат имеджинари (sqrt(I*I+Q*Q)). Ну и такой спектр еще очень любят потом логарифмировать для качественной визуальной оценки. Корень квадратный и логарифмирование запросто сожрут все эти попытки оптимизации FFT. Тем более не понятно где Вы их взяли для int. Сами писали?

Цитата(hd44780 @ Nov 21 2012, 12:21) *
Точек сейчас - 512.


Цитата(hd44780 @ Nov 21 2012, 12:21) *
Ваш код (целочисленный) сейчас читаю.

Как я понял, у Вас там 2 функции - int fn_aT_ditNbrRadix2FFT_int и fn_aT_ditNbrRadix2ReFFT_int - где какой (имею в виду "за одно комплексное двойной длины")?

Спасибо.

целочисленный - это просто 2-а комплексных БПФ. Прямое и обратное. Отличаются знаком комплексной экспоненты и внесением множителя 1/n для обратного БПФ в одиночный битовый сдвиг при каждом проходе каскада.

А нужно еще завернуть такое БПФ для получения БПФ вещественной последовательности. Это другой архив. Там ряд функций. БПФ прямое и обратное для действительной последовательности с отбрасыванием зеркально-сопряженной симметрии и без. Но Вам нужна функция fn_a_2RealFFT() делающая 2 БПФ действительного ряда чисел за раз внутри которой комплексное БПФ такой же длинны. Переделайте эту функцию для int(тривиально) и внутрь вставте либо мою(из того другого архива) целочисленную комплексную БПФ либо чью-то другую.
hd44780
Цитата(DRUID3 @ Nov 21 2012, 13:07) *
такой спектр еще очень любят потом логарифмировать для качественной визуальной оценки. Корень квадратный и логарифмирование запросто сожрут все эти попытки оптимизации FFT. Тем более не понятно где Вы их взяли для int. Сами писали?

Понял, о чём Вы rolleyes.gif .
Спектр не логарифмический, логарифмов вообще нигде нету ... И без корней:
Цитата
#define FMUL(a,b,q) (((long)(a)*(cool.gif)>>(q))
enum { FFT_Q=11 }; //exponent
#define FFT_POWER 9
#define FFT_N (1 << FFT_POWER) // 512 - размер выборки

...........
for ( i = 0; i < FFT_N; i ++ )
{
// Scaling by FFT_N/2=128
fix re = FFTResult[i].Re >> (FFT_POWER / 2);
fix im = FFTResult[i].Im >> (FFT_POWER / 2);
fix Re2, Im2;

// Squareing
Re2 = FMUL ( re, re, FFT_Q );
Im2 = FMUL ( im, im, FFT_Q );
Spectrum [i] = Re2 + Im2;
} // for


Писал не сам, выдрал, по сути, отсюда - http://electronix.ru/forum/index.php?showt...t&p=1111653 и там выше по теме ..
Насколько это корректно, не знаю biggrin.gif . Передирал, как зелёный студент biggrin.gif ....

Цитата(DRUID3 @ Nov 21 2012, 13:07) *
целочисленный - это просто 2-а комплексных БПФ. Прямое и обратное. Отличаются знаком комплексной экспоненты и внесением множителя 1/n для обратного БПФ в одиночный битовый сдвиг при каждом проходе каскада.

А нужно еще завернуть такое БПФ для получения БПФ вещественной последовательности. Это другой архив. Там ряд функций. БПФ прямое и обратное для действительной последовательности с отбрасыванием зеркально-сопряженной симметрии и без. Но Вам нужна функция fn_a_2RealFFT() делающая 2 БПФ действительного ряда чисел за раз внутри которой комплексное БПФ такой же длинны. Переделайте эту функцию для int(тривиально) и внутрь вставте либо мою(из того другого архива) целочисленную комплексную БПФ либо чью-то другую.

Щас буду смотреть ...
DRUID3
Цитата(hd44780 @ Nov 21 2012, 13:41) *
Понял, о чём Вы rolleyes.gif .
Спектр не логарифмический, логарифмов вообще нигде нету ... И без корней:

biggrin.gif Понял. Все уже упрощено дальше некуда. разве что маску наложить. biggrin.gif

Цитата(hd44780 @ Nov 18 2012, 13:26) *
---> DoFFT start
Create complex data: 1 ms
Window function 0: 0 ms
FFT: 9 ms
Determine spektrum: 0 ms
--> DoFFT end

Window function 0 - прямоугольное окно, т.е. вообще там ничего нет.
FFT - скачет 8-9 ms.
Determine spektrum - всегда 0 - значит, меньше 1 ms.

Эти цифры вообще нормальные? Может там собака в другом месте зарыта ..

А какая у Вас тактовая? В одном из приведенных Вами же документов - 40 MHz ~ 3ms.

Тут у меня такая мысль. Вот этот тип данных complex. Это же структура с двумя полями, так? Т.е. перед каждым обращением к полю нужно вначале перейти на указатель на структуру. А это MIPSы. Инлайнь там что или нет. Попробуйте с обыкновенными масивами I и Q.
hd44780
Цитата(DRUID3 @ Nov 21 2012, 14:23) *
А какая у Вас тактовая? В одном из приведенных Вами же документов - 40 MHz ~ 3ms.

48 MHz. Для USB. Хоть ещё ни разу его не использовал sm.gif .

Цитата(DRUID3 @ Nov 21 2012, 14:23) *
Тут у меня такая мысль. Вот этот тип данных complex. Это же структура с двумя полями, так? Т.е. перед каждым обращением к полю нужно вначале перейти на указатель на структуру. А это MIPSы. Инлайнь там что или нет. Попробуйте с обыкновенными масивами I и Q.

попробую. Спасибо.
Я сейчас Ваш смотрю.
Мой вариант по скорости уже приемлемо крутитися, но результаты какие-то странные показывает - от силы 10 полосок из 128, которые я отрисовываю на дисплее. Могу фотку дисплея кинуть вечером. Может "симптоматика" что-то подскажет.
hd44780
DRUID3, а чем отличаются fn_aT_ditNbrRadix2FFT_int и fn_aT_ditNbrRadix2ReFFT_int и какую мне лучше использовать?
DRUID3
Цитата(hd44780 @ Nov 21 2012, 17:01) *
DRUID3, а чем отличаются fn_aT_ditNbrRadix2FFT_int и fn_aT_ditNbrRadix2ReFFT_int и какую мне лучше использовать?

...ну у Вас же прямое преобразование потому первую. Отличаются они знаком комплексной экспоненты и масштабирующим коэффициентом 1/N. Я его внес в каскады в виде битовых сдвигов прямого преобразования - так спектр в масштабе сигнала получается. Т.е. если синус амплитудой 16384, то и палка от него будет такой же.

Кстати Вы пишете, что картинка Вас не радует на винамп не похожа. Так в винампе она в логарифмическом масштабе. А в прямом там действительно только основные гармоники будут.

P.S.: ...там мое тоже не ахти по оптимальности. Нет битреверса потому использованы 2-а дополнительных массива. Но для того чтобы "сэкономить место" используется факт, что синус это косинус + pi/2, а это дополнительные сложения. Плюс там еще "прыжки по таблице тригонометрии" - это чтобы "маленькие" FFT использовали таблицу для "больших" - и это жрет ресурс. Можно сделать битреверс и "вернуться к классике" - это я просто так экспериментировал. В сети полно FFT степени 2 с битреверсом, а такой формы нет нигде что-то tongue.gif .
hd44780
Цитата(DRUID3 @ Nov 21 2012, 17:52) *
ну у Вас же прямое преобразование потому первую.

Спасибо. Я ещё смотрю. Будут вопросы, спрошу.

Цитата(DRUID3 @ Nov 21 2012, 17:52) *
Кстати Вы пишете, что картинка Вас не радует на винамп не похожа. Так в винампе она в логарифмическом масштабе. А в прямом там действительно только основные гармоники будут.

Да, хотелось бы поближе к винампу rolleyes.gif ...
Там что, надо еще по каждой полоске 10log10 посчитать и взять модуль, тк. dB всегда отрицательные? А отношение к чему?

Написал туда сейчас тупо
Spectrum [i] = (int)(10.0 * log10 ( Re2 + Im2 ) );

вообще ничего не рисует laughing.gif

Цитата(DRUID3 @ Nov 21 2012, 17:52) *
В сети полно FFT степени 2 с битреверсом, а такой формы нет нигде что-то tongue.gif .


Да отож ...
hd44780
Вот сейчас посмотрел Чана - http://elm-chan.org/works/akilcd/report_e.html , логарифмов там нету, а картинка с виду нормальная ...
Неужели квадратный корень так влияет wacko.gif ?

Вот проверил, корень добавил -
Spectrum [i] = (int) sqrt ( (float)Re2 + (float)Im2 );

Вообще ничего не рисует ....

Наверное всё-таки мой алгоритм кривой sad.gif
DRUID3
У Чана логарифмов нету. У него чистое FFT. Корень квадратный навряд-ли так влияет. Может что с FFT.

А Вы ударьте по своему FFT дельта-импульсом. Что будет на выходе?

Цитата(hd44780 @ Nov 21 2012, 19:59) *
Да отож ...

...мы не идем проторенным путем... biggrin.gif

Код
/*=======================================================================*/
int fn_aT_ditNbrRadix2FFT_int
(
const unsigned int const cuic_N,
  int                               ai_inRe[],
  int                               ai_inIm[],
  int                               ai_buffRe[],
  int                               ai_buffIm[],
  int                            **pp_outRe,
  int                            **pp_outIm,
  int                            **pp_inRe,
  int                            **pp_inIm,
  const int const             acc_trigT[],
  const unsigned int        cui_jumpT
)


...там так cui_jumpT - это прыжки по таблице тригонометрии. если у Вас в проекте все FFT одного порядка смело выбрасывайте все математические действия с этой переменной и ее саму.

Указатели на входной/выходной массивы потому как в зависимости от порядка FFT(количества каскадов) результат будет либо во входных массивах либо в буфферных - такой алгоритм.

Во внешнем алгоритме(realFFT за 2-а прохода) обявите просто еще и эти массивы.

Код
   ui_TargS = cui_jumpT*ui_cWcount*ui_distance;  /* шаг для sin(t) */
   ui_TargC = ui_TargS + cui_jumpT*(cuic_N>>2);  /* шаг для cos(t) */

если синус и косинус просто без изврата поместить в 2-е раздельные таблицы, то вычисление индекса массива тригонометрии упростится до:
Код
  ui_TargT = ui_cWcount*ui_distance;                /* шаг для sin(t)/cos(t) */

Вот где-то так...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.