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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
//! A signal processing framework for making music with rust. //! //! `oxcable` is designed with simple but powerful abstractions, with minimal //! performance loss, while functioning in real-time. //! //! `oxcable` seeks to provide the basic building blocks necessary to build //! digital instruments and effects, and provide the tools to chain these //! devices together quickly and easily. //! //! # Getting started //! //! Let's start with a simple example. This script will generate a sine wave at //! 440Hz, and play it on your computer's speakers or headphones in an infinite //! loop: //! //! ```no_run //! extern crate oxcable; //! use oxcable::chain::{DeviceChain, Tick}; //! use oxcable::io::audio::AudioEngine; //! use oxcable::oscillator::{Oscillator, Sine}; //! //! fn main() { //! let engine = AudioEngine::with_buffer_size(256).unwrap(); //! let mut chain = DeviceChain::from( //! Oscillator::new(Sine).freq(440.0) //! ).into( //! engine.default_output(1).unwrap() //! ); //! chain.tick_forever(); //! } //! ``` //! //! # Devices //! //! Defining an audio device can be done by implenting the //! [`AudioDevice` trait](types/trait.AudioDevice.html). //! //! Let's define a very simple audio device: one that simply passes its input //! straight to the output. This can be done in just a few lines: //! //! ``` //! use oxcable::types::{AudioDevice, Sample, Time}; //! //! struct IdentityFilter; //! impl AudioDevice for IdentityFilter { //! fn num_inputs(&self) -> usize { 1 } //! fn num_outputs(&self) -> usize { 1 } //! fn tick(&mut self, _: Time, inputs: &[Sample], outputs: &mut[Sample]) { //! outputs[0] = inputs[0]; //! } //! } //! ``` //! //! Once we've defined a device, it is simple to use the device in isolation. //! Say I want to test my filter. I can manually call tick a few times to //! generate outputs: //! //! ``` //! # use oxcable::types::{AudioDevice, Sample, Time}; //! # struct IdentityFilter; //! # impl AudioDevice for IdentityFilter { //! # fn num_inputs(&self) -> usize { 1 } //! # fn num_outputs(&self) -> usize { 1 } //! # fn tick(&mut self, _: Time, inputs: &[Sample], outputs: &mut[Sample]) { //! # outputs[0] = inputs[0]; //! # } //! # } //! # //! let mut input = [0.0]; //! let mut output = [0.0]; //! let mut filter = IdentityFilter; //! //! for i in 0..8 { //! input[0] = i as f32; //! filter.tick(i, &input, &mut output); //! assert_eq!(i as f32, output[0]); //! } //! ``` //! //! By adhering to the `AudioDevice` trait, however, this new device will drop //! straight into generic containers like [`DeviceChain`](chain/index.html) or //! [`DeviceGraph`](graph/index.html), and into wrappers such as the [`Buffered` //! wrapper](wrappers/struct.Buffered.html). //! //! `oxcable` defines many simple devices itself. A list of these devices may be //! found under the [`AudioDevice` //! documentation](types/trait.AudioDevice.html#implementors). //! //! # Message Passing //! //! To allow modifying audio device parameters while they are inside containers //! or processesing in seperate threads, all setter behavior is instead //! encapsulated inside a message passing system. Each device has its own //! message `enum` type that describes the different actions it can handle. The //! device then handles those messages by implementing the //! [`MessageReceiver` trait](types/trait.MessageReceiver.html). //! //! Using this trait, setters can be used by calling the `handle_message` //! function and passing the specific message directly to the device. //! //! However, when devices are hidden behind trait objects or used to process in //! a seperate thread, there is no way to get to the device to hand it the //! message directly. In this case the [`Messaged` //! wrapper](wrappers/struct.Messaged.html) provides an abstraction using //! [Rust channels](https://doc.rust-lang.org/std/sync/mpsc/fn.channel.html). //! //! # Thread Safety //! //! Unfortunately, `oxcable` is not able to provide `AudioDevice` containers //! that are `Send`. This is due to a limitation in the `rust-portaudio` crate, //! in which audio streams are not `Send`. This prohibits binding `AudioDevice` //! trait objects with `Send`. //! //! Therefore, when using generic containers, the signal chain must be //! initialized in the thread it will eventually process audio. extern crate byteorder; extern crate num; extern crate portaudio; extern crate portmidi; extern crate rand; pub mod chain; pub mod error; pub mod filters; pub mod graph; pub mod io; pub mod level_detector; pub mod mixers; pub mod oscillator; pub mod tick; pub mod types; pub mod utils; pub mod voice_array; pub mod wrappers; #[cfg(test)] mod testing;