31 lines
2.2 KiB
Python
31 lines
2.2 KiB
Python
"""Check installed Mac speech linkage and real recognition of an owned PCM fixture."""
|
|
import argparse,json,struct,subprocess
|
|
from pathlib import Path
|
|
|
|
def check_runtime(runtime):
|
|
names={p.name for p in runtime.iterdir() if p.is_file()}
|
|
for p in runtime.iterdir():
|
|
if not p.is_file() or not (p.name=='searchi-speech-worker' or p.suffix in {'.dylib','.so'}):continue
|
|
loads=subprocess.check_output(['otool','-L',str(p)],text=True).splitlines()[1:]
|
|
for line in loads:
|
|
dep=line.strip().split(' (',1)[0]
|
|
assert dep.startswith(('/System/Library/','/usr/lib/')) or dep.startswith('@rpath/') and Path(dep).name in names,(p.name,dep)
|
|
meta=subprocess.check_output(['otool','-l',str(p)],text=True).splitlines()
|
|
paths=[meta[i+2].strip().split(' (',1)[0].removeprefix('path ')for i,l in enumerate(meta)if l.strip()=='cmd LC_RPATH']
|
|
assert paths and all(x=='@loader_path' for x in paths),(p.name,paths)
|
|
|
|
def frames(raw):
|
|
out=[]
|
|
while raw:
|
|
assert len(raw)>=4
|
|
n=struct.unpack('<I',raw[:4])[0];assert 0<n<=4*1024*1024 and len(raw)>=4+n
|
|
out.append(json.loads(raw[4:4+n]));raw=raw[4+n:]
|
|
return out
|
|
|
|
if __name__=='__main__':
|
|
a=argparse.ArgumentParser();a.add_argument('--runtime',type=Path,required=True);a.add_argument('--models',type=Path,required=True);a.add_argument('--pcm',type=Path,required=True);a.add_argument('--output',type=Path,required=True);args=a.parse_args();check_runtime(args.runtime)
|
|
pcm=args.pcm.read_bytes();assert len(pcm)%4==0 and 0<len(pcm)//4<=480000
|
|
command=[str(args.runtime/'searchi-speech-worker'),str(args.models/'ggml-base.bin'),str(args.models/'ggml-silero-v6.2.0.bin'),'auto']
|
|
result=subprocess.run(command,input=b'\x02'+struct.pack('<I',len(pcm)//4)+pcm,capture_output=True,timeout=180,check=True)
|
|
messages=frames(result.stdout);assert len(messages)==2 and messages[0]['ready'] and messages[0]['distribution_auto'];assert messages[1]['ok'];text=' '.join(x.get('text','')for x in messages[1].get('sentences',[])).lower();assert 'free' in text and 'equal' in text,text;args.output.write_text(json.dumps(messages,indent=2));print('PASS: installed @loader_path closure and actual recognition; backend',messages[1].get('backend_observed'))
|