diff --git a/ComputeGraph/README.md b/ComputeGraph/README.md index 4bcc1ba7..7d802a95 100644 --- a/ComputeGraph/README.md +++ b/ComputeGraph/README.md @@ -319,7 +319,17 @@ Horizontal or vertical layout for the graph. By default, the graph is displaying the FIFO sizes. If you want to know with FIFO variable is used in the code, you can set this option to true and the graph will display the FIFO variable names. +### Options for connections +It is now possible to write something like: + +```python +g.connect(src.o,b.i,fifoClass="FIFOSource") +``` + +The `fifoClass` argument allows to choose a specific FIFO class in the generated C++ or Python. + +Only the `FIFO` class is provided by default. Any new implementation must inherit from `FIFObase` ## How to build the examples diff --git a/ComputeGraph/examples/example2/test.dot b/ComputeGraph/examples/example2/test.dot index 1666c0bf..67fc3288 100644 --- a/ComputeGraph/examples/example2/test.dot +++ b/ComputeGraph/examples/example2/test.dot @@ -109,7 +109,7 @@ toMono [label=< >]; -srcDelay [label=< +srctoMonoDelay [label=< @@ -117,10 +117,10 @@ srcDelay [label=<
10
>]; -src:i -> srcDelay:i [label="",taillabel=<
320 +src:i -> srctoMonoDelay:i [label="",taillabel=<
320
>] -srcDelay:i -> toMono:i [label="f32(330)" +srctoMonoDelay:i -> toMono:i [label="f32(330)" ,headlabel=<
320
>] diff --git a/ComputeGraph/examples/example5/graph.py b/ComputeGraph/examples/example5/graph.py index 6ad75244..ad9f15d8 100644 --- a/ComputeGraph/examples/example5/graph.py +++ b/ComputeGraph/examples/example5/graph.py @@ -18,7 +18,7 @@ src=WavSource("src",NBCHANNELS*AUDIO_INTERRUPT_LENGTH) src.addLiteralArg(True) src.addLiteralArg("test_stereo.wav") -toMono=StereoToMono("toMono",q15Type,AUDIO_INTERRUPT_LENGTH) +toMono=InterleavedStereoToMono("toMono",q15Type,AUDIO_INTERRUPT_LENGTH) slidingAudio=SlidingBuffer("audioWin",q15Type,FFTSize,AudioOverlap) slidingMFCC=SlidingBuffer("mfccWin",q15Type,numOfDctOutputs*nbMFCCOutputs,numOfDctOutputs*nbMFCCOutputs>>1) diff --git a/ComputeGraph/examples/example5/sched.py b/ComputeGraph/examples/example5/sched.py index 06f3b8cb..3a96a154 100644 --- a/ComputeGraph/examples/example5/sched.py +++ b/ComputeGraph/examples/example5/sched.py @@ -74,7 +74,7 @@ def scheduler(mfccConfig,dispbuf): mfccWin = SlidingBuffer(754,377,fifo3,fifo4) sink = NumpySink(754,fifo4,dispbuf) src = WavSource(384,fifo0,True,"test_stereo.wav") - toMono = StereoToMono(384,192,fifo0,fifo1) + toMono = InterleavedStereoToMono(384,192,fifo0,fifo1) while((cgStaticError==0) and (debugCounter > 0)): nbSchedule = nbSchedule + 1 diff --git a/ComputeGraph/examples/example5/test.dot b/ComputeGraph/examples/example5/test.dot index 161ca823..d2f50729 100644 --- a/ComputeGraph/examples/example5/test.dot +++ b/ComputeGraph/examples/example5/test.dot @@ -47,7 +47,7 @@ src [label=< toMono [label=< - +
toMono
(StereoToMono)
toMono
(InterleavedStereoToMono)
>]; diff --git a/ComputeGraph/examples/example9/test.dot b/ComputeGraph/examples/example9/test.dot index c9f0cbcf..5092cba0 100644 --- a/ComputeGraph/examples/example9/test.dot +++ b/ComputeGraph/examples/example9/test.dot @@ -60,7 +60,7 @@ dup0 -> sink:i [label="f32(5)" ,headlabel=<
5
> ] -dup0Delay [label=< +dup0filterDelay [label=< @@ -69,9 +69,9 @@ dup0Delay [label=< -dup0 -> dup0Delay:i [label=""] +dup0 -> dup0filterDelay:i [label=""] -dup0Delay:i -> filter:ib [label="f32(5)" +dup0filterDelay:i -> filter:ib [label="f32(5)" ,headlabel=<
5
5
>] diff --git a/PythonWrapper/cmsisdsp_pkg/src/cmsisdsp_filtering.c b/PythonWrapper/cmsisdsp_pkg/src/cmsisdsp_filtering.c index ab6b693c..fb2781c5 100755 --- a/PythonWrapper/cmsisdsp_pkg/src/cmsisdsp_filtering.c +++ b/PythonWrapper/cmsisdsp_pkg/src/cmsisdsp_filtering.c @@ -4711,6 +4711,7 @@ cmsis_arm_fir_decimate_f32(PyObject *obj, PyObject *args) float32_t *pSrc_converted=NULL; // input float32_t *pDst=NULL; // output uint32_t blockSize; // input + uint32_t outBlockSize; // input if (PyArg_ParseTuple(args,"OO",&S,&pSrc)) { @@ -4718,12 +4719,13 @@ cmsis_arm_fir_decimate_f32(PyObject *obj, PyObject *args) dsp_arm_fir_decimate_instance_f32Object *selfS = (dsp_arm_fir_decimate_instance_f32Object *)S; GETARGUMENT(pSrc,NPY_DOUBLE,double,float32_t); blockSize = arraySizepSrc ; + outBlockSize = arraySizepSrc / selfS->instance->M; - pDst=PyMem_Malloc(sizeof(float32_t)*blockSize); + pDst=PyMem_Malloc(sizeof(float32_t)*outBlockSize); arm_fir_decimate_f32(selfS->instance,pSrc_converted,pDst,blockSize); - FLOATARRAY1(pDstOBJ,blockSize,pDst); + FLOATARRAY1(pDstOBJ,outBlockSize,pDst); PyObject *pythonResult = Py_BuildValue("O",pDstOBJ); @@ -4779,19 +4781,21 @@ cmsis_arm_fir_decimate_q15(PyObject *obj, PyObject *args) q15_t *pSrc_converted=NULL; // input q15_t *pDst=NULL; // output uint32_t blockSize; // input + uint32_t outBlockSize; // input if (PyArg_ParseTuple(args,"OO",&S,&pSrc)) { dsp_arm_fir_decimate_instance_q15Object *selfS = (dsp_arm_fir_decimate_instance_q15Object *)S; GETARGUMENT(pSrc,NPY_INT16,int16_t,int16_t); - blockSize = arraySizepSrc ; + blockSize = arraySizepSrc; + outBlockSize = arraySizepSrc / selfS->instance->M; - pDst=PyMem_Malloc(sizeof(q15_t)*blockSize); + pDst=PyMem_Malloc(sizeof(q15_t)*outBlockSize); arm_fir_decimate_q15(selfS->instance,pSrc_converted,pDst,blockSize); - INT16ARRAY1(pDstOBJ,blockSize,pDst); + INT16ARRAY1(pDstOBJ,outBlockSize,pDst); PyObject *pythonResult = Py_BuildValue("O",pDstOBJ); @@ -4813,6 +4817,7 @@ cmsis_arm_fir_decimate_fast_q15(PyObject *obj, PyObject *args) q15_t *pSrc_converted=NULL; // input q15_t *pDst=NULL; // output uint32_t blockSize; // input + uint32_t outBlockSize; // input if (PyArg_ParseTuple(args,"OO",&S,&pSrc)) { @@ -4820,12 +4825,13 @@ cmsis_arm_fir_decimate_fast_q15(PyObject *obj, PyObject *args) dsp_arm_fir_decimate_instance_q15Object *selfS = (dsp_arm_fir_decimate_instance_q15Object *)S; GETARGUMENT(pSrc,NPY_INT16,int16_t,int16_t); blockSize = arraySizepSrc ; + outBlockSize = arraySizepSrc / selfS->instance->M; - pDst=PyMem_Malloc(sizeof(q15_t)*blockSize); + pDst=PyMem_Malloc(sizeof(q15_t)*outBlockSize); arm_fir_decimate_fast_q15(selfS->instance,pSrc_converted,pDst,blockSize); - INT16ARRAY1(pDstOBJ,blockSize,pDst); + INT16ARRAY1(pDstOBJ,outBlockSize,pDst); PyObject *pythonResult = Py_BuildValue("O",pDstOBJ); @@ -4881,6 +4887,7 @@ cmsis_arm_fir_decimate_q31(PyObject *obj, PyObject *args) q31_t *pSrc_converted=NULL; // input q31_t *pDst=NULL; // output uint32_t blockSize; // input + uint32_t outBlockSize; // input if (PyArg_ParseTuple(args,"OO",&S,&pSrc)) { @@ -4888,12 +4895,13 @@ cmsis_arm_fir_decimate_q31(PyObject *obj, PyObject *args) dsp_arm_fir_decimate_instance_q31Object *selfS = (dsp_arm_fir_decimate_instance_q31Object *)S; GETARGUMENT(pSrc,NPY_INT32,int32_t,int32_t); blockSize = arraySizepSrc ; + outBlockSize = arraySizepSrc / selfS->instance->M; - pDst=PyMem_Malloc(sizeof(q31_t)*blockSize); + pDst=PyMem_Malloc(sizeof(q31_t)*outBlockSize); arm_fir_decimate_q31(selfS->instance,pSrc_converted,pDst,blockSize); - INT32ARRAY1(pDstOBJ,blockSize,pDst); + INT32ARRAY1(pDstOBJ,outBlockSize,pDst); PyObject *pythonResult = Py_BuildValue("O",pDstOBJ); @@ -4915,19 +4923,21 @@ cmsis_arm_fir_decimate_fast_q31(PyObject *obj, PyObject *args) q31_t *pSrc_converted=NULL; // input q31_t *pDst=NULL; // output uint32_t blockSize; // input + uint32_t outBlockSize; // input if (PyArg_ParseTuple(args,"OO",&S,&pSrc)) { dsp_arm_fir_decimate_instance_q31Object *selfS = (dsp_arm_fir_decimate_instance_q31Object *)S; GETARGUMENT(pSrc,NPY_INT32,int32_t,int32_t); - blockSize = arraySizepSrc ; + blockSize = arraySizepSrc; + outBlockSize = arraySizepSrc / selfS->instance->M; - pDst=PyMem_Malloc(sizeof(q31_t)*blockSize); + pDst=PyMem_Malloc(sizeof(q31_t)*outBlockSize); arm_fir_decimate_fast_q31(selfS->instance,pSrc_converted,pDst,blockSize); - INT32ARRAY1(pDstOBJ,blockSize,pDst); + INT32ARRAY1(pDstOBJ,outBlockSize,pDst); PyObject *pythonResult = Py_BuildValue("O",pDstOBJ); @@ -4983,6 +4993,7 @@ cmsis_arm_fir_interpolate_q15(PyObject *obj, PyObject *args) q15_t *pSrc_converted=NULL; // input q15_t *pDst=NULL; // output uint32_t blockSize; // input + uint32_t outBlockSize; // input if (PyArg_ParseTuple(args,"OO",&S,&pSrc)) { @@ -4990,12 +5001,13 @@ cmsis_arm_fir_interpolate_q15(PyObject *obj, PyObject *args) dsp_arm_fir_interpolate_instance_q15Object *selfS = (dsp_arm_fir_interpolate_instance_q15Object *)S; GETARGUMENT(pSrc,NPY_INT16,int16_t,int16_t); blockSize = arraySizepSrc ; + outBlockSize = arraySizepSrc * selfS->instance->L; - pDst=PyMem_Malloc(sizeof(q15_t)*blockSize); + pDst=PyMem_Malloc(sizeof(q15_t)*outBlockSize); arm_fir_interpolate_q15(selfS->instance,pSrc_converted,pDst,blockSize); - INT16ARRAY1(pDstOBJ,blockSize,pDst); + INT16ARRAY1(pDstOBJ,outBlockSize,pDst); PyObject *pythonResult = Py_BuildValue("O",pDstOBJ); @@ -5051,6 +5063,7 @@ cmsis_arm_fir_interpolate_q31(PyObject *obj, PyObject *args) q31_t *pSrc_converted=NULL; // input q31_t *pDst=NULL; // output uint32_t blockSize; // input + uint32_t outBlockSize; // input if (PyArg_ParseTuple(args,"OO",&S,&pSrc)) { @@ -5058,12 +5071,13 @@ cmsis_arm_fir_interpolate_q31(PyObject *obj, PyObject *args) dsp_arm_fir_interpolate_instance_q31Object *selfS = (dsp_arm_fir_interpolate_instance_q31Object *)S; GETARGUMENT(pSrc,NPY_INT32,int32_t,int32_t); blockSize = arraySizepSrc ; + outBlockSize = arraySizepSrc * selfS->instance->L; - pDst=PyMem_Malloc(sizeof(q31_t)*blockSize); + pDst=PyMem_Malloc(sizeof(q31_t)*outBlockSize); arm_fir_interpolate_q31(selfS->instance,pSrc_converted,pDst,blockSize); - INT32ARRAY1(pDstOBJ,blockSize,pDst); + INT32ARRAY1(pDstOBJ,outBlockSize,pDst); PyObject *pythonResult = Py_BuildValue("O",pDstOBJ); @@ -5119,19 +5133,21 @@ cmsis_arm_fir_interpolate_f32(PyObject *obj, PyObject *args) float32_t *pSrc_converted=NULL; // input float32_t *pDst=NULL; // output uint32_t blockSize; // input + uint32_t outBlockSize; // input if (PyArg_ParseTuple(args,"OO",&S,&pSrc)) { dsp_arm_fir_interpolate_instance_f32Object *selfS = (dsp_arm_fir_interpolate_instance_f32Object *)S; GETARGUMENT(pSrc,NPY_DOUBLE,double,float32_t); - blockSize = arraySizepSrc ; + blockSize = arraySizepSrc; + outBlockSize = arraySizepSrc * selfS->instance->L; - pDst=PyMem_Malloc(sizeof(float32_t)*blockSize); + pDst=PyMem_Malloc(sizeof(float32_t)*outBlockSize); arm_fir_interpolate_f32(selfS->instance,pSrc_converted,pDst,blockSize); - FLOATARRAY1(pDstOBJ,blockSize,pDst); + FLOATARRAY1(pDstOBJ,outBlockSize,pDst); PyObject *pythonResult = Py_BuildValue("O",pDstOBJ); diff --git a/PythonWrapper/cmsisdsp_pkg/src/cmsisdsp_support.c b/PythonWrapper/cmsisdsp_pkg/src/cmsisdsp_support.c index 910e61ce..5672b6c1 100755 --- a/PythonWrapper/cmsisdsp_pkg/src/cmsisdsp_support.c +++ b/PythonWrapper/cmsisdsp_pkg/src/cmsisdsp_support.c @@ -880,7 +880,6 @@ cmsis_arm_barycenter_f32(PyObject *obj, PyObject *args) if (PyArg_ParseTuple(args,"OOkk",&pSrcA,&pSrcB,&nbVectors,&vecDim)) { - GETARGUMENT(pSrcA,NPY_DOUBLE,double,float32_t); GETARGUMENT(pSrcB,NPY_DOUBLE,double,float32_t); diff --git a/PythonWrapper/cmsisdsp_pkg/src/cmsisdsp_transform.c b/PythonWrapper/cmsisdsp_pkg/src/cmsisdsp_transform.c index 5137a513..b2798c5f 100755 --- a/PythonWrapper/cmsisdsp_pkg/src/cmsisdsp_transform.c +++ b/PythonWrapper/cmsisdsp_pkg/src/cmsisdsp_transform.c @@ -1817,8 +1817,8 @@ void typeRegistration(PyObject *module) { ADDTYPE(arm_cfft_instance_f32); ADDTYPE(arm_rfft_instance_q15); ADDTYPE(arm_rfft_instance_q31); - ADDTYPE(arm_rfft_instance_f32); ADDTYPE(arm_rfft_fast_instance_f32); + ADDTYPE(arm_rfft_fast_instance_f64); ADDTYPE(arm_dct4_instance_f32); ADDTYPE(arm_dct4_instance_q31); ADDTYPE(arm_dct4_instance_q15); @@ -2206,7 +2206,7 @@ cmsis_arm_cfft_f64(PyObject *obj, PyObject *args) GETARGUMENT(p1,NPY_DOUBLE,double,float64_t); arm_cfft_f64(selfS->instance,p1_converted,(uint8_t)ifftFlag,(uint8_t)bitReverseFlag); - FLOATARRAY1(p1OBJ,2*selfS->instance->fftLen,p1_converted); + FLOAT64ARRAY1(p1OBJ,2*selfS->instance->fftLen,p1_converted); PyObject *pythonResult = Py_BuildValue("O",p1OBJ); @@ -2283,15 +2283,28 @@ cmsis_arm_rfft_q15(PyObject *obj, PyObject *args) if (PyArg_ParseTuple(args,"OO",&S,&pSrc)) { + int inputSize; + int outputSize; + + dsp_arm_rfft_instance_q15Object *selfS = (dsp_arm_rfft_instance_q15Object *)S; + + inputSize=selfS->instance->fftLenReal; + if (selfS->instance->ifftFlagR) + { + outputSize = inputSize-2; + } + else + { + outputSize = 2*inputSize+2; + } - dsp_arm_rfft_instance_q15Object *selfS = (dsp_arm_rfft_instance_q15Object *)S; GETARGUMENT(pSrc,NPY_INT16,int16_t,int16_t); - pDst=PyMem_Malloc(sizeof(q15_t)*2*selfS->instance->fftLenReal); + pDst=PyMem_Malloc(sizeof(q15_t)*outputSize); arm_rfft_q15(selfS->instance,pSrc_converted,pDst); - INT16ARRAY1(pDstOBJ,2*selfS->instance->fftLenReal,pDst); + INT16ARRAY1(pDstOBJ,outputSize,pDst); PyObject *pythonResult = Py_BuildValue("O",pDstOBJ); @@ -2340,17 +2353,32 @@ cmsis_arm_rfft_q31(PyObject *obj, PyObject *args) q31_t *pSrc_converted=NULL; // input q31_t *pDst=NULL; // output + + if (PyArg_ParseTuple(args,"OO",&S,&pSrc)) { - - dsp_arm_rfft_instance_q31Object *selfS = (dsp_arm_rfft_instance_q31Object *)S; + int inputSize; + int outputSize; + + dsp_arm_rfft_instance_q31Object *selfS = (dsp_arm_rfft_instance_q31Object *)S; + + inputSize=selfS->instance->fftLenReal; + if (selfS->instance->ifftFlagR) + { + outputSize = inputSize-2; + } + else + { + outputSize = 2*inputSize+2; + } + GETARGUMENT(pSrc,NPY_INT32,int32_t,int32_t); - pDst=PyMem_Malloc(sizeof(q31_t)*2*selfS->instance->fftLenReal); + pDst=PyMem_Malloc(sizeof(q31_t)*outputSize); arm_rfft_q31(selfS->instance,pSrc_converted,pDst); - INT32ARRAY1(pDstOBJ,2*selfS->instance->fftLenReal,pDst); + INT32ARRAY1(pDstOBJ,outputSize,pDst); PyObject *pythonResult = Py_BuildValue("O",pDstOBJ); @@ -2465,11 +2493,11 @@ cmsis_arm_rfft_fast_f64(PyObject *obj, PyObject *args) dsp_arm_rfft_fast_instance_f64Object *selfS = (dsp_arm_rfft_fast_instance_f64Object *)S; GETARGUMENT(p,NPY_DOUBLE,double,float64_t); - pOut=PyMem_Malloc(sizeof(float64_t)*2*selfS->instance->fftLenRFFT); + pOut=PyMem_Malloc(sizeof(float64_t)*selfS->instance->fftLenRFFT); arm_rfft_fast_f64(selfS->instance,p_converted,pOut,(uint8_t)ifftFlag); - FLOATARRAY1(pOutOBJ,2*selfS->instance->fftLenRFFT,pOut); + FLOAT64ARRAY1(pOutOBJ,selfS->instance->fftLenRFFT,pOut); PyObject *pythonResult = Py_BuildValue("O",pOutOBJ); @@ -3139,9 +3167,8 @@ static PyMethodDef CMSISDSPMethods[] = { {"arm_rfft_q15", cmsis_arm_rfft_q15, METH_VARARGS,""}, {"arm_rfft_init_q31", cmsis_arm_rfft_init_q31, METH_VARARGS,""}, {"arm_rfft_q31", cmsis_arm_rfft_q31, METH_VARARGS,""}, -{"arm_rfft_init_f32", cmsis_arm_rfft_init_f32, METH_VARARGS,""}, -{"arm_rfft_f32", cmsis_arm_rfft_f32, METH_VARARGS,""}, {"arm_rfft_fast_init_f64", cmsis_arm_rfft_fast_init_f64, METH_VARARGS,""}, +{"arm_rfft_fast_f64", cmsis_arm_rfft_fast_f64, METH_VARARGS,""}, {"arm_rfft_fast_f32", cmsis_arm_rfft_fast_f32, METH_VARARGS,""}, {"arm_rfft_fast_init_f32", cmsis_arm_rfft_fast_init_f32, METH_VARARGS,""}, {"arm_rfft_fast_f32", cmsis_arm_rfft_fast_f32, METH_VARARGS,""}, diff --git a/PythonWrapper/examples/example_1_9.py b/PythonWrapper/examples/example_1_9.py new file mode 100644 index 00000000..5d211ce4 --- /dev/null +++ b/PythonWrapper/examples/example_1_9.py @@ -0,0 +1,163 @@ +# Bug corrections for version 1.9 +import cmsisdsp as dsp +import cmsisdsp.fixedpoint as f +import numpy as np +import math +import colorama +from colorama import init,Fore, Back, Style +from numpy.testing import assert_allclose +import matplotlib.pyplot as plt +from scipy import signal + +init() + +def printTitle(s): + print("\n" + Fore.GREEN + Style.BRIGHT + s + Style.RESET_ALL) + +def printSubTitle(s): + print("\n" + Style.BRIGHT + s + Style.RESET_ALL) + +printTitle("Decimate") + +test_length_seconds = 0.1 +signal_frequency = 100 +sampling_freq = 8000 +nbSamples = int(test_length_seconds*sampling_freq) +wave = np.sin(2*np.pi*signal_frequency*np.linspace(0,test_length_seconds,nbSamples)) + +#plt.plot(wave) +#plt.show() + +decimationFactor = 4 + +numTaps = 9 +downsamplingFilter = signal.firwin(numTaps,1.0 / decimationFactor) +block_size = 160 +assert(block_size % decimationFactor == 0) + +ds_state = np.zeros(block_size + len(downsamplingFilter)-1) +decimator = dsp.arm_fir_decimate_instance_f32() + +status = dsp.arm_fir_decimate_init_f32(decimator,numTaps,decimationFactor, downsamplingFilter, ds_state) + +def processSignal(sig,dec,f): + result = [] + for blockNb in range(len(sig) // block_size): + s = blockNb * block_size + e = s + block_size + + r = f(dec,sig[s:e]) + result.append(r) + output = np.hstack(result) + return(output) + +ref = processSignal(wave,decimator,dsp.arm_fir_decimate_f32) +#plt.plot(ref) +#plt.show() + +printSubTitle("Decimate Q31") +waveQ31 = f.toQ31(wave) +downsamplingFilterQ31 = f.toQ31(downsamplingFilter) +stateQ31 = np.zeros(block_size + len(downsamplingFilter)-1) +decimatorQ31 = dsp.arm_fir_decimate_instance_q31() +status = dsp.arm_fir_decimate_init_q31(decimatorQ31,numTaps,decimationFactor, + downsamplingFilterQ31, stateQ31) + +outputQ31 = processSignal(waveQ31,decimatorQ31,dsp.arm_fir_decimate_q31) +outputF32 = f.Q31toF32(outputQ31) + +printSubTitle("Decimate Fast Q31") +waveQ31 = f.toQ31(wave) +downsamplingFilterQ31 = f.toQ31(downsamplingFilter) +stateQ31 = np.zeros(block_size + len(downsamplingFilter)-1) +decimatorQ31 = dsp.arm_fir_decimate_instance_q31() +status = dsp.arm_fir_decimate_init_q31(decimatorQ31,numTaps,decimationFactor, + downsamplingFilterQ31, stateQ31) + +outputQ31 = processSignal(waveQ31,decimatorQ31,dsp.arm_fir_decimate_fast_q31) +outputF32 = f.Q31toF32(outputQ31) + +printSubTitle("Decimate Q15") + +waveQ15 = f.toQ15(wave) +downsamplingFilterQ15 = f.toQ15(downsamplingFilter) +stateQ15 = np.zeros(block_size + len(downsamplingFilter)-1) +decimatorQ15 = dsp.arm_fir_decimate_instance_q15() +status = dsp.arm_fir_decimate_init_q15(decimatorQ15,numTaps,decimationFactor, + downsamplingFilterQ15, stateQ15) + +outputQ15 = processSignal(waveQ15,decimatorQ15,dsp.arm_fir_decimate_q15) +outputF32 = f.Q15toF32(outputQ15) +#plt.plot(outputF32) +#plt.show() +assert_allclose(ref,outputF32,rtol=2e-3,atol=1e-3) + +printSubTitle("Decimate Fast Q15") + +waveQ15 = f.toQ15(wave) +downsamplingFilterQ15 = f.toQ15(downsamplingFilter) +stateQ15 = np.zeros(block_size + len(downsamplingFilter)-1) +decimatorQ15 = dsp.arm_fir_decimate_instance_q15() +status = dsp.arm_fir_decimate_init_q15(decimatorQ15,numTaps,decimationFactor, + downsamplingFilterQ15, stateQ15) + +outputQ15 = processSignal(waveQ15,decimatorQ15,dsp.arm_fir_decimate_fast_q15) +outputF32 = f.Q15toF32(outputQ15) +#plt.plot(outputF32) +#plt.show() +assert_allclose(ref,outputF32,rtol=2e-3,atol=1e-3) + + +printTitle("Interpolate") + +upsamplingFactor = 4 + +numTaps = 16 +upsamplingFilter = signal.firwin(numTaps,1.0 / upsamplingFactor) +assert(numTaps % upsamplingFactor == 0) +block_size = 40 + + +printSubTitle("Interpolate F32") + +state = np.zeros(block_size + len(upsamplingFilter)//upsamplingFactor-1) +interpolator = dsp.arm_fir_interpolate_instance_f32() +status = dsp.arm_fir_interpolate_init_f32(interpolator,upsamplingFactor,numTaps, + upsamplingFilter, state) + +output = processSignal(ref,interpolator,dsp.arm_fir_interpolate_f32) +output = output / np.max(output) +#t = range(nbSamples) +#plt.plot(t,wave,t[:-11],output[11:]) +#plt.show() + +d = 11 +assert_allclose(wave[:-d],output[d:],atol=0.1) + +printSubTitle("Interpolate Q31") + +upsamplingFilterQ31 = f.toQ31(upsamplingFilter) +stateQ31 = np.zeros(block_size + len(upsamplingFilter)//upsamplingFactor-1) +interpolatorQ31 = dsp.arm_fir_interpolate_instance_q31() +status = dsp.arm_fir_interpolate_init_q31(interpolatorQ31,upsamplingFactor,numTaps, + upsamplingFilterQ31, stateQ31) + +outputQ31 = processSignal(outputQ31,interpolatorQ31,dsp.arm_fir_interpolate_q31) +outputF32 = f.Q31toF32(outputQ31) +outputF32 = outputF32 / np.max(outputF32) + +assert_allclose(wave[:-d],outputF32[d:],atol=0.1) + +printSubTitle("Interpolate Q15") + +upsamplingFilterQ15 = f.toQ15(upsamplingFilter) +stateQ15 = np.zeros(block_size + len(upsamplingFilter)//upsamplingFactor-1) +interpolatorQ15 = dsp.arm_fir_interpolate_instance_q15() +status = dsp.arm_fir_interpolate_init_q15(interpolatorQ15,upsamplingFactor,numTaps, + upsamplingFilterQ15, stateQ15) + +outputQ15 = processSignal(outputQ15,interpolatorQ15,dsp.arm_fir_interpolate_q15) +outputF32 = f.Q15toF32(outputQ15) +outputF32 = outputF32 / np.max(outputF32) + +assert_allclose(wave[:-d],outputF32[d:],atol=0.1) diff --git a/PythonWrapper/examples/testdsp5.py b/PythonWrapper/examples/testdsp5.py index 24e09a84..099616e3 100755 --- a/PythonWrapper/examples/testdsp5.py +++ b/PythonWrapper/examples/testdsp5.py @@ -71,9 +71,10 @@ assert i==-10 print("Barycenter") -a=[0] * 12 -w=np.array([[2] * 12]) -w[0,11]=3 +a=np.zeros((12,3)) +w=np.array([[2.0] * 12])[0] +w[0]=3 +w[11]=3 a[0] =[0., 0., -0.951057] a[1] =[0., 0., 0.951057] a[2] =[-0.850651, 0., -0.425325] @@ -87,15 +88,19 @@ a[9] =[-0.262866, 0.809017, -0.425325] a[10]=[0.262866, -0.809017, 0.425325] a[11]=[0.262866, 0.809017, 0.425325] -scaled=a * w.T + +scaled= np.dot(a.T , w) ref=np.sum(scaled,axis=0)/np.sum(w) -print(ref) +#print(ref) points = np.array(a).reshape(12*3) weights = w.reshape(12) +#print(points) +#print(weights) + result=dsp.arm_barycenter_f32(points,weights,12,3) -print(result) +#print(result) assert_allclose(ref,result,1e-6) diff --git a/PythonWrapper/examples/testrfft_all.py b/PythonWrapper/examples/testrfft_all.py new file mode 100644 index 00000000..0e2597b3 --- /dev/null +++ b/PythonWrapper/examples/testrfft_all.py @@ -0,0 +1,146 @@ +import cmsisdsp as dsp +import cmsisdsp.fixedpoint as f + +import numpy as np +from scipy import signal +import matplotlib.pyplot as plt +import scipy.fft + +import colorama +from colorama import init,Fore, Back, Style +from numpy.testing import assert_allclose + +init() + +def printTitle(s): + print("\n" + Fore.GREEN + Style.BRIGHT + s + Style.RESET_ALL) + +def printSubTitle(s): + print("\n" + Style.BRIGHT + s + Style.RESET_ALL) + + +def chop(A, eps = 1e-6): + B = np.copy(A) + B[np.abs(A) < eps] = 0 + return B + +nb = 32 +signal = np.cos(2 * np.pi * np.arange(nb) / nb)*np.cos(0.2*2 * np.pi * np.arange(nb) / nb) + +ref=scipy.fft.rfft(signal) +invref = scipy.fft.irfft(ref) + +# Convert ref to CMSIS-DSP format +referenceFloat=np.zeros(nb) +# Replace complex datatype by real datatype +referenceFloat[0::2] = np.real(ref)[:-1] +referenceFloat[1::2] = np.imag(ref)[:-1] +# Copy Nyquist frequency value into first +# sample.This is just a storage trick so that the +# output of the RFFT has same length as input +# It is legacy behavior that we need to keep +# for backward compatibility but it is not +# very pretty +referenceFloat[1] = np.real(ref[-1]) + +printTitle("RFFT FAST F64") + +printSubTitle("RFFT") + + +rfftf64=dsp.arm_rfft_fast_instance_f64() +status=dsp.arm_rfft_fast_init_f64(rfftf64,nb) +result = dsp.arm_rfft_fast_f64(rfftf64,signal,0) + + +assert_allclose(referenceFloat,result) + +printSubTitle("RIFFT") + +rifftf64=dsp.arm_rfft_fast_instance_f64() +status=dsp.arm_rfft_fast_init_f64(rifftf64,nb) +result = dsp.arm_rfft_fast_f64(rifftf64,referenceFloat,1) + +assert_allclose(invref,result,atol=1e-15) + +printTitle("RFFT FAST F32") + +printSubTitle("RFFT") + + +rfftf32=dsp.arm_rfft_fast_instance_f32() +status=dsp.arm_rfft_fast_init_f32(rfftf32,nb) +result = dsp.arm_rfft_fast_f32(rfftf32,signal,0) + + +assert_allclose(referenceFloat,result,rtol=3e-6) + +printSubTitle("RIFFT") + +rifftf32=dsp.arm_rfft_fast_instance_f32() +status=dsp.arm_rfft_fast_init_f32(rifftf32,nb) +result = dsp.arm_rfft_fast_f32(rifftf32,referenceFloat,1) + +assert_allclose(invref,result,atol=1e-7) + +# Fixed point +# Reference from fixed point arithmetric. +# The RFFT are not packing the Nyquist frequency +# real value in sample 0 +referenceFloat=np.zeros(nb+2) +# Replace complex datatype by real datatype +referenceFloat[0::2] = np.real(ref) +referenceFloat[1::2] = np.imag(ref) + +printTitle("RFFT Q31") + +printSubTitle("RFFT") + +signalQ31 = f.toQ31(signal) +rfftQ31=dsp.arm_rfft_instance_q31() +status=dsp.arm_rfft_init_q31(rfftQ31,nb,0,1) +resultQ31 = dsp.arm_rfft_q31(rfftQ31,signalQ31) +# Drop the conjugate part which is not computed by scipy +resultQ31 = resultQ31[:nb+2] +resultF = f.Q31toF32(resultQ31) * nb + +assert_allclose(referenceFloat,resultF,rtol=1e-6,atol=1e-6) + + +printSubTitle("RIFFT") + +rifftQ31=dsp.arm_rfft_instance_q31() +status=dsp.arm_rfft_init_q31(rifftQ31,nb,1,1) +# Apply CMSIS-DSP scaling +referenceQ31 = f.toQ31(referenceFloat / nb) +resultQ31 = dsp.arm_rfft_q31(rifftQ31,referenceFloat) +resultF = f.Q31toF32(resultQ31) + +assert_allclose(invref,result,atol=1e-6) + +printTitle("RFFT Q15") + +printSubTitle("RFFT") + +signalQ15 = f.toQ15(signal) +rfftQ15=dsp.arm_rfft_instance_q15() +status=dsp.arm_rfft_init_q15(rfftQ15,nb,0,1) +resultQ15 = dsp.arm_rfft_q15(rfftQ15,signalQ15) +# Drop the conjugate part which is not computed by scipy +resultQ15 = resultQ15[:nb+2] +resultF = f.Q15toF32(resultQ15) * nb + +assert_allclose(referenceFloat,resultF,rtol=1e-6,atol=1e-2) + + +printSubTitle("RIFFT") + +rifftQ15=dsp.arm_rfft_instance_q15() +status=dsp.arm_rfft_init_q15(rifftQ15,nb,1,1) +# Apply CMSIS-DSP scaling +referenceQ15 = f.toQ15(referenceFloat / nb) +resultQ15 = dsp.arm_rfft_q15(rifftQ15,referenceFloat) +resultF = f.Q15toF32(resultQ15) + +assert_allclose(invref,result,atol=1e-2) + diff --git a/PythonWrapper/examples/testrfft_fast.py b/PythonWrapper/examples/testrfft_fast.py deleted file mode 100755 index a4f60b11..00000000 --- a/PythonWrapper/examples/testrfft_fast.py +++ /dev/null @@ -1,27 +0,0 @@ -import cmsisdsp as dsp -import numpy as np -from scipy import signal -import matplotlib.pyplot as plt -import scipy.fft - - -def chop(A, eps = 1e-6): - B = np.copy(A) - B[np.abs(A) < eps] = 0 - return B - -nb = 32 -signal = np.cos(2 * np.pi * np.arange(nb) / nb)*np.cos(0.2*2 * np.pi * np.arange(nb) / nb) - -#print("{") -#for x in signal: -# print("%f," % x) -#print("}") - -result1=scipy.fft.rfft(signal) -print(chop(result1)) -rfftf32=dsp.arm_rfft_fast_instance_f32() -status=dsp.arm_rfft_fast_init_f32(rfftf32,nb) -print(status) -resultI = dsp.arm_rfft_fast_f32(rfftf32,signal,0) -print(chop(resultI)) \ No newline at end of file diff --git a/PythonWrapper_README.md b/PythonWrapper_README.md index bac6a6f7..96c6ddf2 100644 --- a/PythonWrapper_README.md +++ b/PythonWrapper_README.md @@ -239,6 +239,12 @@ The wrapper is now containing the compute graph Python scripts and you should re # Change history +## Version 1.9.3: + +* Corrected real FFTs in the wrapper +* Corrected arm_fir_decimate and arm_fir_interpolate +* Possibility to customize the FIFO class on a connection for the Python wrapper + ## Version 1.9.2: * New customization options for the compute graph: diff --git a/Source/FilteringFunctions/arm_fir_decimate_f32.c b/Source/FilteringFunctions/arm_fir_decimate_f32.c index 9b125988..6d7a320f 100644 --- a/Source/FilteringFunctions/arm_fir_decimate_f32.c +++ b/Source/FilteringFunctions/arm_fir_decimate_f32.c @@ -121,7 +121,7 @@ @param[in] S points to an instance of the floating-point FIR decimator structure @param[in] pSrc points to the block of input data @param[out] pDst points to the block of output data - @param[in] blockSize number of samples to process + @param[in] blockSize number of input samples to process @return none */ #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) diff --git a/Source/FilteringFunctions/arm_fir_decimate_q31.c b/Source/FilteringFunctions/arm_fir_decimate_q31.c index 77bfc168..dbaf2531 100644 --- a/Source/FilteringFunctions/arm_fir_decimate_q31.c +++ b/Source/FilteringFunctions/arm_fir_decimate_q31.c @@ -42,7 +42,7 @@ @param[in] S points to an instance of the Q31 FIR decimator structure @param[in] pSrc points to the block of input data @param[out] pDst points to the block of output data - @param[in] blockSize number of samples to process + @param[in] blockSize number of input samples to process @return none @par Scaling and Overflow Behavior diff --git a/Source/FilteringFunctions/arm_fir_interpolate_f32.c b/Source/FilteringFunctions/arm_fir_interpolate_f32.c index b6a6ecb7..f16bd309 100644 --- a/Source/FilteringFunctions/arm_fir_interpolate_f32.c +++ b/Source/FilteringFunctions/arm_fir_interpolate_f32.c @@ -125,7 +125,7 @@ @param[in] S points to an instance of the floating-point FIR interpolator structure @param[in] pSrc points to the block of input data @param[out] pDst points to the block of output data - @param[in] blockSize number of samples to process + @param[in] blockSize number of input samples to process @return none */ diff --git a/Source/FilteringFunctions/arm_fir_interpolate_q15.c b/Source/FilteringFunctions/arm_fir_interpolate_q15.c index 523e1557..4e1bf63e 100644 --- a/Source/FilteringFunctions/arm_fir_interpolate_q15.c +++ b/Source/FilteringFunctions/arm_fir_interpolate_q15.c @@ -42,7 +42,7 @@ @param[in] S points to an instance of the Q15 FIR interpolator structure @param[in] pSrc points to the block of input data @param[out] pDst points to the block of output data - @param[in] blockSize number of samples to process + @param[in] blockSize number of input samples to process @return none @par Scaling and Overflow Behavior diff --git a/Source/FilteringFunctions/arm_fir_interpolate_q31.c b/Source/FilteringFunctions/arm_fir_interpolate_q31.c index ea217603..0761fcdc 100644 --- a/Source/FilteringFunctions/arm_fir_interpolate_q31.c +++ b/Source/FilteringFunctions/arm_fir_interpolate_q31.c @@ -42,7 +42,7 @@ @param[in] S points to an instance of the Q31 FIR interpolator structure @param[in] pSrc points to the block of input data @param[out] pDst points to the block of output data - @param[in] blockSize number of samples to process + @param[in] blockSize number of input samples to process @return none @par Scaling and Overflow Behavior diff --git a/Source/TransformFunctions/arm_rfft_q15.c b/Source/TransformFunctions/arm_rfft_q15.c index d0b99ed6..33d94ac1 100644 --- a/Source/TransformFunctions/arm_rfft_q15.c +++ b/Source/TransformFunctions/arm_rfft_q15.c @@ -93,11 +93,12 @@ void arm_split_rifft_q15( | 8192 | 1.15 | 13.3 | 0 | @par - If the input buffer is of length N, the output buffer must have length 2*N. + If the input buffer is of length N (fftLenReal), the output buffer must have length 2N + 2 + since it is containing the conjugate part. (N/2 + 1 + N/2 complex samples) The input buffer is modified by this function. @par - For the RIFFT, the source buffer must at least have length - fftLenReal + 2. + For the RIFFT, the source buffer must have at least length + fftLenReal + 2 which is (N/2 + 1 complex samples). It is not using the conjugate part. The last two elements must be equal to what would be generated by the RFFT: (pSrc[0] - pSrc[1]) >> 1 and 0 diff --git a/Source/TransformFunctions/arm_rfft_q31.c b/Source/TransformFunctions/arm_rfft_q31.c index 483b8514..0f325a9c 100644 --- a/Source/TransformFunctions/arm_rfft_q31.c +++ b/Source/TransformFunctions/arm_rfft_q31.c @@ -93,11 +93,12 @@ void arm_split_rifft_q31( | 8192 | 1.31 | 13.19 | 0 | @par - If the input buffer is of length N, the output buffer must have length 2*N. + If the input buffer is of length N (fftLenReal), the output buffer must have length 2N + 2 + since it is containing the conjugate part. (N/2 + 1 + N/2 complex samples) The input buffer is modified by this function. @par - For the RIFFT, the source buffer must at least have length - fftLenReal + 2. + For the RIFFT, the source buffer must have at least length + fftLenReal + 2 which is (N/2 + 1 complex samples). It is not using the conjugate part. The last two elements must be equal to what would be generated by the RFFT: (pSrc[0] - pSrc[1]) >> 1 and 0 diff --git a/cmsisdsp/__init__.py b/cmsisdsp/__init__.py index ae3b3767..7aaef0a6 100755 --- a/cmsisdsp/__init__.py +++ b/cmsisdsp/__init__.py @@ -19,15 +19,15 @@ from cmsisdsp_svm import * __version__ = cmsisdsp.version.__version__ # CMSIS-DSP Version used to build the wrapper -cmsis_dsp_version="1.14.1" +cmsis_dsp_version="1.14.2" # CMSIS-DSP Commit hash used to build the wrapper -commit_hash="8ed2ef7a7e2c6fce29c59d18ba7ee0f9f66027c2" +commit_hash="0705c6756809e0dac25ac2986f455c2088dad5c2" # True if development version of CMSIS-DSP used # (So several CMSIS-DSP versions may have same version number hence the commit hash) -developmentVersion=False +developmentVersion=True __all__ = ["datatype", "fixedpoint", "mfcc"] diff --git a/cmsisdsp/cg/static/scheduler/description.py b/cmsisdsp/cg/static/scheduler/description.py index 21f6012d..600f773e 100644 --- a/cmsisdsp/cg/static/scheduler/description.py +++ b/cmsisdsp/cg/static/scheduler/description.py @@ -90,6 +90,7 @@ class FIFODesc: self.dst = None # FIFO delay self.delay=0 + self.fifoClass = "FIFO" # Used for liveliness analysis # To share buffers between FIFO in memory optimization @@ -169,6 +170,7 @@ class Graph(): self._totalMemory=0 self._allFIFOs = None self._allBuffers = None + self._FIFOClasses = {} # Topological sorting of nodes # computed during topology matrix # and used for some scheduling @@ -211,11 +213,11 @@ class Graph(): #print(self._topologicalSort) - def connectDup(self,destination,outputIO,theId): + def connectDup(self,destination,outputIO,theId,fifoClass="FIFO"): if (destination[theId][1]!=0): - self.connectWithDelay(outputIO,destination[theId][0],destination[theId][1],dupAllowed=False) + self.connectWithDelay(outputIO,destination[theId][0],destination[theId][1],dupAllowed=False,fifoClass=destination[theId][2]) else: - self.connect(outputIO,destination[theId][0],dupAllowed=False) + self.connect(outputIO,destination[theId][0],dupAllowed=False,fifoClass=destination[theId][2]) @@ -287,12 +289,17 @@ class Graph(): nodea = f[0] nodeb = f[1] + fifoClass = "FIFO" + if (nodea,nodeb) in self._FIFOClasses: + fifoClass = self._FIFOClasses[(nodea,nodeb)] + + if (nodea,nodeb) in self._delays: delay = self._delays[(nodea,nodeb)] else: delay = 0 - destinations.append((nodeb,delay)) + destinations.append((nodeb,delay,fifoClass)) nodea.fifo=None nodeb.fifo=None @@ -309,6 +316,8 @@ class Graph(): if self._g.has_edge(nodea.owner,nodeb.owner): self._g.remove_edge(nodea.owner,nodeb.owner) del self._edges[(nodea,nodeb)] + if (nodea,nodeb) in self._FIFOClasses: + del self._FIFOClasses[(nodea,nodeb)] if (nodea,nodeb) in self._delays: del self._delays[(nodea,nodeb)] @@ -333,7 +342,7 @@ class Graph(): - def connect(self,nodea,nodeb,dupAllowed=True): + def connect(self,nodea,nodeb,dupAllowed=True,fifoClass="FIFO"): # When connecting to a constant node we do nothing # since there is no FIFO in this case # and it does not participate to the scheduling. @@ -353,6 +362,7 @@ class Graph(): nodea.fifo=(nodea,nodeb) nodeb.fifo=(nodea,nodeb) self._edges[(nodea,nodeb)]=True + self._FIFOClasses[(nodea,nodeb)] = fifoClass if not (nodea.owner in self._nodes): self._nodes[nodea.owner]=True if not (nodeb.owner in self._nodes): @@ -360,12 +370,12 @@ class Graph(): else: raise IncompatibleIO - def connectWithDelay(self,nodea,nodeb,delay,dupAllowed=True): + def connectWithDelay(self,nodea,nodeb,delay,dupAllowed=True,fifoClass="FIFO"): # We cannot connect with delay to a constant node if (isinstance(nodea,Constant)): raise CannotDelayConstantError else: - self.connect(nodea,nodeb,dupAllowed=dupAllowed) + self.connect(nodea,nodeb,dupAllowed=dupAllowed,fifoClass=fifoClass) self._delays[(nodea,nodeb)] = delay def __str__(self): @@ -384,6 +394,9 @@ class Graph(): edge = self._sortedEdges[fifo.fifoID] fifo.length = fifoLengths[fifo.fifoID] src,dst = edge + if edge in self._FIFOClasses: + fifoClass = self._FIFOClasses[edge] + fifo.fifoClass = fifoClass fifo.src=src fifo.dst=dst fifo.delay=self.getDelay(edge) diff --git a/cmsisdsp/cg/static/scheduler/templates/code.py b/cmsisdsp/cg/static/scheduler/templates/code.py index 32f0df5c..1afcf57b 100644 --- a/cmsisdsp/cg/static/scheduler/templates/code.py +++ b/cmsisdsp/cg/static/scheduler/templates/code.py @@ -50,9 +50,9 @@ def {{config.schedName}}({{optionalargs()}}): # {% for id in range(nbFifos) %} {% if fifos[id].hasDelay %} - fifo{{id}}=FIFO(FIFOSIZE{{id}},{{config.prefix}}buf{{id}},delay={{fifos[id].delay}}) + fifo{{id}}={{fifos[id].fifoClass}}(FIFOSIZE{{id}},{{config.prefix}}buf{{id}},delay={{fifos[id].delay}}) {% else %} - fifo{{id}}=FIFO(FIFOSIZE{{id}},{{config.prefix}}buf{{id}}) + fifo{{id}}={{fifos[id].fifoClass}}(FIFOSIZE{{id}},{{config.prefix}}buf{{id}}) {% endif %} {% endfor %} diff --git a/cmsisdsp/cg/static/scheduler/templates/codeArray.cpp b/cmsisdsp/cg/static/scheduler/templates/codeArray.cpp index a7ee0a10..eb224983 100644 --- a/cmsisdsp/cg/static/scheduler/templates/codeArray.cpp +++ b/cmsisdsp/cg/static/scheduler/templates/codeArray.cpp @@ -101,9 +101,9 @@ uint32_t {{config.schedName}}(int *error{{optionalargs()}}) */ {% for id in range(nbFifos) %} {% if fifos[id].hasDelay %} - FIFO<{{fifos[id].theType.ctype}},FIFOSIZE{{id}},{{fifos[id].isArrayAsInt}}> fifo{{id}}({{config.prefix}}buf{{fifos[id].buffer._bufferID}},{{fifos[id].delay}}); + {{fifos[id].fifoClass}}<{{fifos[id].theType.ctype}},FIFOSIZE{{id}},{{fifos[id].isArrayAsInt}}> fifo{{id}}({{config.prefix}}buf{{fifos[id].buffer._bufferID}},{{fifos[id].delay}}); {% else %} - FIFO<{{fifos[id].theType.ctype}},FIFOSIZE{{id}},{{fifos[id].isArrayAsInt}}> fifo{{id}}({{config.prefix}}buf{{fifos[id].buffer._bufferID}}); + {{fifos[id].fifoClass}}<{{fifos[id].theType.ctype}},FIFOSIZE{{id}},{{fifos[id].isArrayAsInt}}> fifo{{id}}({{config.prefix}}buf{{fifos[id].buffer._bufferID}}); {% endif %} {% endfor %} diff --git a/cmsisdsp/cg/static/scheduler/templates/commonc.cpp b/cmsisdsp/cg/static/scheduler/templates/commonc.cpp index fcb9480a..1480f3eb 100644 --- a/cmsisdsp/cg/static/scheduler/templates/commonc.cpp +++ b/cmsisdsp/cg/static/scheduler/templates/commonc.cpp @@ -66,9 +66,9 @@ uint32_t {{config.schedName}}(int *error{{optionalargs()}}) */ {% for id in range(nbFifos) %} {% if fifos[id].hasDelay %} - FIFO<{{fifos[id].theType.ctype}},FIFOSIZE{{id}},{{fifos[id].isArrayAsInt}}> fifo{{id}}({{config.prefix}}buf{{fifos[id].buffer._bufferID}},{{fifos[id].delay}}); + {{fifos[id].fifoClass}}<{{fifos[id].theType.ctype}},FIFOSIZE{{id}},{{fifos[id].isArrayAsInt}}> fifo{{id}}({{config.prefix}}buf{{fifos[id].buffer._bufferID}},{{fifos[id].delay}}); {% else %} - FIFO<{{fifos[id].theType.ctype}},FIFOSIZE{{id}},{{fifos[id].isArrayAsInt}}> fifo{{id}}({{config.prefix}}buf{{fifos[id].buffer._bufferID}}); + {{fifos[id].fifoClass}}<{{fifos[id].theType.ctype}},FIFOSIZE{{id}},{{fifos[id].isArrayAsInt}}> fifo{{id}}({{config.prefix}}buf{{fifos[id].buffer._bufferID}}); {% endif %} {% endfor %} diff --git a/cmsisdsp/cg/static/scheduler/templates/dot_template.dot b/cmsisdsp/cg/static/scheduler/templates/dot_template.dot index 083a6c05..e4e1c730 100644 --- a/cmsisdsp/cg/static/scheduler/templates/dot_template.dot +++ b/cmsisdsp/cg/static/scheduler/templates/dot_template.dot @@ -15,7 +15,7 @@ {{constEdges[theID][1].owner.nodeID}}:{{constEdges[theID][1].name}} {% endmacro -%} -{% macro delayBoxID(id) -%}{{fifos[id].src.owner.nodeID}}Delay{%- endmacro %} +{% macro delayBoxID(id) -%}{{fifos[id].src.owner.nodeID}}{{fifos[id].dst.owner.nodeID}}Delay{%- endmacro %} {% macro delayBox(edge) -%} {% if fifos[edge].hasDelay %} diff --git a/cmsisdsp/version.py b/cmsisdsp/version.py index e551dabb..446ee8bb 100755 --- a/cmsisdsp/version.py +++ b/cmsisdsp/version.py @@ -1,2 +1,2 @@ # Python wrapper version -__version__ = "1.9.2" +__version__ = "1.9.3"