jcxz 235 6 марта, 2021 Опубликовано 6 марта, 2021 · Жалоба 1 минуту назад, andyp сказал: Угу. Что там со стабильностью у такого генератора? Слыхал, что у него полюса прямиком на единичной окружности ;) Чтобы не накапливались ошибки, достаточно каждые N сэмплов делать перезапуск, вычисляя 2 сэмпла традиционно - через sin(). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andyp 9 6 марта, 2021 Опубликовано 6 марта, 2021 (изменено) · Жалоба 46 minutes ago, jcxz said: Чтобы не накапливались ошибки, достаточно каждые N сэмплов делать перезапуск, вычисляя 2 сэмпла традиционно - через sin(). И ещё сделать так, чтобы при этом фаза не рвалась. Код становится уже не так и прост. Имхо, табличный генератор не так уж и плох. Тем более, что таблица залетает в кеш. Изменено 6 марта, 2021 пользователем andyp Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
FatRobot 1 6 марта, 2021 Опубликовано 6 марта, 2021 · Жалоба Вы могли бы прикинуть SFDR для такого решения? Для сравнения: NCO с таблицей из 2K float и линейной интерполяцией имеет SFDR > 150dB 1 hour ago, jcxz said: Чтобы не накапливались ошибки, достаточно каждые N сэмплов делать перезапуск, вычисляя 2 сэмпла традиционно - через sin(). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Allregia 9 6 марта, 2021 Опубликовано 6 марта, 2021 · Жалоба 5 hours ago, jcxz said: (PI / 0x80000000u) - это выражение уже считается компилятором в double с соответствующей точностью, и только результат конвертируется в float. Я про это и сказал, что "если считается в компайл-тайм" 5 hours ago, jcxz said: Элементарно же! ОК, спасибо, попробую. 3 hours ago, andyp said: Тем более, что таблица залетает в кеш. У меня не залетает, во 1-х ввиду своего размера (оно вообще в ОЗУ не лезет, поэтому из феша, если не считать синус на ходу), во 2-х - ввиду отсусттвия кеша как такового. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andyp 9 6 марта, 2021 Опубликовано 6 марта, 2021 · Жалоба 27 minutes ago, Allregia said: У меня не залетает, во 1-х ввиду своего размера (оно вообще в ОЗУ не лезет, поэтому из феша, если не считать синус на ходу), во 2-х - ввиду отсусттвия кеша как такового. Ну ОК, что уж. Вообще генераторы на биквадах часто приходится стабилизировать по крайней мере по амплитуде, что по мне, так такое себе удовольствие. В моих приложениях мне такое даром не надо. Хочу, чтобы DDFSка делала мне синус нужного качества без сюрпризов на протяжении многих отсчетов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Allregia 9 6 марта, 2021 Опубликовано 6 марта, 2021 · Жалоба 1 minute ago, andyp said: Хочу, чтобы DDFSка делала мне синус нужного качества без сюрпризов на протяжении многих отсчетов. Аналогично :) Я пробовал с таблицей, расчитанной в дабл флоат, резулььтат аналогичный. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andyp 9 6 марта, 2021 Опубликовано 6 марта, 2021 · Жалоба 4 minutes ago, Allregia said: Аналогично :) Я пробовал с таблицей, расчитанной в дабл флоат, резулььтат аналогичный. Ну конечно, это ж в общем случае работает. Я ж предупредил о marginal stability, больше не смею мешать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Allregia 9 6 марта, 2021 Опубликовано 6 марта, 2021 · Жалоба 3 minutes ago, andyp said: Ну конечно, это ж в общем случае работает. Я понимаю что работает, это далеко не первый мой программный DDS, но я раньше не генерировал частот, приближающихся к Fs/2. И очень интереснол, как-же сделали в ARTA, что у них алиас намного меньшей амплитуды? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andyp 9 6 марта, 2021 Опубликовано 6 марта, 2021 · Жалоба Не очень понимаю, о чём разговор. Амплитудный спектр синуса - всегда две палки, симметричных относительно 0 . С учётом периодичности спектра дискретного сигнала, компонент окажется на частоте Fs-Fg. Fg - та частота, которую генерируете. Fs - частота дискретизации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 6 марта, 2021 Опубликовано 6 марта, 2021 (изменено) · Жалоба typedef uint32_t ncoftw_t; typedef int32_t ncoftwi_t; #define NCOFTWBITS 32 // количество битов в ncoftw_t #define FTWROUND(ftw) ((uint32_t) (ftw)) #define FTWAF001(freq) (((int_fast64_t) (freq) << NCOFTWBITS) / ARMI2SRATE100) #define FTWAF(freq) (((int_fast64_t) (freq) << NCOFTWBITS) / ARMI2SRATE) static FLOAT_t omega2ftw_k1; // = POWF(2, NCOFTWBITS); #define OMEGA2FTWI(angle) ((ncoftwi_t) ((FLOAT_t) (angle) * omega2ftw_k1 / (FLOAT_t) M_TWOPI)) // angle in radians -pi..+pi to signed version of ftw_t // Convert ncoftw_t to q31 argument for arm_sin_cos_q31 // The Q31 input value is in the range [-1 0.999999] and is mapped to a degree value in the range [-180 179]. #define FTW2_SINCOS_Q31(angle) ((ncoftwi_t) (angle)) // Convert ncoftw_t to q31 argument for arm_sin_q31 // The Q31 input value is in the range [0 +0.9999] and is mapped to a radian value in the range [0 2*PI). #define FTW2_COS_Q31(angle) ((q31_t) ((((ncoftw_t) (angle)) + 0x80000000uL) / 2)) #define FAST_Q31_2_FLOAT(val) ((q31_t) (val) / (FLOAT_t) 2147483648) static RAMFUNC FLOAT_t getsinf(ncoftw_t angle) { FLOAT_t v; const q31_t sinv = arm_sin_q31(FTW2_COS_Q31(angle)); //v = FAST_Q31_2_FLOAT(sinv); // todo: use arm_q31_to_float arm_q31_to_float(& sinv, & v, 1); return v; } static RAMFUNC FLOAT_t getcosf(ncoftw_t angle) { FLOAT_t v; const q31_t cosv = arm_cos_q31(FTW2_COS_Q31(angle)); //v = FAST_Q31_2_FLOAT(cosv); // todo: use arm_q31_to_float arm_q31_to_float(& cosv, & v, 1); return v; } static RAMFUNC FLOAT32P_t getsincosf(ncoftw_t angle) { FLOAT32P_t v; q31_t sincosv [2]; #if 1 sincosv [0] = arm_sin_q31(FTW2_COS_Q31(angle)); sincosv [1] = arm_cos_q31(FTW2_COS_Q31(angle)); #else arm_sin_cos_q31(FTW2_SINCOS_Q31(angle), & sincosv [0], & sincosv [1]); // at index 0 all fine // at index 1 with sidetones #endif arm_q31_to_float(sincosv, v.ivqv, 2); return v; } static RAMDTCM ncoftw_t anglestep_lout2 = FTWAF(5600), anglestep_rout2 = FTWAF(6300); static RAMDTCM ncoftw_t angle_lout2, angle_rout2; static int get_lout24(void) { // Формирование значения для LOUT //const int v = arm_sin_q31(angle_lout2 / 2) / 256; const int v = getcosf(angle_lout2) * INT24_MAX; angle_lout2 = FTWROUND(angle_lout2 + anglestep_lout2); return v; } После перехода с таблицы 90 градусов из 16385 float без апроксимации на CMSIS DSP спектр стал лучше Изменено 6 марта, 2021 пользователем GenaSPB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 235 7 марта, 2021 Опубликовано 7 марта, 2021 · Жалоба 8 часов назад, FatRobot сказал: Вы могли бы прикинуть SFDR для такого решения? Я практически не реализовывал его - не было надобности. Но вроде как если синус первых 2-х шагов рассчитан с достаточно большой точностью, то не ошибка не должна быстро накапливаться. 5 часов назад, Allregia сказал: У меня не залетает, во 1-х ввиду своего размера (оно вообще в ОЗУ не лезет, поэтому из феша, если не считать синус на ходу), во 2-х - ввиду отсусттвия кеша как такового. А что у Вас за МК? Я из контекста понял, что Cortex-M4. Но разве они бывают без кеша? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Allregia 9 7 марта, 2021 Опубликовано 7 марта, 2021 · Жалоба 4 hours ago, jcxz said: Я практически не реализовывал его - не было надобности. Но вроде как если синус первых 2-х шагов рассчитан с достаточно большой точностью, то не ошибка не должна быстро накапливаться. А что у Вас за МК? Я из контекста понял, что Cortex-M4. Но разве они бывают без кеша? STM32F427 8 hours ago, andyp said: Не очень понимаю, о чём разговор. Амплитудный спектр синуса - всегда две палки, симметричных относительно 0 . С учётом периодичности спектра дискретного сигнала, компонент окажется на частоте Fs-Fg. Fg - та частота, которую генерируете. Fs - частота дискретизации. Это в теории, а на практике - имеем два DDS генератора, работающие на те-же ЦАП/АЦП. Оба генерируют 20кгц при 48кгц семплирования. Оба дают алиас на 28кгц, но у первого он -90дб а у моего -20. Я тоже хочу -90, меня бы это вполне устроило. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
FatRobot 1 7 марта, 2021 Опубликовано 7 марта, 2021 · Жалоба Скажите, какая у вас схема измерений, что при частоте отсчетов 48ksps вы видите что-то на 28kHz? Скорее всего у вас что-то с фильтром после ЦАП 11 hours ago, Allregia said: Оба дают алиас на 28кгц, но у первого он -90дб а у моего -20. Я тоже хочу -90, меня бы это вполне устроило. Ясно-понятно. 16 hours ago, jcxz said: Я практически не реализовывал его - не было надобности. Но вроде как [...] с достаточно большой [...] не должна [...] Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Allregia 9 7 марта, 2021 Опубликовано 7 марта, 2021 · Жалоба 3 minutes ago, FatRobot said: Скажите, а как при частоте отсчетов 48ksps вы видите что-то на 28kHz? Ясно-понятно. См. выше - 48ksps это частота DDS+DAC, оцифровывается это потом АЦП на 96 или 192, потому 28 и видно :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
FatRobot 1 7 марта, 2021 Опубликовано 7 марта, 2021 · Жалоба фильтр после цап присутствует? 1 minute ago, Allregia said: См. выше - 48ksps это частота DDS+DAC, оцифровывается это потом АЦП на 96 или 192, потому 28 и видно :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться