mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-10-04 13:24:13 +08:00
Apply per-speaker calibration only to displayed music cues
This commit is contained in:
@@ -35,6 +35,8 @@ output_device=select_device(sd.query_devices(),output_metadata) if output_metada
|
||||
if output_device is not None:
|
||||
sd.check_output_settings(device=output_device,channels=2,dtype='float32',samplerate=48000)
|
||||
output_metadata['portaudio_device']=output_device
|
||||
from operator_output import PresentationDelay
|
||||
presentation_delay=PresentationDelay(root,output_provider=lambda: {'id':output_metadata['output_identity']} if output_metadata.get('bluetooth_selected') else None)
|
||||
(run/'output_device.json').write_text(json.dumps(output_metadata,indent=2)+'\n')
|
||||
if os.environ.get('ROADSCORE_RESIDENT')=='1':
|
||||
import atexit
|
||||
@@ -390,7 +392,7 @@ try:
|
||||
if songform:snapshot.update(songform.snapshot())
|
||||
if composition:snapshot.update(composition.snapshot(frames/rate))
|
||||
if gestures:snapshot.update(gestures.status())
|
||||
trace.write(json.dumps(snapshot)+'\n');f=run/'status.tmp';f.write_text(json.dumps(snapshot));f.replace(run/'status.json')
|
||||
trace.write(json.dumps(snapshot)+'\n');f=run/'status.tmp';f.write_text(json.dumps(presentation_delay.apply(snapshot)));f.replace(run/'status.json')
|
||||
if time.monotonic()-last_progress>15:raise RuntimeError('Replay model input stalled')
|
||||
finally:
|
||||
audio_started=False
|
||||
|
||||
@@ -294,7 +294,8 @@ class OutputOwner:
|
||||
|
||||
|
||||
PRESENTATION_FIELDS = ('phase', 'kind', 'amount', 'activation', 'strength', 'section', 'next_section',
|
||||
'gesture_active', 'gesture_queued', 'turn_signal_music')
|
||||
'gesture_active', 'gesture_queued', 'turn_signal_music', 'lead', 'predicted_peak', 'scheduled',
|
||||
'signal_shaker', 'core_apex', 'alert_accent', 'engagement_presentation')
|
||||
|
||||
|
||||
class PresentationDelay:
|
||||
|
||||
@@ -86,6 +86,25 @@ class OutputTests(unittest.TestCase):
|
||||
self.assertEqual(shown['phase'],'curve');self.assertEqual(shown['readiness'],'DEGRADED')
|
||||
self.assertEqual(shown['buffered'],80);self.assertEqual(next_snapshot['phase'],'apex')
|
||||
|
||||
def test_rendered_cues_delay_without_touching_raw_audio_clock_or_core(self):
|
||||
import copy
|
||||
self.owner.dispatch('set_latency',latency_ms=250)
|
||||
delay=m.PresentationDelay(self.root,lambda:self.output,self.clock)
|
||||
raw=dict(signal_shaker={'rendered_active':True},core_apex={'rendered_active':True},alert_accent={'rendered_active':False},engagement_presentation={'active':True},elapsed=50,route_t=10,source_cutoff_ns=123,buffered=80,readiness='READY')
|
||||
original=copy.deepcopy(raw)
|
||||
first=delay.apply(raw)
|
||||
self.assertNotIn('signal_shaker',first)
|
||||
self.assertEqual(first['elapsed'],50);self.assertEqual(first['source_cutoff_ns'],123)
|
||||
self.clock.value+=.26
|
||||
current={**raw,'signal_shaker':{'rendered_active':False},'route_t':11,'elapsed':50.26,'readiness':'DEGRADED'}
|
||||
shown=delay.apply(current)
|
||||
self.assertTrue(shown['signal_shaker']['rendered_active'])
|
||||
self.assertEqual(shown['readiness'],'DEGRADED');self.assertEqual(shown['route_t'],11)
|
||||
self.assertEqual(raw,original);self.assertFalse(current['signal_shaker']['rendered_active'])
|
||||
self.output=None;self.clock.value+=3
|
||||
bypass=delay.apply(current)
|
||||
self.assertEqual(bypass['presentation_latency_ms'],0);self.assertFalse(bypass['signal_shaker']['rendered_active'])
|
||||
|
||||
def test_watchdog_cancels_own_audio_and_releases_leases(self):
|
||||
token=self.owner.dispatch('calibration_start',attended=True)['session']
|
||||
sink=self.owner.session['sink']
|
||||
|
||||
Reference in New Issue
Block a user