реклама на сайте
подробности

 
 
4 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Сдвиг сигнала на небольшое время (меньше интервала дискретизации).
AlexOr
сообщение Nov 20 2008, 12:44
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 89
Регистрация: 30-12-04
Из: Санкт-Петербург
Пользователь №: 1 754



Как осуществить сдвиг сигнала во временной области на небольшое время с наименьшими потерями по точности? Речь о временном ряде ограниченном по длине таким образом, что количество отсчетов кратно 2 в целой степени.

Время дискретизации - Td;
Требуемый сдвиг - Tsh;
Число отсчетов - N;

Есть идея для сдвига на произвольное время Tsh:
1. сделать дискретное преобразование Фурье
2. перевести полученные комплексные коэффициенты в показательную форму
3. изменить показатель(фазу) каждого коэффициента на соответствующий угол.
4. сделать обратное дискретное преобразование Фурье

Показатель(фазу) менять на величину k * 2 * PI * Tsh/ (Td * N), где k – номер коэффициента ДПФ. Таким образом показатель нулевого коэффициента не меняется, а первый и остальные меняются. Собственно тут производится сдвиг на одинаковое время всех спектральных составляющих сигнала.

Насколько правильна или неправильна такая идея?
Может быть есть другие варианты?
Go to the top of the page
 
+Quote Post
fontp
сообщение Nov 20 2008, 13:33
Сообщение #2


Эксперт
*****

Группа: Свой
Сообщений: 1 467
Регистрация: 25-06-04
Пользователь №: 183



Цитата(AlexOr @ Nov 20 2008, 15:44) *
Как осуществить сдвиг сигнала во временной области на небольшое время с наименьшими потерями по точности? Речь о временном ряде ограниченном по длине таким образом, что количество отсчетов кратно 2 в целой степени.

Время дискретизации - Td;
Требуемый сдвиг - Tsh;
Число отсчетов - N;

Есть идея для сдвига на произвольное время Tsh:
1. сделать дискретное преобразование Фурье
2. перевести полученные комплексные коэффициенты в показательную форму
3. изменить показатель(фазу) каждого коэффициента на соответствующий угол.
4. сделать обратное дискретное преобразование Фурье

Показатель(фазу) менять на величину k * 2 * PI * Tsh/ (Td * N), где k – номер коэффициента ДПФ. Таким образом показатель нулевого коэффициента не меняется, а первый и остальные меняются. Собственно тут производится сдвиг на одинаковое время всех спектральных составляющих сигнала.

Насколько правильна или неправильна такая идея?
Может быть есть другие варианты?


Оно может и правильно, только сдвиг наверно получется циклическим ))

Обычно делают не так:

1. Если нужно сдвигать на фиксированую дельту лучшие результаты получаются если применить полиморфную фильтрацию. Вставляют нули между реальными отсчетами и фильтруют хорошим НЧ фильтром - получается интерполяция на более мелкую сетку. Потом обратно прорежают под другой фазой (или даже частотой)

2. Если нужно двигать на произвольную дельту используют сплайн интерполяцию чаще кубическую.
В-сплайны
Go to the top of the page
 
+Quote Post
AlexOr
сообщение Nov 20 2008, 13:44
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 89
Регистрация: 30-12-04
Из: Санкт-Петербург
Пользователь №: 1 754



Цитата(fontp @ Nov 20 2008, 23:33) *
Оно может и правильно, только сдвиг наверно получется циклическим ))


Циклически даже хорошо. Главное чтоб это было правильно в принципе...
Go to the top of the page
 
+Quote Post
alex_os
сообщение Nov 20 2008, 14:06
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 521
Регистрация: 12-05-06
Пользователь №: 17 030



Цитата(AlexOr @ Nov 20 2008, 16:44) *
Циклически даже хорошо. Главное чтоб это было правильно в принципе...

А попробовать? Мне кажется какая-то засада есть в этой технологии, кроме циклического сдвига.


--------------------
ну не художники мы...
Go to the top of the page
 
+Quote Post
AlexOr
сообщение Nov 20 2008, 15:28
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 89
Регистрация: 30-12-04
Из: Санкт-Петербург
Пользователь №: 1 754



Уже...
Все работает на ура.

C#

Код
using System;
using System.Collections.Generic;
using System.Text;
using AP;

namespace _27corrector
{
    class Misc
    {

