Skip to main content

使用 Python 控制 reSpeaker XVF3800

简介

在本节中,我们将讨论如何使用 Python SDK 控制您的 ReSpeaker XVF-3800。这使得想要构建自己应用程序的用户开发更加便利。 例如,您可以检测声音来源方向、执行语音活动检测(VAD)、控制 LED 等等。

Python SDK

我们有一个全面的 Python 指南,介绍如何使用 USB 固件与 XVF3800 通信。这个 Python 脚本可以在您喜欢的 IDE 中运行,无需 XVF3800 XVF_Host

您需要安装 pyusb 库。

如何获取 DOA 和 VAD

import sys
import struct
import usb.core
import usb.util
import time

# name, resid, cmdid, length, type
PARAMETERS = {
"VERSION": (48, 0, 3, "ro", "uint8"),
"AEC_AZIMUTH_VALUES": (33, 75, 16, "ro", "radians"),
"DOA_VALUE": (20, 18, 4, "ro", "uint16"),
"REBOOT": (48, 7, 1, "wo", "uint8"),
}

class ReSpeaker:
TIMEOUT = 100000 # USB timeout

def __init__(self, dev):
self.dev = dev # store device

def write(self, name, data_list):
try:
data = PARAMETERS[name] # get param data
except KeyError:
return

if data[3] == "ro": # check read-only
raise ValueError('{} is read-only'.format(name))

if len(data_list) != data[2]: # count mismatch
raise ValueError('{} value count is not {}'.format(name, data[2]))

windex = data[0] # resid index
wvalue = data[1] # command ID
data_type = data[4] # type info
data_cnt = data[2] # value count
payload = [] # USB payload

if data_type == 'float' or data_type == 'radians': # float pack
for i in range(data_cnt):
payload += struct.pack(b'f', float(data_list[i]))
elif data_type == 'char' or data_type == 'uint8': # byte pack
for i in range(data_cnt):
payload += data_list[i].to_bytes(1, byteorder='little')
else: # int pack
for i in range(data_cnt):
payload += struct.pack(b'i', data_list[i])

print("WriteCMD: cmdid: {}, resid: {}, payload: {}".format(wvalue, windex, payload))

# send control transfer
self.dev.ctrl_transfer(
usb.util.CTRL_OUT | usb.util.CTRL_TYPE_VENDOR | usb.util.CTRL_RECIPIENT_DEVICE,
0, wvalue, windex, payload, self.TIMEOUT)

def read(self, name):
try:
data = PARAMETERS[name] # get param info
except KeyError:
return

resid = data[0] # resource ID
cmdid = 0x80 | data[1] # read command
length = data[2] + 1 # add status byte

# read control transfer
response = self.dev.ctrl_transfer(
usb.util.CTRL_IN | usb.util.CTRL_TYPE_VENDOR | usb.util.CTRL_RECIPIENT_DEVICE,
0, cmdid, resid, length, self.TIMEOUT)

if data[4] == 'uint8': # return bytes
result = response.tolist()
elif data[4] == 'radians': # unpack floats
byte_data = response.tobytes()
num_values = (length - 1) / 4
match_str = '<'
for i in range(int(num_values)):
match_str += 'f'
result = struct.unpack(match_str, byte_data[1:length])
elif data[4] == 'uint16': # return uint16 list
result = response.tolist()

return result # return parsed data

def close(self):
usb.util.dispose_resources(self.dev) # release device

def find(vid=0x2886, pid=0x001A):
dev = usb.core.find(idVendor=vid, idProduct=pid) # find device
if not dev:
return
return ReSpeaker(dev) # return instance

def main():
dev = find() # find device
if not dev:
print('No device found')
sys.exit(1)

print('{}: {}'.format("VERSION", dev.read("VERSION"))) # print version

while True:
result = dev.read("DOA_VALUE") # read direction
print('{}: {}, {}: {}'.format("SPEECH_DETECTED", result[3], "DOA_VALUE", result[1]))
time.sleep(1) # delay 1 sec

dev.close() # close device

if __name__ == '__main__':
main() # run program

使用 XVF_Host

请参考文档了解什么是 XVF_Host。 在本节中,我们将使用 Python 脚本与 [XVF_Host](https://wiki.seeedstudio.com/cn/respeaker_xvf3800_introduction/#如何控制 respeaker-xvf3800) 一起工作。

ReSpeaker XVF3800 的 Python 示例

note

如果您想了解更多关于通过 xvf_host 使用 python 脚本进行控制的信息,请阅读这篇文章

适用于 Windows

git clone https://github.com/KasunThushara/reSpeakerXVF.git
cd reSpeakerXVF
python test.py

确保已安装 Python 并且 ReSpeaker XVF3800 通过 USB 连接。

test.py 文件可以按如下方式探索。这是您在 Linux 上的参考。

import subprocess
import sys
import time

# Path to your xvf_host binary
XVF_HOST_PATH = "./xvf_host" # Change this if xvf_host is in a different location

def run_command(*args):
"""Run a command using the xvf_host tool."""
command = ["sudo", XVF_HOST_PATH] + list(map(str, args))
try:
print(f"Running: {' '.join(command)}")
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, text=True)
print("Output:\n", result.stdout)
except subprocess.CalledProcessError as e:
print("Error:\n", e.stderr)
sys.exit(1)

if __name__ == "__main__":
# Example: Get device version
run_command("VERSION")
time.sleep(0.005)

# Example: Set LED to breath mode with orange color
run_command("led_effect", 1)
time.sleep(0.005)
run_command("led_color", "0xff8800")
time.sleep(0.005)
run_command("led_speed", 1)
time.sleep(0.005)
run_command("led_brightness", 255)
time.sleep(0.005)

# Example: Save current configuration
#run_command("save_configuration", 1)

# Uncomment to clear config
run_command("clear_configuration", 1)
time.sleep(0.005)

pir

技术支持与产品讨论

感谢您选择我们的产品!我们在这里为您提供不同的支持,以确保您使用我们产品的体验尽可能顺畅。我们提供多种沟通渠道,以满足不同的偏好和需求。

Loading Comments...