Skip to content

Commit b099aef

Browse files
authored
Merge branch 'docusaurus-version' into docusaurus-version
2 parents f16cb83 + ac822bf commit b099aef

39 files changed

+33716
-2394
lines changed

docusaurus.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
title: 'Serve Build',
3+
url: 'https://wiki.seeedstudio.com',
4+
baseUrl: '/',
5+
favicon: 'img/favicon.ico',
6+
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
"typecheck": "tsc",
2929
"generatewiki": "node scripts/generateWiki.js",
3030
"generate-lang-map": "node scripts/generate-language-map.js",
31+
"generate-jetson-config": "node scripts/generate-jetson-config.js",
3132
"normalize-frontmatter": "node scripts/normalize-frontmatter.js"
32-
3333
},
3434
"dependencies": {
3535
"@ant-design/icons": "^5.4.0",

scripts/generate-jetson-config.js

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
#!/usr/bin/env node
2+
3+
const fs = require('fs');
4+
const path = require('path');
5+
6+
// 定义要搜索的多语言目录
7+
const APP_DIRS = {
8+
en: 'sites/en/docs/Edge/NVIDIA_Jetson/Application',
9+
zh: 'sites/zh-CN/docs/Edge/NVIDIA_Jetson/Application',
10+
ja: 'sites/ja/docs/Edge/NVIDIA_Jetson/Application',
11+
es: 'sites/es/docs/Edge/NVIDIA_Jetson/Application'
12+
};
13+
14+
// 站点语言前缀
15+
const LANG_URL_PREFIX = {
16+
en: '',
17+
zh: '/cn',
18+
ja: '/ja',
19+
es: '/es'
20+
};
21+
22+
// 定义分类映射(目录名 -> 配置变量名)
23+
const CATEGORY_MAPPING = {
24+
'Computer_Vision': 'communityList_cv',
25+
'Generative_AI': 'communityList_gen',
26+
'Robotics': 'communityList_robot',
27+
'Developer_Tools': 'developerToolsList',
28+
'Multimodal_AI': 'multimodalList',
29+
'Physical_AI': 'physicalAIList',
30+
'Managed_Services': 'managedServicesList'
31+
};
32+
33+
// 存储提取的数据(按分类)
34+
const data = {
35+
communityList_cv: [],
36+
communityList_gen: [],
37+
communityList_robot: [],
38+
developerToolsList: [],
39+
multimodalList: [],
40+
physicalAIList: [],
41+
managedServicesList: []
42+
};
43+
44+
// 用于跨语言聚合同一项目
45+
const projectMap = {
46+
communityList_cv: new Map(),
47+
communityList_gen: new Map(),
48+
communityList_robot: new Map(),
49+
developerToolsList: new Map(),
50+
multimodalList: new Map(),
51+
physicalAIList: new Map(),
52+
managedServicesList: new Map()
53+
};
54+
55+
// 遍历目录提取数据
56+
function extractData() {
57+
Object.entries(APP_DIRS).forEach(([lang, dir]) => {
58+
if (!fs.existsSync(dir)) {
59+
console.warn(`[WARN] Directory not found for ${lang}: ${dir}`);
60+
return;
61+
}
62+
63+
fs.readdirSync(dir, { withFileTypes: true }).forEach(categoryDir => {
64+
if (!categoryDir.isDirectory()) return;
65+
66+
const category = categoryDir.name;
67+
const categoryKey = CATEGORY_MAPPING[category] || 'communityList_cv';
68+
const categoryPath = path.join(dir, category);
69+
70+
fs.readdirSync(categoryPath, { withFileTypes: true }).forEach(file => {
71+
if (!file.isFile() || !(file.name.endsWith('.md') || file.name.endsWith('.mdx'))) {
72+
return;
73+
}
74+
75+
const filePath = path.join(categoryPath, file.name);
76+
const content = fs.readFileSync(filePath, 'utf8');
77+
78+
const project = extractProjectInfo(content, filePath, lang);
79+
if (!project) return;
80+
81+
const map = projectMap[categoryKey];
82+
const mergeKey = project.mergeKey;
83+
84+
if (!map.has(mergeKey)) {
85+
map.set(mergeKey, {
86+
name: {},
87+
img: project.img,
88+
URL: {},
89+
category: {},
90+
lastUpdated: project.lastUpdated,
91+
author: project.author
92+
});
93+
}
94+
95+
const existing = map.get(mergeKey);
96+
97+
existing.name[lang] = project.name;
98+
existing.URL[lang] = project.URL;
99+
existing.category[lang] = project.category;
100+
101+
if (!existing.img && project.img) {
102+
existing.img = project.img;
103+
}
104+
105+
if (lang === 'en' || !existing.lastUpdated) {
106+
existing.lastUpdated = project.lastUpdated;
107+
}
108+
109+
if (lang === 'en' || !existing.author) {
110+
existing.author = project.author;
111+
}
112+
});
113+
});
114+
});
115+
116+
Object.keys(projectMap).forEach(categoryKey => {
117+
data[categoryKey] = Array.from(projectMap[categoryKey].values());
118+
});
119+
}
120+
121+
// 从文件内容中提取项目信息
122+
function extractProjectInfo(content, filePath, lang) {
123+
// 提取 frontmatter
124+
const frontmatterMatch = content.match(/^---\s*\n([\s\S]*?)\n---/);
125+
const frontmatter = frontmatterMatch ? frontmatterMatch[1] : '';
126+
127+
// 提取标题(优先从 frontmatter 的 title 字段,否则从正文)
128+
const titleMatch = frontmatter.match(/^title:\s*(.*)$/m) || content.match(/^#\s+(.*)$/m);
129+
if (!titleMatch) return null;
130+
131+
const name = cleanValue(titleMatch[1]);
132+
133+
// 提取图片(优先从 frontmatter 的 image 字段)
134+
let img = 'https://files.seeedstudio.com/wiki/reComputer-Jetson/default-project.png';
135+
const frontmatterImgMatch = frontmatter.match(/^image:\s*(.*)$/m);
136+
137+
if (frontmatterImgMatch) {
138+
img = cleanValue(frontmatterImgMatch[1]);
139+
140+
// 如果是临时图片,寻找文档中的首个真实图片
141+
if (img === 'https://files.seeedstudio.com/wiki/wiki-platform/S-tempor.png') {
142+
const markdownImgMatch = content.match(/!\[.*?\]\((.*?\.(jpg|jpeg|png|webp|gif))\)/i);
143+
const htmlImgMatch = content.match(/<img[^>]+src=["']([^"']*?\.(jpg|jpeg|png|webp|gif))["']?[^>]*>/is);
144+
const htmlImgMatchMultiline = content.match(/<img[^>]*src=["']([^"']*?\.(jpg|jpeg|png|webp|gif))["']?[^>]*>/is);
145+
146+
if (markdownImgMatch && markdownImgMatch[1] !== img) {
147+
img = markdownImgMatch[1];
148+
} else if (htmlImgMatch && htmlImgMatch[1] !== img) {
149+
img = htmlImgMatch[1].replace(/\s+/g, '');
150+
} else if (htmlImgMatchMultiline && htmlImgMatchMultiline[1] !== img) {
151+
img = htmlImgMatchMultiline[1].replace(/\s+/g, '');
152+
}
153+
}
154+
} else {
155+
const markdownImgMatch = content.match(/!\[.*?\]\((.*?)\)/);
156+
const htmlImgMatch = content.match(/<img[^>]+src=["']([^"']+)["'][^>]*>/i);
157+
158+
if (markdownImgMatch) {
159+
img = markdownImgMatch[1];
160+
} else if (htmlImgMatch) {
161+
img = htmlImgMatch[1].replace(/\s+/g, '');
162+
}
163+
}
164+
165+
// 生成 URL(所有语言 slug 相同,靠站点前缀区分)
166+
let slug = '';
167+
const slugMatch = frontmatter.match(/^slug:\s*(.*)$/m);
168+
169+
if (slugMatch) {
170+
slug = cleanSlug(slugMatch[1]);
171+
} else {
172+
slug = buildSlugFromFilePath(filePath, lang);
173+
}
174+
175+
const URL = `https://wiki.seeedstudio.com${LANG_URL_PREFIX[lang]}${slug}`;
176+
const mergeKey = slug;
177+
178+
// 提取分类标签
179+
const categoryMatch = content.match(/categories:\s*\[(.*?)\]/s);
180+
const categoryArray = categoryMatch
181+
? categoryMatch[1]
182+
.split(',')
183+
.map(c => c.trim().replace(/['"]/g, ''))
184+
.filter(Boolean)
185+
: [];
186+
187+
// 提取最后更新时间
188+
const dateMatch =
189+
frontmatter.match(/last_update:\s*\n\s*date:\s*(.*)/) ||
190+
content.match(/lastUpdated:\s*(.*)/);
191+
192+
const lastUpdated = dateMatch ? cleanValue(dateMatch[1]) : new Date().toLocaleDateString();
193+
194+
// 提取作者
195+
const authorMatch =
196+
frontmatter.match(/last_update:\s*\n[\s\S]*?author:\s*(.*)/) ||
197+
content.match(/author:\s*(.*)/);
198+
199+
const author = authorMatch ? cleanValue(authorMatch[1]) : 'Seeed Studio';
200+
201+
return {
202+
mergeKey,
203+
name,
204+
img,
205+
URL,
206+
category: categoryArray,
207+
lastUpdated,
208+
author
209+
};
210+
}
211+
212+
function cleanValue(value) {
213+
return String(value || '')
214+
.trim()
215+
.replace(/^['"]|['"]$/g, '');
216+
}
217+
218+
function cleanSlug(value) {
219+
const slug = cleanValue(value);
220+
if (!slug) return '';
221+
return slug.startsWith('/') ? slug : `/${slug}`;
222+
}
223+
224+
// 当没有 slug 时,从文件名推导 slug
225+
function buildSlugFromFilePath(filePath, lang) {
226+
const normalized = filePath.replace(/\\/g, '/');
227+
const baseDir = APP_DIRS[lang].replace(/\\/g, '/');
228+
229+
let relativePath = normalized.replace(`${baseDir}/`, '').replace(/\.mdx?$/, '');
230+
231+
// 只取文件名作为 slug,避免把 docs 目录路径带进 URL
232+
const fileName = path.basename(relativePath);
233+
return `/${fileName}`;
234+
}
235+
236+
// 生成配置文件
237+
function generateConfig() {
238+
let output = `// Auto-generated by generate-jetson-config.js
239+
// DO NOT EDIT MANUALLY - Run "node scripts/generate-jetson-config.js" to regenerate
240+
// Generated at: ${new Date().toISOString()}\n\n`;
241+
242+
Object.entries(data).forEach(([key, projects]) => {
243+
output += `export const ${key} = [\n`;
244+
projects.forEach((project, index) => {
245+
const jsonStr = JSON.stringify(project, null, 2);
246+
const indentedStr = jsonStr.split('\n').map(line => ' ' + line).join('\n');
247+
output += indentedStr;
248+
if (index < projects.length - 1) {
249+
output += ',\n';
250+
}
251+
});
252+
output += '\n]\n\n';
253+
});
254+
255+
const outputPath = path.join(__dirname, '../src/components/jetson/config.auto.js');
256+
fs.writeFileSync(outputPath, output);
257+
console.log(`Generated config.auto.js at ${outputPath}`);
258+
console.log(`Total projects extracted: ${Object.values(data).reduce((sum, arr) => sum + arr.length, 0)}`);
259+
}
260+
261+
// 执行提取和生成
262+
if (require.main === module) {
263+
console.log('Extracting Jetson project data...');
264+
extractData();
265+
generateConfig();
266+
console.log('Done!');
267+
}
268+
269+
module.exports = { extractData, generateConfig };

sites/en/docs/Sensor/reSpeaker_XVF3800_USB_4_Mic_Array/respeaker_xvf3800_usb_4_mic_array.md

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ sku: 101991441,114993701
99
last_update:
1010
date: 11/10/2025
1111
author: Kasun Thushara
12-
createdAt: '2023-08-20'
13-
updatedAt: '2026-03-03'
12+
createdAt: '2025-08-20'
13+
updatedAt: '2026-03-06'
1414
url: https://wiki.seeedstudio.com/respeaker_xvf3800_introduction/
1515
---
1616

@@ -192,24 +192,71 @@ Each type of firmware on the ReSpeaker XVF3800 supports different update methods
192192

193193
### Update Firmware
194194

195-
Connect the reSpeaker XVF3800 to your PC via the USB cable. Note that you need to use the XMOS USB-C port(close to 3.5mm jack port) to flash XMOS’s firmware.
195+
Three firmware versions are available in the official GitHub repository. You can choose and flash the appropriate firmware depending on your application requirements. For more details and downloads, please refer to the [Github Link](https://github.com/respeaker/reSpeaker_XVF3800_USB_4MIC_ARRAY)
196+
197+
:::note
198+
Please make sure that you will need to download whole repository.
199+
:::
200+
201+
import Tabs from '@theme/Tabs';
202+
import TabItem from '@theme/TabItem';
203+
204+
<Tabs>
205+
<TabItem value="USB" label="USB">
206+
207+
The USB firmware is designed for use with host operating systems such as **Windows, Linux, and macOS** when communicating through the USB hardware interface.
208+
209+
Two firmware variants are available: **respeaker_xvf3800_usb_dfu_firmware_v2.0.x.bin**, which provides **2-channel** audio, and **respeaker_xvf3800_usb_dfu_firmware_6chl_v2.0.x.bin**, which provides **6-channel** audio. Both firmware versions operate at a **16 kHz** sampling rate with **32-bit** depth.
210+
211+
You can explore these firmware files in [this link](https://github.com/respeaker/reSpeaker_XVF3800_USB_4MIC_ARRAY/tree/master/xmos_firmwares/usb)
212+
213+
196214

197215
| Firmware | Channels | Notes |
198216
|---------|----------|-------|
199217
| respeaker_xvf3800_usb_dfu_firmware_v2.0.x.bin | 2 | Processed 2-channel output <br /> Channel 0: Conference <br /> Channel 1: ASR |
200218
| respeaker_xvf3800_usb_dfu_firmware_6chl_v2.0.x.bin | 6 | Channel 0: Processed audio (Conference) <br /> Channel 1: Processed audio (ASR) <br /> Channel 2: Mic 0 raw data <br /> Channel 3: Mic 1 raw data <br /> Channel 4: Mic 2 raw data <br /> Channel 5: Mic 3 raw data |
219+
220+
221+
</TabItem>
222+
223+
<TabItem value="I2S" label="I2S">
224+
225+
The I2S firmware is intended for use when the device is connected to a microcontroller host such as the **XIAO ESP32S3**. In this configuration, voice data is transmitted using the I2S protocol.
226+
227+
The firmware file **respeaker_xvf3800_i2s_dfu_firmware_v1.0.x.bin** is available in [here](https://github.com/respeaker/reSpeaker_XVF3800_USB_4MIC_ARRAY/tree/master/xmos_firmwares/i2s). This firmware supports **2-channel** audio with a **32-bit** depth.
228+
229+
| Firmware | Channels | Notes |
230+
|---------|----------|-------|
201231
| respeaker_xvf3800_i2s_dfu_firmware_v1.0.x.bin | 2 | Processed 2-channel output <br /> Channel 0: Conference <br /> Channel 1: ASR |
232+
233+
</TabItem>
234+
235+
<TabItem value="HA" label="HA">
236+
237+
The Home Assistant firmware is another I2S-based firmware specifically designed for integration with Home Assistant. This optimized firmware uses 2-channel audio with a 48 kHz sampling rate, providing better compatibility and performance within the Home Assistant environment.
238+
You can view the firmware from [here](https://github.com/formatBCE/Respeaker-XVF3800-ESPHome-integration/tree/main)
239+
240+
241+
242+
| Firmware | Channels | Notes |
243+
|---------|----------|-------|
202244
| respeaker_xvf3800_i2s_master_dfu_firmware_v1.0.x_48k.bin | 2 | Processed 2-channel output <br /> Channel 0: ASR <br /> Channel 1: Wake word |
203245

204-
Users can modify the processed output channel selection for the firmware variants mentioned above.
205-
Please refer to the [XMOS documentation](https://www.xmos.com/documentation/XM-014888-PC/html/modules/fwk_xvf/doc/user_guide/03_using_the_host_application.html#output-selection) for details:
246+
</TabItem>
247+
</Tabs>
248+
249+
250+
251+
Connect the reSpeaker XVF3800 to your PC via the USB cable. Note that you need to use the XMOS USB-C port(close to 3.5mm jack port) to flash XMOS’s firmware.
252+
253+
206254

207255
#### Install DFU Util
208256

209257
[`dfu-util`](http://dfu-util.sourceforge.net/) is a command line tool for Device Firmware Upgrade via USB.
210258

211-
import Tabs from '@theme/Tabs';
212-
import TabItem from '@theme/TabItem';
259+
213260

214261
<Tabs>
215262
<TabItem value="windows" label="Windows">
@@ -316,7 +363,7 @@ Found DFU: [2886:001a] ver=0202, devnum=5, cfg=1, intf=3, path="1-1.1", alt=0, n
316363

317364
#### Flash Firmware
318365

319-
Download Firmware From Here.[`XMOS XVF 3800`](https://github.com/respeaker/reSpeaker_XVF3800_USB_4MIC_ARRAY)
366+
Download the complete firmware repository from GitHub here[`XMOS XVF 3800`](https://github.com/respeaker/reSpeaker_XVF3800_USB_4MIC_ARRAY)
320367

321368
- Run the following command to flash the firmware
322369

0 commit comments

Comments
 (0)