mod bformat;
mod bmixer;
mod bstream;
mod renderer;
pub mod constants;
pub mod sources;
pub use bmixer::{bmixer, BmixerComposer, BstreamMixer};
pub use bstream::{bstream, Bstream, BstreamConfig, SoundController};
pub use renderer::{BstreamHrtfRenderer, BstreamStereoRenderer, HrtfConfig, StereoConfig};
pub use rodio;
use std::f32;
use std::sync::Arc;
pub enum PlaybackConfiguration {
Stereo(StereoConfig),
Hrtf(HrtfConfig),
}
impl Default for PlaybackConfiguration {
fn default() -> Self {
PlaybackConfiguration::Stereo(StereoConfig::default())
}
}
impl From<StereoConfig> for PlaybackConfiguration {
fn from(cfg: StereoConfig) -> Self {
PlaybackConfiguration::Stereo(cfg)
}
}
impl From<HrtfConfig> for PlaybackConfiguration {
fn from(cfg: HrtfConfig) -> Self {
PlaybackConfiguration::Hrtf(cfg)
}
}
pub struct AmbisonicBuilder {
device: Option<rodio::Device>,
sample_rate: u32,
config: PlaybackConfiguration,
}
impl AmbisonicBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn build(self) -> Ambisonic {
let (stream, stream_handle) = if let Some(device) = self.device {
rodio::OutputStream::try_from_device(&device).unwrap()
} else {
rodio::OutputStream::try_default().unwrap()
};
let sink = rodio::Sink::try_new(&stream_handle).unwrap();
let (mixer, controller) = bmixer::bmixer(self.sample_rate);
match self.config {
PlaybackConfiguration::Stereo(cfg) => {
let output = renderer::BstreamStereoRenderer::new(mixer, cfg);
sink.append(output);
}
PlaybackConfiguration::Hrtf(cfg) => {
let output = renderer::BstreamHrtfRenderer::new(mixer, cfg);
sink.append(output);
}
}
Ambisonic {
sink,
output_stream: stream,
composer: controller,
}
}
pub fn with_device(self, device: rodio::Device) -> Self {
AmbisonicBuilder {
device: Some(device),
..self
}
}
pub fn with_sample_rate(self, sample_rate: u32) -> Self {
AmbisonicBuilder {
sample_rate,
..self
}
}
pub fn with_config(self, config: PlaybackConfiguration) -> Self {
AmbisonicBuilder { config, ..self }
}
}
impl Default for AmbisonicBuilder {
fn default() -> Self {
AmbisonicBuilder {
device: None,
sample_rate: 48000,
config: PlaybackConfiguration::default(),
}
}
}
pub struct Ambisonic {
#[allow(dead_code)]
sink: rodio::Sink,
#[allow(dead_code)]
output_stream: rodio::OutputStream,
composer: Arc<BmixerComposer>,
}
impl Ambisonic {
#[deprecated(
since = "0.3.0",
note = "please use one of the `play_*` methods instead"
)]
#[inline(always)]
pub fn play<I>(&self, input: I) -> SoundController
where
I: rodio::Source<Item = f32> + Send + 'static,
{
self.play_omni(input)
}
#[inline(always)]
pub fn play_omni<I>(&self, input: I) -> SoundController
where
I: rodio::Source<Item = f32> + Send + 'static,
{
self.composer.play(input, BstreamConfig::new())
}
#[inline(always)]
pub fn play_at<I>(&self, input: I, pos: [f32; 3]) -> SoundController
where
I: rodio::Source<Item = f32> + Send + 'static,
{
self.composer
.play(input, BstreamConfig::new().with_position(pos))
}
}