        //Сдвиг сигнала на произвольную величину
        //x - сигнал
        //offs - сдвиг выраженный в отсчетах
        public static double[] ShiftSignal(double[] x, double offs)
        {
            int N = x.Length;
            Complex[] s = new Complex[N];
            for (int n = 0; n < N; n++) s[n].real = x[n];
            s = Misc.DFT(s);
            //
            int j = N - 1;
            for (int k = 1; k < N / 2 + 1; k++)
            {
                double fi = System.Math.Atan2(s[k].image, s[k].real);
                double mod = AP.Math.AbsComplex(s[k]);
                fi += k * offs * 2 * System.Math.PI / N;
                s[k].real = mod * System.Math.Cos(fi);
                s[k].image = mod * System.Math.Sin(fi);
                //
                if (j != 0)
                {
                    s[j].real = s[k].real;
                    s[j].image = -s[k].image;
                }
                j--;
            }
            s = Misc.IDFT(s);
            double[] result = new double[N];
            for (int n = 0; n < N; n++) result[n] = s[n].real;
            return result;
        }

        //Прямое преобразование Фурье
        public static Complex[] DFT(Complex[] x)
        {
            int N = x.Length;
            Complex[] X = new Complex[N];
            for (int k = 0; k < N; k++)
            {
                for (int n = 0; n < N; n++)
                {
                    double fi = -2 * System.Math.PI * k * n / N;
                    Complex e = new Complex(System.Math.Cos(fi), System.Math.Sin(fi));
                    X[k] += x[n] * e;
                }
            }
            return X;
        }

        //Обратное преобразование Фурье
        public static Complex[] IDFT(Complex[] X)
        {
            int N = X.Length;
            Complex[] x = new Complex[N];
            for (int n = 0; n < N; n++)
            {
                for (int k = 0; k < N; k++)
                {
                    double fi = 2 * System.Math.PI * k * n / N;
                    Complex e = new Complex(System.Math.Cos(fi), System.Math.Sin(fi));
                    x[n] += X[k] * e;
                }
                x[n] /= N;
            }
            return x;
        }
    }
}


Сообщение отредактировал AlexOr - Nov 20 2008, 15:29
Go to the top of the page
 
+Quote Post
vadkudr
сообщение Nov 24 2008, 14:47
Сообщение #6


Участник
*

Группа: Новичок
Сообщений: 26
Регистрация: 20-11-07
Пользователь №: 32 502



А Fractional Delay Filters не пробовали?
Go to the top of the page
 
+Quote Post
Fat Robot
сообщение Nov 24 2008, 19:28
Сообщение #7


ʕʘ̅͜ʘ̅ʔ
*****

Группа: Свой
Сообщений: 1 008
Регистрация: 3-05-05
Пользователь №: 4 691



http://www.acoustics.hut.fi/~vpv/publicati...icassp00-fd.pdf

ну и в окрестностях посмотрите.

В приведенной статье методы перечислены в 2.1 и 2.2.

Успехов.
Go to the top of the page
 
+Quote Post
ivan219
сообщение Nov 24 2008, 21:13
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 350
Регистрация: 16-11-08
Пользователь №: 41 680



AlexOr

А в исходниках на Delphi есть???
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 24 2008, 21:46
Сообщение #9


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Применение для сдвига прямого и обратного FFT вероятно будет самым медленным из возможных алгоритмов. Хотя при желании можно придумать ещё более медленный smile.gif
ИМХО из самых скорострельных и достаточно точных алгоритмов для сдвига сигнала на любую дельту между отсчётами будет (почти как и предлагал fontp) пересчёт новых отсчётов сигнала по sinx/x. Для хорошей точности нового отсчёта достаточно посчитать свёртку в окресности 10..100 отсчётов. Желательно на нечётное кол-во, симметричное слева и справа. Итого будет N*K (K=10..100, а N=кол-во отсчётов) умножений и сложений. SinX/X для оптимизации быстродействия можно посчитать один раз для нужного сдвига и занести в таблицу.

Сообщение отредактировал GetSmart - Nov 24 2008, 22:04


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Stanislav
сообщение Nov 24 2008, 22:29
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 4 363
Регистрация: 13-05-05
Из: Москва
Пользователь №: 4 987



Цитата(fontp @ Nov 20 2008, 16:33) *
Оно может и правильно, только сдвиг наверно получется циклическим ))
И что из того?
Читайте условие внимательнее. Речь идёт о небольших сдвигах.
По моему скромному недомыслию, в пределах +/- 0,5 временнОй дискреты. smile.gif Больше не имеет смысла.
Впрочем, произвольная величина сдвига принципиального значения также не имеет.

Цитата(fontp @ Nov 20 2008, 16:33) *
1. Если нужно сдвигать на фиксированую дельту лучшие результаты получаются если применить полиморфную фильтрацию. Вставляют нули между реальными отсчетами и фильтруют хорошим НЧ фильтром - получается интерполяция на более мелкую сетку. Потом обратно прорежают под другой фазой (или даже частотой)
Если точность большая не нужна, это в некоторых случаях может оказаться и быстрее FFT, но если нужна - увы...

