[C] DSP - FM, triangle

0

Potrzebuję funkcji:
double triangle(double x,double amp,double freq);
która generuje falę trójkątną, o danej amplitudzie i częstotliwości.
Potrzebuję również funkcji która przeprowadzi FM dla danych funkcji.
Szukałem, ale zawsze zamiast FM otrzymuję PM. Czy ktoś wie jak to zaimplementować?
((FM potrzebuje chyba dodatkowego parametru niż PM lub AM - dewiacja?? - ktoś wie coś więcej?))

0

Rozumiem, że fukcja ma zwracać próbkę w czesie x? Jak usiądę do kompa z kompilatorem to to napiszę. I co masz na myśli pod FM? Modulację częstotliwościową?

PS. Musi być w C czy może być w C++?

0

Może być w C++.
x oznacza czas
FM Frequency Modulation - modulacja czestotliwości. Tak chodzi mi o to.
Dla przykłady PM obliczam tak

f1(x) - fala nośna
f2(x) - fala modulująca (sygnał)
pm(x)=func1(x+func2(x))
Czyli widać przesunięcie w fazie.

0

Zrobiłem już kod na piłę, ale do trójkąta trochę brakuje...

0

No i napisałem

inline double modulo(double a, double b)
{
 int result = static_cast<int>( a / b );
 float mod = a - static_cast<double>( result ) * b;
 return mod;
}

bool prostokat(double x,double freq)
{
 double okres = 1/freq ;
 double mod = modulo(x, okres);
 double przeskalowane_mod = mod / okres;
 if(przeskalowane_mod > 0.5) return 1;
 else return 0;
}

double pila(double x,double amp,double freq)
{
 double okres = 1/freq ;
 double mod = modulo(x, okres);
 double przeskalowane_mod = mod / okres;
 double pila = przeskalowane_mod * amp;
 return pila;
}

double triangle(double x,double amp,double freq)
{
 double _pila = pila(x,amp,freq);
 bool inwersja = prostokat(x,freq/2);
 double trojkat;
 if(inwersja) trojkat = amp-_pila;
 else         trojkat =     _pila;
 return trojkat;
}

Funkcja działa poprawnie tylko dla dodatnich x, zwraca wartość od 0 do amp!

Z FM będzie trochę gorzej, bo sama zmiana częstotliwości spowoduje przeskok w fazie... Ale coś się wymyśli.

A z ciekawości: Co tak w ogóle piszesz?

0

Dzięki. Mogą być problemy z rzutowaniem w modulo, ale coś wymyślę. (only C)
Na razie jest to prosta aplikacja wizualizująca. Są 3 wykresy: 2 z nich to funkcje sin square triangle, z ustawianą częstotliwością i amplitudą, a trzeci to ich AM, FM, PM, lub suma. Parametry ustawia się suwakami i od razu wykresy są aktualizowane. Używam GTK+, koduję pod Linuksem. Może potem zrobię filtry. Potem zabiorę się za syntezę dźwięku.

0

Znalazłem małego buga w mojej funkcji - a bug wygląda tak:
http://w811.wrzuta.pl/obraz/azRJ4eJZTY4/bug
http://w811.wrzuta.pl/obraz/9w8SPieUoRW/bug2

Może wynika o z małego rozsynchronizowania funkcji na piłę i na prostokąt... Albo z błędów zmiennoprzecinkowych. W każdym razie w większy powiększeniu nie zauważyłem aby ten pik był szerszy...

PS. rzutowanie static_cast można chyba przerobić na normalne C...

0

Witam!

Po pierwsze różnica pomiędzy FM i PM będzie minimalna. Powiedzmy że będzie pewne opóźnienie pomiędzy FM a PM, no i ewentualnie różnica w dewiacji.

Jeśli chodzi o wytworzenie sygnału y(t) zmodulowanego sygnałem m(t) to spróbował bym np takiej zależności:

y(t) = Asin(2pi*(f+(m(t)*Df/m_max))*t)

Wzór napisałem teraz z głowy i różni się od tego co piszą w książkach. Zaraz napiszę jakiś szybki testowy programik.

0

