วงจรชีวิตของโอเวอร์เลย์เสียง(macOS)¶
กลุ่มเป้าหมาย: ผู้มีส่วนร่วมพัฒนาแอป macOS เป้าหมาย: ทำให้โอเวอร์เลย์เสียงมีพฤติกรรมที่คาดเดาได้เมื่อ wake-word และ push-to-talk ซ้อนทับกัน
เจตนาปัจจุบัน¶
- หากโอเวอร์เลย์แสดงอยู่แล้วจากเวกเวิร์ดและผู้ใช้กดปุ่มลัด เซสชันกดคุยจะ รับช่วง ข้อความที่มีอยู่แทนการรีเซ็ต โอเวอร์เลย์จะคงอยู่ขณะกดปุ่มลัด เมื่อผู้ใช้ปล่อย: ส่งหากมีข้อความที่ตัดแต่งแล้ว มิฉะนั้นให้ปิด โอเวอร์เลย์จะแสดงค้างไว้ขณะกดปุ่มลัดค้าง เมื่อผู้ใช้ปล่อยปุ่ม: ส่งหากมีข้อความที่ถูกตัดแล้ว มิฉะนั้นให้ปิดทิ้ง
- เวกเวิร์ดอย่างเดียวยังคงส่งอัตโนมัติเมื่อเงียบ; กดคุยจะส่งทันทีเมื่อปล่อย
ที่ได้ติดตั้งแล้ว(9 ธ.ค. 2025)¶
- เซสชันของโอเวอร์เลย์จะมีโทเคนต่อการจับเสียงหนึ่งครั้ง (wake-word หรือ push-to-talk) เซสชันโอเวอร์เลย์จะมีโทเคนต่อการจับเสียงแต่ละครั้ง(เวกเวิร์ดหรือกดคุย) การอัปเดตแบบ partial/final/send/dismiss/level จะถูกทิ้งเมื่อโทเคนไม่ตรงกัน เพื่อหลีกเลี่ยงคอลแบ็กค้าง
- push-to-talk จะรับข้อความโอเวอร์เลย์ที่มองเห็นอยู่มาเป็นคำนำหน้า (ดังนั้นการกดปุ่มลัดขณะโอเวอร์เลย์จาก wake แสดงอยู่จะคงข้อความเดิมไว้และต่อท้ายด้วยเสียงใหม่) รอสูงสุด 1.5 วินาทีเพื่อรับทรานสคริปต์สุดท้าย ก่อนจะย้อนกลับไปใช้ข้อความปัจจุบัน
- มีการส่งบันทึก chime/overlay ที่
infoในหมวดหมู่voicewake.overlay,voicewake.ptt, และvoicewake.chime(เริ่มเซสชัน, partial, final, send, dismiss, เหตุผลของ chime)
ขั้นตอนถัดไป¶
- VoiceSessionCoordinator (actor)
- เป็นเจ้าของ
VoiceSessionได้เพียงหนึ่งรายการในเวลาเดียว - API(อิงโทเคน):beginWakeCapture,beginPushToTalk,updatePartial,endCapture,cancel,applyCooldown. - ทิ้งคอลแบ็กที่พกโทเคนค้าง(ป้องกัน recognizer เก่าจากการเปิดโอเวอร์เลย์อีกครั้ง) - VoiceSession (model)
- ฟิลด์:
token,source(wakeWord|pushToTalk), ข้อความที่คอมมิต/ชั่วคราว, แฟล็ก chime, ตัวจับเวลา(ส่งอัตโนมัติ, ว่าง),overlayMode(display|editing|sending), เดดไลน์คูลดาวน์ - การผูกกับโอเวอร์เลย์
-
VoiceSessionPublisher(ObservableObject) สะท้อนเซสชันที่ใช้งานอยู่เข้าสู่ SwiftUI -VoiceWakeOverlayViewเรนเดอร์ผ่าน publisher เท่านั้น ไม่แก้ไข singleton ส่วนกลางโดยตรง - การกระทำของผู้ใช้บนโอเวอร์เลย์(sendNow,dismiss,edit) เรียกกลับไปยัง coordinator พร้อมโทเคนของเซสชัน - เส้นทางการส่งแบบรวม
- เมื่อ
endCapture: หากข้อความที่ตัดแต่งแล้วว่าง → ปิด; มิฉะนั้นperformSend(session:)(เล่น chime การส่งหนึ่งครั้ง ส่งต่อ และปิด) - กดคุย: ไม่หน่วงเวลา; เวกเวิร์ด: หน่วงเวลาได้ตามตัวเลือกสำหรับการส่งอัตโนมัติ - ใช้คูลดาวน์สั้นๆกับรันไทม์เวกหลังจากกดคุยเสร็จ เพื่อไม่ให้เวกเวิร์ดทริกเกอร์ซ้ำทันที - การบันทึก
- Coordinator ส่งบันทึก
.infoใน subsystembot.molt, หมวดหมู่voicewake.overlayและvoicewake.chime. - เหตุการณ์สำคัญ:session_started,adopted_by_push_to_talk,partial,finalized,send,dismiss,cancel,cooldown.
เช็กลิสต์การดีบัก¶
- สตรีมบันทึกขณะทำซ้ำปัญหาโอเวอร์เลย์ค้าง:
bash
sudo log stream --predicate 'subsystem == "bot.molt" AND category CONTAINS "voicewake"' --level info --style compact
-
ตรวจสอบให้มีโทเคนเซสชันที่ใช้งานอยู่เพียงหนึ่งเดียว; คอลแบ็กค้างควรถูก coordinator ทิ้ง
-
ตรวจสอบให้แน่ใจว่าการปล่อยกดคุยเรียก
endCaptureด้วยโทเคนที่ใช้งานอยู่เสมอ; หากข้อความว่าง ควรเห็นdismissโดยไม่มี chime หรือการส่ง
ขั้นตอนการย้าย(แนะนำ)¶
- เพิ่ม
VoiceSessionCoordinator,VoiceSession, และVoiceSessionPublisher. - รีแฟกเตอร์
VoiceWakeRuntimeให้สร้าง/อัปเดต/จบเซสชันแทนการแตะVoiceWakeOverlayControllerโดยตรง - รีแฟกเตอร์
VoicePushToTalkให้รับช่วงเซสชันที่มีอยู่และเรียกendCaptureเมื่อปล่อย; ใช้คูลดาวน์ของรันไทม์ - เชื่อม
VoiceWakeOverlayControllerเข้ากับ publisher; เอาการเรียกโดยตรงจากรันไทม์/PTT ออก - เพิ่มการทดสอบแบบบูรณาการสำหรับการรับช่วงเซสชัน คูลดาวน์ และการปิดเมื่อข้อความว่าง