Obniżenie ilości próbek

0

Witam!

Usiłuję napisać funkcję która obniży częstotliwość próbkowania sygnału "data" z "rate_in" na "rate_out":

int down_rate(double * data, int len, int rate_in, int rate_out){
	static double sum = 0;
	static int index = 0;
	int i1=0, i2=0;
	while(i1 < len){
		sum += data[i1++];
		index += rate_out;

		if(index < rate_in)
			continue;

		data[i2++] = sum / ((double)index / rate_out);
		index -= rate_out;
		sum = 0;
	}	
	return i2;
}

Obniżenie częstotliwości polega na uśrednieniu próbek tak aby ilość próbek wyjściowych była równa rate_in/rate_out razy mniejsza niż wejściowa.
Jednak mam wrażenie że algorytm nawala. Czy coś faktycznie z nią jest nie tak?

Kod pisałem z pamięci, więc przepraszam za ewentualne literówki.

0
        index+=rate_in; 
        if(index>=rate_out)
          {
           index-=rate_out; 
           data[i2++]=sum*rate_out/index;
           sum=0;
          }
0
_13th_Dragon napisał(a):
        index+=rate_in; 
        if(index>=rate_out)
          {
           index-=rate_out; 
           data[i2++]=sum*rate_out/index;
           sum=0;
          }

Warunek będzie zawsze spełniony bo:
rate_in(próbkowanie wejściowe do funkcji obniżającej) jest zawsze większe niż rate_out(wyjściowe próbkowanie), więc to nie to...

Jeżeli chcę obniżyć próbkowanie 2krotnie to:

int down_rate2(double * data, int len){
    static double sum = 0;
    static int index = 0;
    int i1=0, i2=0;
    while(i1 < len){
        sum += data[i1++];
        index  += 1 /* tutaj 1 - mniejsza wartość - rate_out */;
 
        if(index < 2 /* tutaj 2 - większa wartość - rate_in */)
            continue;
 
        data[i2++] = sum / 2;
        index -= 2;
        sum = 0;
    }    
    return i2;
}

Przyjmując:

rate_in = 2;
rate_out = 1;

Lecz dalej jest coś nie tak. Albo ostro pobłądziłem, albo mam błąd gdzieś indziej...

0
        index+=rate_out; 
        if(index>=rate_in)
          {
           index-=rate_in; 
           data[i2++]=sum*rate_in/index;
           sum=0;
          }
0
_13th_Dragon napisał(a):
        index+=rate_out; 
        if(index>=rate_in)
          {
           index-=rate_in; 
           data[i2++]=sum*rate_in/index;
           sum=0;
          }

Jeśli:

rate_in = 2;
rate_out = 1;

To dla tych wartości warunek będzie spełniony dla wartości

index = 2; // index jest zwiększany o 1

więc

rate_in/index -> 2/2 == 1

A powinno być dzielone przez 2
więc:

           data[i2++]=sum*rate_out/index;

Modyfikując lekko warunek, wyjdzie ten sam kod co w pierwszym moim poście.

0

Nie wyjdzie to samo, w twoim kodzie:

        index += rate_out;
        ...
        index -= rate_out;

czyli dodajesz i odejmujesz to samo. Nie zwracałem uwagę na przeliczenia. Oraz na index wyzerowany przed użyciem.
http://ideone.com/uRPcRl

#include <stdio.h>

size_t down_rate(double *data,size_t len,unsigned rate_in,unsigned rate_out)
  {
   double sum=0;
   size_t index=0,out=0,in=0;
   while(in<len)
     {
      sum+=data[in++];
      index+=rate_out; 
      if(index>=rate_in)
        {
         data[out++]=sum*rate_out/index;
         index-=rate_in;
         sum=0;
        }
     }    
   return out;
  }

int main()
  {
   double data[]={1,2,3,4,5,6,7,8,9,10};
   const size_t len=sizeof(data)/sizeof(*data);
   size_t i,nlen;
   for(i=0;i<len;++i) printf("%6.1lf",data[i]); printf("\n");
   nlen=down_rate(data,len,2,1);
   for(i=0;i<nlen;++i) printf("%6.1lf",data[i]); printf("\n");
   return 0;
  }
0
_13th_Dragon napisał(a):

Nie wyjdzie to samo, w twoim kodzie:

        index += rate_out;
        ...
        index -= rate_out;

No tak, błąd przy przepisywaniu na forum z pamięci. Czyli błąd mam gdzieś indziej...
Dzięki ;)

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