Add hermes_audio and draw the mouth from the real waveform
audio_state taps the microphone and the speaker monitor with parec and publishes levels, a speaking/listening/quiet activity, and trigger-locked waveform windows; audio itself stays out of ROS. The activity detector calibrates its noise floor at start-up and absorbs steady noise, so a room at -43 dBFS does not read as "listening" forever, and it ignores the mic while the robot speaks. The face arbitrates the state it shows: sleeping (agent side only, so room sound never wakes a face that means "no agent connected") > speaking > listening > thinking > idle, and draws the mouth from the real samples while fresh scope data exists, auto-scaled so a quiet voice is still visible. Checked: a tone played to the sink shows as `speaking` with the mic ignored. The microphone-to-mouth path with a live voice is not yet confirmed. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AFN8nRRCiDiMN7ChBpHJhs
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
import pytest
|
||||
|
||||
from hermes_face.arbiter import resolve_state
|
||||
|
||||
|
||||
@pytest.mark.parametrize('agent,audio,expected', [
|
||||
('sleeping', 'quiet', 'sleeping'),
|
||||
('sleeping', 'listening', 'sleeping'), # room sound never wakes the face
|
||||
('sleeping', 'speaking', 'sleeping'),
|
||||
('idle', 'quiet', 'idle'),
|
||||
('idle', 'listening', 'listening'),
|
||||
('idle', 'speaking', 'speaking'),
|
||||
('thinking', 'quiet', 'thinking'),
|
||||
('thinking', 'listening', 'listening'), # a voice interrupts the thinking face
|
||||
('listening', 'quiet', 'listening'),
|
||||
('speaking', 'quiet', 'speaking'), # the agent says it is speaking before the audio shows it
|
||||
('thinking', 'speaking', 'speaking'),
|
||||
])
|
||||
def test_priority(agent, audio, expected):
|
||||
assert resolve_state(agent, audio) == expected
|
||||
Reference in New Issue
Block a user