KPAH 0 26 января, 2006 Опубликовано 26 января, 2006 · Жалоба SSerge, так вам надо постоянно генерировать синусоиду во времени или всё-таки синусы произвольных аргументов считать? Для первого случая ничего лучше sin(a + b) не придумаешь. Для второго случая: я писал библиотеку для TI DSP 64XX. Использовал свой формат с плавающей точкой мантисса - 23 бита, только нормированные числа так что значащих бит вообще 22. Синус считал тейлором на отрезке 0 - Пи/4 (для синуса на этом отрезке полином был такой x + A*x^3 + B*x^5 + C*x^7) в итоге для всего допустимого диапазона значений аргумента (что-то типа до 2^24) получается погрешность 4 ULP от floata, то есть 2 ULP от моего представления. A, B и C похожи на тейлоровские но слегка модифицированные чтобы минимизировать относительную погрешность. По любому больше чем 18 бит точности (не забываем ещё и про argument reduction, который у меня есть и соответственно он тоже привносит ненулевую погрешность). Без argument reduction на 0 - Пи/4 ошибка 1 ULP флоата (в принципе это неустранимая ошибка так как мантисса на 1 бит меньше). вот на всякий случай кодд: CAFloat sin1 = -0.16666666666666666666666666666667f; CAFloat sin2 = 0.0083333333333333333333333333333333f; CAFloat sin3 = -0.0001984126984126984126984126984127f*0.9925f; inline CAFloat CF_sin_reduced(const CAFloat &x) { if(_ext(x.x, 0, 24) < -11) return x; CAFloat arg = x * x; return x + x*(sin1 + arg*(sin2 + arg*sin3))*arg; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
eteP 0 7 февраля, 2006 Опубликовано 7 февраля, 2006 · Жалоба Посмотрите эту статью. Можно зайти на сайт GlobalDSP Стастья за декабрь 2003 года -> Algorithms (Fast, Continuous, Sine Wave Generator) Судя по статье, результаты не плохие. Там же есть пример кода на DSP. Успехов.Pages_from_GlobalDSP_December2003.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Adlex 0 7 февраля, 2006 Опубликовано 7 февраля, 2006 · Жалоба Попробуйте применить DDS (прямой цифровой синтез) или, по крайней мере, применить те же алгоритмы Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sansh 0 3 марта, 2006 Опубликовано 3 марта, 2006 · Жалоба Попробуйте применить DDS (прямой цифровой синтез) или, по крайней мере, применить те же алгоритмы Это же чистая табличная реализация, с нее-то и начинали. А в Spartan'е, между прочим, память свободная не завалялась? А то можно взять и просто сделать аккумулятор фазы бита на 32 и иметь ~0,01Гц разешение (см. теорию DDS лучше по datasheet на AD9854) . Хотя -90dB получишь где-то в районе 32к-точечной таблицы... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bill 0 26 апреля, 2006 Опубликовано 26 апреля, 2006 · Жалоба Требуется сформировать 2 синуса (естественно в цифре). Можно пойти табличным методом - но для 8 бит и 1к хватит, а для 18 бит и метра может мало оказатся. Есть другой метод http://www.gaw.ru/html.cgi/txt/doc/...v/max2000_5.htm . Но интересные эфекты: даже при инт64 вылазеют гармоники на уровне -70 дб + к этому и частота не точно заданная. Попробывал так: X(n)=k*X(n-1)-X(n-2), где k=2*cos(2*Pi*F/Fd); для 0 градусов X(-1)=0, X(-2)=-A*sin(2*Pi*F/Fd); для 90 градусов X(-1)=A, X(-2)=A*sin(pi/2+2*Pi*F/Fd) 90 гр. частота на сотые доли процентов выше и уползает вперёд по отношению к 0 гр. Сейчас хочу через приблежённое вычеслени по Тейлору попробывать. Но явно по вычислениям более накладно будет. Может ещё есть способ с минимум вычислений сгенерить синус? (Всё должно в итоге оказатся в FPGA Спартан3). А микросхему DDS поставить не проще? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
K A A 0 15 июня, 2006 Опубликовано 15 июня, 2006 · Жалоба Попробуйте применить DDS (прямой цифровой синтез) или, по крайней мере, применить те же алгоритмы Это же чистая табличная реализация, с нее-то и начинали. А в Spartan'е, между прочим, память свободная не завалялась? А то можно взять и просто сделать аккумулятор фазы бита на 32 и иметь ~0,01Гц разешение (см. теорию DDS лучше по datasheet на AD9854) . Хотя -90dB получишь где-то в районе 32к-точечной таблицы... Я реализовал DDS на сигнальном процессоре. Для сокращения объема выборок (оставил 1024 отсчета) использовал линейную интерполяцию между соседними отсчетами (старшие 10 бит фазового аккумулятора адресуют выборку из таблицы, а младшие (32-10) бит используются для интерполяции). На интерполяцию ушло 2 умножения и 3 сложения. Проверял в MathCad, отличие от чистой синусоиды не более 5*10^-4 % (я, правда, не учитывал, что выборки 16-битные). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sansh 0 15 июня, 2006 Опубликовано 15 июня, 2006 (изменено) · Жалоба А что, линейная интерполяция... не так уж и плохо... А хранить можно только pi/2, усложнив адресацию и добавив (+/-). Кстати, где-то видел науку о кусочно-линейной интерполяции синуса, причем с нелинейным разбиением по времени (в зависимости от скорости нарастания). Приводило это все к радикальному уменьшению размера памяти выборок. 5e-4% - это не так и много, около -66dB, а как получено это значение (среднее квадратичное отклонение или...)? Посчитать бы еще Кг. Изменено 15 июня, 2006 пользователем sansh Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 15 июня, 2006 Опубликовано 15 июня, 2006 · Жалоба Думаю, что ещё раз в 10 улучшить интерполяцию синуса можно если линейно интерполировать производную, а потом брать от неё интеграл. Например если нарисовать производную в виде треугольного сигнала, то первообразная будет очень похожа на синус. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sansh 0 15 июня, 2006 Опубликовано 15 июня, 2006 · Жалоба Дык производная ж - тот самый синус: sin'(x) = cos(x) = sin(x+pi/2). И про интегрирование не понял, как его делать? Каждый новый отсчет в копилку класть? Тогда быстро за пару десятков периодов набежит ошибка. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 15 июня, 2006 Опубликовано 15 июня, 2006 · Жалоба Есть две табличные точки А и Б. Б-А = интеграл от производной. При линейной интерполяции подразумевается производная = const = (Б-А)/шаг таблицы. Однако если производную наклонить так, чтобы "определённый интеграл" не изменился, то получится гораздо большая точность. При этом производная будет прямой наклонённой линией. Никаких накоплений для этого делать не надо. Немного больше арифметических действий и фсё. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vladv 0 22 июня, 2006 Опубликовано 22 июня, 2006 · Жалоба http://www.gaw.ru/html.cgi/txt/doc/micros/...v/max2000_5.htm Требуется генерить синусоиды с частотами от 300 Гц до 2,5 МГц с шагом 1 Гц. Желательно с нелиненостями -90 дБ. Проект - селективный вольтметр, с полосами 30 и 100 Гц, желательно и со спектроанализатором. Основная идея - сигнал с ацп перемножаем с синусом и косинусом по отдельности, фильтруем и децимируем. перемножаем каждый из них на самого себя, складываем и из постоянной состовляющей извлекаем корень квадратный - значение уровня сигнала в выбранной полосе на выбранной частоте. Т.к. в спартане умножители 18 битные, то и синус желательно сформировать 18 битный. Частота опорного генератора 10 МГц. Готовый DDC, например AD6620, не хотите попробовать? А так, для этой задачи не столько нелинейность синуса важна, сколько SFDR (хотя они взаимосвязаны). При этом спектральные "палки" можно с помощью дизеринга "размазать". У нас, например, -110dBc SFDR получалось на таблице 256x25 бит с линейной интерполяцией и дизерингом фазы (около -90dBc без дизеринга). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 22 июня, 2006 Опубликовано 22 июня, 2006 · Жалоба Подскажите кто-нибудь сколько я насчитал децибелл. Составил прогу на паскале с линейной интерполяцией синуса по таблице 256*16 бит. Максимальное отклонение по центру между колонками составило 3.1e-6 относительно самого синуса (+-1.0). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 22 июня, 2006 Опубликовано 22 июня, 2006 (изменено) · Жалоба Аномалия какая-то!!! Таблица 128*13 бит с линейной интерполяцией даёт ещё большее качество - 0.9e-6 !!! Кто-нибудь может мне это объяснить? Изменено 22 июня, 2006 пользователем GetSmart Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vladv 0 22 июня, 2006 Опубликовано 22 июня, 2006 · Жалоба Подскажите кто-нибудь сколько я насчитал децибелл. Составил прогу на паскале с линейной интерполяцией синуса по таблице 256*16 бит. Максимальное отклонение по центру между колонками составило 3.1e-6 относительно самого синуса (+-1.0). Странно. При ширине выхода таблицы 16бит, максимальное отклонение от "истинного" синуса должно было быть порядка 1.5e-5. Или в программе что-то не то, или я не правильно понял, что такое "Максимальное отклонение по центру между колонками" :(. При отклонении от "идеального" синуса на 3.1e-6, SFDR даже в самом поганом случае (вся "энергия" отклонения "ушла" в один спур), думаю, будет ниже -110dBc. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 22 июня, 2006 Опубликовано 22 июня, 2006 (изменено) · Жалоба Вот прога на паскале. Если кто хочет меня проверить. При отклонении от "идеального" синуса на 3.1e-6, SFDR даже в самом поганом случае (вся "энергия" отклонения "ушла" в один спур), думаю, будет ниже -110dBc. Правда? А для 0.9e-6 сколько децибелл будет? sinus.rar Изменено 22 июня, 2006 пользователем GetSmart Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться