Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extern crate cpal;
- extern crate hound;
- use std::f32;
- use std::sync::{Arc, Mutex};
- use std::sync::atomic::{AtomicBool, Ordering};
- use std::thread;
- use std::ops;
- use cpal::{StreamData, UnknownTypeOutputBuffer};
- trait Sample {
- fn as_u16(&self) -> u16;
- fn as_i16(&self) -> i16;
- fn as_f32(&self) -> f32;
- fn zero() -> Self;
- }
- /*
- /// Blanket impl for references
- impl<'a, T: Sample> Sample for &'a T {
- fn as_u16(&self) -> u16 {
- T::as_u16(self)
- }
- fn as_i16(&self) -> i16 {
- T::as_i16(self)
- }
- fn as_f32(&self) -> f32 {
- T::as_f32(self)
- }
- fn zero() -> Self {
- T::zero()
- }
- }*/
- impl Sample for i16 {
- fn as_u16(&self) -> u16 {
- ((u16::max_value() / 2) as i32 + *self as i32) as u16
- }
- fn as_i16(&self) -> i16 {
- *self
- }
- fn as_f32(&self) -> f32 {
- *self as f32 / i16::max_value() as f32
- }
- fn zero() -> Self {
- 0
- }
- }
- impl Sample for f32 {
- fn as_u16(&self) -> u16 {
- ((u16::max_value() / 2) as i32 + self.as_i16() as i32) as u16
- }
- fn as_i16(&self) -> i16 {
- (*self * i16::max_value() as f32) as i16
- }
- fn as_f32(&self) -> f32 {
- *self
- }
- fn zero() -> Self {
- 0.0
- }
- }
- trait Stream: Iterator {
- fn n_channels(&self) -> usize;
- fn broadcast(self, n: usize) -> Broadcast<Self::Item, Self>
- where
- Self: Sized,
- Self::Item: Sample,
- {
- Broadcast {
- inner: self,
- n_channels: n,
- current_sample: Self::Item::zero(),
- reps_to_go: 0,
- }
- }
- fn floatify(self) -> Floatify<Self>
- where
- Self: Sized,
- {
- Floatify {
- inner: self,
- }
- }
- fn repeat(self) -> Repeated<Self::Item>
- where
- Self: Sized,
- {
- Repeated {
- n_channels: self.n_channels(),
- buffer: self.collect(),
- index: 0,
- }
- }
- }
- impl<'a, S> Stream for std::iter::Cloned<std::slice::Iter<'a, S>>
- where S: Sample + Clone
- {
- fn n_channels(&self) -> usize {
- 1
- }
- }
- impl<'a, S> Stream for std::vec::IntoIter<S>
- where S: Sample + Clone
- {
- fn n_channels(&self) -> usize {
- 1
- }
- }
- struct Floatify<T> {
- inner: T,
- }
- impl<S, T> Stream for Floatify<T>
- where
- T: Stream<Item=S>,
- S: Sample,
- {
- fn n_channels(&self) -> usize {
- self.inner.n_channels()
- }
- }
- impl<S, T> Iterator for Floatify<T>
- where
- T: Stream<Item=S>,
- S: Sample,
- {
- type Item = f32;
- fn next(&mut self) -> Option<f32> {
- self.inner.next().map(|s| s.as_f32())
- }
- }
- struct Repeated<S> {
- n_channels: usize,
- buffer: Vec<S>,
- index: usize,
- }
- impl<S> Stream for Repeated<S>
- where
- S: Clone,
- {
- fn n_channels(&self) -> usize {
- self.n_channels
- }
- }
- impl<S> Iterator for Repeated<S>
- where
- S: Clone,
- {
- type Item = S;
- fn next(&mut self) -> Option<S> {
- if self.index >= self.buffer.len() {
- if self.buffer.len() == 0 {
- return None
- }
- self.index = 0;
- }
- let x = self.buffer[self.index].clone();
- self.index += 1;
- Some(x)
- }
- }
- #[derive(Clone)]
- struct SharedBuffer<S: 'static> {
- n_channels: usize,
- buffer: Arc<Vec<S>>,
- index: usize,
- }
- impl<S> Stream for SharedBuffer<S>
- where
- S: Clone + 'static,
- {
- fn n_channels(&self) -> usize {
- self.n_channels
- }
- }
- impl<S> Iterator for SharedBuffer<S>
- where
- S: Clone + 'static,
- {
- type Item = S;
- fn next(&mut self) -> Option<S> {
- if self.index >= self.buffer.len() {
- None
- } else {
- let x = self.buffer[self.index].clone();
- self.index += 1;
- Some(x)
- }
- }
- }
- struct Broadcast<S, T>
- {
- inner: T,
- n_channels: usize,
- current_sample: S,
- reps_to_go: usize,
- }
- impl<S, T> Stream for Broadcast<S, T>
- where
- T: Stream<Item=S>,
- S: Sample + Clone,
- {
- fn n_channels(&self) -> usize {
- self.n_channels
- }
- }
- impl<S, T> Iterator for Broadcast<S, T>
- where
- T: Stream<Item=S>,
- S: Sample + Clone,
- {
- type Item = S;
- fn next(&mut self) -> Option<Self::Item> {
- if self.reps_to_go == 0 {
- self.current_sample = self.inner.next()?;
- self.reps_to_go = self.n_channels;
- }
- self.reps_to_go -= 1;
- Some(self.current_sample.clone())
- }
- }
- struct BFormat {
- w: f32,
- x: f32,
- y: f32,
- z: f32,
- }
- impl BFormat {
- fn virtual_microphone(&self, dir: [f32; 3], p: f32) -> f32 {
- p * 2f32.sqrt() * self.w + (1.0 - p) * (dir[0] * self.x + dir[1] * self.y + dir[2] * self.z)
- }
- }
- impl Default for BFormat {
- fn default() -> Self {
- BFormat {w: 0.0, x: 0.0, y: 0.0, z: 0.0}
- }
- }
- impl ops::AddAssign for BFormat {
- fn add_assign(&mut self, other: Self) {
- self.w += other.w;
- self.x += other.x;
- self.y += other.y;
- self.z += other.z;
- }
- }
- impl<'a> ops::Mul<f32> for &'a BFormat {
- type Output = BFormat;
- fn mul(self, s: f32) -> BFormat {
- BFormat {
- w: self.w * s,
- x: self.x * s,
- y: self.y * s,
- z: self.z * s,
- }
- }
- }
- impl From<[f32; 3]> for BFormat {
- fn from(dir: [f32; 3]) -> Self {
- let l = (dir[0] * dir[0] + dir[1] * dir[1] + dir[1] * dir[2]).sqrt();
- BFormat {
- w: 1.0 / 2f32.sqrt(),
- x: dir[0] / l,
- y: dir[1] / l,
- z: dir[2] / l,
- }
- }
- }
- struct BStreamStereoDecoder {
- input: BStreamMixer,
- left_mic: [f32; 3],
- right_mic: [f32; 3],
- buffered_sample: Option<f32>,
- }
- impl BStreamStereoDecoder {
- fn new(input: BStreamMixer) -> Self {
- BStreamStereoDecoder {
- input,
- left_mic: [-1.0 / 2f32.sqrt(), 1.0 / 2f32.sqrt(), 0.0],
- right_mic: [1.0 / 2f32.sqrt(), 1.0 / 2f32.sqrt(), 0.0],
- buffered_sample: None,
- }
- }
- }
- impl Stream for BStreamStereoDecoder {
- fn n_channels(&self) -> usize {
- 2
- }
- }
- impl Iterator for BStreamStereoDecoder {
- type Item = f32;
- fn next(&mut self) -> Option<f32> {
- match self.buffered_sample.take() {
- Some(s) => Some(s),
- None => {
- let sample = self.input.next()?;
- let left = sample.virtual_microphone(self.left_mic, 0.5);
- let right = sample.virtual_microphone(self.right_mic, 0.5);
- // emit left channel now, and right channel on next call
- self.buffered_sample = Some(right);
- Some(left)
- },
- }
- }
- }
- fn bstream() -> (BStreamMixer, Arc<BStreamController>) {
- let controller = Arc::new(BStreamController {
- pending_streams: Mutex::new(Vec::new()),
- has_pending: AtomicBool::new(false),
- });
- let mixer = BStreamMixer {
- input: controller.clone(),
- active_streams: Vec::with_capacity(8),
- };
- (mixer, controller)
- }
- struct BStreamMixer {
- input: Arc<BStreamController>,
- active_streams: Vec<SpatialStream>,
- }
- impl Iterator for BStreamMixer {
- type Item = BFormat;
- fn next(&mut self) -> Option<Self::Item> {
- if self.input.has_pending.load(Ordering::SeqCst) {
- let mut pending = self.input.pending_streams.lock().expect("Cannot lock pending streams");
- self.active_streams.extend(pending.drain(..));
- self.input.has_pending.store(false, Ordering::SeqCst);
- }
- let mut mix = BFormat::default();
- let mut done = Vec::new();
- for (i, stream) in self.active_streams.iter_mut().enumerate() {
- match stream.next() {
- Some(x) => mix += x,
- None => done.push(i),
- }
- }
- for i in done {
- self.active_streams.remove(i);
- }
- Some(mix)
- }
- }
- struct BStreamController {
- pending_streams: Mutex<Vec<SpatialStream>>,
- has_pending: AtomicBool,
- }
- impl BStreamController {
- fn attach<T: 'static + Stream<Item = f32> + Send>(&self, stream: T, direction: [f32; 3]) -> Arc<SpatialStreamController> {
- let controller = Arc::new(SpatialStreamController{
- direction: Mutex::new(direction),
- update: AtomicBool::new(false),
- });
- let sstream = SpatialStream {
- inner: Box::new(stream),
- bfactors: direction.into(),
- controller: controller.clone(),
- };
- self.pending_streams.lock().expect("Cannot lock pending streams").push(sstream);
- self.has_pending.store(true, Ordering::SeqCst);
- controller
- }
- }
- struct SpatialStream {
- inner: Box<Stream<Item = f32> + Send>,
- bfactors: BFormat,
- controller: Arc<SpatialStreamController>,
- }
- impl Iterator for SpatialStream {
- type Item = BFormat;
- fn next(&mut self) -> Option<Self::Item> {
- if self.controller.update.load(Ordering::SeqCst) {
- self.bfactors = (*self.controller.direction.lock().unwrap()).into();
- self.controller.update.store(false, Ordering::SeqCst);
- }
- let x = self.inner.next()?;
- Some(&self.bfactors * x)
- }
- }
- struct SpatialStreamController {
- direction: Mutex<[f32; 3]>,
- update: AtomicBool,
- }
- impl SpatialStreamController {
- fn set_direction(&self, d: [f32; 3]) {
- *self.direction.lock().unwrap() = d;
- self.update.store(true, Ordering::SeqCst);
- }
- }
- fn stream_player<T>(device: &cpal::Device, format: &cpal::Format, mut stream: T) -> thread::JoinHandle<()>
- where
- T: Stream + Send + 'static,
- T::Item: Sample,
- {
- let event_loop = cpal::EventLoop::new();
- let stream_id = event_loop.build_output_stream(&device, &format).unwrap();
- event_loop.play_stream(stream_id);
- thread::spawn(move || {
- event_loop.run(move |_stream_id, stream_data| {
- match stream_data {
- StreamData::Output { buffer: UnknownTypeOutputBuffer::U16(mut buffer) } => {
- for elem in buffer.iter_mut() {
- *elem = stream.next().unwrap().as_u16();
- }
- },
- StreamData::Output { buffer: UnknownTypeOutputBuffer::I16(mut buffer) } => {
- for elem in buffer.iter_mut() {
- *elem = stream.next().unwrap().as_i16();
- }
- },
- StreamData::Output { buffer: UnknownTypeOutputBuffer::F32(mut buffer) } => {
- for elem in buffer.iter_mut() {
- *elem = stream.next().unwrap().as_f32();
- }
- },
- _ => (),
- }
- });
- })
- }
- fn main() {
- println!("Hello, world!");
- let mut reader = hound::WavReader::open(r"U:\Ling\Audio wav files\short\A.wav").unwrap();
- println!("{:?}", reader.spec());
- let sound: Vec<_> = reader
- .samples::<i16>()
- .map(|s| s.unwrap())
- .collect();
- let sound = Arc::new(sound);
- let sound = SharedBuffer {
- n_channels: 1,
- buffer: sound,
- index: 0,
- };
- println!("Audio Devices:");
- for device in cpal::devices() {
- println!(" -> {}", device.name());
- }
- let device = cpal::default_output_device().expect("no output device available");
- println!("Default Device:\n {}", device.name());
- let supported_formats_range = device.supported_output_formats()
- .expect("error while querying formats");
- println!("Supported formats:");
- for format in supported_formats_range {
- println!("{:?}", format);
- }
- let format = device.supported_output_formats().unwrap().next()
- .expect("no supported format?!")
- .with_max_sample_rate();
- let (mixer, controller) = bstream();
- let decoder = BStreamStereoDecoder::new(mixer);
- let player = stream_player(&device, &format, decoder);
- /*for a in 0..=16 {
- let a = a as f32 / 16.0 * 2.0 * f32::consts::PI;
- controller.attach(sound.clone().into_iter().floatify(), [a.sin(), a.cos(), 0.0]);
- thread::sleep_ms(1000);
- }*/
- //let player = stream_player(&device, &format, sound.into_iter().broadcast(2));
- //let sc = controller.attach(sound.clone().into_iter().floatify().repeat(), [0.0, 1.0, 0.0]);
- //controller.attach(sound.clone().floatify(), [-1.0, 0.0, 0.0]);
- //thread::sleep_ms(500);
- let sc = controller.attach(sound.floatify().repeat(), [0.0, 1.0, 0.0]);
- for a in 0..1000 {
- let a = a as f32 / 100.0;
- sc.set_direction([a.sin(), a.cos(), 0.0]);
- thread::sleep_ms(10);
- }
- //thread::sleep_ms(5000);
- //player.join();
- }
Add Comment
Please, Sign In to add comment