diff --git a/SDFTools/.gitignore b/SDFTools/.gitignore index 2fbbb5ee..029b9be8 100755 --- a/SDFTools/.gitignore +++ b/SDFTools/.gitignore @@ -9,4 +9,10 @@ examples/build/bin_example2 examples/build/bin_dsp/ examples/build/bin_example3/ *.pyd +examples/build/localcreate.bat +examples/build/input_example3.txt +examples/build/bin_example6/ +examples/build/input_example6.txt +examples/build/output_example3.txt +examples/build/output_example6.txt diff --git a/SDFTools/README.md b/SDFTools/README.md index c8dca30d..6a787f45 100755 --- a/SDFTools/README.md +++ b/SDFTools/README.md @@ -173,3 +173,23 @@ Here is a list of the nodes supported by default. More can be easily added: - [Example 3 : Working example with CMSIS-DSP and FFT](documentation/example3.md) - [Example 4 : Same as example 3 but with the CMSIS-DSP Python wrapper](documentation/example4.md) +Examples 5 and 6 are showing how to use the CMSIS-DSP MFCC with a synchronous data flow. + +## Building the examples + +The script `create.bat` or `create.sh` in folder `examples/build` must be changed to use the path to the root CMSIS-DSP folder. + +Then, those scripts can be used to create a make using cmake. + +After those steps, typing `make` will build the C examples. + +To run the first one for example you'll have to type (from `build` folder): `bin_example1\example1` + +For the python examples, you need to go to the example folder (for instance `example4`). In the folder, type `python main.py`. + + + +If the dataflow is changed for any Python example, from the corresponding example folder you'll have to type `python graph.py` to regenerate the schedule. And you'll have to type `dot -Tpdf -o test.pdf test.dot` in the Python examples to regenerate the graph picture. + +For the C++ examples, the make is taking care of regenerating the schedule and the dot graph when `graph.py` is edited. + diff --git a/SDFTools/documentation/example2.md b/SDFTools/documentation/example2.md index 61f0dba2..ef8f8bb6 100755 --- a/SDFTools/documentation/example2.md +++ b/SDFTools/documentation/example2.md @@ -20,12 +20,14 @@ It is much more complex: - The node HALF representing a constant is introduced (constant arrays are also supported) - The two streams are added using a CMSIS-DSP function - Then we have a sliding buffer -- A block representing a MFCC +- A block representing a MFCC (a fake MFCC) - Another sliding buffer -- An a block representing TensorFlow Lite for Micro +- An a block representing TensorFlow Lite for Micro (a fake TFLite node) Note that those blocks (MFCC, TFLite) are doing nothing in this example. It is just to illustrate a more complex example that someone may want to experiment with for keyword spotting. +Examples 5 and 6 are showing how to use the CMSIS-DSP MFCC. + The new features compared to `example1` are: - Delay diff --git a/SDFTools/examples/CMakeLists.txt b/SDFTools/examples/CMakeLists.txt index c24ff55a..4b50fb4f 100755 --- a/SDFTools/examples/CMakeLists.txt +++ b/SDFTools/examples/CMakeLists.txt @@ -47,3 +47,4 @@ add_subdirectory(${DSP}/Source bin_dsp) add_subdirectory(example1 bin_example1) add_subdirectory(example2 bin_example2) add_subdirectory(example3 bin_example3) +add_subdirectory(example6 bin_example6) diff --git a/SDFTools/examples/example2/graph.py b/SDFTools/examples/example2/graph.py index 6656b906..ca375007 100755 --- a/SDFTools/examples/example2/graph.py +++ b/SDFTools/examples/example2/graph.py @@ -32,6 +32,7 @@ class StereoSource(GenericSource): def typeName(self): return "StereoSource" +# This is a fake TFLite node just for illustration class TFLite(GenericSink): def __init__(self,name): GenericSink.__init__(self,name) @@ -41,6 +42,8 @@ class TFLite(GenericSink): def typeName(self): return "TFLite" +# This is a fake MFCC just to illustrate how it could be used in a graph. +# For a real MFCC example, look at example5 class MFCC(GenericNode): def __init__(self,name,inLength): GenericNode.__init__(self,name) diff --git a/SDFTools/examples/example3/AppNodes.h b/SDFTools/examples/example3/AppNodes.h index 652c6356..910d296e 100755 --- a/SDFTools/examples/example3/AppNodes.h +++ b/SDFTools/examples/example3/AppNodes.h @@ -35,8 +35,8 @@ using namespace std; #include #include "arm_math.h" -#include "FileSink.h" -#include "FileSource.h" +#include "host/FileSink.h" +#include "host/FileSource.h" #include "CFFT.h" #include "ICFFT.h" diff --git a/SDFTools/examples/example3/custom.h b/SDFTools/examples/example3/custom.h index 5e113834..59b715cf 100755 --- a/SDFTools/examples/example3/custom.h +++ b/SDFTools/examples/example3/custom.h @@ -3,8 +3,6 @@ #define HALF 0.5 extern const float32_t HANN[256]; -extern arm_cfft_instance_f32 CFFT1; -extern arm_cfft_instance_f32 ICFFT1; #endif \ No newline at end of file diff --git a/SDFTools/examples/example4/CMakeLists.txt b/SDFTools/examples/example4/CMakeLists.txt deleted file mode 100755 index 868e39e9..00000000 --- a/SDFTools/examples/example4/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -cmake_minimum_required (VERSION 3.14) -include(CMakePrintHelpers) - -project(Example3) - - -add_executable(example3 main.cpp custom.cpp) - -sdf(example3) -add_sdf_dir(example3) - -target_include_directories(example3 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) - -target_link_libraries(example3 PRIVATE CMSISDSP) - -file(COPY input_example3.txt DESTINATION ${CMAKE_BINARY_DIR}) \ No newline at end of file diff --git a/SDFTools/examples/example4/appnodes.py b/SDFTools/examples/example4/appnodes.py index b62594b1..b20c6257 100755 --- a/SDFTools/examples/example4/appnodes.py +++ b/SDFTools/examples/example4/appnodes.py @@ -28,8 +28,8 @@ from sdf.schedule.simu import * from custom import * -from sdf.nodes.py.FileSink import * -from sdf.nodes.py.FileSource import * +from sdf.nodes.py.host.FileSink import * +from sdf.nodes.py.host.FileSource import * from sdf.nodes.py.CFFT import * from sdf.nodes.py.ICFFT import * from sdf.nodes.py.ToComplex import * diff --git a/SDFTools/examples/example5/appnodes.py b/SDFTools/examples/example5/appnodes.py new file mode 100755 index 00000000..488049d1 --- /dev/null +++ b/SDFTools/examples/example5/appnodes.py @@ -0,0 +1,45 @@ +########################################### +# Project: CMSIS DSP Library +# Title: appnodes.py +# Description: Application nodes for Example 4 +# +# $Date: 29 July 2021 +# $Revision: V1.10.0 +# +# Target Processor: Cortex-M and Cortex-A cores +# -------------------------------------------------------------------- */ +# +# Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the License); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an AS IS BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +############################################ +from sdf.schedule.simu import * +from custom import * + +# Host only nodes +from sdf.nodes.py.host.NumpySink import * +from sdf.nodes.py.host.WavSource import * + +# Embedded nodes +from sdf.nodes.py.StereoToMono import * +from sdf.nodes.py.MFCC import * + + + + + + + + diff --git a/SDFTools/examples/example5/custom.py b/SDFTools/examples/example5/custom.py new file mode 100755 index 00000000..63da65a3 --- /dev/null +++ b/SDFTools/examples/example5/custom.py @@ -0,0 +1,4 @@ +import numpy as np + + + diff --git a/SDFTools/examples/example5/dynamic_image.py b/SDFTools/examples/example5/dynamic_image.py new file mode 100755 index 00000000..5543da03 --- /dev/null +++ b/SDFTools/examples/example5/dynamic_image.py @@ -0,0 +1,46 @@ +""" +================================================= +Animated image using a precomputed list of images +================================================= + +""" + +import numpy as np +import matplotlib.pyplot as plt +import matplotlib.animation as animation + +fig, ax = plt.subplots() + + +def f(x, y): + return np.sin(x) + np.cos(y) + +x = np.linspace(0, 2 * np.pi, 120) +y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1) + +# ims is a list of lists, each row is a list of artists to draw in the +# current frame; here we are just animating one artist, the image, in +# each frame +ims = [] +for i in range(60): + x += np.pi / 15. + y += np.pi / 20. + im = ax.imshow(f(x, y), animated=True) + if i == 0: + ax.imshow(f(x, y)) # show an initial one first + ims.append([im]) + +ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True, + repeat_delay=1000) + +# To save the animation, use e.g. +# +# ani.save("movie.mp4") +# +# or +# +# writer = animation.FFMpegWriter( +# fps=15, metadata=dict(artist='Me'), bitrate=1800) +# ani.save("movie.mp4", writer=writer) + +plt.show() diff --git a/SDFTools/examples/example5/graph.py b/SDFTools/examples/example5/graph.py new file mode 100755 index 00000000..6d6ef45b --- /dev/null +++ b/SDFTools/examples/example5/graph.py @@ -0,0 +1,60 @@ +import sys +import numpy as np + +sys.path.append("../..") + +from sdf import * + +from sharedconfig import * + + + +q15Type = CType(Q15) + +### The feature computed by the graph is one second of MFCCs. +### So the nbMFCCOutputs is computed from this and with the additional +### assumption that it must be even. +### Because the MFCC slising window is sliding by half a second +### each time (half number of MFCCs) +src=WavSource("src",NBCHANNELS*AUDIO_INTERRUPT_LENGTH) +src.addLiteralArg("test_stereo.wav") + +toMono=StereoToMono("toMono",q15Type,AUDIO_INTERRUPT_LENGTH) + +slidingAudio=SlidingBuffer("audioWin",q15Type,FFTSize,AudioOverlap) +slidingMFCC=SlidingBuffer("mfccWin",q15Type,numOfDctOutputs*nbMFCCOutputs,numOfDctOutputs*nbMFCCOutputs>>1) + +mfcc=MFCC("mfcc",q15Type,FFTSize,numOfDctOutputs) +mfcc.addVariableArg("mfccConfig") + +sink=NumpySink("sink",q15Type,nbMFCCOutputs * numOfDctOutputs) +sink.addVariableArg("dispbuf") + +g = Graph() + +g.connect(src.o, toMono.i) + +g.connect(toMono.o, slidingAudio.i) + +g.connect(slidingAudio.o, mfcc.i) + +g.connect(mfcc.o,slidingMFCC.i) +g.connect(slidingMFCC.o,sink.i) + +print("Generate graphviz and code") + + + +sched = g.computeSchedule() +print("Schedule length = %d" % sched.scheduleLength) +print("Memory usage %d bytes" % sched.memory) +# +conf=Configuration() +conf.debugLimit=12 +conf.pyOptionalArgs="mfccConfig,dispbuf" + +sched.pythoncode(".",config=conf) + +with open("test.dot","w") as f: + sched.graphviz(f) + diff --git a/SDFTools/examples/example5/main.py b/SDFTools/examples/example5/main.py new file mode 100755 index 00000000..be134250 --- /dev/null +++ b/SDFTools/examples/example5/main.py @@ -0,0 +1,56 @@ +import sched as s +import matplotlib.pyplot as plt +from matplotlib import cm +import matplotlib.animation as animation + +import cmsisdsp as dsp +import numpy as np +import cmsisdsp.fixedpoint as f +import cmsisdsp.mfcc as mfcc +import scipy.signal as sig +from cmsisdsp.datatype import F32,Q31,Q15 +from sharedconfig import * +import cmsisdsp.datatype as dt + +mfccq15=dsp.arm_mfcc_instance_q15() + +windowQ15 = dt.convert(sig.hamming(FFTSize, sym=False),Q15) +filtLen,filtPos,packedFiltersQ15 = mfcc.melFilterMatrix(Q15,freq_min, freq_high, numOfMelFilters,sample_rate,FFTSize) +dctMatrixFiltersQ15 = mfcc.dctMatrix(Q15,numOfDctOutputs, numOfMelFilters) + + +status=dsp.arm_mfcc_init_q15(mfccq15,FFTSize,numOfMelFilters,numOfDctOutputs, + dctMatrixFiltersQ15, + filtPos,filtLen,packedFiltersQ15,windowQ15) + +#DISPBUF = np.zeros(nbMFCCOutputs*numOfDctOutputs) +DISPBUF=[] +print("Start") + +nb,error = s.scheduler(mfccq15,DISPBUF) + +print("Nb sched = %d" % nb) + + +fig, ax = plt.subplots() + +# The test signal is 5 second long +# MFCC are slided by 0.5 second by the last window +# Each sink entry is a one second of MFCC +ims = [] +for i in range(10): + mfccdata = (1<<8)*f.Q15toF32(DISPBUF[i]) + mfccdata=mfccdata.reshape((nbMFCCOutputs,numOfDctOutputs)) + mfccdata= np.swapaxes(mfccdata, 0 ,1) + if i==0: + ax.imshow(mfccdata, vmin=-10, vmax=10,interpolation='nearest',cmap=cm.coolwarm ,origin='lower') + + im=ax.imshow(mfccdata, vmin=-10, vmax=10,interpolation='nearest', animated=True,cmap=cm.coolwarm ,origin='lower') + ims.append([im]) + +ani = animation.ArtistAnimation(fig, ims, interval=500, blit=True, + repeat_delay=500) + +#ani.save("mfcc.mp4") + +plt.show() diff --git a/SDFTools/examples/example5/mfcc.mp4 b/SDFTools/examples/example5/mfcc.mp4 new file mode 100755 index 00000000..01db42a8 Binary files /dev/null and b/SDFTools/examples/example5/mfcc.mp4 differ diff --git a/SDFTools/examples/example5/sched.py b/SDFTools/examples/example5/sched.py new file mode 100755 index 00000000..972c8f51 --- /dev/null +++ b/SDFTools/examples/example5/sched.py @@ -0,0 +1,947 @@ +# +# Generated with CMSIS-DSP SDF Scripts. +# The generated code is not covered by CMSIS-DSP license. +# +# The support classes and code is covered by CMSIS-DSP license. +# + +import sys + +# To find SDF module +sys.path.append("../..") + +import numpy as np +import cmsisdsp as dsp +from sdf.schedule.simu import * +from appnodes import * +from custom import * + +DEBUGSCHED=False + +# +# FIFO buffers +# + + +FIFOSIZE0=384 +buf0=np.zeros(FIFOSIZE0,dtype=np.int16) + +FIFOSIZE1=768 +buf1=np.zeros(FIFOSIZE1,dtype=np.int16) + +FIFOSIZE2=1024 +buf2=np.zeros(FIFOSIZE2,dtype=np.int16) + +FIFOSIZE3=377 +buf3=np.zeros(FIFOSIZE3,dtype=np.int16) + +FIFOSIZE4=754 +buf4=np.zeros(FIFOSIZE4,dtype=np.int16) + + +def scheduler(mfccConfig,dispbuf): + sdfError=0 + nbSchedule=0 + debugCounter=12 + + # + # Create FIFOs objects + # + fifo0=FIFO(FIFOSIZE0,buf0) + fifo1=FIFO(FIFOSIZE1,buf1) + fifo2=FIFO(FIFOSIZE2,buf2) + fifo3=FIFO(FIFOSIZE3,buf3) + fifo4=FIFO(FIFOSIZE4,buf4) + + # + # Create node objects + # + audioWin = SlidingBuffer(1024,256,fifo1,fifo2); + mfcc = MFCC(1024,13,fifo2,fifo3,mfccConfig); + mfccWin = SlidingBuffer(754,377,fifo3,fifo4); + sink = NumpySink(754,fifo4,dispbuf); + src = WavSource(384,fifo0,"test_stereo.wav"); + toMono = StereoToMono(384,192,fifo0,fifo1); + + while((sdfError==0) and (debugCounter > 0)): + nbSchedule = nbSchedule + 1 + + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = src.run() + if sdfError < 0: + break + sdfError = toMono.run() + if sdfError < 0: + break + sdfError = audioWin.run() + if sdfError < 0: + break + sdfError = mfcc.run() + if sdfError < 0: + break + sdfError = mfccWin.run() + if sdfError < 0: + break + sdfError = sink.run() + if sdfError < 0: + break + + debugCounter = debugCounter - 1 + return(nbSchedule,sdfError) diff --git a/SDFTools/examples/example5/sharedconfig.py b/SDFTools/examples/example5/sharedconfig.py new file mode 100755 index 00000000..2e9c99c3 --- /dev/null +++ b/SDFTools/examples/example5/sharedconfig.py @@ -0,0 +1,25 @@ +import sys +import numpy as np + + +FS=16000 +NBCHANNELS=2 # stereo +# You can try with 120 +AUDIO_INTERRUPT_LENGTH = 192 + +# MFCC Description +sample_rate = 16000 +FFTSize = 1024 +AudioOverlap = 256 +numOfDctOutputs = 13 + +freq_min = 64 +freq_high = sample_rate / 2 +numOfMelFilters = 20 + +# NB MFCC Outputs to cover one second of signal with the window overlap +nbMFCCOutputs = int(np.floor((sample_rate - FFTSize) / AudioOverlap)) + +if nbMFCCOutputs%2 == 1: + nbMFCCOutputs = nbMFCCOutputs + 1 + diff --git a/SDFTools/examples/example5/test.dot b/SDFTools/examples/example5/test.dot new file mode 100755 index 00000000..2bbf4bd7 --- /dev/null +++ b/SDFTools/examples/example5/test.dot @@ -0,0 +1,66 @@ + + + +digraph structs { + node [shape=plaintext] + rankdir=LR + edge [arrowsize=0.5] + fontname="times" + + +audioWin [label=< + + + + +
audioWin
(SlidingBuffer)
>]; + +mfcc [label=< + + + + +
mfcc
(MFCC)
>]; + +mfccWin [label=< + + + + +
mfccWin
(SlidingBuffer)
>]; + +sink [label=< + + + + +
sink
(NumpySink)
>]; + +src [label=< + + + + +
src
(WavSource)
>]; + +toMono [label=< + + + + +
toMono
(StereoToMono)
>]; + + + +src:i -> toMono:i [headlabel=<384>,taillabel=<384>,label="q15(384)"] + +toMono:i -> audioWin:i [headlabel=<768>,taillabel=<192>,label="q15(768)"] + +audioWin:i -> mfcc:i [headlabel=<1024>,taillabel=<1024>,label="q15(1024)"] + +mfcc:i -> mfccWin:i [headlabel=<377>,taillabel=<13>,label="q15(377)"] + +mfccWin:i -> sink:i [headlabel=<754>,taillabel=<754>,label="q15(754)"] + + +} diff --git a/SDFTools/examples/example5/test.pdf b/SDFTools/examples/example5/test.pdf new file mode 100755 index 00000000..bac671a5 Binary files /dev/null and b/SDFTools/examples/example5/test.pdf differ diff --git a/SDFTools/examples/example5/test_stereo.wav b/SDFTools/examples/example5/test_stereo.wav new file mode 100755 index 00000000..369e67b1 Binary files /dev/null and b/SDFTools/examples/example5/test_stereo.wav differ diff --git a/SDFTools/examples/example6/AppNodes.h b/SDFTools/examples/example6/AppNodes.h new file mode 100755 index 00000000..2179291e --- /dev/null +++ b/SDFTools/examples/example6/AppNodes.h @@ -0,0 +1,44 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: AppNodes.h + * Description: Application nodes for Example 6 + * + * $Date: 29 July 2021 + * $Revision: V1.10.0 + * + * Target Processor: Cortex-M and Cortex-A cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _APPNODES_H_ +#define _APPNODES_H_ + +#include +#include +#include +using namespace std; +#include +#include "arm_math.h" + +#include "host/FileSink.h" +#include "host/FileSource.h" +#include "MFCC.h" + + + +#endif \ No newline at end of file diff --git a/SDFTools/examples/example6/CMakeLists.txt b/SDFTools/examples/example6/CMakeLists.txt new file mode 100755 index 00000000..1591cd23 --- /dev/null +++ b/SDFTools/examples/example6/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required (VERSION 3.14) +include(CMakePrintHelpers) + +project(Example6) + + +add_executable(example6 main.cpp mfccConfigData.c) + +sdf(example6) +add_sdf_dir(example6) + +target_include_directories(example6 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(example6 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/generated) + +target_link_libraries(example6 PRIVATE CMSISDSP) + +file(COPY input_example6.txt DESTINATION ${CMAKE_BINARY_DIR}) \ No newline at end of file diff --git a/SDFTools/examples/example6/custom.h b/SDFTools/examples/example6/custom.h new file mode 100755 index 00000000..1b94b756 --- /dev/null +++ b/SDFTools/examples/example6/custom.h @@ -0,0 +1,4 @@ +#ifndef _CUSTOM_H_ + + +#endif \ No newline at end of file diff --git a/SDFTools/examples/example6/generated/scheduler.cpp b/SDFTools/examples/example6/generated/scheduler.cpp new file mode 100755 index 00000000..8edc781d --- /dev/null +++ b/SDFTools/examples/example6/generated/scheduler.cpp @@ -0,0 +1,106 @@ +/* + +Generated with CMSIS-DSP SDF Scripts. +The generated code is not covered by CMSIS-DSP license. + +The support classes and code is covered by CMSIS-DSP license. + +*/ + + +#include "arm_math.h" +#include "custom.h" +#include "GenericNodes.h" +#include "AppNodes.h" +#include "scheduler.h" + +/*********** + +FIFO buffers + +************/ +#define FIFOSIZE0 256 +#define FIFOSIZE1 256 +#define FIFOSIZE2 13 +#define FIFOSIZE3 26 + +#define BUFFERSIZE0 256 +float32_t buf0[BUFFERSIZE0]={0}; + +#define BUFFERSIZE1 256 +float32_t buf1[BUFFERSIZE1]={0}; + +#define BUFFERSIZE2 13 +float32_t buf2[BUFFERSIZE2]={0}; + +#define BUFFERSIZE3 26 +float32_t buf3[BUFFERSIZE3]={0}; + + +uint32_t scheduler(int *error,arm_mfcc_instance_f32 *mfccConfig) +{ + int sdfError=0; + uint32_t nbSchedule=0; + int32_t debugCounter=1; + + /* + Create FIFOs objects + */ + FIFO fifo0(buf0); + FIFO fifo1(buf1); + FIFO fifo2(buf2); + FIFO fifo3(buf3); + + /* + Create node objects + */ + SlidingBuffer audioWin(fifo0,fifo1); + MFCC mfcc(fifo1,fifo2,mfccConfig); + SlidingBuffer mfccWin(fifo2,fifo3); + FileSink sink(fifo3,"output_example6.txt"); + FileSource src(fifo0,"input_example6.txt"); + + while((sdfError==0) && (debugCounter > 0)) + { + + sdfError = src.run(); + CHECKERROR; + sdfError = audioWin.run(); + CHECKERROR; + sdfError = mfcc.run(); + CHECKERROR; + sdfError = mfccWin.run(); + CHECKERROR; + sdfError = sink.run(); + CHECKERROR; + sdfError = sink.run(); + CHECKERROR; + sdfError = src.run(); + CHECKERROR; + sdfError = audioWin.run(); + CHECKERROR; + sdfError = mfcc.run(); + CHECKERROR; + sdfError = mfccWin.run(); + CHECKERROR; + sdfError = sink.run(); + CHECKERROR; + sdfError = sink.run(); + CHECKERROR; + sdfError = audioWin.run(); + CHECKERROR; + sdfError = mfcc.run(); + CHECKERROR; + sdfError = mfccWin.run(); + CHECKERROR; + sdfError = sink.run(); + CHECKERROR; + sdfError = sink.run(); + CHECKERROR; + + debugCounter--; + nbSchedule++; + } + *error=sdfError; + return(nbSchedule); +} diff --git a/SDFTools/examples/example6/generated/scheduler.h b/SDFTools/examples/example6/generated/scheduler.h new file mode 100755 index 00000000..ce6845ae --- /dev/null +++ b/SDFTools/examples/example6/generated/scheduler.h @@ -0,0 +1,25 @@ +/* + +Generated with CMSIS-DSP SDF Scripts. +The generated code is not covered by CMSIS-DSP license. + +The support classes and code is covered by CMSIS-DSP license. + +*/ + +#ifndef _SCHED_H_ +#define _SCHED_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern uint32_t scheduler(int *error,arm_mfcc_instance_f32 *mfccConfig); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/SDFTools/examples/example6/graph.py b/SDFTools/examples/example6/graph.py new file mode 100755 index 00000000..a7972885 --- /dev/null +++ b/SDFTools/examples/example6/graph.py @@ -0,0 +1,57 @@ +import sys +import numpy as np + +sys.path.append("../..") + +from sdf import * + +from sharedconfig import * + + + +floatType = CType(F32) + +### The feature computed by the graph is one second of MFCCs. +### So the nbMFCCOutputs is computed from this and with the additional +### assumption that it must be even. +### Because the MFCC slising window is sliding by half a second +### each time (half number of MFCCs) +src=FileSource("src",NBCHANNELS*AUDIO_INTERRUPT_LENGTH) +src.addLiteralArg("input_example6.txt") + + +slidingAudio=SlidingBuffer("audioWin",floatType,FFTSize,FFTSize>>1) +slidingMFCC=SlidingBuffer("mfccWin",floatType,2*numOfDctOutputs,numOfDctOutputs) + +mfcc=MFCC("mfcc",floatType,FFTSize,numOfDctOutputs) +mfcc.addVariableArg("mfccConfig") + +sink=FileSink("sink",numOfDctOutputs) +sink.addLiteralArg("output_example6.txt") + +g = Graph() + +g.connect(src.o, slidingAudio.i) + +g.connect(slidingAudio.o, mfcc.i) + +g.connect(mfcc.o,slidingMFCC.i) +g.connect(slidingMFCC.o,sink.i) + +print("Generate graphviz and code") + + + +sched = g.computeSchedule() +print("Schedule length = %d" % sched.scheduleLength) +print("Memory usage %d bytes" % sched.memory) +# +conf=Configuration() +conf.debugLimit=1 +conf.cOptionalArgs="arm_mfcc_instance_f32 *mfccConfig" + +sched.ccode("generated",config=conf) + +with open("test.dot","w") as f: + sched.graphviz(f) + diff --git a/SDFTools/examples/example6/input_example6.txt b/SDFTools/examples/example6/input_example6.txt new file mode 100755 index 00000000..b5a520aa --- /dev/null +++ b/SDFTools/examples/example6/input_example6.txt @@ -0,0 +1,256 @@ +0.65507051 +-0.94647589 +0.00627239 +0.14151286 +-0.10863318 +-0.36370327 +0.05777126 +-0.11915792 +0.50183546 +-0.31461335 +0.66440771 +0.05389963 +0.39690544 +0.25424852 +-0.17045277 +0.09649268 +0.87357385 +-0.44666372 +-0.02637822 +-0.10055151 +-0.14610252 +-0.05981251 +-0.02999124 +0.60923213 +0.10530095 +0.35684248 +0.21845946 +0.47845017 +-0.60206979 +0.25186908 +-0.27410056 +-0.07080467 +-0.05109539 +-0.2666572 +0.25483105 +-0.86459185 +0.07733397 +-0.58535444 +0.06230904 +-0.04161475 +-0.17467296 +0.77721125 +-0.01728161 +-0.32141218 +0.36674466 +-0.17932843 +0.78486115 +0.12469579 +-0.94796877 +0.05536031 +0.32627676 +0.46628512 +-0.02585836 +-0.51439834 +0.21387904 +0.16319442 +-0.01020818 +-0.77161183 +0.07754634 +-0.24970455 +0.2368003 +0.35167963 +0.14620137 +-0.02415204 +0.91086167 +-0.02434647 +-0.3968239 +-0.04703925 +-0.43905103 +-0.34834965 +0.33728158 +0.15138992 +-0.43218885 +0.26619718 +0.07177906 +0.33393581 +-0.50306915 +-0.63101084 +-0.08128395 +-0.06569788 +0.84232797 +-0.32436751 +0.02528537 +-0.3498329 +0.41859931 +0.07794887 +0.4571989 +0.24290963 +0.08437417 +-0.01371585 +-0.00103008 +0.83978697 +-0.29001237 +0.14438743 +0.11943318 +-0.25576402 +0.25151083 +0.07886626 +0.11565781 +-0.01582203 +0.1310246 +-0.5553611 +-0.37950665 +0.44179691 +0.08460877 +0.30646419 +0.48927934 +-0.21240309 +0.36844264 +0.49686615 +-0.81617664 +0.52221472 +-0.05188992 +-0.03929655 +-0.47674501 +-0.54506781 +0.30711148 +0.10049337 +-0.47549213 +0.59106713 +-0.62276051 +-0.35182917 +0.14612027 +0.56142168 +-0.01053732 +0.35782179 +-0.27220781 +-0.03672346 +-0.11282222 +0.3364912 +-0.22352515 +-0.04245287 +0.56968605 +-0.14023724 +-0.82982905 +0.00860008 +0.37920345 +-0.53749318 +-0.12761215 +0.08567603 +0.47020765 +-0.28794812 +-0.33888971 +0.01850441 +0.66848233 +-0.26532759 +-0.20777571 +-0.68342729 +-0.41498696 +0.00593224 +0.02229368 +0.75596329 +0.29447568 +-0.1106449 +0.24181939 +0.05807497 +-0.14343857 +0.304988 +0.00689148 +-0.06264758 +0.25864714 +-0.22252155 +0.28621689 +0.17031599 +-0.34694027 +-0.01625718 +0.39834181 +0.01259659 +-0.28022716 +-0.02506168 +-0.10276881 +0.31733924 +0.02787068 +-0.09824124 +0.45147797 +0.14451518 +0.17996395 +-0.70594978 +-0.92943177 +0.13649282 +-0.5938426 +0.50289928 +0.19635269 +0.16811504 +0.05803999 +0.0037204 +0.13847419 +0.30568038 +0.3700732 +0.21257548 +-0.31151753 +-0.28836886 +0.68743932 +-0.11084429 +-0.4673766 +0.16637754 +-0.38992572 +0.16505578 +-0.07499844 +0.04226538 +-0.11042177 +0.0704542 +-0.632819 +-0.54898472 +0.26498649 +-0.59380386 +0.93387213 +0.06526726 +-0.23223558 +0.07941394 +0.14325166 +0.26914661 +0.00925575 +-0.34282161 +-0.51418231 +-0.12011075 +-0.26676314 +-0.09999028 +0.03027513 +0.22846503 +-0.08930338 +-0.1867156 +0.66297846 +0.32220769 +-0.06015469 +0.04034043 +0.09595597 +-1. +-0.42933352 +0.25069376 +-0.26030918 +-0.28511861 +-0.19931228 +0.24408572 +-0.3231952 +0.45688981 +-0.07354078 +0.25669449 +-0.44202722 +0.11928406 +-0.32826109 +0.52660984 +0.03067858 +0.11095242 +0.19933679 +0.03042371 +-0.34768682 +0.09108447 +0.61234556 +0.1854931 +0.19680502 +0.27617564 +0.33381827 +-0.47358967 +0.28714328 +-0.27495982 \ No newline at end of file diff --git a/SDFTools/examples/example6/main.cpp b/SDFTools/examples/example6/main.cpp new file mode 100755 index 00000000..b02773f2 --- /dev/null +++ b/SDFTools/examples/example6/main.cpp @@ -0,0 +1,23 @@ +#include +#include +#include "arm_math.h" +#include "scheduler.h" +#include "mfccConfigData.h" + +static arm_mfcc_instance_f32 mfcc; + +int main(int argc, char const *argv[]) +{ + int error; + printf("Start\n"); + + arm_mfcc_init_f32(&mfcc, + 256,20,13,mfcc_dct_coefs_config1_f32, + mfcc_filter_pos_config1_f32,mfcc_filter_len_config1_f32, + mfcc_filter_coefs_config1_f32, + mfcc_window_coefs_config1_f32); + + uint32_t nb = scheduler(&error,&mfcc); + printf("Nb = %d\n",nb); + return 0; +} \ No newline at end of file diff --git a/SDFTools/examples/example6/mfccConfigData.c b/SDFTools/examples/example6/mfccConfigData.c new file mode 100755 index 00000000..bc5ff2c0 --- /dev/null +++ b/SDFTools/examples/example6/mfccConfigData.c @@ -0,0 +1,105 @@ +#include "mfccConfigData.h" + + +const float32_t mfcc_dct_coefs_config1_f32[NB_MFCC_DCT_COEFS_CONFIG1_F32]={ +0.316228f,0.316228f,0.316228f,0.316228f,0.316228f,0.316228f,0.316228f,0.316228f,0.316228f,0.316228f, +0.316228f,0.316228f,0.316228f,0.316228f,0.316228f,0.316228f,0.316228f,0.316228f,0.316228f,0.316228f, +0.315253f,0.307490f,0.292156f,0.269628f,0.240461f,0.205374f,0.165229f,0.121015f,0.073822f,0.024811f, +-0.024811f,-0.073822f,-0.121015f,-0.165229f,-0.205374f,-0.240461f,-0.269628f,-0.292156f,-0.307490f,-0.315253f, +0.312334f,0.281761f,0.223607f,0.143564f,0.049469f,-0.049469f,-0.143564f,-0.223607f,-0.281761f,-0.312334f, +-0.312334f,-0.281761f,-0.223607f,-0.143564f,-0.049469f,0.049469f,0.143564f,0.223607f,0.281761f,0.312334f, +0.307490f,0.240461f,0.121015f,-0.024811f,-0.165229f,-0.269628f,-0.315253f,-0.292156f,-0.205374f,-0.073822f, +0.073822f,0.205374f,0.292156f,0.315253f,0.269628f,0.165229f,0.024811f,-0.121015f,-0.240461f,-0.307490f, +0.300750f,0.185874f,0.000000f,-0.185874f,-0.300750f,-0.300750f,-0.185874f,-0.000000f,0.185874f,0.300750f, +0.300750f,0.185874f,0.000000f,-0.185874f,-0.300750f,-0.300750f,-0.185874f,-0.000000f,0.185874f,0.300750f, +0.292156f,0.121015f,-0.121015f,-0.292156f,-0.292156f,-0.121015f,0.121015f,0.292156f,0.292156f,0.121015f, +-0.121015f,-0.292156f,-0.292156f,-0.121015f,0.121015f,0.292156f,0.292156f,0.121015f,-0.121015f,-0.292156f, +0.281761f,0.049469f,-0.223607f,-0.312334f,-0.143564f,0.143564f,0.312334f,0.223607f,-0.049469f,-0.281761f, +-0.281761f,-0.049469f,0.223607f,0.312334f,0.143564f,-0.143564f,-0.312334f,-0.223607f,0.049469f,0.281761f, +0.269628f,-0.024811f,-0.292156f,-0.240461f,0.073822f,0.307490f,0.205374f,-0.121015f,-0.315253f,-0.165229f, +0.165229f,0.315253f,0.121015f,-0.205374f,-0.307490f,-0.073822f,0.240461f,0.292156f,0.024811f,-0.269628f, +0.255834f,-0.097720f,-0.316228f,-0.097720f,0.255834f,0.255834f,-0.097720f,-0.316228f,-0.097720f,0.255834f, +0.255834f,-0.097720f,-0.316228f,-0.097720f,0.255834f,0.255834f,-0.097720f,-0.316228f,-0.097720f,0.255834f, +0.240461f,-0.165229f,-0.292156f,0.073822f,0.315253f,0.024811f,-0.307490f,-0.121015f,0.269628f,0.205374f, +-0.205374f,-0.269628f,0.121015f,0.307490f,-0.024811f,-0.315253f,-0.073822f,0.292156f,0.165229f,-0.240461f, +0.223607f,-0.223607f,-0.223607f,0.223607f,0.223607f,-0.223607f,-0.223607f,0.223607f,0.223607f,-0.223607f, +-0.223607f,0.223607f,0.223607f,-0.223607f,-0.223607f,0.223607f,0.223607f,-0.223607f,-0.223607f,0.223607f, +0.205374f,-0.269628f,-0.121015f,0.307490f,0.024811f,-0.315253f,0.073822f,0.292156f,-0.165229f,-0.240461f, +0.240461f,0.165229f,-0.292156f,-0.073822f,0.315253f,-0.024811f,-0.307490f,0.121015f,0.269628f,-0.205374f, +0.185874f,-0.300750f,-0.000000f,0.300750f,-0.185874f,-0.185874f,0.300750f,0.000000f,-0.300750f,0.185874f, +0.185874f,-0.300750f,-0.000000f,0.300750f,-0.185874f,-0.185874f,0.300750f,-0.000000f,-0.300750f,0.185874f, +}; + + + + +const float32_t mfcc_window_coefs_config1_f32[NB_MFCC_WIN_COEFS_CONFIG1_F32]={ +0.080000f,0.080139f,0.080554f,0.081246f,0.082215f,0.083459f,0.084979f,0.086772f,0.088839f,0.091177f, +0.093786f,0.096663f,0.099807f,0.103217f,0.106890f,0.110823f,0.115015f,0.119464f,0.124165f,0.129117f, +0.134316f,0.139760f,0.145445f,0.151367f,0.157524f,0.163911f,0.170525f,0.177361f,0.184415f,0.191684f, +0.199162f,0.206846f,0.214731f,0.222811f,0.231083f,0.239540f,0.248179f,0.256993f,0.265978f,0.275128f, +0.284438f,0.293901f,0.303513f,0.313267f,0.323157f,0.333179f,0.343325f,0.353589f,0.363966f,0.374448f, +0.385031f,0.395706f,0.406469f,0.417312f,0.428229f,0.439213f,0.450258f,0.461358f,0.472504f,0.483691f, +0.494912f,0.506160f,0.517429f,0.528711f,0.540000f,0.551289f,0.562571f,0.573840f,0.585088f,0.596309f, +0.607496f,0.618642f,0.629742f,0.640787f,0.651771f,0.662688f,0.673531f,0.684294f,0.694969f,0.705552f, +0.716034f,0.726411f,0.736675f,0.746821f,0.756842f,0.766733f,0.776487f,0.786099f,0.795562f,0.804872f, +0.814022f,0.823007f,0.831821f,0.840460f,0.848917f,0.857189f,0.865269f,0.873154f,0.880838f,0.888316f, +0.895585f,0.902639f,0.909475f,0.916089f,0.922476f,0.928633f,0.934555f,0.940240f,0.945684f,0.950883f, +0.955835f,0.960536f,0.964985f,0.969177f,0.973110f,0.976783f,0.980193f,0.983337f,0.986214f,0.988823f, +0.991161f,0.993228f,0.995021f,0.996541f,0.997785f,0.998754f,0.999446f,0.999861f,1.000000f,0.999861f, +0.999446f,0.998754f,0.997785f,0.996541f,0.995021f,0.993228f,0.991161f,0.988823f,0.986214f,0.983337f, +0.980193f,0.976783f,0.973110f,0.969177f,0.964985f,0.960536f,0.955835f,0.950883f,0.945684f,0.940240f, +0.934555f,0.928633f,0.922476f,0.916089f,0.909475f,0.902639f,0.895585f,0.888316f,0.880838f,0.873154f, +0.865269f,0.857189f,0.848917f,0.840460f,0.831821f,0.823007f,0.814022f,0.804872f,0.795562f,0.786099f, +0.776487f,0.766733f,0.756842f,0.746821f,0.736675f,0.726411f,0.716034f,0.705552f,0.694969f,0.684294f, +0.673531f,0.662688f,0.651771f,0.640787f,0.629742f,0.618642f,0.607496f,0.596309f,0.585088f,0.573840f, +0.562571f,0.551289f,0.540000f,0.528711f,0.517429f,0.506160f,0.494912f,0.483691f,0.472504f,0.461358f, +0.450258f,0.439213f,0.428229f,0.417312f,0.406469f,0.395706f,0.385031f,0.374448f,0.363966f,0.353589f, +0.343325f,0.333179f,0.323157f,0.313267f,0.303513f,0.293901f,0.284438f,0.275128f,0.265978f,0.256993f, +0.248179f,0.239540f,0.231083f,0.222811f,0.214731f,0.206846f,0.199162f,0.191684f,0.184415f,0.177361f, +0.170525f,0.163911f,0.157524f,0.151367f,0.145445f,0.139760f,0.134316f,0.129117f,0.124165f,0.119464f, +0.115015f,0.110823f,0.106890f,0.103217f,0.099807f,0.096663f,0.093786f,0.091177f,0.088839f,0.086772f, +0.084979f,0.083459f,0.082215f,0.081246f,0.080554f,0.080139f,}; + + + +const uint32_t mfcc_filter_pos_config1_f32[NB_MFCC_NB_FILTER_CONFIG1_F32]={ +2,3,5,7,9,11,14,17,20,24, +28,33,38,44,51,59,67,77,88,100, +}; +const uint32_t mfcc_filter_len_config1_f32[NB_MFCC_NB_FILTER_CONFIG1_F32]={ +3,4,4,4,5,6,6,7,8,9, +10,11,13,15,16,18,21,23,25,28, +}; + + + + +const float32_t mfcc_filter_coefs_config1_f32[NB_MFCC_FILTER_COEFS_CONFIG1_F32]={ +0.663153f,0.706417f,0.118907f,0.293583f,0.881093f,0.568845f,0.051741f,0.431155f,0.948259f,0.563868f, +0.102097f,0.436132f,0.897903f,0.663777f,0.246640f,0.336223f,0.753360f,0.848733f,0.468360f,0.104042f, +0.151267f,0.531640f,0.895958f,0.754478f,0.418519f,0.095146f,0.245522f,0.581481f,0.904854f,0.783449f, +0.482615f,0.191913f,0.216551f,0.517385f,0.808087f,0.910681f,0.638322f,0.374294f,0.118101f,0.089319f, +0.361678f,0.625706f,0.881899f,0.869293f,0.627454f,0.392207f,0.163200f,0.130707f,0.372546f,0.607793f, +0.836800f,0.940111f,0.722642f,0.510517f,0.303479f,0.101291f,0.059889f,0.277358f,0.489483f,0.696521f, +0.898709f,0.903729f,0.710588f,0.521674f,0.336804f,0.155811f,0.096271f,0.289412f,0.478326f,0.663196f, +0.844189f,0.978535f,0.804826f,0.634543f,0.467554f,0.303734f,0.142965f,0.021465f,0.195174f,0.365457f, +0.532446f,0.696266f,0.857035f,0.985135f,0.830139f,0.677876f,0.528253f,0.381178f,0.236568f,0.094340f, +0.014865f,0.169861f,0.322124f,0.471747f,0.618822f,0.763432f,0.905660f,0.954417f,0.816725f,0.681196f, +0.547761f,0.416357f,0.286924f,0.159402f,0.033737f,0.045583f,0.183275f,0.318804f,0.452239f,0.583643f, +0.713076f,0.840598f,0.966263f,0.909875f,0.787764f,0.667357f,0.548606f,0.431467f,0.315895f,0.201850f, +0.089293f,0.090125f,0.212236f,0.332643f,0.451394f,0.568533f,0.684105f,0.798150f,0.910707f,0.978184f, +0.868486f,0.760166f,0.653187f,0.547518f,0.443127f,0.339983f,0.238056f,0.137319f,0.037744f,0.021816f, +0.131514f,0.239834f,0.346813f,0.452482f,0.556873f,0.660017f,0.761944f,0.862681f,0.962256f,0.939305f, +0.841975f,0.745730f,0.650547f,0.556401f,0.463272f,0.371136f,0.279973f,0.189762f,0.100485f,0.012121f, +0.060695f,0.158025f,0.254270f,0.349453f,0.443599f,0.536728f,0.628864f,0.720027f,0.810238f,0.899515f, +0.987879f,0.924653f,0.838062f,0.752330f,0.667442f,0.583381f,0.500130f,0.417674f,0.335998f,0.255088f, +0.174929f,0.095508f,0.016810f,0.075347f,0.161938f,0.247670f,0.332558f,0.416619f,0.499870f,0.582326f, +0.664002f,0.744912f,0.825071f,0.904492f,0.983190f,0.938824f,0.861535f,0.784933f,0.709004f,0.633737f, +0.559120f,0.485144f,0.411795f,0.339065f,0.266942f,0.195416f,0.124479f,0.054119f,0.061176f,0.138465f, +0.215067f,0.290996f,0.366263f,0.440880f,0.514856f,0.588205f,0.660935f,0.733058f,0.804583f,0.875521f, +0.945881f,0.984329f,0.915098f,0.846418f,0.778279f,0.710675f,0.643596f,0.577034f,0.510981f,0.445430f, +0.380372f,0.315802f,0.251710f,0.188091f,0.124938f,0.062243f,}; + + + diff --git a/SDFTools/examples/example6/mfccConfigData.h b/SDFTools/examples/example6/mfccConfigData.h new file mode 100755 index 00000000..21513561 --- /dev/null +++ b/SDFTools/examples/example6/mfccConfigData.h @@ -0,0 +1,61 @@ +#ifndef _MFCC_DATA_H_ +#define _MFCC_DATA_H_ + +#include "arm_math_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/***** + + DCT COEFFICIENTS FOR THE MFCC + +*****/ + + +#define NB_MFCC_DCT_COEFS_CONFIG1_F32 260 +extern const float32_t mfcc_dct_coefs_config1_f32[NB_MFCC_DCT_COEFS_CONFIG1_F32]; + + + +/***** + + WINDOW COEFFICIENTS + +*****/ + + +#define NB_MFCC_WIN_COEFS_CONFIG1_F32 256 +extern const float32_t mfcc_window_coefs_config1_f32[NB_MFCC_WIN_COEFS_CONFIG1_F32]; + + + +/***** + + MEL FILTER COEFFICIENTS FOR THE MFCC + +*****/ + +#define NB_MFCC_NB_FILTER_CONFIG1_F32 20 +extern const uint32_t mfcc_filter_pos_config1_f32[NB_MFCC_NB_FILTER_CONFIG1_F32]; +extern const uint32_t mfcc_filter_len_config1_f32[NB_MFCC_NB_FILTER_CONFIG1_F32]; + + + + + +#define NB_MFCC_FILTER_COEFS_CONFIG1_F32 236 +extern const float32_t mfcc_filter_coefs_config1_f32[NB_MFCC_FILTER_COEFS_CONFIG1_F32]; + + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/SDFTools/examples/example6/mfccconfig.yaml b/SDFTools/examples/example6/mfccconfig.yaml new file mode 100755 index 00000000..ceb8dad9 --- /dev/null +++ b/SDFTools/examples/example6/mfccconfig.yaml @@ -0,0 +1,20 @@ +dct: + config1_f32: + melFilters: 20 + dctOutputs: 13 + type: "f32" + +melfilter: + config1_f32 : + fftlength: 256 + fmin: 64 + fmax: 8000 + samplingRate : 16000 + melFilters: 20 + type: "f32" + +window: + config1_f32: + fftlength: 256 + type: "f32" + win: "hamming" diff --git a/SDFTools/examples/example6/sharedconfig.py b/SDFTools/examples/example6/sharedconfig.py new file mode 100755 index 00000000..1b39be27 --- /dev/null +++ b/SDFTools/examples/example6/sharedconfig.py @@ -0,0 +1,25 @@ +import sys +import numpy as np + + +FS=16000 +NBCHANNELS=1 # stereo +# You can try with 120 +AUDIO_INTERRUPT_LENGTH = 192 + +# MFCC Description +sample_rate = 16000 +FFTSize = 256 +numOfDctOutputs = 13 + +freq_min = 64 +freq_high = sample_rate / 2 +numOfMelFilters = 20 + +# NB MFCC Outputs to cover one second of signal with the window overlap +nbMFCCOutputs = int(np.floor(sample_rate / (FFTSize >> 1))) + +if nbMFCCOutputs%2 == 1: + nbMFCCOutputs = nbMFCCOutputs + 1 + +print(nbMFCCOutputs) \ No newline at end of file diff --git a/SDFTools/examples/example6/test.dot b/SDFTools/examples/example6/test.dot new file mode 100755 index 00000000..5d03f6b6 --- /dev/null +++ b/SDFTools/examples/example6/test.dot @@ -0,0 +1,57 @@ + + + +digraph structs { + node [shape=plaintext] + rankdir=LR + edge [arrowsize=0.5] + fontname="times" + + +audioWin [label=< + + + + +
audioWin
(SlidingBuffer)
>]; + +mfcc [label=< + + + + +
mfcc
(MFCC)
>]; + +mfccWin [label=< + + + + +
mfccWin
(SlidingBuffer)
>]; + +sink [label=< + + + + +
sink
(FileSink)
>]; + +src [label=< + + + + +
src
(FileSource)
>]; + + + +src:i -> audioWin:i [headlabel=<128>,taillabel=<192>,label="f32(256)"] + +audioWin:i -> mfcc:i [headlabel=<256>,taillabel=<256>,label="f32(256)"] + +mfcc:i -> mfccWin:i [headlabel=<13>,taillabel=<13>,label="f32(13)"] + +mfccWin:i -> sink:i [headlabel=<13>,taillabel=<26>,label="f32(26)"] + + +} diff --git a/SDFTools/examples/example6/test.pdf b/SDFTools/examples/example6/test.pdf new file mode 100755 index 00000000..dcf9b4c8 Binary files /dev/null and b/SDFTools/examples/example6/test.pdf differ diff --git a/SDFTools/sdf/nodes/cpp/CFFT.h b/SDFTools/sdf/nodes/cpp/CFFT.h index f86b0d34..59ad9737 100755 --- a/SDFTools/sdf/nodes/cpp/CFFT.h +++ b/SDFTools/sdf/nodes/cpp/CFFT.h @@ -57,6 +57,33 @@ public: }; +#if defined(ARM_FLOAT16_SUPPORTED) +/* + +The CMSIS-DSP CFFT F32 + +*/ +template +class CFFT: public GenericNode +{ +public: + CFFT(FIFOBase &src,FIFOBase &dst):GenericNode(src,dst){ + arm_status status; + status=arm_cfft_init_f16(&sfft,inputSize>>1); + }; + + int run(){ + float16_t *a=this->getReadBuffer(); + float16_t *b=this->getWriteBuffer(); + memcpy((void*)b,(void*)a,inputSize*sizeof(float16_t)); + arm_cfft_f16(&sfft,b,0,1); + return(0); + }; + + arm_cfft_instance_f16 sfft; + +}; +#endif /* The CMSIS-DSP CFFT Q15 diff --git a/SDFTools/sdf/nodes/cpp/ICFFT.h b/SDFTools/sdf/nodes/cpp/ICFFT.h index b702acb9..dfcdee84 100755 --- a/SDFTools/sdf/nodes/cpp/ICFFT.h +++ b/SDFTools/sdf/nodes/cpp/ICFFT.h @@ -57,6 +57,34 @@ public: }; +#if defined(ARM_FLOAT16_SUPPORTED) +/* + +The CMSIS-DSP ICFFT F32 + +*/ +template +class ICFFT: public GenericNode +{ +public: + ICFFT(FIFOBase &src,FIFOBase &dst):GenericNode(src,dst){ + arm_status status; + status=arm_cfft_init_f16(&sifft,inputSize>>1); + }; + + int run(){ + float16_t *a=this->getReadBuffer(); + float16_t *b=this->getWriteBuffer(); + memcpy((void*)b,(void*)a,inputSize*sizeof(float16_t)); + arm_cfft_f16(&sifft,b,1,1); + return(0); + }; + + arm_cfft_instance_f16 sifft; + +}; +#endif + /* The CMSIS-DSP ICFFT Q15 diff --git a/SDFTools/sdf/nodes/cpp/MFCC.h b/SDFTools/sdf/nodes/cpp/MFCC.h new file mode 100755 index 00000000..8cb872d1 --- /dev/null +++ b/SDFTools/sdf/nodes/cpp/MFCC.h @@ -0,0 +1,154 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: MFCC.h + * Description: Node for CMSIS-DSP MFCC + * + * $Date: 06 October 2021 + * $Revision: V1.10.0 + * + * Target Processor: Cortex-M and Cortex-A cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _MFCC_H_ +#define _MFCC_H_ + +#include + +template +class MFCC; + +/* + +The MFCC configuration data has to be generated with the script DSP/Scripts/GenMFCCDataForCPP.py. +It is using a yaml file to describe the configuration + +*/ + +/* + +The CMSIS-DSP MFCC F32 + +*/ +template +class MFCC: public GenericNode +{ +public: + MFCC(FIFOBase &src,FIFOBase &dst,const arm_mfcc_instance_f32 *config):GenericNode(src,dst){ + mfccConfig = config; +#if defined(ARM_MFCC_CFFT_BASED) + memory.resize(2*inputSize); +#else + memory.resize(inputSize + 2); +#endif + }; + + int run(){ + float32_t *a=this->getReadBuffer(); + float32_t *b=this->getWriteBuffer(); + arm_mfcc_f32(mfccConfig,a,b,memory.data()); + return(0); + }; + + const arm_mfcc_instance_f32 *mfccConfig; + std::vector memory; +}; + +#if defined(ARM_FLOAT16_SUPPORTED) +/* + +The CMSIS-DSP MFCC F16 + +*/ +template +class MFCC: public GenericNode +{ +public: + MFCC(FIFOBase &src,FIFOBase &dst,const arm_mfcc_instance_f16 *config):GenericNode(src,dst){ + mfccConfig = config; +#if defined(ARM_MFCC_CFFT_BASED) + memory.resize(2*inputSize); +#else + memory.resize(inputSize + 2); +#endif + }; + + int run(){ + float16_t *a=this->getReadBuffer(); + float16_t *b=this->getWriteBuffer(); + arm_mfcc_f16(mfccConfig,a,b,memory.data()); + return(0); + }; + + const arm_mfcc_instance_f16 *mfccConfig; + std::vector memory; +}; +#endif + +/* + +The CMSIS-DSP MFCC Q31 + +*/ +template +class MFCC: public GenericNode +{ +public: + MFCC(FIFOBase &src,FIFOBase &dst,const arm_mfcc_instance_q31 *config):GenericNode(src,dst){ + mfccConfig = config; + memory.resize(2*inputSize); + }; + + int run(){ + q31_t *a=this->getReadBuffer(); + q31_t *b=this->getWriteBuffer(); + arm_mfcc_q31(mfccConfig,a,b,memory.data()); + return(0); + }; + + const arm_mfcc_instance_q31 *mfccConfig; + std::vector memory; +}; + +/* + +The CMSIS-DSP MFCC Q15 + +*/ +template +class MFCC: public GenericNode +{ +public: + MFCC(FIFOBase &src,FIFOBase &dst,const arm_mfcc_instance_q15 *config):GenericNode(src,dst){ + mfccConfig = config; + memory.resize(2*inputSize); + }; + + int run(){ + q15_t *a=this->getReadBuffer(); + q15_t *b=this->getWriteBuffer(); + arm_mfcc_q15(mfccConfig,a,b,memory.data()); + return(0); + }; + + const arm_mfcc_instance_q15 *mfccConfig; + std::vector memory; +}; + + +#endif \ No newline at end of file diff --git a/SDFTools/sdf/nodes/cpp/StereoToMonoQ15.h b/SDFTools/sdf/nodes/cpp/StereoToMono.h similarity index 54% rename from SDFTools/sdf/nodes/cpp/StereoToMonoQ15.h rename to SDFTools/sdf/nodes/cpp/StereoToMono.h index 5421b0f9..e885b79a 100755 --- a/SDFTools/sdf/nodes/cpp/StereoToMonoQ15.h +++ b/SDFTools/sdf/nodes/cpp/StereoToMono.h @@ -26,15 +26,15 @@ * limitations under the License. */ -#ifndef _STEREOTOMONOQ15_H_ -#define _STEREOTOMONOQ15_H_ +#ifndef _STEREOTOMONO_H_ +#define _STEREOTOMONO_H_ template -class StereoToMonoQ15; +class StereoToMono; template -class StereoToMonoQ15: public GenericNode +class StereoToMono: public GenericNode { public: StereoToMonoQ15(FIFOBase &src,FIFOBase &dst): @@ -53,4 +53,44 @@ public: }; +template +class StereoToMono: public GenericNode +{ +public: + StereoToMono(FIFOBase &src,FIFOBase &dst): + GenericNode(src,dst){}; + + + int run(){ + q31_t *a=this->getReadBuffer(); + q31_t *b=this->getWriteBuffer(); + for(int i = 0; i>1) + (a[2*i+1]>>1); + } + return(0); + }; + +}; + +template +class StereoToMono: public GenericNode +{ +public: + StereoToMono(FIFOBase &src,FIFOBase &dst): + GenericNode(src,dst){}; + + + int run(){ + float32_t *a=this->getReadBuffer(); + float32_t *b=this->getWriteBuffer(); + for(int i = 0; i 0: a[:frame.size] = frame a[frame.size:] = 0 return(0) else: - return(-1) + a[:]=0 + return(0) def __del__(self): self._file.close() \ No newline at end of file diff --git a/SDFTools/sdf/schedule/simu.py b/SDFTools/sdf/schedule/simu.py index 3b56e5a6..a1d7a013 100755 --- a/SDFTools/sdf/schedule/simu.py +++ b/SDFTools/sdf/schedule/simu.py @@ -141,7 +141,7 @@ class SlidingBuffer(GenericNode): a=self.getReadBuffer() b=self.getWriteBuffer() b[:self._overlap] = self._memory - b[self._overlap:self._windowSize]=a + b[self._overlap:self._windowSize]=a[:self._windowSize-self._overlap] self._memory[:self._overlap] = a[self._windowSize-(self._overlap<<1):self._windowSize-self._overlap] return(0) diff --git a/SDFTools/sdf/schedule/standard.py b/SDFTools/sdf/schedule/standard.py index 7225f5da..488b6175 100755 --- a/SDFTools/sdf/schedule/standard.py +++ b/SDFTools/sdf/schedule/standard.py @@ -104,6 +104,43 @@ class ToReal(GenericNode): def typeName(self): return "ToReal" + +class NullSink(GenericSink): + def __init__(self,name,theType,inLength): + GenericSink.__init__(self,name) + self.addInput("i",theType,inLength) + + @property + def typeName(self): + return "NullSink" + +class StereoToMono(GenericNode): + def __init__(self,name,theType,outLength): + GenericNode.__init__(self,name) + self.addInput("i",theType,2*outLength) + self.addOutput("o",theType,outLength) + + @property + def typeName(self): + return "StereoToMono" + + +class MFCC(GenericNode): + def __init__(self,name,theType,inLength,outLength): + GenericNode.__init__(self,name) + + self.addInput("i",theType,inLength) + self.addOutput("o",theType,outLength) + + @property + def typeName(self): + return "MFCC" + +############################# +# +# Host only Nodes +# + class FileSource(GenericSource): def __init__(self,name,inLength): GenericSource.__init__(self,name) @@ -124,29 +161,9 @@ class FileSink(GenericSink): def typeName(self): return "FileSink" -class NullSink(GenericSink): - def __init__(self,name,theType,inLength): - GenericSink.__init__(self,name) - self.addInput("i",theType,inLength) - - @property - def typeName(self): - return "NullSink" - -class StereoToMonoQ15(GenericNode): - def __init__(self,name,outLength): - GenericNode.__init__(self,name) - q15Type=CType(Q15) - self.addInput("i",q15Type,2*outLength) - self.addOutput("o",q15Type,outLength) - - @property - def typeName(self): - return "StereoToMonoQ15" - ############################# # -# Python only Nodes +# Python and host only Nodes # @@ -170,3 +187,12 @@ class WavSink(GenericSink): def typeName(self): return "WavSink" +class NumpySink(GenericSink): + def __init__(self,name,theType,inLength): + GenericSink.__init__(self,name) + self.addInput("i",theType,inLength) + + @property + def typeName(self): + return "NumpySink" + diff --git a/SDFTools/sdf/templates/code.py b/SDFTools/sdf/templates/code.py index 9f190954..130e0af2 100755 --- a/SDFTools/sdf/templates/code.py +++ b/SDFTools/sdf/templates/code.py @@ -41,7 +41,7 @@ def {{config.schedName}}({{optionalargs()}}): sdfError=0 nbSchedule=0 {% if config.debug %} - debugCounter={{config.debugLimit}}; + debugCounter={{config.debugLimit}} {% endif %} # diff --git a/Scripts/GenMFCCDataForCPP.py b/Scripts/GenMFCCDataForCPP.py index 84e162dd..c933d862 100755 --- a/Scripts/GenMFCCDataForCPP.py +++ b/Scripts/GenMFCCDataForCPP.py @@ -45,7 +45,7 @@ parser = argparse.ArgumentParser(description='Generate MFCC Data for CPP') parser.add_argument('-n', nargs='?',type = str, default="mfccdata", help="mfcc file name") parser.add_argument('-d', nargs='?',type = str, default="Testing/Source/Tests", help="mfcc c file directory") parser.add_argument('-i', nargs='?',type = str, default="Testing/Include/Tests", help="mfcc h file directory") -parser.add_argument('others', nargs=argparse.REMAINDER) +parser.add_argument('others', help="yaml configuration file", nargs=argparse.REMAINDER) args = parser.parse_args() diff --git a/Source/TransformFunctions/arm_mfcc_q15.c b/Source/TransformFunctions/arm_mfcc_q15.c index b0058d94..417cf9ee 100755 --- a/Source/TransformFunctions/arm_mfcc_q15.c +++ b/Source/TransformFunctions/arm_mfcc_q15.c @@ -69,13 +69,17 @@ @return none @par Description - The number of input samples if the FFT length used + The number of input samples is the FFT length used when initializing the instance data structure. The temporary buffer has a 2*fft length. The source buffer is modified by this function. + The function may saturate. If the FFT length is too + big and the number of MEL filters too small then the fixed + point computations may saturate. + */ arm_status arm_mfcc_q15( diff --git a/Source/TransformFunctions/arm_mfcc_q31.c b/Source/TransformFunctions/arm_mfcc_q31.c index c3798c7a..57db4b35 100755 --- a/Source/TransformFunctions/arm_mfcc_q31.c +++ b/Source/TransformFunctions/arm_mfcc_q31.c @@ -69,13 +69,17 @@ @return none @par Description - The number of input samples if the FFT length used + The number of input samples is the FFT length used when initializing the instance data structure. The temporary buffer has a 2*fft length. The source buffer is modified by this function. + The function may saturate. If the FFT length is too + big and the number of MEL filters too small then the fixed + point computations may saturate. + */