#!/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]} ") 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?")