Skip to content

Commit 7d6b224

Browse files
committed
modules: tensorflow: Add initial tensorflow micro module
This is WIP and adds a TFLM module based on micro_speech example to do audio classification. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
1 parent 6b08180 commit 7d6b224

22 files changed

+1707
-0
lines changed

app/boards/intel_adsp_ace15_mtpm.conf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ CONFIG_LIBRARY_MANAGER=y
5757
CONFIG_LIBRARY_AUTH_SUPPORT=y
5858
CONFIG_LIBRARY_BASE_ADDRESS=0xa0688000
5959
CONFIG_LIBRARY_BUILD_LIB=y
60+
CONFIG_CPP=y
61+
CONFIG_STD_CPP17=y
6062

6163
# SOF / logging
6264
CONFIG_SOF_LOG_LEVEL_INF=y

app/configs/mtl/modules.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ CONFIG_COMP_MULTIBAND_DRC=m
2121
CONFIG_COMP_GOOGLE_CTC_AUDIO_PROCESSING=m
2222
CONFIG_COMP_GOOGLE_RTC_AUDIO_PROCESSING=m
2323
CONFIG_COMP_TESTER=m
24+
CONFIG_COMP_TFMICRO=m

scripts/tensorflow-clone.sh

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/bin/bash
2+
# SPDX-License-Identifier: BSD-3-Clause
3+
# Copyright(c) 2025 Intel Corporation. All rights reserved.
4+
5+
# fail immediately on any errors
6+
set -e
7+
8+
# Array of TFLM Git repository URLs. Add or remove repositories as needed.
9+
declare -a REPOS=(
10+
"https://github.com/thesofproject/nnlib-hifi4"
11+
"https://github.com/tensorflow/tflite-micro"
12+
"https://github.com/thesofproject/flatbuffers"
13+
"https://github.com/google/gemmlowp"
14+
"https://github.com/google/ruy"
15+
)
16+
17+
# Commit ID to check for (optional). If specified, the script will update
18+
# the repository if this commit ID is not found. Leave empty to skip.
19+
declare -a COMMIT_ID=(
20+
"cdedfb1a1044eb774915de21b63a1b6aa93276f6"
21+
"e86d97b6237f88ab5925c0b41e3e3589a1560d86"
22+
"f5acabf4e1a3fcba024081bb1871a2ed59aa1c28"
23+
"719139ce755a0f31cbf1c37f7f98adcc7fc9f425"
24+
"d37128311b445e758136b8602d1bbd2a755e115d"
25+
)
26+
27+
# Directory where repositories will be cloned/updated.
28+
BASE_DIR="$HOME/work/sof" # Or any other desired location
29+
30+
# Function to check if a commit ID exists in a repository
31+
check_commit() {
32+
local repo_dir="$1"
33+
local commit_id="$2"
34+
35+
if [ -z "$commit_id" ]; then
36+
return 0 # Skip check if no commit ID is provided
37+
fi
38+
39+
if ! git -C "$repo_dir" rev-parse --quiet --verify "$commit_id" >/dev/null 2>&1; then
40+
return 1 # Commit ID not found
41+
else
42+
return 0 # Commit ID found
43+
fi
44+
}
45+
46+
47+
# Function to update the repository
48+
update_repo() {
49+
local repo_dir="$1"
50+
echo "Updating repository: $repo_dir"
51+
git -C "$repo_dir" fetch --all
52+
git -C "$repo_dir" pull
53+
}
54+
55+
# Main script logic
56+
mkdir -p "$BASE_DIR"
57+
58+
for ((i = 0; i < ${#REPOS[@]}; i++)); do
59+
echo "Counter: $i, Value: ${REPOS[i]}"
60+
repo_url=${REPOS[i]}
61+
62+
repo_name=$(basename "$repo_url" .git) # Extract repo name
63+
repo_dir="$BASE_DIR/$repo_name"
64+
65+
if [ ! -d "$repo_dir" ]; then
66+
echo "Cloning repository: $repo_url"
67+
git clone "$repo_url" "$repo_dir" || { echo "git clone failed for $repo_url"; exit 1; }
68+
elif ! check_commit "$repo_dir" "${COMMIT_ID[i]}"; then
69+
update_repo "$repo_dir"
70+
else
71+
echo "Repository $repo_name is up to date."
72+
fi
73+
done
74+
75+
echo "All repositories processed."

src/audio/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ if(NOT CONFIG_COMP_MODULE_SHARED_LIBRARY_BUILD)
8989
if(CONFIG_COMP_VOLUME)
9090
add_subdirectory(volume)
9191
endif()
92+
if(CONFIG_COMP_TFMICRO)
93+
add_subdirectory(tfmicro)
94+
endif()
9295
if(CONFIG_ZEPHYR_NATIVE_DRIVERS)
9396
list(APPEND base_files host-zephyr.c)
9497
sof_list_append_ifdef(CONFIG_COMP_DAI base_files dai-zephyr.c)
@@ -146,6 +149,9 @@ if(NOT CONFIG_COMP_MODULE_SHARED_LIBRARY_BUILD)
146149
if(CONFIG_DTS_CODEC)
147150
add_subdirectory(codec)
148151
endif()
152+
if(CONFIG_COMP_TFMICRO)
153+
add_subdirectory(tfmicro)
154+
endif()
149155

150156
return()
151157
endif()

src/audio/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ rsource "asrc/Kconfig"
143143

144144
rsource "tdfb/Kconfig"
145145

146+
rsource "tfmicro/Kconfig"
147+
146148
config COMP_MODULE_ADAPTER
147149
bool "Module adapter"
148150
default y

src/audio/tfmicro/CMakeLists.txt

Lines changed: 456 additions & 0 deletions
Large diffs are not rendered by default.

src/audio/tfmicro/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
3+
config COMP_TFMICRO
4+
tristate "Tensorflow Micro component"
5+
default n
6+
help
7+
Select for Tensorflow component support.

src/audio/tfmicro/README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# SOF Tensorflow Micro Integration
2+
3+
The TFLM module integrates tensorflow micro into SOF as an audio classifiction and in the future an audio processing module. This module is currently still work in progress, and needs a few features to be completed before its ready for production.
4+
5+
## Building
6+
7+
Please run ```./scripts/tensorflow-clone.sh``` before building as this will clone all dependecies required to build tensor flow micro with optimized xtensa kernels.
8+
9+
To build as built-in, select ```CONFIG_COMP_TFMICRO=y``` in Kconfig and build.
10+
11+
To build as a module, select ```CONFIG_COMP_TFMICRO=m``` in Kconfig and the build. This will build the llext module but currently this module will be missing symbols from tfmicro and nnlib archives. A manual step needs done to link in those symbols. i.e.
12+
13+
```cd build-mtl/zephyr/tfmicro```
14+
15+
```xt-clang++ -flto -r tfmicro.llext -nostdlib -nodefaultlibs -ffreestanding -mno-generate-flix -L . -ltfmicro_lib -lnn_hifi_lib -lc++ -lc -lm -fno-rtti -ffunction-sections -fdata-sections -lgcc -o tftest -Wl,--gc-sections -Wl,--entry=sys_comp_module_tfmicro_interface_init```
16+
17+
```xt-objcopy --remove-section=.xt.* tftest```
18+
19+
This will create a llext module called ```tftest``` that will contain all the nessessary symbols. Please note the commands above are WIP and will be optimized as development continues.
20+
21+
## Running
22+
23+
The TFLM SOF module needs features craeted by the MFCC module as its input. This step is still in progress. The following pipeline will be used
24+
25+
``` Mic --> MFCC --> TFLM --> Clasification ```
26+
27+
## TODO
28+
29+
1) Create MFCC pipeline and align with TFLM micro_speech audio feature extraction configuration.
30+
31+
2) Support compressed output PCM with classification results.
32+
33+
3) Load tflite models via binary kcontrol.
34+
35+
4) Support audio processing via TFLM module.

