106 lines
3.5 KiB
Python
106 lines
3.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Test different PCM streaming approaches on G1 voice service."""
|
|
|
|
import sys
|
|
import time
|
|
import json
|
|
import wave
|
|
import numpy as np
|
|
from pathlib import Path
|
|
from unitree_sdk2py.core.channel import ChannelFactoryInitialize
|
|
from unitree_sdk2py.g1.audio.g1_audio_client import AudioClient
|
|
from unitree_sdk2py.g1.audio.g1_audio_api import *
|
|
|
|
if len(sys.argv) < 2:
|
|
print(f"Usage: python3 {sys.argv[0]} <network_interface>")
|
|
sys.exit(1)
|
|
|
|
ChannelFactoryInitialize(0, sys.argv[1])
|
|
client = AudioClient()
|
|
client.SetTimeout(10.0)
|
|
client.Init()
|
|
|
|
# Load a small WAV chunk
|
|
wav_path = Path(__file__).parent / "DataG1" / "greeting.wav"
|
|
with wave.open(str(wav_path), "rb") as wf:
|
|
pcm_all = wf.readframes(wf.getnframes())
|
|
rate = wf.getframerate()
|
|
channels = wf.getnchannels()
|
|
|
|
print(f"Loaded {len(pcm_all)} bytes, {rate}Hz, {channels}ch")
|
|
chunk = pcm_all[:2048] # small test chunk
|
|
|
|
print("\n=== Approach 1: Register stream then send binary chunks ===")
|
|
# Step 1: Open stream
|
|
param = json.dumps({"app_name": "rec", "stream_id": "s1"})
|
|
code, data = client._Call(ROBOT_API_ID_AUDIO_START_PLAY, param)
|
|
print(f" Open stream: code={code}, data={data}")
|
|
|
|
# Step 2: Send binary chunk (no reply)
|
|
try:
|
|
client._CallBinaryNoReply(ROBOT_API_ID_AUDIO_START_PLAY, list(chunk))
|
|
print(" _CallBinaryNoReply: sent (no reply)")
|
|
except Exception as e:
|
|
print(f" _CallBinaryNoReply: {e}")
|
|
|
|
time.sleep(1)
|
|
|
|
# Step 3: Stop
|
|
param_stop = json.dumps({"app_name": "rec"})
|
|
code, _ = client._Call(ROBOT_API_ID_AUDIO_STOP_PLAY, param_stop)
|
|
print(f" Stop: code={code}")
|
|
|
|
print("\n=== Approach 2: _CallNoReply with JSON+PCM ===")
|
|
try:
|
|
param2 = json.dumps({"app_name": "rec2", "stream_id": "s2", "pcm": list(chunk[:512])})
|
|
client._CallNoReply(ROBOT_API_ID_AUDIO_START_PLAY, param2)
|
|
print(" _CallNoReply: sent")
|
|
except Exception as e:
|
|
print(f" _CallNoReply: {e}")
|
|
|
|
time.sleep(1)
|
|
|
|
print("\n=== Approach 3: Multiple small _CallBinary chunks ===")
|
|
# Register first
|
|
param3 = json.dumps({"app_name": "rec3", "stream_id": "s3"})
|
|
code, _ = client._Call(ROBOT_API_ID_AUDIO_START_PLAY, param3)
|
|
print(f" Register: code={code}")
|
|
|
|
for i in range(5):
|
|
off = i * 512
|
|
small = pcm_all[off:off+512]
|
|
try:
|
|
code, _ = client._CallBinary(ROBOT_API_ID_AUDIO_START_PLAY, list(small))
|
|
print(f" Chunk {i}: code={code}")
|
|
except Exception as e:
|
|
print(f" Chunk {i}: {e}")
|
|
break
|
|
|
|
print("\n=== Approach 4: Check all registered API methods ===")
|
|
for api_name, api_id in [
|
|
("TTS", ROBOT_API_ID_AUDIO_TTS),
|
|
("ASR", ROBOT_API_ID_AUDIO_ASR),
|
|
("START_PLAY", ROBOT_API_ID_AUDIO_START_PLAY),
|
|
("STOP_PLAY", ROBOT_API_ID_AUDIO_STOP_PLAY),
|
|
("GET_VOLUME", ROBOT_API_ID_AUDIO_GET_VOLUME),
|
|
("SET_VOLUME", ROBOT_API_ID_AUDIO_SET_VOLUME),
|
|
("SET_RGB_LED", ROBOT_API_ID_AUDIO_SET_RGB_LED),
|
|
]:
|
|
print(f" {api_name} = {api_id}")
|
|
|
|
print("\n=== Approach 5: TTS with file path (maybe voice service can play files?) ===")
|
|
# Try passing a file path to TTS or a special API
|
|
param5 = json.dumps({"file": "/tmp/greeting.wav"})
|
|
code, data = client._Call(ROBOT_API_ID_AUDIO_START_PLAY, param5)
|
|
print(f" file path via START_PLAY: code={code}, data={data}")
|
|
|
|
param5b = json.dumps({"url": "/tmp/greeting.wav"})
|
|
code, data = client._Call(ROBOT_API_ID_AUDIO_START_PLAY, param5b)
|
|
print(f" url path via START_PLAY: code={code}, data={data}")
|
|
|
|
param5c = json.dumps({"path": "/tmp/greeting.wav"})
|
|
code, data = client._Call(ROBOT_API_ID_AUDIO_START_PLAY, param5c)
|
|
print(f" path via START_PLAY: code={code}, data={data}")
|
|
|
|
print("\nDone. Did you hear anything?")
|