cpp 脚本清理:移除批量脚本、修正单条运行脚本 BSP 路径、README 对齐预编译发布

#4
by inoryQwQ - opened
README.md CHANGED
@@ -98,14 +98,6 @@ LD_LIBRARY_PATH=<BSP_LIB_DIR> cpp/bin/openwakeword_ax630c \
98
  --threshold 0.5
99
  ```
100
 
101
- 也可以使用仓库内的批量运行脚本:
102
-
103
- ```bash
104
- THRESHOLD=0.5 bash cpp/run_batch_openwakeword_ax650.sh # AX650
105
- THRESHOLD=0.5 bash cpp/run_batch_openwakeword_ax630c.sh # AX630C
106
- ```
107
-
108
- 结果分别写入 `outputs/cpp_ax650_batch/` 和 `outputs/cpp_ax630c_batch/`。
109
  详细 C++ 说明见 `cpp/README.md`。
110
 
111
  ### 共享库(二次开发)
 
98
  --threshold 0.5
99
  ```
100
 
 
 
 
 
 
 
 
 
101
  详细 C++ 说明见 `cpp/README.md`。
102
 
103
  ### 共享库(二次开发)
cpp/README.md CHANGED
@@ -1,122 +1,58 @@
1
- # openWakeWord C++ 推理
2
 
3
- 本目录 AX650 和 AX630C C++ 推理程序WAV、STFT、mel 和缓存更新在 CPU
4
- 端完成,embedding classifier 使用对应平台的 `axmodel`。
 
5
 
6
- ## 编译环境
7
-
8
- AX650 与 AX630C 共用 Arm GNU 9.2 AArch64 交叉编译器:
9
-
10
- ```bash
11
- mkdir -p cpp/toolchains
12
- wget -P cpp/toolchains \
13
- https://developer.arm.com/-/media/Files/downloads/gnu-a/9.2-2019.12/binrel/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu.tar.xz
14
- tar -xf cpp/toolchains/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu.tar.xz \
15
- -C cpp/toolchains
16
- ```
17
-
18
- 下载 BSP:
19
-
20
- ```bash
21
- bash cpp/download_bsp.sh all
22
- ```
23
-
24
- | 平台 | BSP 压缩包 | 编译目录 |
25
- | --- | --- | --- |
26
- | AX650 | `msp_50_3.10.2.zip` | `cpp/toolchains/ax650n_bsp_sdk/msp/out` |
27
- | AX630C | `msp_20e_3.0.0.zip` | `cpp/toolchains/ax620e_bsp_sdk/msp/out/arm64_glibc` |
28
-
29
- ## 交叉编译
30
-
31
- ```bash
32
- export TOOLCHAIN_ROOT="cpp/toolchains/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu"
33
-
34
- bash cpp/build_ax650.sh
35
- bash cpp/build_ax630c.sh
36
- ```
37
-
38
- 生成:
39
 
40
  ```text
41
- cpp/bin/openwakeword_ax650
42
- cpp/bin/openwakeword_ax630c
 
 
 
 
 
 
 
43
  ```
44
 
45
- BSP 放其他位置可设置 `BSP_MSP_DIR`。AX650 应指向包含 `include/`
46
- `lib/` `msp/out`;AX630C 应指向 `msp/out/arm64_glibc`
47
 
48
- ## 板端运行
49
 
50
- AX650 单条推理
51
 
52
  ```bash
53
- AUDIO=audio/openwakeword/alexa_test.wav \
54
- bash cpp/run_openwakeword_ax650.sh
55
  ```
56
 
57
- AX630C 单条推理
58
 
59
  ```bash
60
- AUDIO=audio/openwakeword/alexa_test.wav \
61
- bash cpp/run_openwakeword_ax630c.sh
62
  ```
63
 
64
- 批量测试:
 
65
 
66
  ```bash
67
- THRESHOLD=0.5 bash cpp/run_batch_openwakeword_ax650.sh
68
- THRESHOLD=0.5 bash cpp/run_batch_openwakeword_ax630c.sh
69
- ```
70
-
71
- 模型目录必须与平台对应:
72
-
73
- ```text
74
- models/650/
75
- models/630C/
76
  ```
