Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: неправильно работает Speex на TMS320F28335
Форум разработчиков электроники ELECTRONIX.ru > Цифровая обработка сигналов - ЦОС (DSP) > Алгоритмы ЦОС (DSP)
sigmaN
Наконец-то всё запустилось и вроде даже заработало, но как всегда не всё так гладко.
Отредактировал config.h и arch.h, так, что они совпадают для WIN и TMS версий.

Пробный frame объявлен так(на самом деле он больше, но для примера сгодится и так)
Код
const int input_table[160]={
0x0000,0x0001,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0001,0x0000,0x0000,
0x0000,0x0000,0x0001,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0001,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0001,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0xFFFF,0x0001,0x0000,0x0000,0x0001,0x0000,
0x0000,0x0000,0x0000,0xFFFF,0x0000,0x0000,0xFFFF,0x0000,
0x0001,0x0000,0x0000,0x0000,0xFFFF,0x0000,0x0000,0x0001,
0x0000,0x0000,0x0000,0x0000,0xFFFF,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0001,0xFFFF,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xFFFF,
0x0000,0x0000,0xFFFF,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0xFFFF,0xFFFF,0x0000,0x0000,0x0001,0x0000,0x0000,
0x0000,0x0000,0xFFFF,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0xFFFF,0xFFFF,0xFFFE,0xFFFE,0xFFFE,0xFFFE,
0xFFFE,0x0001,0x0001,0x0001,0xFFFF,0xFFFC,0xFFF3,0xFFEB,
0xFFE4,0xFFE5,0xFFEE,0xFFF7,0x0005,0x001E,0x001D,0x0006,
0xFFE7,0xFFB7,0xFF89,0xFF72,0xFF6C,0xFFA1,0x000E,0x0048,
0x0089,0x00BB,0x0021,0xFF4F,0xFEAC,0xFD77,0xFCA3,0xFC80,
0xFCB4,0xFDC4,0xFFEA,0x0332,0x05CC,0x069B,0x0802,0x0728};

Далее, поскольку speex "портит" входной буфер, я объявил input_buf[160]
Код
extern const signed int input_table[];
signed int input_buf[160];

Перед вызовом я заполняю input_buf и
Код
speex_encode_int(enc_state, &input_buf, &encBits);

Аналогично поступаю на WIN реализаци.
После вызова, я сначала сравнивал выход. Но потом я посмотрел на вход(он ведь портачит входной буфер) и там тоже оказываются разные значения. Т.е. внутри, получается, он поразному обрабатывает буфер! Почему??
К примеру WIN изменяет только значения с input_buf[150] до input_buf[159], на TI меняются со 115 до 159 плюс ещё вразнобой, значений 6-7...
Выходы, естественно тоже не соответствуют.
Что делать? Как такое может быть?
Пробывал как FIXED_POINT, так и FLOAT - результаты одинаковы.
Перед вызовом буферы одинаковы.
С памятью вроде всё ok - нигде не переполняется.
Оптимизации компилятора выкл.
sigmaN
Проблема была в том модели памяти. Стояла Unified Memory Model. Не знаю, как её использовать(или может она вообще для этих процов не пригодна), но при её использовании творится чёрти-что! Я когда прошагал асм код, сгенерированный компилятором и увидел, как он прыгает к разным инструкциям, причём даже вверх(!) без всяких видимых причин! Ужас! Переставил на Large и всё сразу встало на свои места!
А я купился на:

Use this switch if your memory map is configured as a single unified space. This will allow the compiler to generate RPT PREAD instructions for most memcpy calls and structure assignments. This will also allow MAC instructions to be generated. This switch will also allow more efficient data memory instructions to be used to access switch tables.

И потратил 3 с половиной часа на разборки кто виноват и что делать )
[/i]

А всё-таки на FLOATING_POINT выход не сходится...первые 4 байта ok а потом расхождения. FIXED_POINT всё Ok.
Это изза погрешностей плавающей точки?? Как можно подобное объяснить?
fontp
Цитата(sigmaN @ May 23 2008, 15:11) *
А всё-таки на FLOATING_POINT выход не сходится...первые 4 байта ok а потом расхождения. FIXED_POINT всё Ok.
Это изза погрешностей плавающей точки?? Как можно подобное объяснить?


