Skip to content

Commit a26349d

Browse files
authored
Merge pull request #1850 from christophe0606/main
Getting Started with CMSIS-DSP Using Python
2 parents 2f9ca1a + 58017b5 commit a26349d

File tree

19 files changed

+1364
-0
lines changed

19 files changed

+1364
-0
lines changed

config.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ cloudFrontDistributionID = "E2NEF61QWPFRIH"
2727
[markup.goldmark]
2828
[markup.goldmark.renderer]
2929
unsafe = true
30+
[markup.goldmark.extensions]
31+
[markup.goldmark.extensions.passthrough]
32+
enable = true
33+
[markup.goldmark.extensions.passthrough.delimiters]
34+
block = [['\[', '\]'], ['$$', '$$']]
35+
inline = [['\(', '\)']]
3036

3137
[frontmatter]
3238
lastmod = ["lastmod", ":git", "date", "publishDate"]
@@ -83,3 +89,5 @@ title = 'Arm Learning Paths'
8389
description = 'Tutorials with code examples, created by the Arm ecosystem to develop better code faster across all platforms: Servers, phones, laptops, embedded devices, and microcontrollers.'
8490
social_image = '/img/social-image.png'
8591
twitter_handle = '@ArmSoftwareDev'
92+
93+
math = true
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
---
2+
title: Getting Started with CMSIS-DSP Using Python
3+
4+
minutes_to_complete: 30
5+
6+
who_is_this_for: Developers writing DSP/AI software
7+
8+
learning_objectives:
9+
- Understand how to use the CMSIS-DSP Python package
10+
- Understand how the Python implementation maps to the C implementation
11+
- Develop a complex application using CMSIS-DSP
12+
13+
prerequisites:
14+
- Some familiarity with DSP programming
15+
- Some familiarity with Python programming
16+
- Knowledge of C
17+
- Some familiarity with CMSIS-DSP
18+
- Python installed on your system
19+
20+
author: Christophe Favergeon
21+
22+
### Tags
23+
skilllevels: Advanced
24+
subjects: Libraries
25+
armips:
26+
- Cortex-M
27+
- Cortex-A
28+
tools_software_languages:
29+
- VS Code
30+
- CMSIS-DSP
31+
- Python
32+
- C
33+
- Jupyter Notebook
34+
operatingsystems:
35+
- Linux
36+
- Windows
37+
- macOS
38+
39+
40+
41+
42+
43+
further_reading:
44+
- resource:
45+
title: Biquad filters with CMSIS-DSP Python package
46+
link: https://developer.arm.com/documentation/102463/latest/
47+
type: documentation
48+
- resource:
49+
title: CMSIS-DSP library
50+
link: https://github.com/ARM-software/CMSIS-DSP
51+
type: Open-source project
52+
- resource:
53+
title: CMSIS-DSP python package
54+
link: https://pypi.org/project/cmsisdsp/
55+
type: Open-source project
56+
- resource:
57+
title: CMSIS-DSP Python package examples and tests
58+
link: https://github.com/ARM-software/CMSIS-DSP/tree/main/PythonWrapper/examples
59+
type: Open-source project
60+
- resource:
61+
title: CMSIS-Stream
62+
link: https://github.com/ARM-software/CMSIS-Stream
63+
type: Open-source project
64+
65+
66+
### FIXED, DO NOT MODIFY
67+
# ================================================================================
68+
weight: 1 # _index.md always has weight of 1 to order correctly
69+
layout: "learningpathall" # All files under learning paths have this same wrapper
70+
learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content.
71+
---
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
# ================================================================================
3+
# FIXED, DO NOT MODIFY THIS FILE
4+
# ================================================================================
5+
weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation.
6+
title: "Next Steps" # Always the same, html page title.
7+
layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing.
8+
---
8.1 KB
Loading
23 KB
Loading
24.1 KB
Loading
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
title: What is the CMSIS-DSP Python package ?
3+
weight: 2
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
## What is CMSIS-DSP ?
10+
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+
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+
15+
## What is the CMSIS-DSP Python package ?
16+
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.
18+
19+
For this reason, the Python API is as close as possible to the C one.
20+
21+
Fixed-point arithmetic is rarely provided by Python packages, which generally focus on floating-point operations. The CMSIS-DSP Python package provides the same fixed-point arithmetic functions as the C version: Q31, Q15 and Q7. The package also provides floating-point functions and will also support half-precision floats in the future, like the C API.
22+
23+
Finally, the CMSIS-DSP Python package is compatible with NumPy and can be used with all other scientific and AI Python packages such as SciPy and PyTorch.
24+
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
---
2+
title: Install the Python packages
3+
weight: 3
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
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.
11+
12+
Activate the Python environment you have chosen.
13+
14+
The first package to install is CMSIS-DSP:
15+
16+
```bash
17+
pip install cmsisdsp
18+
```
19+
It will also install `NumPy`, which is a dependency of the CMSIS-DSP Python package.
20+
21+
You'll be working with a Jupyter notebook, so the jupyter package must also be installed:
22+
23+
```bash
24+
pip install jupyter
25+
```
26+
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+
35+
36+
```bash
37+
pip install soundfile
38+
pip install matplotlib
39+
```
40+
41+
you can now launch the Jupyter notebook:
42+
43+
```bash
44+
jupyter notebook
45+
```
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.
51+
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.
54+
55+
```python
56+
import cmsisdsp as dsp
57+
import cmsisdsp.fixedpoint as fix
58+
import numpy as np
59+
from numpy.lib.stride_tricks import sliding_window_view
60+
61+
# Package for plotting
62+
import matplotlib.pyplot as plt
63+
64+
# Package to display audio widgets in the notebook and upload sound files
65+
import ipywidgets
66+
from IPython.display import display,Audio
67+
68+
# To convert a sound file to a NumPy array
69+
import io
70+
import soundfile as sf
71+
72+
# To load test patterns from the Arm Virtual Hardware Echo Canceller dem
73+
from urllib.request import urlopen
74+
```
75+
76+
You're now ready to move on to the next steps.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
---
2+
title: Load an audio file
3+
weight: 4
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
## Load an audio file
10+
11+
Load an audio file from one of the Arm demo repositories on GitHub.
12+
13+
14+
```python
15+
test_pattern_url="https://github.com/ARM-software/VHT-SystemModeling/blob/main/EchoCanceller/sounds/yesno.wav?raw=true"
16+
f = urlopen(test_pattern_url)
17+
filedata = f.read()
18+
```
19+
20+
You can now play and listen to the audio:
21+
```python
22+
audio=Audio(data=filedata,autoplay=False)
23+
audio
24+
```
25+
26+
An audio widget will appear in your Jupyter notebook. It will look like this:
27+
28+
![audio widget alt-text#center](audiowidget.png "Figure 1. Audio widget")
29+
30+
You can use it to listen to the audio.
31+
32+
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+
35+
36+
Next, convert the audio into a NumPy array so that it can be processed using CMSIS-DSP:
37+
38+
```python
39+
data, samplerate = sf.read(io.BytesIO(filedata))
40+
if len(data.shape)>1:
41+
data=data[:,0]
42+
data = data.astype(np.float32)
43+
data=data/np.max(np.abs(data))
44+
dataQ15 = fix.toQ15(data)
45+
```
46+
47+
The code above does the following:
48+
- Converts the audio into a NumPy array
49+
- If the audio is stereo, only one channel is kept
50+
- Normalizes the audio to ensure no value exceeds 1
51+
- Converts the audio to Q15 fixed-point representation to enable the use of CMSIS-DSP fixed-point functions
52+
53+
Now, plot the audio waveform:
54+
55+
```python
56+
plt.plot(data)
57+
plt.show()
58+
```
59+
60+
You'll get the following output:
61+
62+
![audio signal alt-text#center](signal.png "Figure 2. Audio signal")
63+
64+
In the picture, you can see a sequence of words. Between the words, the signal is not zero: there is some noise.
65+
66+
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+
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+
71+
72+
```python
73+
winDuration=30e-3/6
74+
winOverlap=15e-3/6
75+
76+
winLength=int(np.floor(samplerate*winDuration))
77+
winOverlap=int(np.floor(samplerate*winOverlap))
78+
slices=sliding_window_view(data,winLength)[::winOverlap,:]
79+
slices_q15=sliding_window_view(dataQ15,winLength)[::winOverlap,:]
80+
```
81+
82+
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.
85+
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.
87+

0 commit comments

Comments
 (0)