rundsp/stream/run/
start.rs

1//! All of the free functions which start the creation of a [`Run`].
2//!
3//! Each of these corresponds to a builder method on [`Run`]; these are purely convenience methods
4//! which are shorthands for `Run::new().method(...)`.
5
6use fundsp::hacker::{U1, U2, multipass};
7
8use crate::{FromStereo, ToStereo};
9
10use super::*;
11
12impl Default for Run {
13    fn default() -> Self {
14        Self::new()
15    }
16}
17
18impl Run {
19    /// Create a new [`Run`] with default parameters.
20    ///
21    /// This cannot be [`run`](Run::run) without a type error until at least one of
22    /// [`input`](Run::input) or [`output`](Run::output) are specified.
23    pub fn new() -> Self {
24        Run {
25            host: None,
26            select_device: Arc::new(|_, _| None),
27            select_config: Arc::new(|_, _| None),
28            input_info: |_| {},
29            output_info: |_| {},
30            timeout: None,
31            start_paused: false,
32            retrying: Arc::new(Mutex::new(|_: &Error| Retry::stop())),
33            control: mpsc::channel(1).1,
34            input: NoInput,
35            output: NoOutput,
36        }
37    }
38}
39
40impl<L, M, I, O> Run<I, O, L, M>
41where
42    L: InputInfo,
43    M: OutputInfo,
44{
45    /// Use the given audio [`Host`].
46    pub fn host(mut self, host: Host) -> Self {
47        self.host = Some(Arc::new(host));
48        self
49    }
50
51    /// Use the specified closure to select which [`Device`] should be used for each end of the
52    /// pipeline.
53    pub fn device(mut self, select_device: impl SelectDevice) -> Self {
54        self.select_device = Arc::new(select_device);
55        self
56    }
57
58    /// Use the specified closure to select which [`SupportedStreamConfig`] should be used for each
59    /// end of the pipeline.
60    pub fn config(mut self, select_config: impl SelectConfig) -> Self {
61        self.select_config = Arc::new(select_config);
62        self
63    }
64
65    /// Use the specified audio node as the input end of the pipeline.
66    ///
67    /// After specifying this, it is now possible to [`run`](Run::run) the pipline, although other
68    /// options may also be specified afterwards.
69    pub fn input<N: StereoInput>(self, input: An<N>) -> Run<An<N>, O, L, M> {
70        let Run {
71            host,
72            select_device,
73            select_config,
74            input_info,
75            output_info,
76            timeout,
77            start_paused,
78            retrying,
79            control,
80            input: _,
81            output,
82        } = self;
83        Run {
84            host,
85            select_device,
86            select_config,
87            input_info,
88            output_info,
89            timeout,
90            start_paused,
91            retrying,
92            control,
93            input,
94            output,
95        }
96    }
97
98    /// Feed the microphone's input directly to the output of the pipeline.
99    ///
100    /// In case of ambiguous type inference, use [`mono_mic`](Run::mono_mic) or
101    /// [`stereo_mic`](Run::stereo_mic) to disambiguate.
102    ///
103    /// After specifying this, it is now possible to [`run`](Run::run) the pipline, although other
104    /// options may also be specified afterwards.
105    pub fn mic<N: FromStereo>(self) -> Run<An<impl StereoInput<Outputs = N>>, O, L, M> {
106        self.input(multipass())
107    }
108
109    /// Feed the microphone's input directly to the output of the pipeline, as *mono* audio.
110    ///
111    /// After specifying this, it is now possible to [`run`](Run::run) the pipline, although other
112    /// options may also be specified afterwards.
113    pub fn mono_mic(self) -> Run<An<impl StereoInput<Outputs = U1>>, O, L, M> {
114        self.mic::<U1>()
115    }
116
117    /// Feed the microphone's input directly to the output of the pipeline, as *stereo* audio.
118    ///
119    /// After specifying this, it is now possible to [`run`](Run::run) the pipline, although other
120    /// options may also be specified afterwards.
121    pub fn stereo_mic(self) -> Run<An<impl StereoInput<Outputs = U2>>, O, L, M> {
122        self.mic::<U2>()
123    }
124
125    /// Use the specified audio node as the output end of the pipeline.
126    ///
127    /// After specifying this, it is now possible to [`run`](Run::run) the pipline, although other
128    /// options may also be specified afterwards.
129    pub fn output<N: StereoOutput>(self, output: An<N>) -> Run<I, An<N>, L, M> {
130        let Run {
131            host,
132            select_device,
133            select_config,
134            input_info,
135            output_info,
136            timeout,
137            start_paused,
138            retrying,
139            control,
140            input,
141            output: _,
142        } = self;
143        Run {
144            host,
145            select_device,
146            select_config,
147            input_info,
148            output_info,
149            timeout,
150            start_paused,
151            retrying,
152            control,
153            input,
154            output,
155        }
156    }
157
158    /// Feed the output of the pipeline directly to the speaker (or headphones).
159    ///
160    /// In case of ambiguous type inference, use [`mono_speaker`](Run::mono_speaker) or
161    /// [`stereo_speaker`](Run::stereo_speaker) to disambiguate.
162    ///
163    /// After specifying this, it is now possible to [`run`](Run::run) the pipline, although other
164    /// options may also be specified afterwards.
165    pub fn speaker<N: ToStereo>(self) -> Run<I, An<impl StereoOutput<Inputs = N>>, L, M> {
166        self.output(multipass())
167    }
168
169    /// Feed the output of the pipeline directly to the speaker (or headphones), as *mono* audio.
170    ///
171    /// After specifying this, it is now possible to [`run`](Run::run) the pipline, although other
172    /// options may also be specified afterwards.
173    pub fn mono_speaker(self) -> Run<I, An<impl StereoOutput<Inputs = U1>>, L, M> {
174        self.speaker::<U1>()
175    }
176
177    /// Feed the output of the pipeline directly to the speaker (or headphones), as *stereo* audio.
178    ///
179    /// After specifying this, it is now possible to [`run`](Run::run) the pipline, although other
180    /// options may also be specified afterwards.
181    pub fn stereo_speaker(self) -> Run<I, An<impl StereoOutput<Inputs = U2>>, L, M> {
182        self.speaker::<U2>()
183    }
184
185    /// Call the given closure every time an input buffer is received.
186    ///
187    /// The closure specified should be fast, non-allocating, and non-blocking; otherwise, audio
188    /// glitches may occur.
189    pub fn on_input<X: InputInfo>(self, input_info: X) -> Run<I, O, X, M> {
190        let Run {
191            host,
192            select_device,
193            select_config,
194            input_info: _,
195            output_info,
196            timeout,
197            start_paused,
198            retrying,
199            control,
200            input,
201            output,
202        } = self;
203        Run {
204            host,
205            select_device,
206            select_config,
207            input_info,
208            output_info,
209            timeout,
210            start_paused,
211            retrying,
212            control,
213            input,
214            output,
215        }
216    }
217
218    /// Call the given closure every time an input buffer is produced.
219    ///
220    /// The closure specified should be fast, non-allocating, and non-blocking; otherwise, audio
221    /// glitches may occur.
222    pub fn on_output<X: OutputInfo>(self, output_info: X) -> Run<I, O, L, X> {
223        let Run {
224            host,
225            select_device,
226            select_config,
227            input_info,
228            output_info: _,
229            timeout,
230            start_paused,
231            retrying,
232            control,
233            input,
234            output,
235        } = self;
236        Run {
237            host,
238            select_device,
239            select_config,
240            input_info,
241            output_info,
242            timeout,
243            start_paused,
244            retrying,
245            control,
246            input,
247            output,
248        }
249    }
250
251    /// Use the given closure to determine how to retry in the event of an error while building or
252    /// running a stream. See [`Retrying`] for more information.
253    pub fn on_error<R: Into<Retry>>(mut self, mut retry: impl Retrying<R>) -> Self {
254        self.retrying = Arc::new(Mutex::new(move |error: &Error| retry(error).into()));
255        self
256    }
257
258    /// Start the audio pipeline paused, so that it has to be manually played.
259    pub fn paused(mut self) -> Self {
260        self.start_paused = true;
261        self
262    }
263
264    /// Run the audio pipeline as specified.
265    ///
266    /// This method call will not type-check unless you have specified at least one of
267    /// [`input`](Run::input) or [`output`](Run::output), or equivalently unless you started the
268    /// builder using [`input`] or [`output`].
269    pub fn run(self) -> Running
270    where
271        I: RunWith<O>,
272    {
273        self.run_audio()
274    }
275}
276
277// Free functions to start building a `Run`:
278
279/// Create a new [`Run`] using a given audio [`Host`].
280///
281/// The resultant [`Run`] cannot be [`run`](Run::run) without a type error until at least one of
282/// [`input`](Run::input) or [`output`](Run::output) are specified.
283pub fn host(host: Host) -> Run {
284    Run::new().host(host)
285}
286
287/// Create a new [`Run`] using the given closure to select an audio [`Device`].
288///
289/// The resultant [`Run`] cannot be [`run`](Run::run) without a type error until at least one of
290/// [`input`](Run::input) or [`output`](Run::output) are specified.
291pub fn device(select_device: impl SelectDevice) -> Run {
292    Run::new().device(select_device)
293}
294
295/// Create a new [`Run`] using the given closure to select an audio [`SupportedStreamConfig`].
296///
297/// The resultant [`Run`] cannot be [`run`](Run::run) without a type error until at least one of
298/// [`input`](Run::input) or [`output`](Run::output) are specified.
299pub fn config(select_config: impl SelectConfig) -> Run {
300    Run::new().config(select_config)
301}
302
303/// Create a new [`Run`] using the given audio node as the input end.
304///
305/// The resultant [`Run`] can be immediately [`run`](Run::run), or further options may be specified.
306pub fn input<I: StereoInput>(input: An<I>) -> Run<An<I>, NoOutput> {
307    Run::new().input(input)
308}
309
310/// Create a new [`Run`] that feeds the microphone's input directly to the output of the pipeline.
311///
312/// In case of ambiguous type inference, use [`mono_mic`](Run::mono_mic) or
313/// [`stereo_mic`](Run::stereo_mic) to disambiguate.
314///
315/// After specifying this, it is now possible to [`run`](Run::run) the pipline, although other
316/// options may also be specified afterwards.
317pub fn mic<N: FromStereo>() -> Run<An<impl StereoInput<Outputs = N>>, NoOutput> {
318    Run::new().mic()
319}
320
321/// Create a new [`Run`] that feeds the microphone's input directly to the output of the pipeline,
322/// as *mono* audio.
323///
324/// After specifying this, it is now possible to [`run`](Run::run) the pipline, although other
325/// options may also be specified afterwards.
326pub fn mono_mic() -> Run<An<impl StereoInput<Outputs = U1>>, NoOutput> {
327    Run::new().mono_mic()
328}
329
330/// Create a new [`Run`] that feeds the microphone's input directly to the output of the pipeline,
331/// as *stereo* audio.
332///
333/// After specifying this, it is now possible to [`run`](Run::run) the pipline, although other
334/// options may also be specified afterwards.
335pub fn stereo_mic() -> Run<An<impl StereoInput<Outputs = U2>>, NoOutput> {
336    Run::new().stereo_mic()
337}
338
339/// Create a new [`Run`] using the given audio node as the output end.
340///
341/// The resultant [`Run`] can be immediately [`run`](Run::run), or further options may be specified.
342pub fn output<O: StereoOutput>(output: An<O>) -> Run<NoInput, An<O>> {
343    Run::new().output(output)
344}
345
346/// Create a new [`Run`] that feeds the output of the pipeline directly to the speaker (or
347/// headphones).
348///
349/// In case of ambiguous type inference, use [`mono_speaker`](Run::mono_speaker) or
350/// [`stereo_speaker`](Run::stereo_speaker) to disambiguate.
351///
352/// After specifying this, it is now possible to [`run`](Run::run) the pipline, although other
353/// options may also be specified afterwards.
354pub fn speaker<N: ToStereo>() -> Run<NoInput, An<impl StereoOutput<Inputs = N>>> {
355    Run::new().speaker()
356}
357
358/// Create a new [`Run`] that feeds the output of the pipeline directly to the speaker (or
359/// headphones), as *mono* audio.
360///
361/// After specifying this, it is now possible to [`run`](Run::run) the pipline, although other
362/// options may also be specified afterwards.
363pub fn mono_speaker() -> Run<NoInput, An<impl StereoOutput<Inputs = U1>>> {
364    Run::new().mono_speaker()
365}
366
367/// Create a new [`Run`] that feeds the output of the pipeline directly to the speaker (or
368/// headphones), as *stereo* audio.
369///
370/// After specifying this, it is now possible to [`run`](Run::run) the pipline, although other
371/// options may also be specified afterwards.
372pub fn stereo_speaker() -> Run<NoInput, An<impl StereoOutput<Inputs = U2>>> {
373    Run::new().stereo_speaker()
374}
375
376/// Create a new [`Run`] which will call the given closure every time an input buffer is received.
377///
378/// The closure specified should be fast, non-allocating, and non-blocking; otherwise, audio
379/// glitches may occur.
380///
381/// The resultant [`Run`] cannot be [`run`](Run::run) without a type error until at least one of
382/// [`input`](Run::input) or [`output`](Run::output) are specified.
383pub fn on_input<I: InputInfo>(input_info: I) -> Run<NoInput, NoOutput, I, FnOutputInfo> {
384    Run::new().on_input(input_info)
385}
386
387/// Create a new [`Run`] which will call the given closure every time an output buffer is produced.
388///
389/// The closure specified should be fast, non-allocating, and non-blocking; otherwise, audio
390/// glitches may occur.
391///
392/// The resultant [`Run`] cannot be [`run`](Run::run) without a type error until at least one of
393/// [`input`](Run::input) or [`output`](Run::output) are specified.
394pub fn on_output<O: OutputInfo>(output_info: O) -> Run<NoInput, NoOutput, FnInputInfo, O> {
395    Run::new().on_output(output_info)
396}
397
398/// Create a new [`Run`] which will use the given closure to determine how to retry in the event of
399/// an error while building or running a stream. See [`Retrying`] for more information.
400///
401/// The resultant [`Run`] cannot be [`run`](Run::run) without a type error until at least one of
402/// [`input`](Run::input) or [`output`](Run::output) are specified.
403pub fn on_error<R: Into<Retry>>(retry: impl Retrying<R>) -> Run {
404    Run::new().on_error(retry)
405}
406
407/// Create a new [`Run`] which will start paused, so that it has to be manually played before audio
408/// will happen.
409///
410/// The resultant [`Run`] cannot be [`run`](Run::run) without a type error until at least one of
411/// [`input`](Run::input) or [`output`](Run::output) are specified.
412pub fn start_paused() -> Run {
413    Run::new().paused()
414}