Натюрлих. Это нормально. Сколько МИПС получилось?
sigmaN
Не сколько)
На радостях я недоглядел.
В действительности и на FIXED тоже выходной буфер лажовый получается.
Совпадают всегда только первые 4 charа всё остальное лажа!
Пробывал это скормить декодеру - на выходе шум со слабыми признаками какой-то искаженной до неузнаваемости речи.

Провел пошаговое сравнение в режиме FIXED с WIN реализацией.
Всё идёт нормально до функции lsp_to_lpc
Она какая-то странная!
Код
void lsp_to_lpc(spx_lsp_t *freq,spx_coef_t *ak,int lpcrdr, char *stack)
int i,j;
    spx_word32_t xout1,xout2,xin;
    spx_word32_t mult, a;
    VARDECL(spx_word16_t *freqn);
    VARDECL(spx_word32_t **xp);
    VARDECL(spx_word32_t *xpmem);
    VARDECL(spx_word32_t **xq);
    VARDECL(spx_word32_t *xqmem);
    int m = lpcrdr>>1;

    /*
    
       Reconstruct P(z) and Q(z) by cascading second order polynomials
       in form 1 - 2cos(w)z(-1) + z(-2), where w is the LSP frequency.
       In the time domain this is:

       y(n) = x(n) - 2cos(w)x(n-1) + x(n-2)
    
       This is what the ALLOCS below are trying to do:

         int xp[m+1][lpcrdr+1+2]; // P matrix in QIMP
         int xq[m+1][lpcrdr+1+2]; // Q matrix in QIMP

       These matrices store the output of each stage on each row.  The
       final (m-th) row has the output of the final (m-th) cascaded
       2nd order filter.  The first row is the impulse input to the
       system (not written as it is known).

       The version below takes advantage of the fact that a lot of the
       outputs are zero or known, for example if we put an inpulse
       into the first section the "clock" it 10 times only the first 3
       outputs samples are non-zero (it's an FIR filter).
    */

    ALLOC(xp, (m+1), spx_word32_t*);
    ALLOC(xpmem, (m+1)*(lpcrdr+1+2), spx_word32_t);

    ALLOC(xq, (m+1), spx_word32_t*);
    ALLOC(xqmem, (m+1)*(lpcrdr+1+2), spx_word32_t);
    
    for(i=0; i<=m; i++) {
      xp[i] = xpmem + i*(lpcrdr+1+2);
      xq[i] = xqmem + i*(lpcrdr+1+2);
              
    }
         //.....покусано.....\\

После этого цикла xp[] ухе не сходятся.
MSVC:
+28652 +163 +28704 +163 +28756 +163 +28808
CCS3.3: -31834 0 -31808 0 -31782 0 -31756 0 -31730 0 -31704 0
Я только-что дошел до этого.
Очень странный вообще результат получается! Смотрел на них в HEX, хотел найти может какую-то закономерность или похожесть....ничего.
xp[i] = xpmem + i*(lpcrdr+1+2) - пока непонятен смысл этого!
Только был вызван ALLOC(xpmem, (m+1)*(lpcrdr+1+2), spx_word32_t); и началось!
Хоть убей не пойму!

в моей конфигурации:
Код
#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type))))
#define VARDECL(var) var
#define ALLOC(var, size, type) var = PUSH(stack, size, type)

Намучено у них тут с этим стеком.... Идея, конечно, хорошая, но мне кажется подглючивает она изза того, что int у нас на TMS 16ти битный.
А кое-где встречаются эти int'ы вместо, предназначенных для этого spx_int16_t. Тоже с char...
Может что-то я не учёл? Помогите плиз. Целый день с ним провозился уже, а результат ==0 help.gif