77
 
78
- 运行脚本会检查 embedding 6 classifier 模型,避免误用其他平台的 axmodel
79
- 输入音频必须为 16 kHz、单声道、16-bit PCM WAV。
80
-
81
- 单条推理会输出 classifier 分数和 `WAKEUP`,并只输出一个 `rtf`。`rtf` 包含
82
- CPU mel 和 NPU 推理,不包含一次性模型加载与初始化。
83
-
84
- 阈值可通过环境变量调整:
85
-
86
- ```bash
87
- THRESHOLD=0.6 AUDIO=audio/openwakeword/hey_mycroft_test.wav \
88
- bash cpp/run_openwakeword_ax630c.sh
89
- ```
90
 
91
  ## 二次开发(共享库)
92
 
93
- 编译产物除可执行文件外,还包含共享库:
94
-
95
- ```text
96
- cpp/lib/ax650/libopenwakeword_ax.so # AX650
97
- cpp/lib/ax630c/libopenwakeword_ax.so # AX630C
98
- cpp/include/openwakeword_ax.hpp # 公共 API 头文件
99
- ```
100
-
101
- 在自己的 CMake 工程中链接:
102
-
103
- ```cmake
104
- add_library(openwakeword_ax SHARED IMPORTED)
105
- set_target_properties(openwakeword_ax PROPERTIES
106
- IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/cpp/lib/ax650/libopenwakeword_ax.so")
107
- target_include_directories(your_app PRIVATE cpp/include)
108
- target_link_libraries(your_app PRIVATE openwakeword_ax)
109
- ```
110
-
111
- 最小使用示例:
112
-
113
  ```cpp
114
  #include "openwakeword_ax.hpp"
115
 
116
  openwakeword::WakeWordDetector detector(
117
- "models/650", // axmodel 目录
118
- "config/openwakeword_mel_weights.bin", // CPU mel 权重
119
- 0.5f); // 阈值
120
 
121
  // 每 80ms 喂一帧 1280 个 int16 样本(16 kHz)
122
  openwakeword::FrameResult result = detector.ProcessFrame(pcm_frame);
@@ -128,9 +64,15 @@ if (result.any_triggered) { /* 唤醒 */ }
128
  detector.Reset(); // 新会话时清空流式状态
129
  ```
130
 
131
- 板端运行时需提供 BSP 动态库路径(AX650 通常为 `/soc/lib`,AX630C 为
132
- `/opt/lib`):
133
 
134
- ```bash
135
- export LD_LIBRARY_PATH=/soc/lib:${LD_LIBRARY_PATH}
 
 
 
 
136
  ```
 
 
 
 
1
+ # openWakeWord C++(HF 发布版)
2
 
3
+ 本目录只包含**预编译产物**:可直接运行的二进制与二次开发链接的共享库
4
+ 源码、构建脚本BSP 下载在 GitHub 仓库:
5
+ <https://github.com/AXERA-TECH/openWakeWord.AXERA>。
6
 
7
+ ## 目录
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
  ```text
10
+ cpp/
11
+ ├── bin/
12
+ │ ├── openwakeword_ax650 # AX650 预编译可执行文件
13
+ │ └── openwakeword_ax630c # AX630C 预编译可执行文件
14
+ ├── lib/
15
+ │ ├── ax650/libopenwakeword_ax.so # AX650 共享库
16
+ │ └── ax630c/libopenwakeword_ax.so # AX630C 共享库
17
+ ├── include/openwakeword_ax.hpp # 公共 API 头文件
18
+ └── run_openwakeword_ax*.sh # 板端单条运行脚本
19
  ```
20
 
21
+ WAV、STFT、mel CPU 端完成embedding 6 classifier 使用对应平台的
22
+ axmodel NPU 执行
23
 
24
+ ## 板端运行(预编译二进制)
25
 
26
+ AX650:
27
 
28
  ```bash
29
+ AUDIO=audio/openwakeword/alexa_test.wav bash cpp/run_openwakeword_ax650.sh
 
30
  ```