Цитата(fontp @ Nov 20 2008, 16:33) *
...2. Если нужно двигать на произвольную дельту используют сплайн интерполяцию чаще кубическую.
В-сплайны
Не понимаю всё же кардинальных преимуществ. sad.gif
Экстраполяцию или интерполяцию краевых участков после FFT-IFFT можно сделать аналогичным образом. Но это займёт гораздо меньше времени, чем полная сплайн-интерполяция, равно как и полиморфная фильтрация всего куска, если нужна мало-мальски приличная точность.
Могу продемонстрировать, как примерно надо делать подобные вещи. wink.gif

Цитата(GetSmart @ Nov 25 2008, 00:46) *
Применение для сдвига прямого и обратного FFT вероятно будет самым медленным из возможных алгоритмов.
Ох, Горе-Горькое...
Сдвиг через БПФ-ОБПФ - это самый быстрый и точный вариант алгоритма сдвига на произвольное время из всех возможных, скажем, для комплексных и полосовых сигналов.
В том числе, и способов, предложенных ув. fontp. Когда ж Вы за ум возьмётесь, наконец, и перестанете писать о вещах, далёких от Вашего понимания?..

Цитата(GetSmart @ Nov 25 2008, 00:46) *
...ИМХО из самых скорострельных и достаточно точных алгоритмов для сдвига сигнала на любую дельту между отсчётами будет (почти как и предлагал fontp) пересчёт новых отсчётов сигнала по sinx/x. Для хорошей точности нового отсчёта достаточно посчитать свёртку в окресности 10..100 отсчётов. Желательно на нечётное кол-во, симметричное слева и справа. Итого будет N*K (K=10..100, а N=кол-во отсчётов) умножений и сложений. SinX/X для оптимизации быстродействия можно посчитать один раз для нужного сдвига и занести в таблицу.
Америка открыта. biggrin.gif


--------------------
Самонадеянность слепа. Сомнения - спутник разума. (с)
Go to the top of the page
 
+Quote Post
petrov
сообщение Nov 25 2008, 08:58
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 220
Регистрация: 21-10-04
Из: Balakhna
Пользователь №: 937



Цитата(Stanislav @ Nov 25 2008, 01:29) *
Сдвиг через БПФ-ОБПФ - это самый быстрый и точный вариант алгоритма сдвига на произвольное время из всех возможных, скажем, для комплексных и полосовых сигналов.
В том числе, и способов, предложенных ув. fontp.


Слишком категорично, а если нужно каждый отсчёт на произвольное время сдвигать, в модемах как раз и используется обычно полифазная фильтрация совместно с интерполятором лагранжа.
Go to the top of the page
 
+Quote Post
Stanislav
сообщение Nov 25 2008, 09:12
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 4 363
Регистрация: 13-05-05
Из: Москва
Пользователь №: 4 987



Цитата(petrov @ Nov 25 2008, 11:58) *
Слишком категорично, а если нужно каждый отсчёт на произвольное время сдвигать, в модемах как раз и используется обычно полифазная фильтрация совместно с интерполятором лагранжа.
Ну, в условии же написано:
Цитата(AlexOr @ Nov 20 2008, 15:44) *
Как осуществить сдвиг сигнала во временной области на небольшое время с наименьшими потерями по точности?..

А как можно сдвинуть сигнал на произвольное время с наименьшими потерями по точности, я и не знаю, честно говоря...

Надо определиться, что вообще подразумевать под произвольным временнЫм сдвигом... Добавление/пропуск выборок допустимы, или сигнал всё же должен оставаться непрерывным?


--------------------
Самонадеянность слепа. Сомнения - спутник разума. (с)
Go to the top of the page
 
+Quote Post
fontp
сообщение Nov 26 2008, 08:12
Сообщение #13


Эксперт
*****

Группа: Свой
Сообщений: 1 467
Регистрация: 25-06-04
Пользователь №: 183



Цитата(GetSmart @ Nov 25 2008, 00:46) *
Применение для сдвига прямого и обратного FFT вероятно будет самым медленным из возможных алгоритмов. Хотя при желании можно придумать ещё более медленный smile.gif
ИМХО из самых скорострельных и достаточно точных алгоритмов для сдвига сигнала на любую дельту между отсчётами будет (почти как и предлагал fontp) пересчёт новых отсчётов сигнала по sinx/x. Для хорошей точности нового отсчёта достаточно посчитать свёртку в окресности 10..100 отсчётов. Желательно на нечётное кол-во, симметричное слева и справа. Итого будет N*K (K=10..100, а N=кол-во отсчётов) умножений и сложений. SinX/X для оптимизации быстродействия можно посчитать один раз для нужного сдвига и занести в таблицу.



Вот! Вы наверно открыли самый медленный! Считать длинную свертку с табличным синком wink.gif

