diff --git a/lasp/c/lasp_siggen.c b/lasp/c/lasp_siggen.c index 7ce94d7..ee8c0e5 100644 --- a/lasp/c/lasp_siggen.c +++ b/lasp/c/lasp_siggen.c @@ -24,10 +24,7 @@ typedef struct Siggen { SignalType signaltype; d fs; // Sampling frequency [Hz] d level_amp; - void* private; - char private_data[PRIVATE_SIZE]; - } Siggen; typedef struct { @@ -35,6 +32,16 @@ typedef struct { d omg; } SinewaveSpecific; +typedef struct { + d fl; + d fu; + d Ts; + d phase; + d tau; + bool pos; + us flags; +} SweepSpecific; + typedef struct { d V1, V2, S; int phase; @@ -51,7 +58,6 @@ Siggen* Siggen_create(SignalType type, const d fs,const d level_dB) { Siggen* siggen = a_malloc(sizeof(Siggen)); siggen->signaltype = type; siggen->fs = fs; - siggen->private = NULL; siggen->level_amp = level_amp(level_dB); feTRACE(15); @@ -61,23 +67,24 @@ Siggen* Siggen_create(SignalType type, const d fs,const d level_dB) { Siggen* Siggen_Sinewave_create(const d fs, const d freq,const d level_dB) { fsTRACE(15); - Siggen* sinesiggen = Siggen_create(SINEWAVE, fs, level_dB); - sinesiggen->private = sinesiggen->private_data; - SinewaveSpecific* sp = (SinewaveSpecific*) sinesiggen->private; + Siggen* sine = Siggen_create(SINEWAVE, fs, level_dB); + dbgassert(sizeof(SinewaveSpecific) <= sizeof(sine->private_data), + "Allocated memory too small"); + SinewaveSpecific* sp = (SinewaveSpecific*) sine->private_data; sp->curtime = 0; sp->omg = 2*number_pi*freq; feTRACE(15); - return sinesiggen; + return sine; } Siggen* Siggen_Whitenoise_create(const d fs, const d level_dB) { fsTRACE(15); Siggen* whitenoise = Siggen_create(WHITENOISE, fs, level_dB); - whitenoise->private = whitenoise->private_data; - dbgassert(sizeof(WhitenoiseSpecific) <= sizeof(whitenoise->private_data), "Allocated memory too small"); - WhitenoiseSpecific* wn = whitenoise->private; + dbgassert(sizeof(WhitenoiseSpecific) <= sizeof(whitenoise->private_data), + "Allocated memory too small"); + WhitenoiseSpecific* wn = (WhitenoiseSpecific*) whitenoise->private_data; wn->phase = 0; wn->V1 = 0; wn->V2 = 0; @@ -87,12 +94,50 @@ Siggen* Siggen_Whitenoise_create(const d fs, const d level_dB) { return whitenoise; } + +Siggen* Siggen_Sweep_create(const d fs,const d fl,const d fu, + const d Ts, const us flags, const d level_dB) { + fsTRACE(15); + + Siggen* sweep = Siggen_create(SWEEP, fs, level_dB); + dbgassert(sizeof(SweepSpecific) <= sizeof(sweep->private_data), + "Allocated memory too small"); + // Set pointer to inplace data storage + SweepSpecific* sp = (SweepSpecific*) sweep->private_data; + if(fl < 0 || fu < 0 || Ts <= 0) { + return NULL; + } + + sp->flags = flags; + + sp->fl = fl; + sp->fu = fu; + sp->Ts = Ts; + sp->phase = 0; + sp->pos = flags & SWEEP_FLAG_BACKWARD ? false: true; + if(flags & SWEEP_FLAG_BACKWARD) { + sp->tau = Ts; + } else { + sp->tau = 0; + } + /* sp->pos = false; */ + /* sp->tau = Ts/2; */ + + feTRACE(15); + return sweep; +} + void Siggen_free(Siggen* siggen) { fsTRACE(15); assertvalidptr(siggen); - if(siggen->signaltype == SWEEP) { - /* Sweep specific stuff here */ + switch(siggen->signaltype) { + case SWEEP: + /* Sweep specific stuff here */ + break; + case SINEWAVE: + /* Sweep specific stuff here */ + break; } a_free(siggen); @@ -114,6 +159,81 @@ static void Sinewave_genSignal(Siggen* siggen, SinewaveSpecific* sine, vd* sampl feTRACE(15); } +static void Sweep_genSignal(Siggen* siggen, SweepSpecific* sweep, + vd* samples) { + fsTRACE(15); + assertvalidptr(sweep); + + const d fl = sweep->fl; + const d fu = sweep->fu; + const d deltat = 1/siggen->fs; + const d Ts = sweep->Ts; + + const d Thalf = Ts/2; + + dVARTRACE(20, deltat); + + // Load state + d tau = sweep->tau; + bool pos = sweep->pos; + + // Obtain flags and expand + us flags = sweep->flags; + bool forward_sweep = flags & SWEEP_FLAG_FORWARD; + bool backward_sweep = flags & SWEEP_FLAG_BACKWARD; + dbgassert(!(forward_sweep && backward_sweep), "Both forward and backward flag set"); + + d k, Treverse; + if(forward_sweep || backward_sweep) { + k = (fu - fl)/Ts; + Treverse = Ts; + } + else { + k = (fu - fl)/Thalf; + Treverse = Ts/2; + } + + + /* const d k = 0; */ + + d phase = sweep->phase; + d curfreq; + for(us i =0; i< samples->n_rows; i++) { + + curfreq = fl + k*tau; + phase = phase + 2*number_pi*curfreq*deltat; + + // Subtract some to avoid possible overflow. Don't know whether such a + // thing really happens + if(phase > 2*number_pi) + phase = phase - 2*number_pi; + + if(pos) { + tau = tau + deltat; + if(tau >= Treverse) { + if(forward_sweep) { tau = 0; } + else if(backward_sweep) { dbgassert(false, "BUG"); } + else { pos = false; } + } + + } else { + /* dbgassert(false, "cannot get here"); */ + tau = tau - deltat; + if(tau <= 0) { + if(backward_sweep) { tau = Treverse; } + else if(forward_sweep) { dbgassert(false, "BUG"); } + else { pos = true; } + } + } + setvecval(samples, i, siggen->level_amp*d_sin(phase)); + } + // Store state + sweep->phase = phase; + sweep->pos = pos; + sweep->tau = tau; + feTRACE(15); +} + static void Whitenoise_genSignal(Siggen* siggen, WhitenoiseSpecific* wn, vd* samples) { fsTRACE(15); d X; @@ -155,19 +275,23 @@ void Siggen_genSignal(Siggen* siggen,vd* samples) { fsTRACE(15); assertvalidptr(siggen); assert_vx(samples); - d fs = siggen->fs; switch(siggen->signaltype) { case SINEWAVE: - Sinewave_genSignal(siggen, (SinewaveSpecific*) siggen->private, + Sinewave_genSignal(siggen, + (SinewaveSpecific*) siggen->private_data, samples); break; case WHITENOISE: - Whitenoise_genSignal(siggen, (WhitenoiseSpecific*) siggen->private, + Whitenoise_genSignal(siggen, + (WhitenoiseSpecific*) siggen->private_data, samples); break; case SWEEP: + Sweep_genSignal(siggen, + (SweepSpecific*) siggen->private_data, + samples); break; default: dbgassert(false, "Not implementend signal type"); diff --git a/lasp/c/lasp_siggen.h b/lasp/c/lasp_siggen.h index ee8d097..553087e 100644 --- a/lasp/c/lasp_siggen.h +++ b/lasp/c/lasp_siggen.h @@ -37,8 +37,30 @@ Siggen* Siggen_Whitenoise_create(const d fs, const d level_dB); */ Siggen* Siggen_Pinknoise_create(const us fs,const d level_dB); -/* Siggen* Siggen_ForwardSweep_create(const d fs,; */ -/* Siggen* Siggen_(const d fs,; */ +// Define this flag to repeat a forward sweep only, or backward only. If not +// set, we do a continuous sweep +#define SWEEP_FLAG_FORWARD 1 +#define SWEEP_FLAG_BACKWARD 2 + +// Types of sweeps +#define SWEEP_FLAG_LINEAR 4 +#define SWEEP_FLAG_EXPONENTIAL 8 +#define SWEEP_FLAG_HYPERBOLIC 16 + +/** + * Create a forward sweep + * + * @param[in] fs: Sampling frequency [Hz] + * @param[in] fl: Lower frequency [Hz] + * @param[in] fl: Upper frequency [Hz] + * @param[in] Ts: Sweep period [s] + * @param[in] sweep_flags: Sweep period [s] + * @param[in] level: Relative level in [dB], should be between -inf and 0 + * @return Siggen* handle + */ +Siggen* Siggen_Sweep_create(const d fs,const d fl,const d fu, + const d Ts, const us sweep_flags, + const d level); /** * Obtain a new piece of signal diff --git a/lasp/c/lasp_sosfilterbank.c b/lasp/c/lasp_sosfilterbank.c index c5f06b8..29d36d4 100644 --- a/lasp/c/lasp_sosfilterbank.c +++ b/lasp/c/lasp_sosfilterbank.c @@ -1,4 +1,4 @@ -#define TRACERPLUS 10 +#define TRACERPLUS (-5) #include "lasp_sosfilterbank.h"