• 声纹(用户语音里提了 3 次的 feature):
    - SpeakerEmbedder.kt: sherpa-onnx SpeakerEmbeddingExtractor 包装
      3dspeaker CAMPPlus 16k zh-cn 模型(28 MB int8 ONNX),192 维 embedding
    - ModelDownloader.ensureSpeakerModel(): 首次启动从 hf-mirror.com 自动下
    - Segment 实体加 embedding/speakerId/speakerSim 三列
    - SpeakerProfile 实体(id/name/embedding/sampleCount/createdAt)+ SpeakerDao
    - RecorderService.handleSegment 每段算 embedding + 与已注册 profiles 算
      cosine,threshold ≥0.5 才 assign
    - RecorderService 通过 speakers.observeAll() 实时 reload profile 缓存
    - MainActivity 点时间轴段 → AlertDialog 输入名字 → 创建 SpeakerProfile
    - TimelineRow 显示 "name (sim=0.xx)" 或 "—" / "未匹配 (0.xx)"
    
    FTS4 全文搜索:
    - TranscriptFts 实体用 @Fts4(contentEntity=Transcript, tokenizer="unicode61")
      Room 自动建虚表 + 同步触发器,unicode61 把中文字当 token
    - searchTimeline DAO 查询 JOIN transcript_fts MATCH :query
    - MainActivity 顶部 OutlinedTextField 实时切换 timelineFlow
    - sanitizeFtsQuery 给每 token 加 * 做前缀匹配,剥掉 FTS metachars
    
    Schema:
    - AppDatabase v1 → v2 + fallbackToDestructiveMigration(v0.3 dev 数据可丢)
    - 新增 SpeakerProfile + TranscriptFts 虚表 + Segment 三列
    
    HANDOFF.md §五 更新:声纹 + 搜索移到「已完成」,下一档变成 LLM 纪要
    worker / 存储 TTL / 段播放 / 多 anchor 平均 / lemonPCRM 回链。
    
    实测(Pixel 8 Pro Tensor G3,Android 16):
    - speaker model load: 441 ms
    - embedding 计算开销 ~10-30 ms/段,跟 paraformer 同期完成
    - enroll "Me" anchor → 后续段在 logcat 见 "speaker=Me sim=0.xx"
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »

  • 让 v1 真能脱离开发环境 24/7 跑的最后三公里:
    
    - SegmentWriter 改 Opus(MediaCodec audio/opus encoder + MediaMuxer OGG)
      ~17× 压缩,~2 KB/s 实测(vs WAV 32 KB/s)
      存储预算:8h 语音/天 → ~57 MB/天,~1.7 GB/月(vs WAV 51 GB/月)
      ffprobe 验证 codec_name=opus, channels=1, OggS magic OK
    
    - BootReceiver 监听 BOOT_COMPLETED / LOCKED_BOOT_COMPLETED /
      QUICKBOOT_POWERON,try-catch 兜底 Android 14+ FG service 限制
    
    - MainActivity 加电池豁免行:dumpsys deviceidle whitelist 实时检测,
      未豁免时给「申请豁免」按钮,触发系统 RequestIgnoreBatteryOptimizations
      对话框;ON_RESUME 生命周期观察让从设置页回来 UI 自动刷新
    
    - AndroidManifest:
      + REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 权限
      + BootReceiver 注册(含 3 个 boot 相关 action)
    
    HANDOFF.md §五 更新待办(v0.2 三项移到「已完成」),加存储预算 +
    Android 14 BOOT_COMPLETED caveat 段落(Pixel 8 Pro 实测能自动续上,
    前提 app 至少开过一次 + RECORD_AUDIO 已授)。
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • §零 环境铁律:whisper 别当默认 STT、模型别提交、asset 不走 mmap、
    线程甜点是 4、AID_INET 必须传、keys.properties gitignored。
    
    §二 核心文件清单:bot 实跑只看 RecorderService.kt + ParaformerEngine.kt
    + MainActivity.kt,sherpa-onnx Kotlin 绑定整目录原样塞别动。
    
    §三 开发内循环、§四 pipeline 链路图、§五§六 优先级排序的 7 项待办、
    §七 踩过的坑清单(VAD 资产 mmap SIGSEGV / silero_vad.onnx LFS 拦截 /
    paraformer t=8 反慢 / hf-mirror 截断 / am 启动非 exported 服务 /
    su 切 uid 丢 AID_INET)、§九 接手 prompt。
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • Pixel 8 Pro 上的本地 lifelog 应用,v1 核心闭环:
    
    - 前台服务 (foregroundServiceType=microphone) + AudioRecord 16k mono PCM
    - Silero VAD on-device 切段(500ms 静音切、300ms 最短、30s 强切)
    - sherpa-onnx + paraformer-zh int8 本地 ASR
      Tensor G3 实测 ~25× realtime,<200ms 处理 1-10s 段
      whisper-small 0.6× 跑不动,paraformer 是甜点选型
    - Room (Segment + Transcript + Summary) + Compose 时间轴 LazyColumn UI
    - 232 MB 模型首次启动从 hf-mirror.com 下载到 app filesDir
    - 讯飞 中文识别大模型 WebSocket 客户端备用(云复核 fallback)
    
    依赖:
    - sherpa-onnx v1.13.2 Android jniLibs (arm64-v8a, ~34 MB)
    - Silero VAD ONNX (~629 KB),sample.wav (3 MB) 内嵌资源
    - AGP 8.7.3 / Kotlin 2.1 / Compose BOM 2024.12.01 / Room 2.6.1
    
    后续待办(按用户语音里提到的优先级):声纹识别 / Opus 编码 /
    FTS5 中文搜索 / hermes-Kimi 纪要 worker。
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »