test-Ordner eingefügt
This commit is contained in:
@@ -0,0 +1,21 @@
|
|||||||
|
build_dir:=./build
|
||||||
|
sources:= test.c ../signalProcessing/signal_path.c
|
||||||
|
|
||||||
|
#compile_cmd:=clang-17 -std=c2x -g -lm
|
||||||
|
compile_cmd_append:=-lm
|
||||||
|
compile_cmd_opt?=-g
|
||||||
|
compile_cmd:=gcc $(compile_cmd_opt)
|
||||||
|
|
||||||
|
#extra_defines:= -DDEBUG_PRINTS
|
||||||
|
pre_build_cmd:=mkdir -p $(build_dir)
|
||||||
|
|
||||||
|
|
||||||
|
$(build_dir)/cSensor_processing_single: $(sources)
|
||||||
|
$(pre_build_cmd)
|
||||||
|
$(compile_cmd) $(sources) -o $(build_dir)/cSensor_processing_single $(extra_defines) -DPLATFORM_GENERIC -DBLOCK_LEN=1 -DMAX_FIR_COEFFS=128 $(compile_cmd_append)
|
||||||
|
$(build_dir)/cSensor_processing_block: $(sources)
|
||||||
|
$(pre_build_cmd)
|
||||||
|
$(compile_cmd) $(sources) -o $(build_dir)/cSensor_processing_block $(extra_defines) -DPLATFORM_GENERIC -DBLOCK_LEN=2 -DMAX_FIR_COEFFS=128 $(compile_cmd_append)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(build_dir)/cSensor_processing_single $(build_dir)/cSensor_processing_block
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from scipy import signal
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
def get_psd(data, fs, bin_width):
|
||||||
|
f, psd = signal.welch(data,
|
||||||
|
fs=fs,
|
||||||
|
nperseg=fs/bin_width,
|
||||||
|
window='hann',
|
||||||
|
axis=0
|
||||||
|
)
|
||||||
|
|
||||||
|
return f[1:], psd[1:] #drop the first value because it makes the plots look bad and is effectively 0
|
||||||
|
|
||||||
|
|
||||||
|
def setup_timeplot(figsize=(11, 6), plot_coeffs=False):
|
||||||
|
global plot1, line1, plot2, line2, plot3, line3, plot4
|
||||||
|
# time domain plot
|
||||||
|
cols = 1
|
||||||
|
rows = 4
|
||||||
|
plt.figure(0, figsize=figsize)
|
||||||
|
plt.clf()
|
||||||
|
|
||||||
|
plot1 = plt.subplot2grid( (rows, cols), (0,0), 1)
|
||||||
|
line1 = plot1.plot([0], label="mic")
|
||||||
|
plt.legend()
|
||||||
|
plot2 = plt.subplot2grid((rows,cols),(1,0), sharex=plot1)
|
||||||
|
line2 = plot2.plot([0], label="acc")
|
||||||
|
plt.legend()
|
||||||
|
plot3 = plt.subplot2grid((rows, cols), (2,0), sharex=plot1)
|
||||||
|
line3 = plot3.plot([0], label="out")
|
||||||
|
plt.legend()
|
||||||
|
|
||||||
|
if plot_coeffs:
|
||||||
|
plot4 = plt.subplot2grid( (rows, cols), (3,0), sharex=plot1, rowspan=3)
|
||||||
|
plt.legend(loc='upper right')
|
||||||
|
|
||||||
|
plt.xlabel("sample")
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
def setup_freqplot(figsize=(11, 6)):
|
||||||
|
global plot_freq, line_freq1, line_freq2, line_freq3
|
||||||
|
cols = 1
|
||||||
|
rows = 1
|
||||||
|
# frequency domain plot
|
||||||
|
plt.figure(1, figsize=figsize)
|
||||||
|
plt.clf()
|
||||||
|
plt.title("Power spectrum")
|
||||||
|
plot_freq = plt.subplot2grid( (rows, cols), (0,0), 1)
|
||||||
|
line_freq1 = plot_freq.loglog([0], label="mic")
|
||||||
|
line_freq2 = plot_freq.loglog([0], label="acc")
|
||||||
|
line_freq3 = plot_freq.loglog([0], label="out")
|
||||||
|
plt.xlabel("frequency / Hz")
|
||||||
|
plt.ylabel("dB²/Hz")
|
||||||
|
plt.legend()
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
def plot_freqdomain(fs, ch1, ch2, output):
|
||||||
|
|
||||||
|
x_min = []
|
||||||
|
x_max = []
|
||||||
|
y_min = []
|
||||||
|
y_max = []
|
||||||
|
|
||||||
|
f, psd = get_psd(ch1, fs, 10)
|
||||||
|
x_min.append(min(f))
|
||||||
|
x_max.append(max(f))
|
||||||
|
y_min.append(min(psd))
|
||||||
|
y_max.append(max(psd))
|
||||||
|
line_freq1[0].set_data(f, psd)
|
||||||
|
|
||||||
|
f, psd = get_psd(ch2, fs, 10)
|
||||||
|
x_min.append(min(f))
|
||||||
|
x_max.append(max(f))
|
||||||
|
y_min.append(min(psd))
|
||||||
|
y_max.append(max(psd))
|
||||||
|
line_freq2[0].set_data(f, psd)
|
||||||
|
|
||||||
|
f, psd = get_psd(output, fs, 10)
|
||||||
|
x_min.append(min(f))
|
||||||
|
x_max.append(max(f))
|
||||||
|
y_min.append(min(psd))
|
||||||
|
y_max.append(max(psd))
|
||||||
|
line_freq3[0].set_data(f, psd)
|
||||||
|
|
||||||
|
plot_freq.set_xlim(min(x_min), max(x_max))
|
||||||
|
plot_freq.set_ylim(min(y_min), max(y_max))
|
||||||
|
|
||||||
|
|
||||||
|
def plot_timedomain(ch1, ch2, output, coeffs: pd.DataFrame =None):
|
||||||
|
#Plot the result
|
||||||
|
data= output
|
||||||
|
line3[0].set_data(range(len(data)), data)
|
||||||
|
plot3.set_xlim(0, len(data))
|
||||||
|
plot3.set_ylim(np.min(data), np.max(data))
|
||||||
|
|
||||||
|
# plot the chirp with noise
|
||||||
|
data = ch1
|
||||||
|
line1[0].set_data(range(len(data)), data)
|
||||||
|
plot1.set_xlim(0, len(data))
|
||||||
|
plot1.set_ylim(min(data), max(data))
|
||||||
|
|
||||||
|
# Plot the noise
|
||||||
|
data = ch2
|
||||||
|
line2[0].set_data(range(len(data)), data)
|
||||||
|
plot2.set_xlim(0, len(data))
|
||||||
|
plot2.set_ylim(min(data), max(data))
|
||||||
|
|
||||||
|
# Plot the coeffs
|
||||||
|
if coeffs is not None:
|
||||||
|
data = coeffs
|
||||||
|
coeffs.plot(ax=plot4)
|
||||||
|
#plot4.legend(bbox_to_anchor=(1.2, 1.05))
|
||||||
|
|
||||||
|
#line4 = plot4.plot([0], label="coeffs")
|
||||||
|
#line4[0].set_data(range(len(data)), data)
|
||||||
|
|
||||||
|
#plot4.set_xlim(0, len(data))
|
||||||
|
#plot4.set_ylim(min(data), max(data))
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,114 @@
|
|||||||
|
/*Test enviornment for testing of the signal path on a generic platform (pc)*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../signalProcessing/include/signal_path.h"
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]){
|
||||||
|
|
||||||
|
/*Some environment related prints*/
|
||||||
|
#ifdef DEBUG_PRINTS
|
||||||
|
printf("The size of int in bytes is: %lu\n", sizeof(int));
|
||||||
|
printf("The size of accum_t in bytes is: %lu\n", sizeof(accum_t));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static SingleSignalPath cSensorSignal;
|
||||||
|
static SingleSignalPath accSensorSignal;
|
||||||
|
//static LmsFilter lms;
|
||||||
|
//int lms_fir_coeffs[MAX_FIR_COEFFS];
|
||||||
|
|
||||||
|
static int16_t cSensor[BLOCK_LEN], accSensor[BLOCK_LEN];
|
||||||
|
static int16_t output_port[BLOCK_LEN];
|
||||||
|
|
||||||
|
// Deactivate preemphasis filter by initializing with coefficients {1., 0., 0., 0., 0.}
|
||||||
|
// can not be modeled on a generic platform (pc)
|
||||||
|
// biquad filter coefficients - off
|
||||||
|
double b0[5]={1., 0., 0., 0., 0.};
|
||||||
|
double b1[5]={1., 0., 0., 0., 0.};
|
||||||
|
int N_lms_fir_coeffs = MAX_FIR_COEFFS;
|
||||||
|
// get parameters from command line
|
||||||
|
OutputMode mode = (OutputMode) (*argv[1] - '0'); // Convert char to int (only works for single digits)
|
||||||
|
int pipe_input = (*argv[2] - '0');
|
||||||
|
int return_coeffs = (*argv[3] - '0');
|
||||||
|
|
||||||
|
init(
|
||||||
|
&cSensorSignal, &accSensorSignal,
|
||||||
|
//&lms, lms_fir_coeffs,
|
||||||
|
b0,
|
||||||
|
b1,
|
||||||
|
0, // sample delay
|
||||||
|
0,
|
||||||
|
1., // weight
|
||||||
|
1.,
|
||||||
|
0.005, // lms learning rate
|
||||||
|
N_lms_fir_coeffs // Numer of lms fir coefficients
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mode == OUTPUT_MODE_FIR){ //FIR filter mit fixen coeffizienten
|
||||||
|
for (int i=0; i<N_lms_fir_coeffs; i++){
|
||||||
|
ptr_fir_lms_coeffs.ptr_start[i] = (int) ((pow(2,31)-1) / N_lms_fir_coeffs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Sample wise signalprocessing, called by an interrupt, use a for loop to simulate it*/
|
||||||
|
FILE *fp1 = fopen("testdata/input/chirp_disturber.txt", "r");
|
||||||
|
FILE *fp2 = fopen("testdata/input/disturber.txt", "r");
|
||||||
|
FILE *fp3 = fopen("testdata/output/out_sim_generic.txt", "w");
|
||||||
|
|
||||||
|
int loop_cnt=0;
|
||||||
|
int keep_loopin=1;
|
||||||
|
while (keep_loopin){
|
||||||
|
// Load a new block from the input
|
||||||
|
for (uint32_t i = 0; i < BLOCK_LEN; i++){ // process block wise
|
||||||
|
if (pipe_input){ // input from pipe
|
||||||
|
if ((scanf("%hd", &cSensor[i]) !=1) || (scanf("%hd", &accSensor[i])!=1)) {
|
||||||
|
keep_loopin=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{// input from file
|
||||||
|
if (feof(fp1)==1 || feof(fp2)==1){
|
||||||
|
keep_loopin=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fscanf(fp1, "%hd", &cSensor[i]);
|
||||||
|
fscanf(fp2, "%hd", &accSensor[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loop_cnt++;
|
||||||
|
calc(
|
||||||
|
&cSensorSignal, &accSensorSignal,
|
||||||
|
//&lms, lms_fir_coeffs,
|
||||||
|
mode, cSensor, accSensor, output_port);
|
||||||
|
|
||||||
|
|
||||||
|
if (pipe_input){ // output to pipe
|
||||||
|
for (uint32_t i = 0; i < BLOCK_LEN; i++){ // return calculation results
|
||||||
|
printf("%d,", output_port[i]); // output to stdout
|
||||||
|
if (return_coeffs == 1){ // print the current coefficients
|
||||||
|
for (int i=0; i< N_lms_fir_coeffs; i++){
|
||||||
|
printf("%d,", ptr_fir_lms_coeffs.ptr_start[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
for (uint32_t i = 0; i < BLOCK_LEN; i++){ // return calculation results
|
||||||
|
printf("%d\n, ", output_port[i]); // output to stdout
|
||||||
|
if (return_coeffs == 1){ // print the current coefficients
|
||||||
|
for (int i=0; i< N_lms_fir_coeffs; i++){
|
||||||
|
printf("%d,", ptr_fir_lms_coeffs.ptr_start[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
fprintf(fp3, "%d\n", output_port[i]); // output to file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pipe_input){
|
||||||
|
fclose(fp1);
|
||||||
|
fclose(fp2);
|
||||||
|
fclose(fp3);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,68 @@
|
|||||||
|
import dwfpy as dwf
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
F_SYSCLK_ANALOG_DISCOVERY=100e6
|
||||||
|
BITS_PER_FRAME=32
|
||||||
|
F_BITCLK=640e3
|
||||||
|
F_FRAMECLK=20e3
|
||||||
|
|
||||||
|
print(f'DWF Version: {dwf.Application.get_version()}')
|
||||||
|
|
||||||
|
def gen_pcm(device, data, f_bitclk=F_BITCLK, words_per_frame=1, bits_per_word=16):
|
||||||
|
|
||||||
|
|
||||||
|
# Convert data to a list of bits
|
||||||
|
bits_list = []
|
||||||
|
for word in data:
|
||||||
|
# Check if word violates the 16-bit signed integer range
|
||||||
|
assert -32768 <= word <= 32767, 'Word value is out of range.'
|
||||||
|
|
||||||
|
# Convert word to binary representation
|
||||||
|
binary = bin(word & 0xFFFF)[2:].zfill(bits_per_word)
|
||||||
|
|
||||||
|
# Add binary representation to bits_list
|
||||||
|
bits_list.extend([int(bit) for bit in binary])
|
||||||
|
|
||||||
|
|
||||||
|
print(f'Found device: {device.name} ({device.serial_number})')
|
||||||
|
|
||||||
|
do_channels = device.digital_output
|
||||||
|
|
||||||
|
f_sysclk=do_channels[0]._module.clock_frequency
|
||||||
|
|
||||||
|
# Setup bitclock
|
||||||
|
counter_bitclk=round(f_sysclk/f_bitclk)
|
||||||
|
print(f"Set f bitclk to :{round(f_sysclk/counter_bitclk, 2)}Hz")
|
||||||
|
assert counter_bitclk % 2 == 0, 'Counter must be even.'
|
||||||
|
high_counter_bitclk=int(counter_bitclk/2)
|
||||||
|
low_counter_bitclk=int(counter_bitclk/2)
|
||||||
|
do_channels[0].setup(output_type=dwf.DigitalOutputType.PULSE, initial_counter=1, high_counter=high_counter_bitclk, low_counter=low_counter_bitclk)
|
||||||
|
|
||||||
|
# Setup frameclock
|
||||||
|
counter_frameclk= counter_bitclk*bits_per_word*words_per_frame
|
||||||
|
assert counter_frameclk % counter_bitclk == 0, 'Counter frameclk must be multiple of bit clock.'
|
||||||
|
do_channels[1].setup(output_type=dwf.DigitalOutputType.PULSE, high_counter=counter_bitclk, low_counter=counter_frameclk-counter_bitclk)
|
||||||
|
|
||||||
|
#setup data
|
||||||
|
do_channels[2].setup(output_type=dwf.DigitalOutputType.CUSTOM, divider=counter_bitclk, high_counter=1, low_counter=1)
|
||||||
|
do_channels[2].set_custom_bits(bits_list)
|
||||||
|
|
||||||
|
return do_channels
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
# Generate sine wave
|
||||||
|
f_sine = 1e3
|
||||||
|
t = np.arange(0, 1/f_sine, 1/F_FRAMECLK)
|
||||||
|
sine_wave = np.sin(2 * np.pi * f_sine * t)*0.5
|
||||||
|
|
||||||
|
# Convert sine wave to PCM data
|
||||||
|
pcm_data = (sine_wave * 32767).astype(int)
|
||||||
|
|
||||||
|
# Generate PCM channels
|
||||||
|
with dwf.Device() as device:
|
||||||
|
channels = gen_pcm(device, pcm_data, f_bitclk=F_BITCLK, words_per_frame=1, bits_per_word=16)
|
||||||
|
channels.configure(start=True)
|
||||||
|
input('Press Enter key to continue.')
|
||||||
|
channels.reset()
|
||||||
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Reference in New Issue
Block a user