00001
00006 #include <bpm/bpm_wf.h>
00007
00008 intwf_t* intwf( int ns, double fs ) {
00009
00010 intwf_t *w;
00011
00012 if ( fs <= 0 ) {
00013 bpm_error( "Cannot have sampling frequency <= 0. in intwf()",
00014 __FILE__, __LINE__ );
00015 return NULL;
00016 }
00017
00018 if ( ns > MAX_ALLOWED_NS ) {
00019 bpm_error( "Maximum allowed number of samples exceeded, failed to allocate.",
00020 __FILE__, __LINE__ );
00021 return NULL;
00022 }
00023
00024 if ( ns > 1 ) {
00025 w = (intwf_t*) calloc( 1, sizeof(intwf_t) );
00026 if ( ! w ) {
00027 bpm_error( "Cannot allocate memory for waveform structure in intwf()",
00028 __FILE__, __LINE__ );
00029 return NULL;
00030 }
00031 w->ns = ns;
00032 w->fs = fs;
00033 w->wf = (int*) calloc( w->ns, sizeof( int ) );
00034 if ( ! w->wf ) {
00035 bpm_error( "Cannot allocate memory for waveform data in intwf()",
00036 __FILE__, __LINE__ );
00037 free( w );
00038 return NULL;
00039 }
00040 } else {
00041 bpm_error( "Invalid number of samples in intwf()", __FILE__, __LINE__ );
00042 return NULL;
00043 }
00044
00045 return w;
00046 }
00047
00048
00049
00050 intwf_t* intwf_sample_series( int ns, double fs ) {
00051
00052 int i = 0;
00053 intwf_t *w = intwf( ns, fs );
00054
00055 if ( ! w ) return w;
00056 for ( i=0; i<w->ns; i++ ) w->wf[i] = i;
00057
00058 return w;
00059 }
00060
00061
00062
00063 intwf_t* intwf_copy_new( intwf_t *w ) {
00064
00065 int i = 0;
00066 intwf_t *s = intwf( w->ns, w->fs );
00067
00068 if ( ! s ) {
00069 bpm_error( "Cannot allocate memory in intwf_copy_new()",
00070 __FILE__, __LINE__ );
00071 return NULL;
00072 };
00073
00074 for ( i=0; i<w->ns; i++ ) s->wf[i] = w->wf[i];
00075
00076 return s;
00077 }
00078
00079
00080
00081 int intwf_copy( intwf_t *copy, intwf_t *src ) {
00082
00083 int i = 0;
00084
00085 if ( ! copy || ! src ) {
00086 bpm_error( "Invalid pointer arguments in intwf_copy()", __FILE__, __LINE__ );
00087 return BPM_FAILURE;
00088 };
00089
00090 if ( intwf_compat( copy, src ) ) {
00091 for ( i=0; i<copy->ns; i++ ) copy->wf[i] = src->wf[i];
00092 } else {
00093 bpm_error( "Incompatible waveforms for in intwf_copy()", __FILE__, __LINE__ );
00094 return BPM_FAILURE;
00095 }
00096
00097 return BPM_SUCCESS;
00098 }
00099
00100
00101
00102 int intwf_subset( intwf_t *sub, intwf_t *w, int i1, int i2 ) {
00103
00104 int i = 0;
00105
00106 if ( ! sub || ! w ) {
00107 bpm_error( "Invalid pointer arguments in intwf_subset()", __FILE__, __LINE__ );
00108 return BPM_FAILURE;
00109 };
00110
00111
00112 sub->ns = 0;
00113 sub->fs = w->fs;
00114
00115 for ( i=MAX(0,i1); i<=MIN(w->ns-1,i2); i++ ) {
00116 sub->wf[i] = w->wf[i-i1];
00117 sub->ns++;
00118 }
00119
00120
00121 return BPM_SUCCESS;
00122 }
00123
00124
00125
00126 int intwf_setvalues( intwf_t *w, int *x ) {
00127
00128 int i = 0;
00129 if ( ! w || ! x ) {
00130 bpm_error( "Invalid pointer arguments in intwf_setvalues()",
00131 __FILE__, __LINE__ );
00132 return BPM_FAILURE;
00133 }
00134
00135 for ( i=0; i<w->ns; i++ ) w->wf[i] = x[i];
00136
00137 return BPM_SUCCESS;
00138 }
00139
00140
00141
00142 int intwf_setfunction( intwf_t *w,
00143 int (*wffun)( double, int, double* ),
00144 int npars, double *par ) {
00145
00146 int i = 0;
00147 if ( ! w || ! wffun ) {
00148 bpm_error( "Invalid pointer arguments in intwf_setfunction()",
00149 __FILE__, __LINE__ );
00150 return BPM_FAILURE;
00151 }
00152
00153 for ( i=0; i<w->ns; i++ ) w->wf[i] = (*wffun)( (double) i / w->fs, npars, par );
00154
00155 return BPM_SUCCESS;
00156 }
00157
00158
00159
00160 int intwf_reset( intwf_t *w ) {
00161
00162 int i = 0;
00163
00164 if ( ! w ) {
00165 bpm_error( "Invalid pointer argument in intwf_reset()",
00166 __FILE__, __LINE__ );
00167 return BPM_FAILURE;
00168 }
00169
00170 for ( i=0; i<w->ns; i++ ) w->wf[i] = 0;
00171
00172 return BPM_SUCCESS;
00173 }
00174
00175
00176
00177 void intwf_delete( intwf_t *w ) {
00178
00179 if ( w ) {
00180 if ( w->wf ) free( w->wf ); else
00181 bpm_warning( "Cannot free intwf_t::wf pointer in intwf()_delete, already NULL !",
00182 __FILE__, __LINE__ );
00183 free( w );
00184 } else {
00185 bpm_warning( "Cannot free intwf_t pointer in intwf()_delete, already NULL !",
00186 __FILE__, __LINE__ );
00187 }
00188
00189 return;
00190 }
00191
00192
00193
00194 doublewf_t* doublewf_cast_new( intwf_t *iw ) {
00195
00196 int i = 0;
00197 doublewf_t *w;
00198
00199 if ( ! w ) {
00200 bpm_error( "Invalid pointer argument in doublewf_cast_new()",
00201 __FILE__, __LINE__ );
00202 return NULL;
00203 }
00204
00205 w = doublewf( iw->ns, iw->fs );
00206 if ( ! w ) {
00207 bpm_error( "Cannot allocate memory for doublewf_t in doublewf_cast_new()",
00208 __FILE__, __LINE__ );
00209 return NULL;
00210 }
00211
00212
00213 for (i=0;i<iw->ns;i++) w->wf[i] = (double) iw->wf[i];
00214
00215 return w;
00216 }
00217
00218
00219
00220 int doublewf_cast( doublewf_t *w, intwf_t *iw ) {
00221
00222 int i = 0;
00223
00224 if ( ! w || ! iw ) {
00225 bpm_error( "Invalid pointer argument in doublewf_cast()",
00226 __FILE__, __LINE__ );
00227 return BPM_FAILURE;
00228 }
00229
00230
00231 for (i=0;i<iw->ns;i++) w->wf[i] = (double) iw->wf[i];
00232
00233 return BPM_SUCCESS;
00234 }
00235
00236
00237
00238 int intwf_compat( intwf_t *w1, intwf_t *w2 ) {
00239
00240 if ( ! w1 || ! w2 ) {
00241 bpm_error( "Invalid pointer arguments in intwf_compat()",
00242 __FILE__, __LINE__ );
00243 return 0;
00244 }
00245
00246 return ((w1->ns==w2->ns)&&(fabs(w1->fs-w2->fs)<WF_EPS)?1:0);
00247 }
00248
00249
00250
00251 int intwf_add( intwf_t *w1, intwf_t *w2 ) {
00252
00253 int i = 0;
00254
00255 if ( ! w1 || ! w2 ) {
00256 bpm_error( "Invalid pointer arguments in intwf_add()",
00257 __FILE__, __LINE__ );
00258 return BPM_FAILURE;
00259 }
00260
00261 if ( ! intwf_compat( w1, w2 ) ) {
00262 bpm_warning( "Incompatible waveforms in intwf_add()", __FILE__, __LINE__ );
00263 }
00264 for ( i=0; i < MIN(w1->ns,w2->ns); i++ ) w1->wf[i] += w2->wf[i];
00265
00266 return BPM_SUCCESS;
00267 }
00268
00269
00270
00271 int intwf_subtract( intwf_t *w1, intwf_t *w2 ) {
00272
00273 int i = 0;
00274
00275 if ( ! w1 || ! w2 ) {
00276 bpm_error( "Invalid pointer arguments in intwf_subtract()",
00277 __FILE__, __LINE__ );
00278 return BPM_FAILURE;
00279 }
00280
00281 if ( ! intwf_compat( w1, w2 ) ) {
00282 bpm_warning( "Incompatible waveforms in intwf_subtract()", __FILE__, __LINE__ );
00283 }
00284 for ( i=0; i < MIN(w1->ns,w2->ns); i++ ) w1->wf[i] -= w2->wf[i];
00285
00286 return BPM_SUCCESS;
00287 }
00288
00289
00290
00291 int intwf_multiply( intwf_t *w1, intwf_t *w2 ) {
00292
00293 int i = 0;
00294
00295 if ( ! w1 || ! w2 ) {
00296 bpm_error( "Invalid pointer arguments in intwf_multiply()",
00297 __FILE__, __LINE__ );
00298 return BPM_FAILURE;
00299 }
00300
00301 if ( ! intwf_compat( w1, w2 ) ) {
00302 bpm_warning( "Incompatible waveforms in intwf_multiply()",
00303 __FILE__, __LINE__ );
00304 }
00305
00306 for ( i=0; i < MIN(w1->ns,w2->ns); i++ ) w1->wf[i] *= w2->wf[i];
00307
00308 return BPM_SUCCESS;
00309 }
00310
00311
00312
00313 int intwf_divide( intwf_t *w1, intwf_t *w2 ) {
00314
00315 int i = 0;
00316
00317 if ( ! w1 || ! w2 ) {
00318 bpm_error( "Invalid pointer arguments in intwf_divide()",
00319 __FILE__, __LINE__ );
00320 return BPM_FAILURE;
00321 }
00322
00323 if ( ! intwf_compat( w1, w2 ) ) {
00324 bpm_warning( "Incompatible waveforms in intwf_divide()",
00325 __FILE__, __LINE__ );
00326 }
00327
00328 for ( i=0; i < MIN(w1->ns,w2->ns); i++ ) {
00329 if ( w2->wf[i] != 0. ) {
00330 w1->wf[i] /= w2->wf[i] ;
00331 } else {
00332 bpm_warning( "Trapped division by 0. in intwf_divide()",
00333 __FILE__, __LINE__ );
00334 w1->wf[i] = 0.;
00335 }
00336 }
00337
00338 return BPM_SUCCESS;
00339 }
00340
00341
00342
00343 int intwf_scale( int f, intwf_t *w ) {
00344
00345 int i = 0;
00346
00347 if ( ! w ) {
00348 bpm_error( "Invalid pointer argument in intwf_scale()",
00349 __FILE__, __LINE__ );
00350 return BPM_FAILURE;
00351 }
00352
00353 for ( i=0; i<w->ns; i++ ) w->wf[i] *= f;
00354
00355 return BPM_SUCCESS;
00356 }
00357
00358
00359
00360 int intwf_bias( int c, intwf_t *w ) {
00361
00362 int i = 0;
00363
00364 if ( ! w ) {
00365 bpm_error( "Invalid pointer argument in intwf_bias()",
00366 __FILE__, __LINE__ );
00367 return BPM_FAILURE;
00368 }
00369
00370 for ( i=0; i<w->ns; i++ ) w->wf[i] += c;
00371
00372 return BPM_SUCCESS;
00373 }
00374
00375
00376
00377 int intwf_add_cwtone( intwf_t *w, double amp, double phase, double freq,
00378 double phasenoise ) {
00379
00380 int i = 0;
00381
00382 if ( ! w ) {
00383 bpm_error( "Invalid pointer argument in intwf_add_cwtone()",
00384 __FILE__, __LINE__ );
00385 return BPM_FAILURE;
00386 }
00387
00388 for (i=0; i<w->ns; i++ )
00389 w->wf[i] += (int) dround ( amp * cos( 2. * PI * freq * (double) i / w->fs +
00390 nr_rangauss( phase, phasenoise ) ) );
00391
00392 return BPM_SUCCESS;
00393 }
00394
00395
00396
00397 int intwf_add_dcywave( intwf_t *w, double amp, double phase, double freq,
00398 double ttrig, double tdcy, double phasenoise ) {
00399
00400 int i = 0;
00401 double t = 0.;
00402
00403 if ( ! w ) {
00404 bpm_error( "Invalid pointer argument in intwf_add_dcywave()",
00405 __FILE__, __LINE__ );
00406 return BPM_FAILURE;
00407 }
00408
00409 for (i=0; i<w->ns; i++ ) {
00410 t = (double) i / w->fs;
00411 if ( t >= ttrig ) {
00412 w->wf[i] += (int) dround( amp * exp( -( t - ttrig ) / tdcy ) *
00413 cos( 2. * PI * freq * ( t - ttrig ) +
00414 nr_rangauss( phase, phasenoise ) ) );
00415 }
00416 }
00417
00418 return BPM_SUCCESS;
00419 }
00420
00421
00422
00423 int intwf_add_ampnoise( intwf_t *w, double sigma ) {
00424
00425 int i = 0;
00426
00427 if ( ! w ) {
00428 bpm_error( "Invalid pointer argument in intwf_add_ampnoise()",
00429 __FILE__, __LINE__ );
00430 return BPM_FAILURE;
00431 }
00432
00433 for (i=0; i<w->ns; i++ ) {
00434 w->wf[i] += (int) dround( nr_rangauss( 0., sigma ) );
00435 }
00436
00437 return BPM_SUCCESS;
00438
00439 }
00440
00441
00442
00443 int intwf_basic_stats( intwf_t *w, int s0, int s1, wfstat_t *stats ) {
00444
00445 doublewf_t *dw = NULL;
00446
00447 if ( ! w || ! stats ) {
00448 bpm_error( "Invalid pointer arguments in intwf_basic_stats()",
00449 __FILE__, __LINE__ );
00450 return BPM_FAILURE;
00451 }
00452
00453 dw = doublewf_cast_new( w );
00454 if ( ! dw ) {
00455 bpm_error( "Cannot allocate memory for temporary doublewf in intwf_basic_stats",
00456 __FILE__, __LINE__ );
00457 return BPM_FAILURE;
00458 }
00459
00460 if ( doublewf_basic_stats( dw, s0, s1, stats ) ) return BPM_FAILURE;
00461
00462 doublewf_delete( dw );
00463
00464 return BPM_SUCCESS;
00465 }
00466
00467
00468
00469 int intwf_derive( intwf_t *w ) {
00470
00471 int i = 0;
00472 double dt = 0;
00473
00474 if ( ! w ) {
00475 bpm_error( "Invalid pointer argument in intwf_derive()",
00476 __FILE__, __LINE__ );
00477 return BPM_FAILURE;
00478 }
00479
00480
00481 dt = 1./w->fs;
00482
00483
00484 for ( i=0; i<w->ns-1; i++ ) w->wf[i] = (int) dround( ( w->wf[i+1] - w->wf[i] ) / dt );
00485
00486
00487 w->wf[w->ns-1] = w->wf[w->ns-2];
00488
00489 return BPM_SUCCESS;
00490 }
00491
00492
00493
00494 int intwf_integrate( intwf_t *w ) {
00495
00496 double tmp = 0., tmp_prev = 0.;
00497 double dt = 0.;
00498 int i = 0;
00499
00500 if ( ! w ) {
00501 bpm_error( "Invalid pointer argument in intwf_integrate()",
00502 __FILE__, __LINE__ );
00503 return BPM_FAILURE;
00504 }
00505
00506
00507 dt = 1./w->fs;
00508
00509
00510 for ( i=0; i<w->ns; i++ ) {
00511 tmp = (double) w->wf[i];
00512 tmp *= dt;
00513
00514 if ( i > 0 ) tmp += tmp_prev;
00515
00516 w->wf[i] = (int) dround( tmp );
00517 tmp_prev = tmp;
00518 }
00519
00520 return BPM_SUCCESS;
00521 }
00522
00523
00524
00525 void intwf_print( FILE *of, intwf_t *w ) {
00526
00527 int i = 0;
00528 if ( !of || !w ) {
00529 bpm_error( "Invalid pointers in intwf_print()", __FILE__, __LINE__ );
00530 return;
00531 }
00532
00533 fprintf( of, "Waveform:\n" );
00534 fprintf( of, "Number of samples : %d\n", w->ns );
00535 fprintf( of, "Sampling frequency : %f MHz\n", w->fs / MHz );
00536 for( i = 0; i < w->ns; i++ ) fprintf( of, " wf[%5d] = %d \n", i, w->wf[i] );
00537 fflush( of );
00538
00539 return;
00540 }
00541
00542
00543
00544 int intwf_getvalue( intwf_t *w, double t, unsigned int mode ) {
00545
00546 int val = 0;
00547 doublewf_t *dw = NULL;
00548
00549 if ( ! w ) {
00550 bpm_error( "Invalid pointer arguments in intwf_getvalue()",
00551 __FILE__, __LINE__ );
00552 return BPM_FAILURE;
00553 }
00554
00555 dw = doublewf_cast_new( w );
00556 if ( ! dw ) {
00557 bpm_error( "Cannot allocate memory for temporary doublewf in intwf_getvalue()",
00558 __FILE__, __LINE__ );
00559 return BPM_FAILURE;
00560 }
00561
00562 val = (int) dround ( doublewf_getvalue( dw, t, mode ) );
00563
00564 doublewf_delete( dw );
00565
00566 return val;
00567 }
00568
00569
00570
00571 int intwf_resample( intwf_t *w2, double fs, intwf_t *w1, unsigned int mode ) {
00572
00573 int i = 0;
00574 doublewf_t *dw = NULL;
00575
00576 if ( ! w1 || ! w2 ) {
00577 bpm_error( "Invalid pointer arguments in intwf_resample()",
00578 __FILE__, __LINE__ );
00579 return BPM_FAILURE;
00580 }
00581
00582 dw = doublewf_cast_new( w1 );
00583 if ( ! dw ) {
00584 bpm_error( "Cannot allocate memory for temporary doublewf in intwf_resample()",
00585 __FILE__, __LINE__ );
00586 return BPM_FAILURE;
00587 }
00588
00589
00590 w2->ns = (int) (w1->ns * fs / w1->fs);
00591 w2->fs = fs;
00592
00593 if ( w2->ns > MAX_ALLOWED_NS ) {
00594 bpm_error( "Maximum allowed number of samples exceeded in intwf_resample()",
00595 __FILE__, __LINE__ );
00596 return BPM_FAILURE;
00597 }
00598
00599 if ( w2->ns < 1 ) {
00600 bpm_error( "Number of new samples is zero in intwf_resample()",
00601 __FILE__, __LINE__ );
00602 return BPM_FAILURE;
00603 }
00604
00605
00606 for ( i=0; i<w2->ns; i++ ) {
00607 w2->wf[i] = (int) dround( doublewf_getvalue( dw, (double) i / w2->fs, mode ) );
00608 }
00609
00610 doublewf_delete( dw );
00611
00612 return BPM_SUCCESS;
00613 }