src/audio/tfmicro/llext-wrap.c

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
//
3+
// Copyright(c) 2025 Intel Corporation. All rights reserved.
4+
5+
#include <stdint.h>
6+
#include <errno.h>
7+
#include <assert.h>
8+
#include <rtos/symbol.h>
9+
10+
/*
11+
* Stubs that are needed for linkage of some applications or libraries
12+
* that come from porting userspace code. Anyone porting should
13+
* make sure that any code does not depend on working copies of these
14+
* reentrant functions. We will fail for any caller.
15+
*/
16+
17+
struct stat;
18+
struct _reent;
19+
20+
size_t _read_r(struct _reent *ptr, int fd, char *buf, size_t cnt)
21+
{
22+
errno = -ENOTSUP;
23+
return -ENOTSUP;
24+
}
25+
EXPORT_SYMBOL(_read_r);
26+
27+
size_t _write_r(struct _reent *ptr, int fd, char *buf, size_t cnt)
28+
{
29+
errno = -ENOTSUP;
30+
return -ENOTSUP;
31+
}
32+
EXPORT_SYMBOL(_write_r);
33+
34+
void *_sbrk_r(struct _reent *ptr, ptrdiff_t incr)
35+
{
36+
errno = -ENOTSUP;
37+
return NULL;
38+
}
39+
EXPORT_SYMBOL(_sbrk_r);
40+
41+
int _lseek_r(struct _reent *ptr, int fd, int pos, int whence)
42+
{
43+
errno = -ENOTSUP;
44+
return -ENOTSUP;
45+
}
46+
EXPORT_SYMBOL(_lseek_r);
47+
48+
int _kill_r(struct _reent *ptr, int pid, int sig)
49+
{
50+
errno = -ENOTSUP;
51+
return -ENOTSUP;
52+
}
53+
EXPORT_SYMBOL(_kill_r);
54+
55+
int _getpid_r(struct _reent *ptr)
56+
{
57+
errno = -ENOTSUP;
58+
return -ENOTSUP;
59+
}
60+
EXPORT_SYMBOL(_getpid_r);
61+
62+
int _fstat_r(struct _reent *ptr, int fd, struct stat *pstat)
63+
{
64+
errno = -ENOTSUP;
65+
return -ENOTSUP;
66+
}
67+
EXPORT_SYMBOL(_fstat_r);
68+
69+
int _close_r(struct _reent *ptr, int fd)
70+
{
71+
errno = -ENOTSUP;
72+
return -ENOTSUP;
73+
}
74+
EXPORT_SYMBOL(_close_r);
75+
76+
void _exit(int status)
77+
{
78+
assert(0);
79+
while(1);
80+
}

0 commit comments

Comments
 (0)