31
 
32
+ AX630C:
33
 
34
  ```bash
35
+ AUDIO=audio/openwakeword/alexa_test.wav bash cpp/run_openwakeword_ax630c.sh
 
36
  ```
37
 
38
+ 运行脚本自动设置板端运行库路径(AX650 默认 `/soc/lib`,AX630C 默认
39
+ `/opt/lib`);如 BSP 在其他位置,用环境变量覆盖:
40
 
41
  ```bash
42
+ AXERA_BSP_LIB_DIR=/path/to/bsp/lib bash cpp/run_openwakeword_ax650.sh
 
 
 
 
 
 
 
 
43
  ```
44
 
45
+ 阈值可通过 `THRESHOLD` 调整。输入音频必须为 16 kHz、单声道、16-bit PCM WAV
 
 
 
 
 
 
 
 
 
 
 
46
 
47
  ## 二次开发(共享库)
48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  ```cpp
50
  #include "openwakeword_ax.hpp"
51
 
52
  openwakeword::WakeWordDetector detector(
53
+ "models/650", // axmodel 目录
54
+ "config/openwakeword_mel_weights.bin", // CPU mel 权重
55
+ 0.5f); // 阈值
56
 
57
  // 每 80ms 喂一帧 1280 个 int16 样本(16 kHz)
58
  openwakeword::FrameResult result = detector.ProcessFrame(pcm_frame);
 
64
  detector.Reset(); // 新会话时清空流式状态
65
  ```
66
 
67
+ 在自己的 CMake 工程中链接:
 
68
 
69
+ ```cmake
70
+ add_library(openwakeword_ax SHARED IMPORTED)
71
+ set_target_properties(openwakeword_ax PROPERTIES
72
+ IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/cpp/lib/ax650/libopenwakeword_ax.so")
73
+ target_include_directories(your_app PRIVATE cpp/include)
74
+ target_link_libraries(your_app PRIVATE openwakeword_ax)
75
  ```
