1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//! The [`Transcriber`] trait and its [`SttError`].
use async_trait;
use AudioFormat;
use MaybeSendSync;
use Arc;
/// The swappable speech-to-text capability: `f32` samples in, a transcript out.
///
/// This is the durable interface. A native engine (`ort`) and a browser engine
/// (Transformers.js in a Web Worker) both implement this one trait, so
/// [`SttStage`](crate::SttStage) — and the pipeline above it — never names a
/// concrete model. The offload decision lives in the *impl* (native offloads to
/// a worker thread; wasm awaits a Web Worker), so the stage stays engine-neutral
/// and just `.await`s [`transcribe`](Transcriber::transcribe).
///
/// `?Send` matches pipecrab's single-threaded execution model, so one
/// implementation runs unchanged on a current-thread executor and on `wasm32`,
/// where `Send` bounds cannot be satisfied.
/// Why a [`Transcriber::transcribe`] call failed.
///
/// Mirrors the message-plus-kind shape of the pipeline's other error types so
/// the conversion at the stage boundary
/// (`impl From<SttError> for StageError`) is direct. There is deliberately no
/// format-mismatch variant: samples are interpreted as
/// [`input_format()`](Transcriber::input_format) and the stage enforces that
/// format fatally, so an engine never sees nonconforming audio to reject.