Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update cmsis-dsp package source and use hanning api provided in PythonWrapper and C #1

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
52 changes: 13 additions & 39 deletions fixed_point_dsp_for_data_scientists.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1099,7 +1099,7 @@
}
],
"source": [
"!pip install git+https://github.com/ARM-software/[email protected]#egg=CMSISDSP\\&subdirectory=CMSIS/DSP/PythonWrapper"
"!pip install cmsisdsp"
]
},
{
Expand Down Expand Up @@ -1163,7 +1163,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"You can see the signal has a similiar shape to the one created with NumPy, however the values on the Y-axis range from -32768 to 32767 rather than 0 to 1.\n"
"You can see the signal has a similiar shape to the one created with NumPy, however the values on the Y-axis range from -32768 to 32767 rather than -1 to 1.\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please make a separate pull request for fixing the text? Thanks.

]
},
{
Expand All @@ -1172,9 +1172,8 @@
"source": [
"### Hanning Window in CMSIS-DSP\n",
"\n",
"CMSIS-DSP does not have a built-in function for creating a Hanning Window for a specific window size. However, we can levergage the built-in [`arm_cos_f32(...)`](https://arm-software.github.io/CMSIS_5/DSP/html/group__cos.html#gace15287f9c64b9b4084d1c797d4c49d8) and `arm_float_to_q15(...)` API's to create a fixed-point Hanning Window. Let's do this using the formula for the [Hann Function](https://en.wikipedia.org/wiki/Hann_function):\n",
"\n",
"$$ f(x; window\\_size) = \\frac{1}{2} \\left[ 1 - cos \\left(\\frac{2\\pi x}{window\\_size}\\right) \\right]$$"
"CMSIS-DSP provide a built-in floating-point Hanning function `arm_hanning_f32(...)` for a specific window size and we can levergage the `arm_float_to_q15(...)` API to to convert to fixed-point format. ",
"\n"
]
},
{
Expand All @@ -1185,15 +1184,9 @@
"source": [
"# Generate the Hanning Window\n",
"from numpy import pi as PI\n",
"from cmsisdsp import arm_cos_f32, arm_float_to_q15\n",
"\n",
"hanning_window_f32 = np.zeros(window_size)\n",
"from cmsisdsp import arm_float_to_q15, arm_hanning_f32\n",
"\n",
"for i in range(window_size):\n",
" hanning_window_f32[i] = 0.5 * (1 - arm_cos_f32(2 * PI * i / window_size ))\n",
" \n",
"\n",
"hanning_window_q15 = arm_float_to_q15(hanning_window_f32)"
"hanning_window_q15 = arm_float_to_q15(arm_hanning_f32(window_size))"
]
},
{
Expand Down Expand Up @@ -1623,7 +1616,7 @@
"As we have seen, the CMSIS-DSP pipeline is similar to the NumPy pipeline. Let's recap the what we've done to create it:\n",
"\n",
"1. Converted the audio samples into Q15 format using the `arm_float_to_q15` function.\n",
"2. Calculated the Hanning Window using the Hann Function formula using the `arm_cos_f32` and `arm_float_to_q15` functions.\n",
"2. Generated the Q15 format Hanning Window using the `arm_hanning_f32` and `arm_float_to_q15` functions.\n",
"3. Learned how to multiply to vectors of the same length using the `arm_mult_q15` function.\n",
"4. Learned how to calculate a Q15 FFT in CMSIS-DSP using the `arm_rfft_instance_q15`, `arm_rfft_init_q15`, and `arm_rfft_q15` functions.\n",
"5. Created a spectrogram representation of the audio signal by striding over the audio signal over time, applying a Hanning Window, and using the FFT function for each window period."
Expand Down Expand Up @@ -1793,27 +1786,20 @@
"\n",
"### Hanning Windows\n",
"\n",
"For the Hanning Window function you must declare a global array variable to store the window function values:\n",
"For the Hanning Window function you must declare two global array variables to hold the floating-point intermediate values and store the final Q15 format window function values:\n",
"\n",
"\n",
"```c\n",
"float_t hanning_window_f32[WINDOW_SIZE];\n",
"q15_t hanning_window_q15[WINDOW_SIZE];\n",
"\n",
"```\n",
"\n",
"Then we can create a C function that initializes the `hanning_window_q15` array at runtime:\n",
"Then we call cmsis functions to initializes the `hanning_window_q15` array at runtime:\n",
"\n",
"```c\n",
"void hanning_window_init_q15(q15_t* hanning_window_q15, size_t size) {\n",
" for (size_t i = 0; i < size; i++) {\n",
" // calculate the Hanning Window value for i as a float32_t\n",
" float32_t f = 0.5 * (1.0 - arm_cos_f32(2 * PI * i / size ));\n",
" \n",
" // convert value for index i from float32_t to q15_t and store\n",
" // in window at position i\n",
" arm_float_to_q15(&f, &hanning_window_q15[i], 1);\n",
" }\n",
"}\n",
"arm_hanning_f32(hanning_window_f32, WINDOW_SIZE);\n",
"arm_float_to_q15(hanning_window_f32, hanning_window_q15, WINDOW_SIZE);\n",
"```\n",
"\n",
"We will need another variable to store the value of the applied Hanning Window on the Input Signal:\n",
Expand Down Expand Up @@ -1932,18 +1918,6 @@
" // all done loop forever ...\n",
" while (1);\n",
"}\n",
"\n",
"\n",
"void hanning_window_init_q15(q15_t* hanning_window_q15, size_t size) {\n",
" for (size_t i = 0; i < size; i++) {\n",
" // calculate the Hanning Window value for i as a float32_t\n",
" float32_t f = 0.5 * (1.0 - arm_cos_f32(2 * PI * i / size ));\n",
"\n",
" // convert value for index i from float32_t to q15_t and store\n",
" // in window at position i\n",
" arm_float_to_q15(&f, &hanning_window_q15[i], 1);\n",
" }\n",
"}\n",
"```"
]
},
Expand Down Expand Up @@ -2039,7 +2013,7 @@
"| | **NumPy** Python | **CMSIS-DSP** Python | **CMSIS-DSP** C |\n",
"| - | ---------------- | -------------------- | --------------- |\n",
"| **Import / Include** | `import numpy as np`| `from cmsisdsp import arm_cos_f32, arm_rfft_instance_q15, arm_rfft_init_q15, arm_mult_q15, arm_rfft_q15, arm_cmplx_mag_q15` | `#include <arm_math.h>` |\n",
"| **Hanning Window initialization** |`hanning_window = np.hanning(window_size)` | <code>hanning_window_f32 = np.zeros(window_size)<br/><br/>for i in range(window_size):<br/>&nbsp;&nbsp;hanning_window_f32[i] = 0.5 * (1 - arm_cos_f32(2 * PI * i / window_size ))<br/><br/>hanning_window_q15 = arm_float_to_q15(hanning_window_f32)</code> | <code>for (size_t i = 0; i < size; i++) {<br/>&nbsp;&nbsp;float32_t f = 0.5 * (1.0 - arm_cos_f32(2 * PI * i / size ));<br/>&nbsp;&nbsp;arm_float_to_q15(&f, &hanning_window_q15[i], 1);<br/>}</code> |\n",
"| **Hanning Window initialization** |`hanning_window = np.hanning(window_size)` | <code>hanning_window_q15 = arm_float_to_q15(arm_hanning_f32(window_size))</code> | <code>arm_hanning_f32(hanning_window_f32, WINDOW_SIZE); arm_float_to_q15(hanning_window_f32, hanning_window_q15, WINDOW_SIZE);</code> |\n",
"| **FFT Initialization** | N/A | <code>rfft_instance_q15 = arm_rfft_instance_q15()<br/>arm_rfft_init_q15(rfft_instance_q15, window_size, 0, 1)</code> | `arm_rfft_init_q15(&S_q15, WINDOW_SIZE, 0, 1);` |\n",
"| **Hanning Window applying** |`processed_window = hanning_window * window` | `processed_window_q15 = arm_mult_q15(window_q15, hanning_window_q15)` | `arm_mult_q15(input_q15, hanning_window_q15, processed_window_q15, WINDOW_SIZE);` |\n",
"| **FFT** | `fft = np.fft.rfft(processed_window)` | `rfft_q15 = arm_rfft_q15(rfft_instance_q15, processed_audio)` | `arm_rfft_q15(&S_q15, processed_window_q15, fft_q15);` |\n",
Expand Down