76
+
77
+ 板端运行时需提供 BSP 动态库路径(AX650 通常为 `/soc/lib`,AX630C 为
78
+ `/opt/lib`)。
cpp/run_batch_openwakeword_ax.sh DELETED
@@ -1,122 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
-
4
- ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
- TARGET="${AXERA_TARGET:-AX650}"
6
- AUDIO_DIR="${AUDIO_DIR:-${ROOT}/audio/openwakeword}"
7
- THRESHOLD="${THRESHOLD:-0.5}"
8
-
9
- case "${TARGET}" in
10
- AX650)
11
- TARGET_SLUG="ax650"
12
- BINARY="${ROOT}/cpp/bin/openwakeword_ax650"
13
- MODELS_DIR="${MODELS_DIR:-${ROOT}/models/650}"
14
- BSP_LIB_DIR="${AXERA_BSP_LIB_DIR:-${AX650_BSP_LIB_DIR:-${ROOT}/cpp/toolchains/ax650n_bsp_sdk/msp/out/lib}}"
15
- BUILD_SCRIPT="cpp/build_ax650.sh"
16
- ;;
17
- AX630C)
18
- TARGET_SLUG="ax630c"
19
- BINARY="${ROOT}/cpp/bin/openwakeword_ax630c"
20
- MODELS_DIR="${MODELS_DIR:-${ROOT}/models/630C}"
21
- BSP_LIB_DIR="${AXERA_BSP_LIB_DIR:-${AX630C_BSP_LIB_DIR:-${ROOT}/cpp/toolchains/ax620e_bsp_sdk/msp/out/arm64_glibc/lib}}"
22
- BUILD_SCRIPT="cpp/build_ax630c.sh"
23
- ;;
24
- *)
25
- echo "ERROR: AXERA_TARGET must be AX650 or AX630C" >&2
26
- exit 2
27
- ;;
28
- esac
29
-
30
- OUTPUT_DIR="${OUTPUT_DIR:-${ROOT}/outputs/cpp_${TARGET_SLUG}_batch}"
31
- if [[ ! -x "${BINARY}" ]]; then
32
- echo "ERROR: ${BINARY} is missing; run bash ${BUILD_SCRIPT} first" >&2
33
- exit 2
34
- fi
35
- if [[ ! -d "${AUDIO_DIR}" ]]; then
36
- echo "ERROR: audio directory does not exist: ${AUDIO_DIR}" >&2
37
- exit 2
38
- fi
39
- for name in embedding_model alexa_v0.1 hey_jarvis_v0.1 hey_mycroft_v0.1 \
40
- hey_rhasspy_v0.1 timer_v0.1 weather_v0.1; do
41
- model="${MODELS_DIR}/openwakeword__${name}.axmodel"
42
- if [[ ! -f "${model}" ]]; then
43
- echo "ERROR: ${TARGET} model is missing: ${model}" >&2
44
- exit 2
45
- fi
46
- done
47
-
48
- mapfile -d '' AUDIO_FILES < <(
49
- find "${AUDIO_DIR}" -maxdepth 1 -type f -iname '*.wav' -print0 | sort -z
50
- )
51
- if [[ "${#AUDIO_FILES[@]}" -eq 0 ]]; then
52
- echo "ERROR: no WAV files found under ${AUDIO_DIR}" >&2
53
- exit 2
54
- fi
55
-
56
- mkdir -p "${OUTPUT_DIR}/logs"
57
- RESULTS="${OUTPUT_DIR}/results.tsv"
58
- SUMMARY="${OUTPUT_DIR}/summary.txt"
59
- printf 'file\taudio_seconds\tfeature_seconds\tnpu_seconds\tinference_seconds\trtf\tmodel_load_seconds\tdetections\n' > "${RESULTS}"
60
-
61
- export LD_LIBRARY_PATH="${BSP_LIB_DIR}:${LD_LIBRARY_PATH:-}"
62
- for audio in "${AUDIO_FILES[@]}"; do
63
- name="$(basename "${audio}")"
64
- stem="${name%.*}"
65
- log="${OUTPUT_DIR}/logs/${stem}.log"
66
- echo "[RUN] target=${TARGET} ${name} threshold=${THRESHOLD}"
67
- "${BINARY}" \
68
- --models-dir "${MODELS_DIR}" \
69
- --mel-weights "${ROOT}/config/openwakeword_mel_weights.bin" \
70
- --audio "${audio}" \
71
- --threshold "${THRESHOLD}" > "${log}" 2>&1
72
- cat "${log}"
73
-
74
- field() {
75
- awk -F': ' -v key="$1" '$1 == key {print $2; exit}' "${log}"
76
- }
77
- audio_seconds="$(field audio_seconds)"
78
- feature_seconds="$(field feature_seconds)"
79
- npu_seconds="$(field npu_seconds)"
80
- inference_seconds="$(field inference_seconds)"
81
- rtf="$(field rtf)"
82
- model_load_seconds="$(field model_load_seconds)"
83
- detections="$(awk '$NF == "WAKEUP" {print $1}' "${log}" | paste -sd ',' -)"
84
- detections="${detections:-none}"
85
-
86
- for value in "${audio_seconds}" "${feature_seconds}" "${npu_seconds}" \
87
- "${inference_seconds}" "${rtf}" "${model_load_seconds}"; do
88
- if [[ -z "${value}" ]]; then
89
- echo "ERROR: timing field missing from ${log}" >&2
90
- exit 1
91
- fi
92
- done
93
- printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \
94
- "${name}" "${audio_seconds}" "${feature_seconds}" "${npu_seconds}" \
95
- "${inference_seconds}" "${rtf}" "${model_load_seconds}" "${detections}" \
96
- >> "${RESULTS}"
97
- done
98
-
99
- awk -F'\t' '
100
- NR > 1 {
101
- files += 1
102
- audio += $2
103
- feature += $3
104
- npu += $4
105
- inference += $5
106
- model_load += $7
107
- }
108
- END {
109
- printf "files: %d\n", files
110
- printf "total_audio_seconds: %.6f\n", audio
111
- printf "total_feature_seconds: %.6f\n", feature
112
- printf "total_npu_seconds: %.6f\n", npu
113
- printf "total_inference_seconds: %.6f\n", inference
114
- printf "total_model_load_seconds: %.6f\n", model_load
115
- printf "rtf: %.6f\n", inference / audio
116
- }
117
- ' "${RESULTS}" > "${SUMMARY}"
118
-
119
- echo "[SUMMARY]"
120
- cat "${SUMMARY}"
121
- echo "results: ${RESULTS}"
122
- echo "logs: ${OUTPUT_DIR}/logs"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cpp/run_batch_openwakeword_ax630c.sh DELETED
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
-
4
- ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
- AXERA_TARGET=AX630C exec bash "${ROOT}/cpp/run_batch_openwakeword_ax.sh"
 
 
 
 
 
 
cpp/run_batch_openwakeword_ax650.sh DELETED
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
-
4
- ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
- AXERA_TARGET=AX650 exec bash "${ROOT}/cpp/run_batch_openwakeword_ax.sh"
 
 
 
 
 
 
cpp/run_openwakeword_ax.sh CHANGED
@@ -10,14 +10,13 @@ case "${TARGET}" in
10
  AX650)
