wavy/lib.rs
1// Wavy
2// Copyright © 2019-2021 Jeron Aldaron Lau.
3//
4// Licensed under any of:
5// - Apache License, Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
6// - MIT License (https://mit-license.org/)
7// - Boost Software License, Version 1.0 (https://www.boost.org/LICENSE_1_0.txt)
8// At your choosing (See accompanying files LICENSE_APACHE_2_0.txt,
9// LICENSE_MIT.txt and LICENSE_BOOST_1_0.txt).
10//
11//! Asynchronous cross-platform real-time audio recording & playback.
12//!
13//! # Getting Started
14//! Add the following to your *Cargo.toml*:
15//!
16//! ```toml
17//! [dependencies]
18//! pasts = "0.7"
19//! wavy = "0.8"
20//! fon = "0.4"
21//! ```
22//!
23//! This example records audio and plays it back in real time as it's being
24//! recorded. (Make sure to wear headphones to avoid feedback):
25//!
26//! ```rust,no_run
27//! use fon::{stereo::Stereo32, Sink, Audio};
28//! use pasts::{exec, wait};
29//! use wavy::{Speakers, Microphone, SpeakersSink, MicrophoneStream};
30//!
31//! /// An event handled by the event loop.
32//! enum Event<'a> {
33//! /// Speaker is ready to play more audio.
34//! Play(SpeakersSink<'a, Stereo32>),
35//! /// Microphone has recorded some audio.
36//! Record(MicrophoneStream<'a, Stereo32>),
37//! }
38//!
39//! /// Shared state between tasks on the thread.
40//! struct State {
41//! /// Temporary buffer for holding real-time audio samples.
42//! buffer: Audio<Stereo32>,
43//! }
44//!
45//! impl State {
46//! /// Event loop. Return false to stop program.
47//! fn event(&mut self, event: Event<'_>) {
48//! match event {
49//! Event::Play(mut speakers) => speakers.stream(self.buffer.drain()),
50//! Event::Record(microphone) => self.buffer.extend(microphone),
51//! }
52//! }
53//! }
54//!
55//! /// Program start.
56//! fn main() {
57//! let mut state = State { buffer: Audio::with_silence(48_000, 0) };
58//! let mut speakers = Speakers::default();
59//! let mut microphone = Microphone::default();
60//!
61//! exec!(state.event(wait! {
62//! Event::Record(microphone.record().await),
63//! Event::Play(speakers.play().await),
64//! }));
65//! }
66//! ```
67
68#![doc(
69 html_logo_url = "https://libcala.github.io/logo.svg",
70 html_favicon_url = "https://libcala.github.io/icon.svg",
71 html_root_url = "https://docs.rs/wavy"
72)]
73#![deny(unsafe_code)]
74#![warn(
75 anonymous_parameters,
76 missing_copy_implementations,
77 missing_debug_implementations,
78 missing_docs,
79 nonstandard_style,
80 rust_2018_idioms,
81 single_use_lifetimes,
82 trivial_casts,
83 trivial_numeric_casts,
84 unreachable_pub,
85 unused_extern_crates,
86 unused_qualifications,
87 variant_size_differences
88)]
89
90#[cfg_attr(target_arch = "wasm32", path = "ffi/wasm/ffi.rs")]
91#[cfg_attr(
92 not(target_arch = "wasm32"),
93 cfg_attr(target_os = "linux", path = "ffi/linux/ffi.rs"),
94 cfg_attr(target_os = "android", path = "ffi/android/ffi.rs"),
95 cfg_attr(target_os = "macos", path = "ffi/macos/ffi.rs"),
96 cfg_attr(target_os = "ios", path = "ffi/ios/ffi.rs"),
97 cfg_attr(target_os = "windows", path = "ffi/windows/ffi.rs"),
98 cfg_attr(
99 any(
100 target_os = "freebsd",
101 target_os = "dragonfly",
102 target_os = "bitrig",
103 target_os = "openbsd",
104 target_os = "netbsd"
105 ),
106 path = "ffi/bsd/ffi.rs"
107 ),
108 cfg_attr(target_os = "fuchsia", path = "ffi/fuchsia/ffi.rs"),
109 cfg_attr(target_os = "redox", path = "ffi/redox/ffi.rs"),
110 cfg_attr(target_os = "none", path = "ffi/none/ffi.rs"),
111 cfg_attr(target_os = "dummy", path = "ffi/dummy/ffi.rs")
112)]
113mod ffi;
114
115mod consts;
116mod microphone;
117mod speakers;
118
119pub use microphone::{Microphone, MicrophoneStream};
120pub use speakers::{Speakers, SpeakersSink};