diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 0352c267..5fe7ed28 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,12 @@ xCORE-200 DSP library change log ================================ +6.0.1 +----- + + * CHANGED: Updated generate_window.py to work with Python 3 + * CHANGED: Updated to use Jenkins shared library 0.14.1 + 6.0.0 ----- diff --git a/Jenkinsfile b/Jenkinsfile index 557cf654..1839009e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,12 +1,13 @@ -@Library('xmos_jenkins_shared_library@develop') _ +@Library('xmos_jenkins_shared_library@v0.14.1') _ getApproval() + pipeline { agent { label 'x86_64&&brew' } environment { REPO = 'lib_dsp' - VIEW = "${env.JOB_NAME.contains('PR-') ? REPO+'_'+env.CHANGE_TARGET : REPO+'_'+env.BRANCH_NAME}" + VIEW = getViewName(REPO) } options { skipDefaultCheckout() diff --git a/lib_dsp/module_build_info b/lib_dsp/module_build_info index 1b8ceaf6..5d4cd9ce 100644 --- a/lib_dsp/module_build_info +++ b/lib_dsp/module_build_info @@ -1,4 +1,4 @@ -VERSION = 6.0.0 +VERSION = 6.0.1 DEPENDENT_MODULES = lib_logging(>=3.0.0) diff --git a/lib_dsp/src/gen/generate_window.py b/lib_dsp/src/gen/generate_window.py index ffacd5ee..808a7c65 100644 --- a/lib_dsp/src/gen/generate_window.py +++ b/lib_dsp/src/gen/generate_window.py @@ -1,104 +1,44 @@ -# Copyright (c) 2015-2018, XMOS Ltd, All rights reserved -import numpy -from numpy import log10, abs, pi -import scipy +# Copyright (c) 2015-2020, XMOS Ltd, All rights reserved +import sys +import numpy as np from scipy import signal -import matplotlib -import matplotlib.pyplot -import matplotlib as mpl -import sys, getopt -import math +import argparse -def main(argv): - outputfile = '' - fn = '' - win_len = '' - try: - opts, args = getopt.getopt(sys.argv[1:],"o:f:l:",["output", "function", "length"]) - except getopt.GetoptError: - print 'generate_window.py -o -w function -l length' - print 'supported functions: boxcar' - print ' triangular' - print ' hanning' - print ' hamming' - print ' blackman' - print ' nuttall' - print ' blackman-nuttall' - print ' blackman-harris' - sys.exit(2) - for opt, arg in opts: - if opt == '-h': - print 'generate_window.py -o -w function -l length' - print 'supported functions: boxcar' - print ' triangular' - print ' hanning' - print ' hamming' - print ' blackman' - print ' nuttall' - print ' blackman-nuttall' - print ' blackman-harris' - sys.exit() - elif opt in ("-o", "--output"): - outputfile = arg - elif opt in ("-f", "--function"): - fn = arg - elif opt in ("-l", "--length"): - win_len = arg +def parse_arguments(): + parser = argparse.ArgumentParser(description="Generates Q31 LUTs from scipy windows") + parser.add_argument("-o", "--output-file", type=str) + parser.add_argument("-f", "--function", type=str) + parser.add_argument("-l", "--length", type=int) + return parser.parse_args() - f = open(outputfile,'w') - N = int(win_len) - print 'Will generate file:', outputfile - print 'With function: ', fn - print 'Window length is ', N, ' ' - print 'LUT length is ', (N/2), ' ' - pi = 3.14159265434 - #check that N is even - f.write('const int window[%d] = {\n' % (N/2)) - for n in range(0, N/2): - val = 1.0 - if fn == 'boxcar': - val = 1.0 - elif fn == 'triangular': - L = N - val = 1.0 - abs((n - (N-1.0)/2.0)/(L/2.0)) - elif fn == 'hanning': - alpha = 0.5 - beta = 1.0-alpha - val = alpha - beta*math.cos(2*pi*n/(N-1)) - elif fn == 'hamming': - alpha = 0.53836 - beta = 1.0-alpha - val = alpha - beta*math.cos(2*pi*n/(N-1)) - elif fn == 'blackman': - alpha = 0.16 - a0 = (1.0-alpha)/2.0 - a1 = 0.5 - a2 = alpha/2.0 - val = a0 - a1*math.cos(2*pi*n/(N-1)) + a2*math.cos(4*pi*n/(N-1)) - elif fn == 'nuttall': - a0 = 0.355768 - a1 = 0.487396 - a2 = 0.144232 - a3 = 0.012604 - val = a0 - a1*math.cos(2*pi*n/(N-1)) + a2*math.cos(4*pi*n/(N-1))- a3*math.cos(6*pi*n/(N-1)) - elif fn == 'blackman-nuttall': - a0 = 0.3635819 - a1 = 0.4891775 - a2 = 0.1365995 - a3 = 0.0106411 - val = a0 - a1*math.cos(2*pi*n/(N-1)) + a2*math.cos(4*pi*n/(N-1))- a3*math.cos(6*pi*n/(N-1)) - elif fn == 'blackman-harris': - a0 = 0.35875 - a1 = 0.48829 - a2 = 0.14128 - a3 = 0.01168 - val = a0 - a1*math.cos(2*pi*n/(N-1)) + a2*math.cos(4*pi*n/(N-1))- a3*math.cos(6*pi*n/(N-1)) - f.write('%d,\n' % int(val*0x7fffffff)); - f.write( '};\n') +def main(): + args = parse_arguments() + if args.length % 2 != 0: + print("Error: Length must be even") + sys.exit(1) + + window = signal.windows.get_window(args.function, args.length) + + # Split the window in half, then scale it to Q31 + + # Window is not quite half - oddity with scipy windows, middle value is 1 so a + # window with even length is non-symmetric + half_int_window = np.array( + window[:(args.length//2)+1] * np.iinfo(np.int32).max, dtype=np.int32 + ) + + # Create a C array + c_window = ( + f"// LUT for {args.function} window, generated by lib_dsp generate_window.py\n" + f"const int window[{len(half_int_window)}] = " + f"{{ {', '.join([str(i) for i in half_int_window])} }};" + ) + + # Write back to output file + with open(args.output_file, 'w') as f: + f.write(c_window + "\n") - f.close(); - if __name__ == "__main__": - main(sys.argv[1:]) + main()