Bug-hunt sweep: fix 13 verified issues (correctness + perf)
From a multi-agent bug-hunt + adversarial verification pass (0 critical/ high; 15 mediums). Fixed 13; 2 deferred as bigger refactors. Correctness: - srs: "Hard" no longer overshoots "Good" for reviewed cards (reps>=2). It compounded ease AND x1.2; now grows x1.2 off the previous interval only. + regression test. - enrich/dates: stop reading the modal verb "may" as the month May (phantom calendar events). "may" needs an ordinal/year/date-preposition now. - enrich/bib: disambiguate colliding BibTeX keys (smith2020, smith2020a, …) — duplicates corrupted reference-manager imports. - learn/glossary: junk-term guard used && (dead); now || so all-stopword terms like "there" are actually skipped. - transcription/engineImpl.web: don't collapse Whisper's null end-timestamp to a zero-length [t,t] segment; estimate from the next chunk or window duration (fixes citation/seam anchors). - transcription/pipeline: re-check the abort signal AFTER each chunk so Cancel works on single-chunk audio (it previously still saved). - db/repo.native: use withExclusiveTransactionAsync for reassign / deleteCourse / upsertVectors / createFlashcards (withTransactionAsync is not isolated on a shared connection → interleaved/half-applied writes). - db/repo.native: don't cache a rejected open/migrate promise — a transient first-open failure no longer bricks storage for the whole session. - stores/transcriptsStore: sequence-guard refresh() so overlapping focus/typing/filter refreshes can't resolve out of order and show stale results. - audio/wav: decode WAVE_FORMAT_EXTENSIBLE (0xFFFE) via its SubFormat GUID + add 24-bit PCM — common ffmpeg/Windows WAVs no longer hard-fail native import. + tests. Performance / footprint: - audio/decode.native: decode straight to 16kHz (decodeAudioData sampleRate hint) so the JS side never holds a full-rate buffer or runs the resample loop — big memory/OOM win on long lectures. - models/catalog display: Settings model sizes are now backend-aware (the no-GPU WASM path pulls ~2x fp32 weights; was advertising ~half). Feature gap: - download: native exports were silent no-ops. New download.native.ts writes to cache + opens the share sheet (expo-sharing); transcript/ICS/Anki-CSV/ BibTeX/RIS exports now work on device. Deferred (bigger): lexical-search recall ceiling (needs a full-corpus rank path on both repos); triple in-memory copy of the encoded file during transcribe (media is keyed by a not-yet-existing transcript id). Validated: tsc clean, 282 tests pass, web export clean (native deps not bundled), arm64 APK compiles with expo-sharing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -156,13 +156,26 @@ export const engine: TranscriptionEngine = {
|
||||
|
||||
const out = await asr(audio.samples, genOpts);
|
||||
|
||||
// Whisper sometimes omits the END timestamp of the last utterance in a
|
||||
// window (transformers.js yields timestamp[1] === null). Don't collapse that
|
||||
// to a zero-length [t, t] segment (it breaks stitch seams + citation spans):
|
||||
// estimate the end from the next chunk's start, else the window's duration.
|
||||
const chunks = out.chunks ?? [];
|
||||
const chunkDurationSec = audio.samples.length / audio.sampleRate;
|
||||
const segments: Segment[] = [];
|
||||
for (const c of out.chunks ?? []) {
|
||||
const [start, end] = c.timestamp;
|
||||
for (let i = 0; i < chunks.length; i++) {
|
||||
const c = chunks[i]!;
|
||||
const [start, rawEnd] = c.timestamp;
|
||||
if (start == null) continue;
|
||||
const text = c.text.trim();
|
||||
if (text.length === 0) continue;
|
||||
segments.push({ start, end: end ?? start, text });
|
||||
let end = rawEnd;
|
||||
if (end == null) {
|
||||
const nextStart = chunks[i + 1]?.timestamp[0];
|
||||
end = nextStart != null && nextStart > start ? nextStart : chunkDurationSec;
|
||||
}
|
||||
if (end < start) end = chunkDurationSec;
|
||||
segments.push({ start, end, text });
|
||||
}
|
||||
return segments;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user