Jump to content

    

Свертка аудиосигнала (длинная) - вопрос чайника

Мало разбираюсь в этом, просто пытаюсь решить проблему. Надо - свертка входного стереосигнала с импульсом (тоже стерео). Из железа ADSP21489

Ядро свертки длинное - 196000 отсчетов (всякие эхо чтобы считало и прочее, будем считать это важно, не стоит говорить, что не надо так длинно). В общем прикинул, вроде бы если разбить ядро фильтра на кусочки, и при помощи overlap save через фурье - вроде бы все нормально. Но попробовал - на паре fft-ifft с такой длиной мой 21489 дает уже совершенно неприличную погрешность, по сути в 4..5 ом знаке после запятой . На небольших 1024 длиной кусках получше, но тогда я просто не успеваю их делать такое количество. Вопрос - я неправильно варю кашу, или действительно какой нибудь STM32H7 с его аппартной double precision float будет лучше? Забабахаю ему фурье тогда сразу подлиннее и все успеет... Мне вопрос цены непринципиален, просто куплены платы с хорошей аудиобвязкой, а ЦП - стоит 21489 . А с его single point у меня вот так криво выходит ((

Share this post


Link to post
Share on other sites
2 hours ago, DASM said:

Вопрос - я неправильно варю кашу, или действительно какой нибудь STM32H7 с его аппартной double precision float будет лучше? Забабахаю ему фурье тогда сразу подлиннее и все успеет... Мне вопрос цены непринципиален, просто куплены платы с хорошей аудиобвязкой, а ЦП - стоит 21489 . А с его single point у меня вот так криво выходит ((

В теории шум FFT плавучки пропорционален  log(sqrt(len)), на сколько помню, так что шум от длины должен меняться очень слабо. Но для таких длин всякие тонкости в реализации алгоритма FFT и математических библиотек начинают сильно влиять. Например, хватает ли точности при вычислении twiddles. Можно их попробовать в double посчитать и округлить.

А так, переход к double - универсальное решение, которое практически всегда помогает имхо.

 

Share this post


Link to post
Share on other sites
17 minutes ago, andyp said:

В теории шум FFT плавучки пропорционален  log(sqrt(len)), на сколько помню, так что шум от длины должен меняться очень слабо. Но для таких длин всякие тонкости в реализации алгоритма FFT и математических библиотек начинают сильно влиять. Например, хватает ли точности при вычислении twiddles. Можно их попробовать в double посчитать и округлить.

А так, переход к double - универсальное решение, которое практически всегда помогает имхо.

 

twidd забиты таблицей вида  3.8349518762146966E-04, то есть знаков напихали сколько могли, но понятное дело - сколько в single float влезет - столько и будет. FFT стандартное от ADI .
Проверяю просто - заполняю вектор на 65536 значения целыми по возрастаанию, считаю fft, потом ifft - должно же получаться тоже самое.

 А вижу 0 1.0032 2.000123 3.00073 и так далее.

Share this post


Link to post
Share on other sites
10 minutes ago, DASM said:

twidd забиты таблицей вида  3.8349518762146966E-04, то есть знаков напихали сколько могли, но понятное дело - сколько в single float влезет - столько и будет. FFT стандартное от ADI .
 

Вопрос в том, как их считали. Если во float, а затем в double распечатали, то может быть плоховатисто уже. Конкретно с либой от ADI я не знаком, но ожидал бы уровня relative rms примерно 1e-7 - 1e-6 от "правильной" реализации.

Share this post


Link to post
Share on other sites

1e-6 в смысле после прямого и назад преобразований? Я тут вообще не очень понимаю как считать. Была бы фикс точка более менее понятно, а тут ведь диапазон значений ого-ого.. Но если я задаю входной вектор не 1 2 3 4 5 а 1000 2000 3000 и т д, то погрешность эта аккуратно едет вслед, то есть относительно значений как бы и не меняется и вот так довольно велика. В шестом знаке она только если 1024 точек ффт

Share this post


Link to post
Share on other sites

Точность float обычно теряется на суммировании. Примитивное последовательное суммирование в одну переменную аккумулятор вполне даст подобную ошибку. Дальше вопросы к реализации fft.

Share this post


Link to post
Share on other sites

ну не знаю.. даже если библиотека ADI (много лет уже ведь) и написана черти как (в чем я лично сомневаюсь) то я уж и подавно лучше не сделаю, да еще и синтаксис ихнего асма полный диссонанс вызывает. Корочь запустил double float на stm32f767 - совсем другое дело, заказываю тогда H серию 500 МГц и буду считать что с чистокровными DSP у меня дружбы не вышло. У Техаса вродь есть DP, но что-то уже охоты мало. И похоже что с кешами у стареньких DSP печалька, если данные в SDRAM то все тормозится раз в 15. У STM мне и внутреннего мегабайта хватит.

Share this post


Link to post
Share on other sites
1 hour ago, DASM said:

1e-6 в смысле после прямого и назад преобразований? Я тут вообще не очень понимаю как считать. Была бы фикс точка более менее понятно, а тут ведь диапазон значений ого-ого.. Но если я задаю входной вектор не 1 2 3 4 5 а 1000 2000 3000 и т д, то погрешность эта аккуратно едет вслед, то есть относительно значений как бы и не меняется и вот так довольно велика. В шестом знаке она только если 1024 точек ффт

Я как раз про относительную среднеквадратическую ошибку. Вот плохо, что она так от длины зависит. У "хорошей" либы должно быть плато по относительной среднеквадратической ошибке для очень больших длин. Если с длиной примерно линейно relative rms error нарастет, то что-то явно не то. Подробности например здесь можно посмотреть:

https://pdfs.semanticscholar.org/9939/893e66a57e89271c5bcd2d64b2a961cf4425.pdf

 

Там из графиков видно, что для длин порядка 100000-200000 и single precision должно быть порядка 10e-6 - 10e-7

Share this post


Link to post
Share on other sites
В 02.05.2019 в 21:50, DASM сказал:

twidd забиты таблицей вида  3.8349518762146966E-04, то есть знаков напихали сколько могли, но понятное дело - сколько в single float влезет - столько и будет. FFT стандартное от ADI .
Проверяю просто - заполняю вектор на 65536 значения целыми по возрастаанию, считаю fft, потом ifft - должно же получаться тоже самое.

 А вижу 0 1.0032 2.000123 3.00073 и так далее.

Это нормально. Относительная погрешность вполне соответствует флоату. Приведи исходные данные в диапазон +-1.

Share this post


Link to post
Share on other sites
1 hour ago, thermit said:

Это нормально. Относительная погрешность вполне соответствует флоату. Приведи исходные данные в диапазон +-1.

да. Я уже сообразил, что и выходит нормально и для звука с головой хватит. А вот с производительностью пока не очень. ((

Share this post


Link to post
Share on other sites

И с производительностью тоже норм.

Share this post


Link to post
Share on other sites

я тут сообразил, что я идиот. Свертку с длинным импульсом ведь можно разбить на мелкие достаточно кусочки, чтобы и сигнал, и кусок свертки и коэффициенты лезли во внутреннюю память целиком. А скорость линейного чтения записи  с СДРАМ ведь очень хорошая, у меня скорость поступления аудиоданным в 500 раз ниже, чем возомжная (навскидку) скорость трансфера сдрам-нутряная. Правда работа при это выглядит как бесконечная пересылка кусков памяти туда сюда, но зато по прикидкам вполне  можно все успеть. Правильно мыслю вообще или снова что-то забыл?

Share this post


Link to post
Share on other sites

Угу. Плюс пересылку можно делать через дма. Плюс есть бпф сопроцессор.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this