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
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
// Copyright Jeron Aldaron Lau 2018 - 2020.
// Distributed under either the Apache License, Version 2.0
//    (See accompanying file LICENSE_APACHE_2_0.txt or copy at
//          https://apache.org/licenses/LICENSE-2.0),
// or the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_BOOST_1_0.txt or copy at
//          https://www.boost.org/LICENSE_1_0.txt)
// at your option. This file may not be copied, modified, or distributed except
// according to those terms.

//! Library for pure Rust advanced audio synthesis.
//!
//! Most audio DSP (Digital Signal Processing) libraries have a concept of an
//! audio graph which connects sources to destinations.  Twang uses a simplified
//! model: a synthesis tree.  Twang doesn't deal with having speakers as a node
//! on a graph, as it's only focus is synthesis.  A synthesis tree can do all of
//! the things that an audio graph can do, but it's simpler and much easier to
//! learn.
//!
//! To start, first you need to construct a **synthesizer**
//! ([`Synth`](struct.Synth.html)).  Then you need a type that implements the
//! `Sink` trait.  `Audio` buffers have a `sink` method you can use to get a
//! `Sink`.  Once you have those, you can synthesize audio with a closure that
//! has one parameter representing the **frequency counter**.  You can use the
//! **frequency counter** to generate continuous pitched waveforms.
//!
//! # A3 (220 Hz) Minor Piano Example
//! This example uses the first ten piano harmonics to generate a sound that
//! sounds like an electric piano.  This is an example of additive synthesis,
//! since it uses the `Mix` trait.
//!
//! ```rust,no_run
//! use fon::{mono::Mono64, Audio, Sink};
//! use twang::{Mix, Synth, Fc, Signal};
//! 
//! // Target sample rate set to 48 KHz
//! const S_RATE: u32 = 48_000;
//! 
//! /// First ten harmonic volumes of a piano sample (sounds like electric piano).
//! const HARMONICS: [f64; 10] = [
//!     0.700, 0.243, 0.229, 0.095, 0.139, 0.087, 0.288, 0.199, 0.124, 0.090,
//! ];
//! /// The three pitches in a perfectly tuned A3 minor chord
//! const PITCHES: [f64; 3] = [220.0, 220.0 * 32.0 / 27.0, 220.0 * 3.0 / 2.0];
//! /// Volume of the piano
//! const VOLUME: f64 = 0.1;
//! 
//! fn main() {
//!     fn piano(_: &mut (), fc: Fc) -> Signal {
//!         PITCHES
//!             .iter()
//!             .map(|p| {
//!                 HARMONICS
//!                     .iter()
//!                     .enumerate()
//!                     .map(|(i, v)| {
//!                         fc.freq(p * (i + 1) as f64).sine().gain(v * VOLUME)
//!                     })
//!                     .mix()
//!             })
//!             .mix()
//!     }
//! 
//!     // Initialize audio with five seconds of silence.
//!     let mut audio = Audio::<Mono64>::with_silence(S_RATE, S_RATE as usize * 5);
//!     // Create the synthesizer.
//!     let mut synth = Synth::new((), piano);
//!     // Generate audio samples.
//!     audio.sink(..).stream(&mut synth);
//! }
//! ```

#![doc(
    html_logo_url = "https://libcala.github.io/logo.svg",
    html_favicon_url = "https://libcala.github.io/icon.svg",
    html_root_url = "https://docs.rs/twang"
)]
#![deny(unsafe_code)]
#![warn(
    anonymous_parameters,
    missing_copy_implementations,
    missing_debug_implementations,
    missing_docs,
    nonstandard_style,
    rust_2018_idioms,
    single_use_lifetimes,
    trivial_casts,
    trivial_numeric_casts,
    unreachable_pub,
    unused_extern_crates,
    unused_qualifications,
    variant_size_differences
)]

mod pink;
mod room;
mod sig;
mod synth;
mod white;

pub use pink::Pink;
pub use room::Room;
pub use sig::Signal;
pub use synth::{Fc, Mix, Synth};
pub use white::White;