Skip to content

Commit f6b9d92

Browse files
authored
Merge pull request #1896 from christophe0606/main
Technical review of CMSIS-DSP : small additional fixes
2 parents f43b26f + 22b44be commit f6b9d92

File tree

4 files changed

+9
-11
lines changed

4 files changed

+9
-11
lines changed

content/learning-paths/embedded-and-microcontrollers/cmsisdsp-dev-with-python/_index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ title: Getting Started with CMSIS-DSP Using Python
33

44
minutes_to_complete: 30
55

6-
draft: true
6+
draft: false
77
cascade:
8-
draft: true
8+
draft: false
99

1010
who_is_this_for: Developers who want to learn how the CMSIS-DSP package can be integrated into their applications
1111

content/learning-paths/embedded-and-microcontrollers/cmsisdsp-dev-with-python/how-to-4.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ First, you need to compute the signal energy from audio in Q15 format using CMSI
6767

6868
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:
6969

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.
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. Using CMSIS-DSP, `arm_negate_q15` is needed to avoid saturation issues that could prevent the value sign from changing (`0x8000` remaining unchanged as `0x8000`). In practice, the mean should be small, and there should be no difference between `-` and `dsp.arm_negate_q15`. However, it is good practice to avoid using `-` or `+` in a fixed-point algorithm when translating it to CMSIS-DSP function calls.
7171
* The resulting `energy` and `dB` values are not in Q15 format because the `power` and `vlog` functions are used
7272
* The multiplication by 10 from the reference implementation is missing
7373

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+
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.
7575

7676

7777
```python

content/learning-paths/embedded-and-microcontrollers/cmsisdsp-dev-with-python/how-to-5.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ The constructor for `NoiseSuppression`:
128128
- Computes the FFT length that can be used for each slice
129129
- Computes the padding needed for the FFT
130130

131-
The FFT length must be a power of 2. The slice length is not necessarily a power of 2. The constructor therefore computes the closest usable power of 2, and the audio slices are padded with zeros on both sides to match the required FFT length. To make the implementation more robust, this could be computed from by taking the smaller power of two greater than the signal length.
131+
The FFT length must be a power of 2. The slice length is not necessarily a power of 2. The constructor therefore computes the smaller power of two greater than the signal length, and the audio slices are padded with zeros on both sides to match the required FFT length.
132132

133133
#### NoiseSuppressionReference constructor
134134

@@ -153,8 +153,7 @@ The constructor for `NoiseSuppressionReference`:
153153

154154
#### subnoise
155155

156-
Calculates the approximate Wiener gain and is applied to all frequency bands of the FFT. The `v` argument is a vector.
157-
156+
Calculates the approximate Wiener gain and it is applied to all frequency bands of the FFT. The `v` argument is a vector. If the gain is negative, it is set to 0. A small value is added to the energy to avoid division by zero.
158157

159158
```python
160159
def subnoise(self,v):
@@ -170,7 +169,6 @@ def subnoise(self,v):
170169
#### remove_noise
171170

172171
Computes the FFT (with padding) and reduces noise in the frequency bands using the approximate Wiener gain.
173-
If the gain is negative, it is set to zero. A small value is added to the energy to avoid division by zero.
174172

175173
The function also uses `window_and_pad`, which is implemented in the final code-block later.
176174
At a glance, this helper method takes care of padding the signal for a basic even-length window, ensuring it runs smoothly with the FFT.

content/learning-paths/embedded-and-microcontrollers/cmsisdsp-dev-with-python/how-to-6.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ if status==0:
8282
3. CMSIS-DSP fixed-point division represents 1 exactly. So in Q31, instead of using `0x7FFFFFFF`, `1` is represented as `0x40000000` with a shift of `1`. This behavior is handled in the algorithm when converting the scaling factor to an approximate Q31 value.
8383

8484
Several safeguards are applied:
85-
* It is assumed that |energy - noise| ≤ energy. If this condition is violated (i.e., noise is greater than energy), the gain is capped at 1 to prevent overflow.
85+
* The Wiener gain is capped at 1 to prevent overflow.
8686
* If the energy is zero, the gain is also set to 1 to avoid divide-by-zero errors.
87-
* When energy == noise, the result should be exactly 1. In this case, `arm_divide_q31` will return a quotient of 0x40000000 and shiftVal of 1. The algorithm detects this specific representation and overrides it, setting quotient = 0x7FFFFFFF and shiftVal = 0, which is a closer approximation to full-scale gain in Q31 without the need for additional shifts.
87+
* When energy == noise, the result should be exactly 1. In this case, `arm_divide_q31` will return a quotient of `0x40000000` and shiftVal of 1. The algorithm detects this specific representation and overrides it, setting quotient = `0x7FFFFFFF` and shiftVal = 0, which is a closer approximation to full-scale gain in Q31 without the need for additional shifts.
8888

8989
```python
9090
quotient=0x7FFFFFFF
@@ -173,7 +173,7 @@ The noise estimation function performs both noise estimation and noise suppressi
173173

174174
## The final Q15 implementation
175175

176-
Try the final implementation first, and then we’ll analyze the differences from the reference implementation.
176+
Try the final implementation:
177177

178178
```python
179179
class NoiseSuppressionQ15(NoiseSuppression):

0 commit comments

Comments
 (0)