You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/learning-paths/embedded-and-microcontrollers/cmsisdsp-dev-with-python/how-to-1.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,18 +1,18 @@
1
1
---
2
-
title: What is the CMSIS-DSP Python package ?
2
+
title: CMSIS-DSP Python package
3
3
weight: 2
4
4
5
5
### FIXED, DO NOT MODIFY
6
6
layout: learningpathall
7
7
---
8
8
9
-
## What is CMSIS-DSP?
9
+
## What is CMSIS-DSP?
10
10
11
11
CMSIS-DSP is a general-purpose compute library with a focus on DSP. It was initially developed for Cortex-M processors and has recently been upgraded to also support Cortex-A.
12
12
13
13
On each processor, CMSIS-DSP is optimized for the architecture: DSP extensions on M4 and M7; Helium on M55 and M85; Neon on A55, etc.
14
14
15
-
## What is the CMSIS-DSP Python package?
15
+
## What is the CMSIS-DSP Python package?
16
16
17
17
The CMSIS-DSP Python package is a Python API for CMSIS-DSP. Its goal is to make it easier to develop a C solution using CMSIS-DSP by decreasing the gap between a design environment like Python and the final C implementation.
Copy file name to clipboardExpand all lines: content/learning-paths/embedded-and-microcontrollers/cmsisdsp-dev-with-python/how-to-2.md
+17-25Lines changed: 17 additions & 25 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,10 +6,13 @@ weight: 3
6
6
layout: learningpathall
7
7
---
8
8
9
-
## Installing the Python packages
10
-
The application you will develop with CMSIS-DSP requires a few additional Python packages besides CMSIS-DSP. These need to be installed before you start writing code.
9
+
The application you will develop requires a few additional Python packages besides CMSIS-DSP. These need to be installed before you start writing code.
11
10
12
-
Activate the Python environment you have chosen.
11
+
You should install the packages in a Python virtual environment. For example, you can use:
12
+
13
+
```
14
+
python -m venv cmsis-dsp-venv
15
+
```
13
16
14
17
The first package to install is CMSIS-DSP:
15
18
@@ -18,43 +21,32 @@ pip install cmsisdsp
18
21
```
19
22
It will also install `NumPy`, which is a dependency of the CMSIS-DSP Python package.
20
23
21
-
You'll be working with a Jupyter notebook, so the jupyter package must also be installed:
24
+
You'll be working with a Jupyter notebook, so the `jupyter` package must also be installed:
22
25
23
26
```bash
24
27
pip install jupyter
25
28
```
26
29
27
-
In the Jupyter notebook, you'll be using widgets to play sound, so you'll need to install some additional Jupyter widgets.
28
-
29
-
```bash
30
-
pip install ipywidgets
31
-
```
32
-
33
-
Finally, you'll need packages to read sound files and display plots:
34
-
30
+
Finally, you'll need packages to read sound files, play sound using widgets, and display plots:
35
31
36
32
```bash
37
-
pip install soundfile
38
-
pip install matplotlib
33
+
pip install soundfile ipywidgets matplotlib
39
34
```
40
35
41
-
you can now launch the Jupyter notebook:
36
+
You can now launch the Jupyter notebook with the following command:
42
37
43
38
```bash
44
39
jupyter notebook
45
40
```
46
-
Create a new Jupyter notebook by clicking `new` and selecting `Python 3 (ipykernel)`.
47
-
48
-
The new notebook will be named `Untitled`. Rename it to something more descriptive.
49
-
50
-
You can now import all the required packages.
41
+
A browser window should open showing the source tree your terminal launched from. Create a new Jupyter notebook by clicking the `New` dropdown and selecting `Python 3 (ipykernel)`. The new notebook will be named `Untitled`. Rename it to something more descriptive, for example `cmsis-dsp`.
51
42
52
-
Type the following Python code into your notebook and run the cell (shift-enter).
53
-
All the Python code in this learning path is intended to be executed in the same Jupyter notebook.
43
+
You can now import all the required packages. Copy the following Python code into your notebook and run the cell (Shift+Enter).
44
+
All the Python code blocks in this learning path are intended to be executed in the same Jupyter notebook.
54
45
55
46
```python
56
-
import cmsisdsp as dsp
47
+
import cmsisdsp as dsp
57
48
import cmsisdsp.fixedpoint as fix
49
+
from cmsisdsp import datatype as dt
58
50
import numpy as np
59
51
from numpy.lib.stride_tricks import sliding_window_view
60
52
@@ -69,8 +61,8 @@ from IPython.display import display,Audio
69
61
import io
70
62
import soundfile as sf
71
63
72
-
# To load test patterns from the Arm Virtual Hardware Echo Canceller dem
64
+
# To load test patterns from the Arm Virtual Hardware Echo Canceller demo
73
65
from urllib.request import urlopen
74
66
```
75
67
76
-
You're now ready to move on to the next steps.
68
+
You're now ready to move on to the next steps, where you will set up some audio files for processing.
You'll hear a sequence of the words "yes" and "no", with some noise between them.
33
-
The goal of this learning path is to design an algorithm to remove the noise.
34
-
30
+
You can use it to listen to the audio. You'll hear a sequence of the words "yes" and "no", with some noise between them. The goal of this learning path is to design an algorithm to remove the noise.
35
31
36
32
Next, convert the audio into a NumPy array so that it can be processed using CMSIS-DSP:
37
33
@@ -65,9 +61,7 @@ In the picture, you can see a sequence of words. Between the words, the signal i
65
61
66
62
In a real application, you don't wait for the entire signal to be received. The signal is continuous. The samples are processed as they are received. Processing can either be sample-based or block-based. For this learning path, the processing will be block-based.
67
63
68
-
Before you can move to the next step, this signal must be split into blocks. The processing will occur on small blocks of samples of a given duration.
69
-
70
-
64
+
Before you can move to the next step, this signal must be split into blocks. The processing will occur on small blocks of samples of a given duration, known as windows.
Refer to the [NumPy documentation](https://numpy.org/doc/stable/reference/generated/numpy.lib.stride_tricks.sliding_window_view.html) for details about `sliding_window_view`. It's not the most efficient function, but it is sufficient for this tutorial.
83
-
84
-
The signal is split into overlapping blocks: each block reuses half of the samples from the previous block as defined by the `winOverlap` variable.
76
+
Refer to the [NumPy documentation](https://numpy.org/doc/stable/reference/generated/numpy.lib.stride_tricks.sliding_window_view.html) for details about `sliding_window_view`. It's not the most efficient function, but it is sufficient for this tutorial. The signal is split into overlapping blocks: each block reuses half of the samples from the previous block as defined by the `winOverlap` variable.
85
77
86
-
You are now ready to move on to the next step: you have an audio signal that has been split into overlapping blocks, and processing will occur on those blocks.
78
+
By running that last block, you have an audio signal that has been split into overlapping blocks. The next step is to do some processing on those blocks.
Copy file name to clipboardExpand all lines: content/learning-paths/embedded-and-microcontrollers/cmsisdsp-dev-with-python/how-to-4.md
+30-34Lines changed: 30 additions & 34 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,15 +8,11 @@ layout: learningpathall
8
8
9
9
## Write a simple voice activity detection
10
10
11
-
To remove the noise between speech segments, you need to detect when voice is present.
11
+
To remove the noise between speech segments, you need to detect when voice is present. Voice activity detection (VAD) can be complex, but for this learning path, you'll implement a very simple and naive approach based on _energy_. The idea is that if the environment isn't too noisy, speech should have more energy than the noise.
12
12
13
-
Voice activity detection can be complex, but for this learning path, you'll implement a very simple and naive approach based on energy. The idea is that if the environment isn't too noisy, speech should have more energy than the noise.
13
+
The detection will rely on a comparison with a threshold that must be manually tuned. That threshold will be hard-coded, which might not work in a real-life use-case, but is a sufficient solution for this learning path. You'll first implement a version of the VAD with NumPy, which will serve as a reference. Then you'll implement the same version using CMSIS-DSP with the Q15 fixed-point format.
14
14
15
-
The detection will rely on a comparison with a threshold that must be manually tuned.
16
-
17
-
You'll first implement a version of the voice activity detection (VAD) with NumPy, which will serve as a reference.
18
-
19
-
Then you'll implement the same version using CMSIS-DSP with the Q15 fixed-point format.
15
+
Throughout this section, you should copy the code-blocks and run them in your Jupyter notebook.
20
16
21
17
### NumPy VAD
22
18
@@ -38,9 +34,7 @@ def signal_vad(window):
38
34
return(0)
39
35
```
40
36
41
-
The threshold is hard-coded. It's not a very clean solution, but it's sufficient for a tutorial.
42
-
43
-
When using such a detector, you'll quickly find that it is not sufficient. You'll need another pass to clean up the detection signal.
37
+
Additionally, you'll need another pass to clean up the detection signal.
44
38
45
39
```python
46
40
defclean_vad(v):
@@ -53,7 +47,7 @@ def clean_vad(v):
53
47
return(vmax)
54
48
```
55
49
56
-
Now you can apply this algorithm to the audio signal and plot the VAD detection over it to see if it's working:
50
+
Now you can apply this algorithm to the audio signal and plot the VAD over it to see if it's working:
57
51
58
52
```python
59
53
_,ax=plt.subplots(1,1)
@@ -62,58 +56,58 @@ vad = np.array([[w]*(winLength-winOverlap) for w in cleaned]).flatten()
62
56
ax.plot(data)
63
57
ax.plot(vad)
64
58
```
65
-