11
  BINARY="${ROOT}/cpp/bin/openwakeword_ax650"
12
  MODELS_DIR="${MODELS_DIR:-${ROOT}/models/650}"
13
- BSP_LIB_DIR="${AXERA_BSP_LIB_DIR:-${AX650_BSP_LIB_DIR:-${ROOT}/cpp/toolchains/ax650n_bsp_sdk/msp/out/lib}}"
14
- BUILD_SCRIPT="cpp/build_ax650.sh"
15
  ;;
16
  AX630C)
17
  BINARY="${ROOT}/cpp/bin/openwakeword_ax630c"
18
  MODELS_DIR="${MODELS_DIR:-${ROOT}/models/630C}"
19
- BSP_LIB_DIR="${AXERA_BSP_LIB_DIR:-${AX630C_BSP_LIB_DIR:-${ROOT}/cpp/toolchains/ax620e_bsp_sdk/msp/out/arm64_glibc/lib}}"
20
- BUILD_SCRIPT="cpp/build_ax630c.sh"
21
  ;;
22
  *)
23
  echo "ERROR: AXERA_TARGET must be AX650 or AX630C" >&2
@@ -26,7 +25,7 @@ case "${TARGET}" in
26
  esac
27
 
28
  if [[ ! -x "${BINARY}" ]]; then
29
- echo "ERROR: ${BINARY} is missing; run bash ${BUILD_SCRIPT} first" >&2
30
  exit 2
31
  fi
32
  for name in embedding_model alexa_v0.1 hey_jarvis_v0.1 hey_mycroft_v0.1 \
 
10
  AX650)
11
  BINARY="${ROOT}/cpp/bin/openwakeword_ax650"
12
  MODELS_DIR="${MODELS_DIR:-${ROOT}/models/650}"
13
+ # 板端运行库默认路径(AX650 通常为 /soc/lib),可用 AXERA_BSP_LIB_DIR 覆盖
14
+ BSP_LIB_DIR="${AXERA_BSP_LIB_DIR:-${AX650_BSP_LIB_DIR:-/soc/lib}}"
15
  ;;
16
  AX630C)
17
  BINARY="${ROOT}/cpp/bin/openwakeword_ax630c"
18
  MODELS_DIR="${MODELS_DIR:-${ROOT}/models/630C}"
19
+ BSP_LIB_DIR="${AXERA_BSP_LIB_DIR:-${AX630C_BSP_LIB_DIR:-/opt/lib}}"
 
20
  ;;
21
  *)
22
  echo "ERROR: AXERA_TARGET must be AX650 or AX630C" >&2
 
25
  esac
26
 
27
  if [[ ! -x "${BINARY}" ]]; then
28
+ echo "ERROR: 预编译二进制不存在: ${BINARY}(HF 发布版应包含 cpp/bin/)" >&2
29
  exit 2
30
  fi
31
  for name in embedding_model alexa_v0.1 hey_jarvis_v0.1 hey_mycroft_v0.1 \