• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

C Code frage

xorg1990

New member
Ich habe mal kurz eine frage zu eien C code snippet wo ich nicht durchblicke.

Code:
struct FIR {
    float *coeffs;
    int filterLength;
    float *delay_line;
};

typedef struct _cpx {
	float re;
	float im;
} TYPECPX;

struct cFIR {
    float *coeffs;
    int filterLength;
    TYPECPX *delay_line;
	float rms;


struct cFIR* init_cfir( int coeffs_len, float *coeff_tab ) 
{
	struct cFIR *result;
	int i;
	// alloc and init buffers
	result = (struct cFIR *)malloc( sizeof( struct cFIR ));
	result->filterLength = coeffs_len ;
	result->coeffs = (float*)malloc( coeffs_len * sizeof( float));
	result->delay_line = (TYPECPX*)malloc( coeffs_len * sizeof( TYPECPX));
	// copy coeffs to struct
	for( i=0 ; i < coeffs_len ; i++ ) {
		result->delay_line[i].re = 0.0;
		result->delay_line[i].im = 0.0;
		result->coeffs[i] = coeff_tab[i];
	}
	return( result );
}


TYPECPX cfir_filt( struct cFIR* f, TYPECPX in ) 
{
	int i;
	TYPECPX acc; 
	float *pt_coeffs, rms;
	TYPECPX *pt_sample;
	int L;
	
	// shift input left for one sample
	L = f->filterLength;
	for( i=0 ; i < L - 1 ; i++ ){
		 f->delay_line[i] = f->delay_line[i+1];
	}
	// add new sample to the end of delay line
	f->delay_line[ L - 1 ] = in;
};

Die Frage ist was passiert hier:
Code:
for( i=0 ; i < L - 1 ; i++ ){
		 f->delay_line[i] = f->delay_line[i+1];
	}

f zeigt auf delay_line was in init_cFIR angelegt wurde. Aber delay line ist doch Complex müsste die schleife nicht durch delay_line.im und delay_line.re laufen.
Und wieso überhaupt result->delay_line.re = 0.0; und nicht result->delay_line.re = 0.0;?

Wie müste die Berechnug in JS aussehen so:

Code:
function init_cFIR(coeffsLength, t){
		this.cFIR = {};
		var filtLength = coeffsLength;
		var delayLine = {};
		delayLine.prototype.re = new Float32Array(filtLength);
		delayLine.prototype.im = new Float32Array(filtLength);
		var coeffs =  new Float32Array(filtLength);
		for(var i=0;i<filtLength;i++){
			delayLine.re[i] = 0.0;
			delayLine.im[i] = 0.0;
			coeffs[i] = t[i];
		}
		this.cFIR.delayLine = delayLine;
		this.cFIR.coeffs = coeffs;


und dann?so?:
Code:
function cfir_filt(cFIR, inp){
	var i;
	cplx.im = 0.0;
	cplx.re = 0.0;
	var coeffs_ptr = 0;
	var sample_ptr = 0;
	for(i=0;i<filtLength-1;i++){
			delayLine.re[i] = delayLine.re[i+1];
			delayLine.im[i] = delayLine.im[i+1];	
		}
	delayLine.re[filtLength-1] = inp.re;
    delayLine.im[filtLength-1] = inp.im;
 
Die Frage ist was passiert hier:
Code:
for( i=0 ; i < L - 1 ; i++ ){
		 f->delay_line[i] = f->delay_line[i+1];
	}
f->delay_line ist ein array von instanzen des typs _cpx. hier wird alles einen index nach vorne kopiert

f zeigt auf delay_line was in init_cFIR angelegt wurde. Aber delay line ist doch Complex
f ist eine array

müsste die schleife nicht durch delay_line.im und delay_line.re laufen.
das sind keine arrays sondern floats

Code:
typedef struct _cpx {
	float re;
	float im;
} TYPECPX;

Wie müste die Berechnug in JS aussehen
in js hättest du ein object
Code:
{
  re: 0.0,
  im: 0.0,
}
und davon ein array. das kannst du aber auch problemlos als ein objekt mit 2 arrays umschreiben. ist in js vermutlich effizienter

Code:
function init_cFIR(coeffsLength, t)
{
    var filtLength = coeffsLength;
    var delayLine = {};
    delayLine.re = new Float32Array(filtLength);
    delayLine.im = new Float32Array(filtLength);
    var coeffs = Float32Array.from(t);
    return {
      coeffs: coeffs,
      filtLength: coeffsLength,
      delayLine: delayLine
    }

Code:
function cfir_filt(cFIR, inp){
  for( var i = 0 ; i < cFIR.filtLength - 1 ; i++ )
  {
     cFIR.delayLine.re[i] = cFIR.delayLine.re[i+1];
     cFIR.delayLine.im[i] = cFIR.delayLine.im[i+1];
  }
  cFIR.delayLine.re[i] = inp.re; // inp muss aber ein objekt mit den eigenschaften re und im bleiben oder du gibst re und im als parameter rein
  cFIR.delayLine.im[i] = inp.im;
};
 
Zuletzt bearbeitet:
Die Frage ist was passiert hier:
Hier werden die komplexen Zahlen um eines weiter geschoben. Du könntest auch den realen und den imaginären Teil separat verschieben/kopieren, aber das wäre mehr Arbeit. So verschiebst du das komplette Objekt und musst nur einen Pointer verändern.

Und wieso überhaupt result->delay_line.re = 0.0; und nicht result->delay_line.re = 0.0;?

delay_line ist ist ein Array von komplexen Zahlen und nicht ein Objekt, das zwei Arrays enthält.

In JS kannst du das natürlich auch anders herum machen, aber das mit dem .prototype ist falsch.
 
Hm so langsam dämmert's. aber noch nicht ganz.

Das hier der Inhalt um eins weiter geschoben wird weiß ich( steht ja auch in den Komentaren;))
Code:
for( i=0 ; i < L - 1 ; i++ ){
		 f->delay_line[i] = f->delay_line[i+1];
	}
in der ersten loop ist das so
Code:
for( i=0 ; i < coeffs_len ; i++ ) {
		result->delay_line[i].re = 0.0;
		result->delay_line[i].im = 0.0;
		result->coeffs[i] = coeff_tab[i];
	}

Warum reicht es aus nur ein "Rechenoperation" zu machen und nicht etwa so:
Code:
for( i=0 ; i < L - 1 ; i++ ){
                f->delay_line[i].re = f->delay_line[i+1].re
		f->delay_line[i].im = f->delay_line[i+1].im
	}
Würde das nicht genau de selbe tun??

genau so wie hier:
f->delay_line[ L - 1 ].im = in->im;
f->delay_line[ L - 1 ].re = in->re;


tsseh hat es ja schon schön beschriben
Code:
  cFIR.delayLine.re[i] = inp.re; // inp muss aber ein objekt mit den eigenschaften re und im bleiben oder du gibst re und im als parameter rein
  cFIR.delayLine.im[i] = inp.im;
So sehe ich das auch ein.

kkapsner schrieb:
aber das mit dem .prototype ist falsch.
Jo, schon gesehen.
 
Zuletzt bearbeitet:
Das hier der Inhalt um eins weiter geschoben wird weiß ich( steht ja auch in den Komentaren;))
du hast gefragt

in der ersten loop ist das so
initialisierung

Warum reicht es aus nur ein "Rechenoperation" zu machen und nicht etwa so:
vergiß das durchgestrichene oder lies es dir erst gar nicht durch, delay_line ist überhaupt kein pointer-array, das hatte ich falsch in erinnerung
ist durch die pointer genau wie in js, du kannst
var x = [{re:0, im:0}, {re:0, im:0}];
x[0]=x[1];
oder
x[0].re = x[1].re;
x[0].im = x[1].im;
schreiben.
im 1. fall weist du x[0] das objekt x[1] zu, wobei x[0] in js und c hier nur ein pointer auf das objekt ist. in js ist das nur versteckt und du merkst es erst, wenn du den inhalt von x[0] änderst.
damit hast du hier einen unterschied zu c, dort werden die werte vom objekt x[1] an die speicherstelle von x[0] kopiert, in js zeigt der versteckte pointer von x[0] auf das objekt auf welches auch x[1] zeigt.
im 2. fall kopierst du die werte im objekt
 
Zuletzt bearbeitet:
Zurück
Oben