Triangle działa.
http://img831.imageshack.us/img831/8420/graphc.png
ale tylko tak.
Pobawię się z piłą. Może coś wyjdzie.
Na FM widziałem sporo wzorów, i nie było zgodności.
PS. Rysujesz punktym czy linie między punktami?

0

Jeśli chodzi o mnie to piszę w Qt, a wykresy robię w qwt.

Qt - http://qt.nokia.com
qwt - http://qwt.sourceforge.net

Polecam.

0
rafal44 napisał(a)

Triangle działa.
http://img831.imageshack.us/img831/8420/graphc.png
ale tylko tak.
Pobawię się z piłą. Może coś wyjdzie.
Na FM widziałem sporo wzorów, i nie było zgodności.
PS. Rysujesz punktym czy linie między punktami?
jesli chodxi o ten przebieg to to jest pila. u mnie funkcja dziala ok, przypominam, w zakresie dodatnich x.

0

Tak, to jest piła. Opierając się na Twoim pomyśle napiszę od początku. Będę się opierał na sin, aby czestotliwość się zgadzała. Square też napisałem opierając się na sin. Potem zobaczę FM.

Kurde, ale mi się nie chce...........eh

0

O i działa:

double modulo(double a,double b)
{
	int result =(int)floor(a/b);
	return a-(double)(result*b);
}

double saw(double x,double amp,double freq)
{
	double okres=1/freq;
	double mod=modulo(x,okres);
	double pmod=mod/okres;
	return pmod*amp*2-amp;
}
double triangle(double x,double amp,double freq)
{
	double temp=saw(x,amp,freq/M_PI);
	if(sin(x*freq)<0) return -temp;
	return temp;
}

Teraz mogę spać spokojnie.

0

A nie lepiej napisać funkcję która zapełni jakąś tam tablicę próbkami?

0
m15ch4 napisał(a)

A nie lepiej napisać funkcję która zapełni jakąś tam tablicę próbkami?
nie lepiej. tak mozna dowolnie ustawic rozdzielczosc, a przy tablicy sie nie da.

0

olo16: raczej można.

Deklaracja funkcji:
void triangle(double *buf, double freq, double amp, int len);

Ewentualnie możesz sobie jeszcze jako parametr podawać częstotliwość próbkowania.

0

Ale tablica zajmuje pamięć. W wynikowym programie można pomyśleć:

  • tablica - narzut na pamięć
    vs
  • ciągłe wywoływanie - narzut na czas

Ale do testów lepsze jest ciągłe wywoływanie. Dlaczego? Bo te funkcje mają odzwiercielać funkcje matemetyczne. A funkcje matemetyczne są BEZSTANOWE. W funkcji z ciągłym wywoływaniem od razu widać korzystanie ze zmiennych globalnych i static, i że funkcja jest zła. A w wersji generującej tablicę tego może tego nie być widać - i można zrobić niematematycznego potworka.

Poza tym funkcje próbkowe można w szybko przerobić na tablicowe w razie potrzeby.

0

Jest jeszcze jedna sprawa - czy chce się uaktualniać wykres punkt po punkcie czy wygenerować dane i narysować wykres za jednym razem?

Poza tym jeśli chce się sygnał obrabiać w jakiś sposób (np. filtrować albo po prostu liczyć fft) to lepiej mieć jakąś porcję danych i ją obrabiać niż dla każdej próbki wywoływać funkcję generującą.

Jeśli wygenerowany sygnał chce się odtworzyć to też zwykle zapełnia się bufor karty muzycznej jakąś porcją danych (a nie jedną próbką) i dopiero się "daje sygnał" do odtworzenia. Podobnie jest z nagrywaniem.

Może matematycznie funkcje takie to "potworki" ale praktycznie tak się robi. Osobiście nigdy nie widziałem żeby program do cyfrowego przetwarzania sygnałów składał się z funkcji jakie ty proponujesz.

Pozdrawiam.

0

Przeczytaj uważnie. Napisałem że w wynikowym programie to ma sens, ale do testów lepsze są funkcje próbkowo - właśnie dlatego żeby nie robić matematycznych potworków. A przerobienie funkcji próbkowej na tablicową to 5 minut...

1 użytkowników online, w tym zalogowanych: 0, gości: 1