Сдвиг через FFT - это в некотором смысле то же самое. Действительно: спектр умножается на чисто линейный фазовый вращатель, после обратного FFT имеем свёртку исходного сигнала с Фурье-преобразованием линейной фазовой экспоненты, т.е. СИНКОМ. В зависимости от длины блока мы имеем разные приближения к идеальной прямоугольной НЧ-фильтрации


Так и те общепринятые методы, что я предложил в начале имеют в основе, с разной степенью точности примерно то же самое:

-полиморфная фильтрация использует прямоугольный фильтр для интерполяции
-интерполяция В-сплайном может аппроксимировать тот же синк кусочным полиномом с конечным носителем


Полиморфная фильтрациия есть очень качественный, эффективный вычислительно и гибкий алгоритм для произвольного фиксированого (чтоб не менялся на лету) ресамплинга. Сдвиг есть частный тривиальный случай ресамплинга

У MDS были неплохие программы для каскодных алгоритмов ресамплинга (доступны, но больше не поддерживаются)
Для ресамплинга - это программа convern. Её можно найти в Сети, хоть и у меня ;-)
Те кто программирует процессоры AD Blackfin могут наслаждаться ассемблерной реализацией для каскодной схемы ресамплинга (многократный ресамплинг прорежение/интерполяция), рассчитываемой
этой программой MDS convern. Это Application Note AN- EE183.
Чтобы получить уровень искажений 100дб или выше фильры НЧ расчитываются с двойной точностью (32 разряда) и так же реализована фильтрация в программах для BF. Эта хренотень "измерительного" качества


теория мультирейта от MDS
http://www.mds.com/support/applicationnotes.asp

практика мультирейта от AD AN-813
http://www.analog.com/en/embedded-processi...rces/index.html
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 26 2008, 09:00
Сообщение #14


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(fontp)
Вот! Вы наверно открыли самый медленный! Считать длинную свертку с табличным синком wink.gif

Берём 64К сэмплов. Свёртка с синком по 20 точкам будет 64К*20 = 1280К умножений и сложений. FFT, сдвиг и IFFT будет 64К*(32+1+32) = 4160К умножений и сложений. Так что не факт, что медленнее FFT. А для миллиона сэмплов (для музыки и прочих сигналов это даже мало) короткая свёртка "порвёт" FFT на несколько кусочков biggrin.gif Про полиморфную фильтрацию не скажу, не знаю.

Кроме этого, "идеализм" FFT как свёртка по всей ширине блока ИМХО избыточна. Считать свёртку, когда функция sinx/x становится ниже шага амплитудной дискретизации, или значительно ниже уровня шумов бессмысленное занятие. Ну очень часто не нужна "экстремальная" точность. Тем более, что и у FFT своих глюков хватает.

PS. И лгавное - короткую свёртку легко делать в рилтайме не запоминая большие блоки сэмплов.

Сообщение отредактировал GetSmart - Nov 26 2008, 09:41


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
fontp
сообщение Nov 26 2008, 09:40
Сообщение #15


Эксперт
*****

Группа: Свой
Сообщений: 1 467
Регистрация: 25-06-04
Пользователь №: 183



Цитата(GetSmart @ Nov 26 2008, 12:00) *
Кроме этого, "идеализм" FFT как свёртка по всей ширине блока ИМХО избыточна. Считать свёртку, когда функция sinx/x становится ниже шага амплитудной дискретизации, или значительно ниже уровня шумов бессмысленное занятие. Ну очень часто не нужна "экстремальная" точность. Тем более, что и у FFT своих глюков хватает.


Ну, синк, конечно, затухает. Но медленно. Как sinc(2*pi*dF*t) Полоса решает, но полоса определяется той фрактальностью, которая должна быть получена, нет здесь свободы wink.gif
Соответственно, если для эффективности нужен фильтр НЧ и покороче и получше, то лучше тогда его синтезировать в Матлабе, а не синк усекать. Как прямоугольный фильтр минимальной длины с максимальной крутизной среза. Вот и получится как раз фильтр, используемый при полиморфной фильтрации. При этом возможен только рациональный ресамплинг, N/M, свои недостатки.

А кубическая синковые сплайн-интерполяция по четырем точкам, наоборот, заведомо самая быстрая, даёт любые сдвиги, но с большими ошибками. Для кого-то и сгодится, а для кого-то - нет. Компания TRW делала 20 лет быстродействующие синковые сплайн-интерполяторы для "произвольного"
ресамплинга сигналов/изображений
Модемщики, правда, обычно не видят синковых интерполяторов, а пользуют лагранжа (без хвостов), поскольку к моменту их использования частота сэмлинга уже в несколько раз (4-8) выше Найквиста

Нет в мире совершенства...
Go to the top of the page
 
+Quote Post

4 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd June 2025 - 20:07
Рейтинг@Mail.ru


Страница сгенерированна за 0.01521 секунд с 7
ELECTRONIX ©2004-2016