Put all state of white noise generator in object. Added possibility of changing output level.
This commit is contained in:
parent
aa3581cf74
commit
86e7cbbbe9
@ -1,4 +1,7 @@
|
||||
cmake_minimum_required (VERSION 3.0)
|
||||
cmake_minimum_required (VERSION 3.0)
|
||||
|
||||
# This is used for code completion in vim
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS=ON)
|
||||
project(LASP)
|
||||
|
||||
# Whether we want to use blas yes or no
|
||||
|
@ -10,20 +10,19 @@
|
||||
#include "lasp_assert.h"
|
||||
#include "lasp_mat.h"
|
||||
|
||||
#define PRIVATE_SIZE 32
|
||||
#define PRIVATE_SIZE 64
|
||||
|
||||
typedef enum {
|
||||
SINEWAVE = 0,
|
||||
WHITENOISE,
|
||||
PINKNOISE,
|
||||
SWEEP,
|
||||
|
||||
} SignalType;
|
||||
|
||||
|
||||
typedef struct {
|
||||
SignalType signaltype;
|
||||
d fs; // Sampling frequency [Hz]
|
||||
d level_amp;
|
||||
void* private;
|
||||
|
||||
char private_data[PRIVATE_SIZE];
|
||||
@ -35,31 +34,58 @@ typedef struct {
|
||||
d omg;
|
||||
} SinewaveSpecific;
|
||||
|
||||
typedef struct {
|
||||
d V1, V2, S;
|
||||
int phase;
|
||||
} WhitenoiseSpecific;
|
||||
|
||||
static d level_amp(d level_dB){
|
||||
return pow(10, level_dB/20);
|
||||
}
|
||||
|
||||
Siggen* Siggen_create(SignalType type, const d fs,const d level_dB) {
|
||||
|
||||
Siggen* Siggen_Sinewave_create(const d fs, const d freq) {
|
||||
fsTRACE(15);
|
||||
|
||||
Siggen* sinesiggen = a_malloc(sizeof(Siggen));
|
||||
sinesiggen->signaltype = SINEWAVE;
|
||||
sinesiggen->fs = fs;
|
||||
Siggen* siggen = a_malloc(sizeof(Siggen));
|
||||
siggen->signaltype = type;
|
||||
siggen->fs = fs;
|
||||
siggen->private = NULL;
|
||||
siggen->level_amp = level_amp(level_dB);
|
||||
|
||||
feTRACE(15);
|
||||
return siggen;
|
||||
}
|
||||
|
||||
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;
|
||||
sp->curtime = 0;
|
||||
sp->omg = 2*number_pi*freq;
|
||||
|
||||
|
||||
feTRACE(15);
|
||||
return sinesiggen;
|
||||
}
|
||||
Siggen* Siggen_Whitenoise_create() {
|
||||
|
||||
Siggen* Siggen_Whitenoise_create(const d fs, const d level_dB) {
|
||||
fsTRACE(15);
|
||||
|
||||
Siggen* whitenoise = a_malloc(sizeof(Siggen));
|
||||
whitenoise->signaltype = WHITENOISE;
|
||||
|
||||
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;
|
||||
wn->phase = 0;
|
||||
wn->V1 = 0;
|
||||
wn->V2 = 0;
|
||||
wn->S = 0;
|
||||
|
||||
feTRACE(15);
|
||||
return whitenoise;
|
||||
}
|
||||
|
||||
void Siggen_free(Siggen* siggen) {
|
||||
fsTRACE(15);
|
||||
assertvalidptr(siggen);
|
||||
@ -67,10 +93,11 @@ void Siggen_free(Siggen* siggen) {
|
||||
if(siggen->signaltype == SWEEP) {
|
||||
/* Sweep specific stuff here */
|
||||
}
|
||||
|
||||
|
||||
a_free(siggen);
|
||||
feTRACE(15);
|
||||
}
|
||||
|
||||
static void Sinewave_genSignal(Siggen* siggen, SinewaveSpecific* sine, vd* samples) {
|
||||
fsTRACE(15);
|
||||
assertvalidptr(sine);
|
||||
@ -79,44 +106,51 @@ static void Sinewave_genSignal(Siggen* siggen, SinewaveSpecific* sine, vd* sampl
|
||||
|
||||
d curtime = sine->curtime;
|
||||
for(us i =0; i< samples->n_rows; i++) {
|
||||
setvecval(samples, i, sin(omg*curtime));
|
||||
setvecval(samples, i, siggen->level_amp*sin(omg*curtime));
|
||||
curtime = curtime + ts;
|
||||
}
|
||||
sine->curtime = curtime;
|
||||
feTRACE(15);
|
||||
}
|
||||
|
||||
static d gaussrand() {
|
||||
static d V1, V2, S;
|
||||
static int phase = 0;
|
||||
d X;
|
||||
static void Whitenoise_genSignal(Siggen* siggen, WhitenoiseSpecific* wn, vd* samples) {
|
||||
fsTRACE(15);
|
||||
d X;
|
||||
d S = wn->S;
|
||||
d V1 = wn->V1;
|
||||
d V2 = wn->V2;
|
||||
int phase = wn->phase;
|
||||
|
||||
if(phase == 0) {
|
||||
do {
|
||||
d U1 = (d)rand() / RAND_MAX;
|
||||
d U2 = (d)rand() / RAND_MAX;
|
||||
|
||||
V1 = 2 * U1 - 1;
|
||||
V2 = 2 * U2 - 1;
|
||||
S = V1 * V1 + V2 * V2;
|
||||
} while(S >= 1 || S == 0);
|
||||
|
||||
X = V1 * sqrt(-2 * log(S) / S);
|
||||
} else
|
||||
X = V2 * sqrt(-2 * log(S) / S);
|
||||
|
||||
phase = 1 - phase;
|
||||
|
||||
return X;
|
||||
}
|
||||
static void Whitenoise_genSignal(Siggen* siggen, vd* samples) {
|
||||
for(us i =0; i< samples->n_rows; i++) {
|
||||
d rn = gaussrand();
|
||||
setvecval(samples, i, rn);
|
||||
|
||||
if(wn->phase == 0) {
|
||||
do {
|
||||
d U1 = (d)rand() / RAND_MAX;
|
||||
d U2 = (d)rand() / RAND_MAX;
|
||||
|
||||
V1 = 2 * U1 - 1;
|
||||
V2 = 2 * U2 - 1;
|
||||
S = V1 * V1 + V2 * V2;
|
||||
} while(S >= 1 || S == 0);
|
||||
|
||||
X = V1 * sqrt(-2 * log(S) / S);
|
||||
} else
|
||||
X = V2 * sqrt(-2 * log(S) / S);
|
||||
|
||||
phase = 1 - phase;
|
||||
|
||||
setvecval(samples, i, siggen->level_amp*X);
|
||||
}
|
||||
wn->S = S;
|
||||
wn->V1 = V1;
|
||||
wn->V2 = V2;
|
||||
wn->phase = phase;
|
||||
feTRACE(15);
|
||||
|
||||
}
|
||||
|
||||
void Siggen_genSignal(Siggen* siggen,vd* samples) {
|
||||
|
||||
fsTRACE(15);
|
||||
assertvalidptr(siggen);
|
||||
assert_vx(samples);
|
||||
@ -129,10 +163,16 @@ void Siggen_genSignal(Siggen* siggen,vd* samples) {
|
||||
|
||||
break;
|
||||
case WHITENOISE:
|
||||
Whitenoise_genSignal(siggen, samples);
|
||||
Whitenoise_genSignal(siggen, (WhitenoiseSpecific*) siggen->private,
|
||||
samples);
|
||||
break;
|
||||
case SWEEP:
|
||||
break;
|
||||
default:
|
||||
dbgassert(false, "Not implementend signal type");
|
||||
|
||||
}
|
||||
|
||||
|
||||
feTRACE(15);
|
||||
}
|
||||
|
||||
|
@ -17,16 +17,17 @@ typedef struct {} Siggen;
|
||||
* Create a sine wave signal generator
|
||||
*
|
||||
* @param[in] fs: Sampling frequency [Hz]
|
||||
* @param[in] level: Relative level in [dB], should be between -inf and 0
|
||||
* @param[freq] Sine wave frequency [Hz]
|
||||
*/
|
||||
Siggen* Siggen_Sinewave_create(const d fs,const d freq);
|
||||
Siggen* Siggen_Sinewave_create(const d fs,const d freq,const d level_dB);
|
||||
|
||||
/**
|
||||
* Create a white noise signal generator
|
||||
*
|
||||
* @return Siggen* handle
|
||||
*/
|
||||
Siggen* Siggen_Whitenoise_create();
|
||||
Siggen* Siggen_Whitenoise_create(const d fs, const d level_dB);
|
||||
|
||||
/**
|
||||
* Create a pink (1/f) noise signal generator
|
||||
@ -34,7 +35,7 @@ Siggen* Siggen_Whitenoise_create();
|
||||
* @param[in] fs: Sampling frequency [Hz]
|
||||
* @return Siggen* handle
|
||||
*/
|
||||
Siggen* Siggen_Pinknoise_create(const us fs);
|
||||
Siggen* Siggen_Pinknoise_create(const us fs,const d level_dB);
|
||||
|
||||
/* Siggen* Siggen_ForwardSweep_create(const d fs,; */
|
||||
/* Siggen* Siggen_(const d fs,; */
|
||||
|
@ -471,8 +471,8 @@ cdef class SPLowpass:
|
||||
|
||||
cdef extern from "lasp_siggen.h":
|
||||
ctypedef struct c_Siggen "Siggen"
|
||||
c_Siggen* Siggen_Whitenoise_create()
|
||||
c_Siggen* Siggen_Sinewave_create(d fs, d freq)
|
||||
c_Siggen* Siggen_Whitenoise_create(d fs, d level_dB)
|
||||
c_Siggen* Siggen_Sinewave_create(d fs, d freq, d level_dB)
|
||||
void Siggen_genSignal(c_Siggen*, vd* samples) nogil
|
||||
void Siggen_free(c_Siggen*)
|
||||
|
||||
@ -505,16 +505,16 @@ cdef class Siggen:
|
||||
|
||||
|
||||
@staticmethod
|
||||
def sineWave(fs, freq):
|
||||
cdef c_Siggen* c_siggen = Siggen_Sinewave_create(fs, freq)
|
||||
def sineWave(d fs,d freq,d level_dB):
|
||||
cdef c_Siggen* c_siggen = Siggen_Sinewave_create(fs, freq, level_dB)
|
||||
siggen = Siggen()
|
||||
siggen._siggen = c_siggen
|
||||
return siggen
|
||||
|
||||
|
||||
@staticmethod
|
||||
def whiteNoise():
|
||||
cdef c_Siggen* c_siggen = Siggen_Whitenoise_create()
|
||||
def whiteNoise(d fs, d level_dB):
|
||||
cdef c_Siggen* c_siggen = Siggen_Whitenoise_create(fs, level_dB)
|
||||
siggen = Siggen()
|
||||
siggen._siggen = c_siggen
|
||||
return siggen
|
||||
|
Loading…
Reference in New Issue
Block a user