Так, дадно. С этими xp[] и xq[] разобрался. Это ведь указатель на указатель, поэтому ему и содержать адрес. А судя по написанному в коменте авторов - это хитрый способ объявления двумерного массива. Числа разные, потому, что адреса разные. И не более того.
Едем дальше....
прогонка кода продолжается...... )
sigmaN
Ха ха ха! Вот горе-то какое )
Просто я удалил из проекта не ту таблицу exc_10_32_table.с там в коментах написано, что она не используется для 8Kbps, а на самом деле используется )) Вот и не сходилось у меня ничего. Сегодня уже утром докопался до истины.
Вот что значит оптимизация ещё до того, как что-то заработает.
Думал зачем нужны лишние таблицы - эти битрейты использовать не буду всё равно....
Мипсов не очень много. До реалтайма не дотягивает пока...Щас буду чё-нибудь инлайнить и переносить ответственные функции в оперативку DSP.
sigmaN
Подскажите как правильнее оптимизировать его, чтобы не вдаваться в подробности алгоритмов и ассемблера...
Ну или, если всё-же придётся - то на что в первую очередь обратить внимание? В мануале указаны функции, которые следовало-бы оптимизировать, но как-то не очень заманчиво выглядит перспектива изучения ещё и ассемблера для данного DSP...т.е. не то, чтобы лень - просто на это нет времени уже.

Ещё вопрос: я когда ставлю полную оптимизацию всего что только можно, при компиляции получаю:
"bits.asm", ERROR! at line 18182: [E0200] Block size out of range
RPTB $C$L266,AR6

1 Assembly Error, No Assembly Warnings

Я так понимаю, RPTB имеет ограничения по размеру и этот кусок кода не проходит эту проверку.
Можно ли как-нибудь сказать компилятору, чтобы не пытался оптимизировать какой-то участок программы??
sigmaN
Всё работает.
Максимальная оптимизация компилятора. Исполнение полностью из внутренней RAM.(кодируемая речь, правда, находится во внешней 10нс StaticRAM)
Производительность: 5сек входа кодируются+декодируются за 2.6сек.
FLOATING POINT
complexity=3
bitrate=8000
highpass=1

Пробывал VBR - как-то странно немного работает....на PC лучше звучит. почему не знаю ) снова мистика какая-то)

А что можно предпринять, чтобы немного сгладить выходной сигнал? Может быть какой-то постфильтр применить...
Немного "рваная" получается речь.
В общем: очень даже ничего, но всё-таки хочется лучше)
fontp
Цитата(sigmaN @ May 26 2008, 03:44) *
Всё работает.
Максимальная оптимизация компилятора. Исполнение полностью из внутренней RAM.(кодируемая речь, правда, находится во внешней 10нс StaticRAM)
Производительность: 5сек входа кодируются+декодируются за 2.6сек.
FLOATING POINT
complexity=3
bitrate=8000
highpass=1


Не ну не так... Нужно запустить таймер и по таймеру измерять мипсы = затраченые такты процессора на обработку фрейма (без ввода/вывода) Потом разделить на время фрейма
Если у процессора есть счётчик тактов (как у bF) то и таймер не нужен
sigmaN
Так дано без ввода/вывода. Сразу
outed=spx_encodeFrame(pinp,pout,160);
z=spx_decodeFrame(pout,outed,&outfrm);
Так и делал(таймер 50Гц, инкрементирует tick++)
Получается 130 тиков.
Если за 1сек. проходит 50тиков => 130/50 = 2.6Сек.
Каждый тик = 20ms.
Кол-во фреймов: 8000*5=40000 сэмплов
фрейм = 160сэмплов => 40000/160 = 250фреймов
далее
130/250фреймов = 0.52тика, что соответствует 10.4ms на фрейм.
При частоте 150mHz длительнотсь цикла = 6.66ns.
Т.е. за одну секунду процессор делает 150150150 операций.
за 10ms=1561561,561 операций.
Может где-то обсчитался....но вроде всё правильно)
Правда с препроцессором и всякими наворотами всё это не вмещается в оперативку DSP, а из внешней памяти realtime не получается. Может flash со своим pipeline спасёт....хотя не верю. Нужно что-то оптимизировать, а с ассемблером(тем более с TI) я не очень дружу.
Вот тут с intrinsics разбираюсь. Может хоть что-то побыстрее пойдёт....
Почему-то не работает нормально компилятор с Unified memory model, хотя именно для неё заявлена улучшеная производительность и генерация продвинутых команд..
В общем разочаровывает пока немного меня этот TI......
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.