Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ cloudFrontDistributionID = "E2NEF61QWPFRIH"
[markup.goldmark]
[markup.goldmark.renderer]
unsafe = true
[markup.goldmark.extensions]
[markup.goldmark.extensions.passthrough]
enable = true
[markup.goldmark.extensions.passthrough.delimiters]
block = [['\[', '\]'], ['$$', '$$']]
inline = [['\(', '\)']]

[frontmatter]
lastmod = ["lastmod", ":git", "date", "publishDate"]
Expand Down Expand Up @@ -83,3 +89,5 @@ title = 'Arm Learning Paths'
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.'
social_image = '/img/social-image.png'
twitter_handle = '@ArmSoftwareDev'

math = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
title: Getting Started with CMSIS-DSP Using Python

minutes_to_complete: 30

who_is_this_for: Developers writing DSP/AI software

learning_objectives:
- Understand how to use the CMSIS-DSP Python package
- Understand how the Python implementation maps to the C implementation
- Develop a complex application using CMSIS-DSP

prerequisites:
- Some familiarity with DSP programming
- Some familiarity with Python programming
- Knowledge of C
- Some familiarity with CMSIS-DSP
- Python installed on your system

author: Christophe Favergeon

### Tags
skilllevels: Advanced
subjects: Libraries
armips:
- Cortex-M
- Cortex-A
tools_software_languages:
- VS Code
- CMSIS-DSP
- Python
- C
- Jupyter Notebook
operatingsystems:
- Linux
- Windows
- macOS





further_reading:
- resource:
title: Biquad filters with CMSIS-DSP Python package
link: https://developer.arm.com/documentation/102463/latest/
type: documentation
- resource:
title: CMSIS-DSP library
link: https://github.com/ARM-software/CMSIS-DSP
type: Open-source project
- resource:
title: CMSIS-DSP python package
link: https://pypi.org/project/cmsisdsp/
type: Open-source project
- resource:
title: CMSIS-DSP Python package examples and tests
link: https://github.com/ARM-software/CMSIS-DSP/tree/main/PythonWrapper/examples
type: Open-source project
- resource:
title: CMSIS-Stream
link: https://github.com/ARM-software/CMSIS-Stream
type: Open-source project


### FIXED, DO NOT MODIFY
# ================================================================================
weight: 1 # _index.md always has weight of 1 to order correctly
layout: "learningpathall" # All files under learning paths have this same wrapper
learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content.
---
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# ================================================================================
# FIXED, DO NOT MODIFY THIS FILE
# ================================================================================
weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation.
title: "Next Steps" # Always the same, html page title.
layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing.
---
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
title: What is the CMSIS-DSP Python package ?
weight: 2

### FIXED, DO NOT MODIFY
layout: learningpathall
---

## What is CMSIS-DSP ?

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.

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.

## What is the CMSIS-DSP Python package ?

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.

For this reason, the Python API is as close as possible to the C one.

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.

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.

Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
title: Install the Python packages
weight: 3

### FIXED, DO NOT MODIFY
layout: learningpathall
---

## Installing the Python packages
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.

Activate the Python environment you have chosen.

The first package to install is CMSIS-DSP:

```bash
pip install cmsisdsp
```
It will also install `NumPy`, which is a dependency of the CMSIS-DSP Python package.

You'll be working with a Jupyter notebook, so the jupyter package must also be installed:

```bash
pip install jupyter
```

In the Jupyter notebook, you'll be using widgets to play sound, so you'll need to install some additional Jupyter widgets.

```bash
pip install ipywidgets
```

Finally, you'll need packages to read sound files and display plots:


```bash
pip install soundfile
pip install matplotlib
```

you can now launch the Jupyter notebook:

```bash
jupyter notebook
```
Create a new Jupyter notebook by clicking `new` and selecting `Python 3 (ipykernel)`.

The new notebook will be named `Untitled`. Rename it to something more descriptive.

You can now import all the required packages.

Type the following Python code into your notebook and run the cell (shift-enter).
All the Python code in this learning path is intended to be executed in the same Jupyter notebook.

```python
import cmsisdsp as dsp
import cmsisdsp.fixedpoint as fix
import numpy as np
from numpy.lib.stride_tricks import sliding_window_view

# Package for plotting
import matplotlib.pyplot as plt

# Package to display audio widgets in the notebook and upload sound files
import ipywidgets
from IPython.display import display,Audio

# To convert a sound file to a NumPy array
import io
import soundfile as sf

# To load test patterns from the Arm Virtual Hardware Echo Canceller dem
from urllib.request import urlopen
```

You're now ready to move on to the next steps.
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
---
title: Load an audio file
weight: 4

### FIXED, DO NOT MODIFY
layout: learningpathall
---

## Load an audio file

Load an audio file from one of the Arm demo repositories on GitHub.


```python
test_pattern_url="https://github.com/ARM-software/VHT-SystemModeling/blob/main/EchoCanceller/sounds/yesno.wav?raw=true"
f = urlopen(test_pattern_url)
filedata = f.read()
```

You can now play and listen to the audio:
```python
audio=Audio(data=filedata,autoplay=False)
audio
```

An audio widget will appear in your Jupyter notebook. It will look like this:

![audio widget alt-text#center](audiowidget.png "Figure 1. Audio widget")

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.


Next, convert the audio into a NumPy array so that it can be processed using CMSIS-DSP:

```python
data, samplerate = sf.read(io.BytesIO(filedata))
if len(data.shape)>1:
data=data[:,0]
data = data.astype(np.float32)
data=data/np.max(np.abs(data))
dataQ15 = fix.toQ15(data)
```

The code above does the following:
- Converts the audio into a NumPy array
- If the audio is stereo, only one channel is kept
- Normalizes the audio to ensure no value exceeds 1
- Converts the audio to Q15 fixed-point representation to enable the use of CMSIS-DSP fixed-point functions

Now, plot the audio waveform:

```python
plt.plot(data)
plt.show()
```

You'll get the following output:

![audio signal alt-text#center](signal.png "Figure 2. Audio signal")

In the picture, you can see a sequence of words. Between the words, the signal is not zero: there is some noise.

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.

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.



```python
winDuration=30e-3/6
winOverlap=15e-3/6

winLength=int(np.floor(samplerate*winDuration))
winOverlap=int(np.floor(samplerate*winOverlap))
slices=sliding_window_view(data,winLength)[::winOverlap,:]
slices_q15=sliding_window_view(dataQ15,winLength)[::winOverlap,:]
```

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.

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.

Loading
Loading