59
+

66
60
67
-
The reference implementation works. You can now implement the same version using CMSIS-DSP.
61
+
This plot shows you that the reference implementation works. The next step is to implement a similar graph using CMSIS-DSP.
68
62
69
63
### CMSIS-DSP Q15 VAD
70
64
71
-
First, you need to compute the signal energy from audio in Q15 format using CMSIS-DSP.
65
+
#### Energy
66
+
First, you need to compute the signal energy from audio in Q15 format using CMSIS-DSP.
72
67
73
-
If you look at the CMSIS-DSP documentation, you'll see that the power and log functions don't produce results in Q15 format. Tracking the fixed-point format throughout all lines of an algorithm can be challenging.
68
+
If you look at the CMSIS-DSP documentation, you'll see that the `power` and `vlog` functions don't produce results in Q15 format. Tracking the fixed-point format throughout all lines of an algorithm can be challenging. In this example, this means that:
69
+
70
+
* Subtracting the mean to center the signal - as you did in the reference implementation - is handled in CMSIS-DSP by negating the mean and applying it as an offset to the window. Because the mean is small and the shift is minor relative to the Q15 range, this adjustment won't cause saturation.
71
+
* The resulting `energy` and `dB` values are not in Q15 format because the `power` and `vlog` functions are used
72
+
* The multiplication by 10 from the reference implementation is missing
73
+
74
+
This means that the `signal_energy_q15` will have a different output than the above implementation. Instead of trying to determine the exact fixed-point format of the output and applying the necessary shift to adjust the output's fixed-point format, you will address it in the next step. By tuning the threshold of the detection function, the comparison with the reference VAD can be valid.
74
75
75
-
For this tutorial, instead of trying to determine the exact fixed-point format of the output and applying the necessary shift to adjust the output's fixed-point format, we'll simply tune the threshold of the detection function.
76
76
77
77
```python
78
78
defsignal_energy_q15(window):
79
+
# Calculate window
79
80
mean=dsp.arm_mean_q15(window)
80
-
# Subtracting the mean won't cause saturation
81
-
# So we use the CMSIS-DSP negate function on an array containing a single sample.
82
81
neg_mean=dsp.arm_negate_q15([mean])[0]
83
82
window=dsp.arm_offset_q15(window,neg_mean)
83
+
84
+
# Energy of the window
84
85
energy=dsp.arm_power_q15(window)
85
-
# Energy is not in Q15 format (refer to the CMSIS-DSP documentation).
86
86
energy=dsp.ssat(energy>>20,16)
87
87
dB=dsp.arm_vlog_q15([energy])
88
-
# The output of the `vlog` is not in q15
89
-
# The multiplication by 10 is missing compared to the NumPy
90
-
# reference implementation.
91
-
# The result of this function is not equivalent to the float implementation due to different
92
-
# formats used in intermediate computations.
93
-
# As a consequence, a different threshold must be used to compensate for these differences.
88
+
94
89
return(dB[0])
95
90
```
96
91
92
+
#### VAD
93
+
97
94
The comparison function is very similar to the NumPy reference, but the threshold is different:
98
95
99
96
```python
100
97
defsignal_vad_q15(window):
101
-
# The threshold is not directly comparable to the float implementation
102
-
# due to the different intermediate formats used in the fixed-point implementation.
103
98
if signal_energy_q15(window)>fix.toQ15(-0.38):
104
99
return(1)
105
100
else:
106
101
return(0)
107
102
```
108
103
109
-
Note that in a C code, you would use the output of `fix.toQ15(-0.38)`.
110
-
111
-
`fix.toQ15` is a utility of the Python package to convert float to fixed-point. It is not available in the CMSIS-DSP C implementation.
112
-
CMSIS-DSP C has functions like `arm_float_to_q15` which work on arrays and are meant to be used at runtime. If you need a precomputed constant, you can use a utility function like `fix.toQ15` and use the resulting value in the code.
104
+
{{% notice Note %}}
105
+
In C code, you would hard-code the output of `fix.toQ15(-0.38)`. `fix.toQ15` is a utility of the Python package to convert float to fixed-point, but it is not available in the CMSIS-DSP C implementation. CMSIS-DSP C has functions like `arm_float_to_q15` which work on arrays and are meant to be used at runtime. If you need a pre-computed constant, you can use a utility function like `fix.toQ15` during development and use the resulting value in the C code.
106
+
{{% /notice %}}
113
107
114
-
The clean VAD function is the same for both the NumPy and Q15 versions.
108
+
#### Plot the Q15 implementation
115
109
116
-
Now you can check whether the Q15 version is working by plotting the signal and the output of the Q15 VAD algorithm.
110
+
The clean VAD function is now the same for both the NumPy and Q15 versions. You can check whether the Q15 version is working by plotting the signal and the output of the Q15 VAD algorithm.
117
111
118
112
```python
119
113
_,ax=plt.subplots(1,1)
@@ -122,4 +116,6 @@ vad_q15 = np.array([[w]*winOverlap for w in cleaned]).flatten()
122
116
ax.plot(data)
123
117
ax.plot(vad_q15)
124
118
125
-
```
119
+
```
120
+
121
+
Now that you have a working VAD implementation, move on to the next section to combine the principles into a Python class for noise suppression.
0 commit comments