init
This commit is contained in:
19
lib_audio_dsp/test/cascaded_biquads/CMakeLists.txt
Normal file
19
lib_audio_dsp/test/cascaded_biquads/CMakeLists.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
cmake_minimum_required(VERSION 3.21)
|
||||
include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake)
|
||||
project(cascaded_biquads_test)
|
||||
|
||||
set(APP_HW_TARGET XCORE-AI-EXPLORER)
|
||||
|
||||
set(APP_COMPILER_FLAGS
|
||||
-O3
|
||||
-g
|
||||
-report
|
||||
-Wall
|
||||
-Werror
|
||||
-fxscope)
|
||||
|
||||
set(APP_DEPENDENT_MODULES lib_audio_dsp)
|
||||
|
||||
set(XMOS_SANDBOX_DIR ${CMAKE_SOURCE_DIR}/../../..)
|
||||
|
||||
XMOS_REGISTER_APP()
|
||||
0
lib_audio_dsp/test/cascaded_biquads/__init__.py
Normal file
0
lib_audio_dsp/test/cascaded_biquads/__init__.py
Normal file
54
lib_audio_dsp/test/cascaded_biquads/src/main.c
Normal file
54
lib_audio_dsp/test/cascaded_biquads/src/main.c
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright 2024-2025 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "dsp/adsp.h"
|
||||
|
||||
FILE * _fopen(char * fname, char* mode) {
|
||||
FILE * fp = fopen(fname, mode);
|
||||
if (fp == NULL)
|
||||
{
|
||||
printf("Error opening a file\n");
|
||||
exit(1);
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int32_t DWORD_ALIGNED taps_buf[40] = {0};
|
||||
int32_t state[64] = {0};
|
||||
left_shift_t lsh[8] = {0};
|
||||
|
||||
FILE * in = _fopen("../sig_48k.bin", "rb");
|
||||
FILE * out = _fopen("sig_out.bin", "wb");
|
||||
FILE * coeffs = _fopen("coeffs.bin", "rb");
|
||||
|
||||
fseek(in, 0, SEEK_END);
|
||||
int in_len = ftell(in) / sizeof(int32_t);
|
||||
fseek(in, 0, SEEK_SET);
|
||||
|
||||
for (unsigned n = 0; n < 8; n++){
|
||||
fread(&taps_buf[n * 5], sizeof(int32_t), 5, coeffs);
|
||||
fread(&lsh[n], sizeof(int32_t), 1, coeffs);
|
||||
//printf("%ld %ld %ld %ld %ld %d\n", taps_buf[n * 5], taps_buf[n * 5 + 1], taps_buf[n * 5 + 2], taps_buf[n * 5 + 3], taps_buf[n * 5 + 4], lsh[n]);
|
||||
}
|
||||
fclose(coeffs);
|
||||
|
||||
for (unsigned i = 0; i < in_len; i++)
|
||||
{
|
||||
int32_t samp = 0, samp_out = 0;
|
||||
fread(&samp, sizeof(int32_t), 1, in);
|
||||
//printf("%ld ", samp);
|
||||
samp_out = adsp_cascaded_biquads_8b(samp, taps_buf, state, lsh);
|
||||
//printf("%ld ", samp_out);
|
||||
fwrite(&samp_out, sizeof(int32_t), 1, out);
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
|
||||
return 0;
|
||||
}
|
||||
133
lib_audio_dsp/test/cascaded_biquads/test_cascaded_biquads_c.py
Normal file
133
lib_audio_dsp/test/cascaded_biquads/test_cascaded_biquads_c.py
Normal file
@@ -0,0 +1,133 @@
|
||||
# Copyright 2024-2025 XMOS LIMITED.
|
||||
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
import numpy as np
|
||||
import soundfile as sf
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
import audio_dsp.dsp.cascaded_biquads as casc_bq
|
||||
from audio_dsp.dsp.generic import Q_SIG
|
||||
import audio_dsp.dsp.signal_gen as gen
|
||||
import pytest
|
||||
import random
|
||||
from test.test_utils import xdist_safe_bin_write, float_to_qxx, qxx_to_float, q_convert_flt
|
||||
|
||||
bin_dir = Path(__file__).parent / "bin"
|
||||
gen_dir = Path(__file__).parent / "autogen"
|
||||
|
||||
fs = 48000
|
||||
|
||||
|
||||
def get_sig(len=0.05):
|
||||
|
||||
sig_fl = gen.log_chirp(fs, len, 0.5)
|
||||
sig_fl = q_convert_flt(sig_fl, 23, Q_SIG)
|
||||
sig_int = float_to_qxx(sig_fl)
|
||||
|
||||
name = "sig_48k"
|
||||
|
||||
sig_path = bin_dir / str(name + ".bin")
|
||||
xdist_safe_bin_write(sig_int, sig_path)
|
||||
|
||||
# wav file does not need to be locked as it is only used for debugging outside pytest
|
||||
wav_path = gen_dir / str(name + ".wav")
|
||||
sf.write(wav_path, sig_fl, int(fs), "PCM_24")
|
||||
|
||||
return sig_fl
|
||||
|
||||
|
||||
def get_c_wav(dir_name, sim = True):
|
||||
app = "xsim" if sim else "xrun --io"
|
||||
run_cmd = app + " " + str(bin_dir / "cascaded_biquads_test.xe")
|
||||
stdout = subprocess.check_output(run_cmd, cwd = dir_name, shell = True)
|
||||
#print("run msg:\n", stdout)
|
||||
|
||||
sig_bin = dir_name / "sig_out.bin"
|
||||
assert sig_bin.is_file(), f"Could not find output bin {sig_bin}"
|
||||
sig_int = np.fromfile(sig_bin, dtype=np.int32)
|
||||
|
||||
sig_fl = qxx_to_float(sig_int)
|
||||
sf.write(gen_dir / "sig_c.wav", sig_fl, fs, "PCM_24")
|
||||
return sig_fl
|
||||
|
||||
|
||||
def run_py(filt: casc_bq.cascaded_biquads_8, sig_fl):
|
||||
out_int = np.zeros(sig_fl.size)
|
||||
out_fl = np.zeros(sig_fl.size)
|
||||
|
||||
for n in range(sig_fl.size):
|
||||
out_int[n] = filt.process_xcore(sig_fl[n])
|
||||
|
||||
# sf.write(gen_dir / "sig_py_int.wav", out_int, fs, "PCM_24")
|
||||
|
||||
return out_int
|
||||
|
||||
|
||||
def single_test(filt, tname, sig_fl):
|
||||
test_dir = bin_dir / tname
|
||||
test_dir.mkdir(exist_ok = True, parents = True)
|
||||
|
||||
all_filt_info = np.empty(0, dtype=np.int32)
|
||||
for biquad in filt.biquads:
|
||||
coeffs_arr = np.array(biquad.int_coeffs, dtype=np.int32)
|
||||
shift_arr = np.array(biquad.b_shift, dtype=np.int32)
|
||||
filt_info = np.append(coeffs_arr, shift_arr)
|
||||
all_filt_info = np.append(all_filt_info, filt_info)
|
||||
|
||||
all_filt_info.tofile(test_dir / "coeffs.bin")
|
||||
|
||||
out_py_int = run_py(filt, sig_fl)
|
||||
out_c = get_c_wav(test_dir)
|
||||
shutil.rmtree(test_dir)
|
||||
|
||||
np.testing.assert_allclose(out_c, out_py_int, rtol=0, atol=0)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def in_signal():
|
||||
bin_dir.mkdir(exist_ok=True, parents=True)
|
||||
gen_dir.mkdir(exist_ok=True, parents=True)
|
||||
return get_sig()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("n_filters", [1, 5, 8])
|
||||
@pytest.mark.parametrize("seed", [1, 5, 11])
|
||||
def test_peq_c(in_signal, n_filters, seed):
|
||||
|
||||
filter_spec = [['lowpass', fs * 0.4, 0.707],
|
||||
['highpass', fs * 0.001, 1],
|
||||
['peaking', 1000, 5, 10],
|
||||
['constant_q', 500, 1, -10],
|
||||
['notch', 2000, 1],
|
||||
['lowshelf', 200, 1, 3],
|
||||
['highshelf', 5000, 1, -2],
|
||||
['bypass'],
|
||||
['gain', -2]]
|
||||
random.Random(seed**n_filters*int(fs/1000)).shuffle(filter_spec)
|
||||
filter_spec = filter_spec[:n_filters]
|
||||
peq = casc_bq.parametric_eq_8band(fs, 1, filter_spec)
|
||||
|
||||
filter_name = f"peq_{n_filters}_{seed}"
|
||||
single_test(peq, filter_name, in_signal)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("filter_type", ["lowpass",
|
||||
"highpass",])
|
||||
@pytest.mark.parametrize("N", [4, 16]) # can only be 16 for now
|
||||
@pytest.mark.parametrize("f", [20, 20000])
|
||||
def test_nth_butterworth_c(in_signal, filter_type, N, f):
|
||||
f = np.min([f, fs / 2 * 0.95])
|
||||
filter_handle = getattr(casc_bq, f"butterworth_{filter_type}")
|
||||
|
||||
filt = filter_handle(fs, 1, N, f)
|
||||
filter_name = f"butterworth_{filter_type}_{N}_{f}"
|
||||
single_test(filt, filter_name, in_signal)
|
||||
|
||||
|
||||
if __name__ =="__main__":
|
||||
bin_dir.mkdir(exist_ok=True, parents=True)
|
||||
gen_dir.mkdir(exist_ok=True, parents=True)
|
||||
sig_fl = get_sig()
|
||||
|
||||
#test_peq_c(sig_fl)
|
||||
test_nth_butterworth_c(sig_fl, "lowpass", 16, 2000)
|
||||
@@ -0,0 +1,300 @@
|
||||
# Copyright 2024-2025 XMOS LIMITED.
|
||||
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
import pytest
|
||||
import numpy as np
|
||||
import random
|
||||
import scipy.signal as spsig
|
||||
|
||||
import audio_dsp.dsp.cascaded_biquads as cbq
|
||||
import audio_dsp.dsp.signal_gen as gen
|
||||
import audio_dsp.dsp.utils as utils
|
||||
|
||||
|
||||
def saturation_test(filter: cbq.cascaded_biquads_8, fs):
|
||||
|
||||
signal = 2**(np.arange(0, 31.5, 0.5)) - 1
|
||||
signal = np.repeat(signal, 2)
|
||||
signal[::2] *= -1
|
||||
|
||||
# # used for lib_xcore_math biquad test
|
||||
# sigint = (np.round(signal).astype(np.int32))
|
||||
# np.savetxt("sig.csv", sigint, fmt="%i", delimiter=",")
|
||||
|
||||
signal *= (2**-31)
|
||||
|
||||
|
||||
|
||||
output_int = np.zeros(len(signal))
|
||||
output_flt = np.zeros(len(signal))
|
||||
output_vpu = np.zeros(len(signal))
|
||||
|
||||
# for n in np.arange(len(signal)):
|
||||
# output_int[n] = filter.process_int(signal[n])
|
||||
# filter.reset_state()
|
||||
# for n in np.arange(len(signal)):
|
||||
# output_flt[n] = filter.process(signal[n])
|
||||
filter.reset_state()
|
||||
for n in np.arange(len(signal)):
|
||||
output_vpu[n] = filter.process_xcore(signal[n])
|
||||
|
||||
# # reference result for lib_xcore_math test
|
||||
# vpu_int = (np.round(output_vpu * 2**31).astype(np.int32))
|
||||
# np.savetxt("out.csv", vpu_int, fmt="%i", delimiter=",")
|
||||
|
||||
# small signals are always going to be ropey due to quantizing, so just check average error of top half
|
||||
top_half = utils.db(output_flt) > -50
|
||||
if np.any(top_half):
|
||||
error_flt = np.abs(utils.db(output_int[top_half])-utils.db(output_flt[top_half]))
|
||||
mean_error_flt = utils.db(np.nanmean(utils.db2gain(error_flt)))
|
||||
assert mean_error_flt < 0.055
|
||||
error_vpu = np.abs(utils.db(output_int[top_half])-utils.db(output_vpu[top_half]))
|
||||
mean_error_vpu = utils.db(np.nanmean(utils.db2gain(error_vpu)))
|
||||
assert mean_error_vpu < 0.05
|
||||
|
||||
|
||||
def chirp_filter_test(filter: cbq.cascaded_biquads_8, fs):
|
||||
length = 0.05
|
||||
signal = gen.log_chirp(fs, length, 0.5)
|
||||
|
||||
output_int = np.zeros(len(signal))
|
||||
output_flt = np.zeros(len(signal))
|
||||
output_vpu = np.zeros(len(signal))
|
||||
|
||||
for n in np.arange(len(signal)):
|
||||
output_int[n] = filter.process_int(signal[n])
|
||||
filter.reset_state()
|
||||
for n in np.arange(len(signal)):
|
||||
output_flt[n] = filter.process(signal[n])
|
||||
filter.reset_state()
|
||||
for n in np.arange(len(signal)):
|
||||
output_vpu[n] = filter.process_xcore(signal[n])
|
||||
|
||||
# small signals are always going to be ropey due to quantizing, so just check average error of top half
|
||||
top_half = utils.db(output_flt) > -50
|
||||
if np.any(top_half):
|
||||
error_flt = np.abs(utils.db(output_int[top_half])-utils.db(output_flt[top_half]))
|
||||
mean_error_flt = utils.db(np.nanmean(utils.db2gain(error_flt)))
|
||||
assert mean_error_flt < 0.055
|
||||
error_vpu = np.abs(utils.db(output_int[top_half])-utils.db(output_vpu[top_half]))
|
||||
mean_error_vpu = utils.db(np.nanmean(utils.db2gain(error_vpu)))
|
||||
assert mean_error_vpu < 0.055
|
||||
|
||||
|
||||
@pytest.mark.parametrize("fs", [16000, 44100, 48000, 88200, 96000, 192000])
|
||||
@pytest.mark.parametrize("n_filters", [1, 3, 5, 8])
|
||||
@pytest.mark.parametrize("seed", [1, 2, 3, 5, 7, 11])
|
||||
def test_peq(fs, n_filters, seed):
|
||||
# a list of some sensible filters, use them in random order
|
||||
filter_spec = [['lowpass', fs*0.4, 0.707],
|
||||
['highpass', fs*0.001, 1],
|
||||
['peaking', fs*1000/48000, 5, 10],
|
||||
['constant_q', fs*500/48000, 1, -10],
|
||||
['notch', fs*2000/48000, 1],
|
||||
['lowshelf', fs*200/48000, 1, 3],
|
||||
['highshelf', fs*5000/48000, 1, -2],
|
||||
['bypass'],
|
||||
['gain', -2]]
|
||||
random.Random(seed**n_filters*int(fs/1000)).shuffle(filter_spec)
|
||||
filter_spec = filter_spec[:n_filters]
|
||||
peq = cbq.parametric_eq_8band(fs, 1, filter_spec)
|
||||
chirp_filter_test(peq, fs)
|
||||
|
||||
|
||||
|
||||
@pytest.mark.parametrize("fs", [16000, 44100, 48000, 88200, 96000, 192000])
|
||||
def test_peq_saturation(fs):
|
||||
# a list of some sensible filters, use them in random order
|
||||
filter_spec = [['notch', fs*0.05, 1],
|
||||
['notch', fs*0.10, 1],
|
||||
['notch', fs*0.15, 1],
|
||||
['notch', fs*0.20, 1],
|
||||
['notch', fs*0.25, 1],
|
||||
['notch', fs*0.30, 1],
|
||||
['notch', fs*0.35, 1],
|
||||
['lowshelf', fs*1000/48000, 1, 3]]
|
||||
|
||||
peq = cbq.parametric_eq_8band(fs, 1, filter_spec, Q_sig=31)
|
||||
saturation_test(peq, fs)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("filter_type", ["lowpass",
|
||||
"highpass"])
|
||||
@pytest.mark.parametrize("f", [20, 100, 1000, 10000, 20000])
|
||||
@pytest.mark.parametrize("order", [4, 8, 16])
|
||||
@pytest.mark.parametrize("fs", [16000, 44100, 48000, 88200, 96000, 192000])
|
||||
def test_nth_butterworth(filter_type, f, order, fs):
|
||||
f = np.min([f, fs/2*0.95])
|
||||
if filter_type == "lowpass":
|
||||
if f < 50:
|
||||
return
|
||||
if f <= 100 and fs > 100000 and order >= 8:
|
||||
return
|
||||
filter = cbq.butterworth_lowpass(fs, 1, order, f)
|
||||
|
||||
elif filter_type == "highpass":
|
||||
if f > 10000:
|
||||
return
|
||||
if f < 50 and fs > 100000:
|
||||
f = 30
|
||||
filter = cbq.butterworth_highpass(fs, 1, order, f)
|
||||
|
||||
chirp_filter_test(filter, fs)
|
||||
|
||||
# compare against scipy butterworth response
|
||||
w, h = filter.freq_response(1024*32)
|
||||
sos = spsig.butter(order, f, fs=fs, btype=filter_type[:-4], output='sos')
|
||||
|
||||
w_ref, h_ref = spsig.sosfreqz(sos, worN=1024*32)
|
||||
|
||||
top_half = utils.db(h) > -50
|
||||
err = np.abs(utils.db(h[top_half]) - utils.db(h_ref[top_half]))
|
||||
mean_error = utils.db(np.nanmean(utils.db2gain(err)))
|
||||
|
||||
assert mean_error < 0.1
|
||||
|
||||
print(mean_error)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("fs", [48000])
|
||||
@pytest.mark.parametrize("n_filters", [1, 3, 5, 8])
|
||||
@pytest.mark.parametrize("seed", [1, 2, 3, 5, 7, 11])
|
||||
@pytest.mark.parametrize("n_chans", [1, 2, 4])
|
||||
@pytest.mark.parametrize("q_format", [27, 31])
|
||||
def test_peq_frame(fs, n_filters, seed, n_chans, q_format):
|
||||
# a list of some sensible filters, use them in random order
|
||||
filter_spec = [['lowpass', fs*0.4, 0.707],
|
||||
['highpass', fs*0.001, 1],
|
||||
['peaking', fs*1000/48000, 5, 10],
|
||||
['constant_q', fs*500/48000, 1, -10],
|
||||
['notch', fs*2000/48000, 1],
|
||||
['lowshelf', fs*200/48000, 1, 3],
|
||||
['highshelf', fs*5000/48000, 1, -2],
|
||||
['bypass'],
|
||||
['gain', -2]]
|
||||
random.Random(seed**n_filters*int(fs/1000)).shuffle(filter_spec)
|
||||
filter_spec = filter_spec[:n_filters]
|
||||
peq = cbq.parametric_eq_8band(fs, n_chans, filter_spec, Q_sig=q_format)
|
||||
|
||||
length = 0.05
|
||||
signal = gen.log_chirp(fs, length, 0.5)
|
||||
signal = np.tile(signal, [n_chans, 1])
|
||||
|
||||
signal_frames = utils.frame_signal(signal, 1, 1)
|
||||
|
||||
output_int = np.zeros_like(signal)
|
||||
output_flt = np.zeros_like(signal)
|
||||
output_vpu = np.zeros_like(signal)
|
||||
frame_size = 1
|
||||
for n in range(len(signal_frames)):
|
||||
output_int[:, n*frame_size:(n+1)*frame_size] = peq.process_frame_int(signal_frames[n])
|
||||
assert np.all(output_int[0, :] == output_int)
|
||||
peq.reset_state()
|
||||
|
||||
for n in range(len(signal_frames)):
|
||||
output_flt[:, n*frame_size:(n+1)*frame_size] = peq.process_frame(signal_frames[n])
|
||||
assert np.all(output_flt[0, :] == output_flt)
|
||||
peq.reset_state()
|
||||
|
||||
for n in range(len(signal_frames)):
|
||||
output_vpu[:, n*frame_size:(n+1)*frame_size] = peq.process_frame_xcore(signal_frames[n])
|
||||
assert np.all(output_vpu[0, :] == output_vpu)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("fs", [48000])
|
||||
@pytest.mark.parametrize("n_filters", [10, 14, 16])
|
||||
@pytest.mark.parametrize("n_chans, seed", [[1, 1],
|
||||
[2, 2],
|
||||
[4, 3],])
|
||||
@pytest.mark.parametrize("q_format", [27, 31])
|
||||
def test_peq16_frame(fs, n_filters, seed, n_chans, q_format):
|
||||
# a list of some sensible filters, use them in random order
|
||||
filter_spec = [['lowpass', fs*0.4, 0.707],
|
||||
['highpass', fs*0.001, 1],
|
||||
['peaking', fs*1000/48000, 5, 10],
|
||||
['constant_q', fs*500/48000, 1, -10],
|
||||
['notch', fs*2000/48000, 1],
|
||||
['lowshelf', fs*200/48000, 1, 3],
|
||||
['highshelf', fs*5000/48000, 1, -2],
|
||||
['bypass'],
|
||||
['gain', -2]]
|
||||
# random.Random(seed**n_filters*int(fs/1000)).shuffle(filter_spec)
|
||||
filter_spec_new = random.Random(seed**n_filters*int(fs/1000)).choices(filter_spec, k=n_filters)
|
||||
peq = cbq.parametric_eq_16band(fs, n_chans, filter_spec_new, Q_sig=q_format)
|
||||
|
||||
length = 0.05
|
||||
signal = gen.log_chirp(fs, length, 0.5)
|
||||
signal = np.tile(signal, [n_chans, 1])
|
||||
|
||||
signal_frames = utils.frame_signal(signal, 1, 1)
|
||||
|
||||
output_int = np.zeros_like(signal)
|
||||
output_flt = np.zeros_like(signal)
|
||||
output_vpu = np.zeros_like(signal)
|
||||
frame_size = 1
|
||||
for n in range(len(signal_frames)):
|
||||
output_int[:, n*frame_size:(n+1)*frame_size] = peq.process_frame_int(signal_frames[n])
|
||||
assert np.all(output_int[0, :] == output_int)
|
||||
peq.reset_state()
|
||||
|
||||
for n in range(len(signal_frames)):
|
||||
output_flt[:, n*frame_size:(n+1)*frame_size] = peq.process_frame(signal_frames[n])
|
||||
assert np.all(output_flt[0, :] == output_flt)
|
||||
peq.reset_state()
|
||||
|
||||
for n in range(len(signal_frames)):
|
||||
output_vpu[:, n*frame_size:(n+1)*frame_size] = peq.process_frame_xcore(signal_frames[n])
|
||||
assert np.all(output_vpu[0, :] == output_vpu)
|
||||
|
||||
|
||||
|
||||
@pytest.mark.parametrize("filter_type", ["lowpass",
|
||||
"highpass"])
|
||||
@pytest.mark.parametrize("fs", [48000])
|
||||
@pytest.mark.parametrize("f", [20, 1000, 20000])
|
||||
@pytest.mark.parametrize("order", [4, 16])
|
||||
@pytest.mark.parametrize("n_chans", [1, 2, 4])
|
||||
@pytest.mark.parametrize("q_format", [27, 31])
|
||||
def test_nth_order_frame(filter_type, fs, f, order, n_chans, q_format):
|
||||
f = np.min([f, fs/2*0.95])
|
||||
if filter_type == "lowpass":
|
||||
if f < 50:
|
||||
return
|
||||
if f <= 100 and fs > 100000 and order >= 8:
|
||||
return
|
||||
filter = cbq.butterworth_lowpass(fs, n_chans, order, f, Q_sig=q_format)
|
||||
|
||||
elif filter_type == "highpass":
|
||||
if f > 10000:
|
||||
return
|
||||
if f < 50 and fs > 100000:
|
||||
f = 30
|
||||
filter = cbq.butterworth_highpass(fs, n_chans, order, f, Q_sig=q_format)
|
||||
|
||||
length = 0.05
|
||||
signal = gen.log_chirp(fs, length, 0.5)
|
||||
signal = np.tile(signal, [n_chans, 1])
|
||||
|
||||
signal_frames = utils.frame_signal(signal, 1, 1)
|
||||
|
||||
output_int = np.zeros_like(signal)
|
||||
output_flt = np.zeros_like(signal)
|
||||
output_vpu = np.zeros_like(signal)
|
||||
frame_size = 1
|
||||
for n in range(len(signal_frames)):
|
||||
output_int[:, n*frame_size:(n+1)*frame_size] = filter.process_frame_int(signal_frames[n])
|
||||
assert np.all(output_int[0, :] == output_int)
|
||||
filter.reset_state()
|
||||
|
||||
for n in range(len(signal_frames)):
|
||||
output_flt[:, n*frame_size:(n+1)*frame_size] = filter.process_frame(signal_frames[n])
|
||||
assert np.all(output_flt[0, :] == output_flt)
|
||||
filter.reset_state()
|
||||
|
||||
for n in range(len(signal_frames)):
|
||||
output_vpu[:, n*frame_size:(n+1)*frame_size] = filter.process_frame_xcore(signal_frames[n])
|
||||
assert np.all(output_vpu[0, :] == output_vpu)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_peq_saturation(48000)
|
||||
# test_nth_butterworth("highpass", 20, 6, 16000)
|
||||
Reference in New Issue
Block a user