alto 3.0.1

Idiomatic interface for OpenAL 1.1 and extensions (including EFX)
Documentation
extern crate alto;

use std::sync::Arc;
use alto::*;


fn main() {
	let alto = if let Ok(alto) = Alto::load_default() {
		alto
	} else {
		println!("No OpenAL implementation present!");
		return;
	};

	println!("Using output: {:?}", alto.default_output().unwrap());
	let dev = alto.open(None).unwrap();
	let ctx = dev.new_context(None).unwrap();

	let mut slot = if dev.is_extension_present(alto::ext::Alc::Efx) {
		println!("Using EFX reverb");
		if let Ok(slot) = (|| -> AltoResult<_> {
			let mut slot = ctx.new_aux_effect_slot()?;
			let mut reverb: efx::EaxReverbEffect = ctx.new_effect()?;
			reverb.set_preset(&efx::REVERB_PRESET_GENERIC)?;
			slot.set_effect(&reverb)?;
			Ok(slot)
		})() {
			Some(slot)
		} else {
			println!("Broken router detected; disabling EFX");
			None
		}
	} else {
		println!("EFX not present");
		None
	};

	{
		let buf = ctx.new_buffer(SinWave::new(44_000 / 440, 0.25).render().take(44_000 / 440).collect::<Vec<_>>(), 44_000).unwrap();
		let buf = Arc::new(buf);

		let mut src = ctx.new_static_source().unwrap();
		src.set_buffer(buf).unwrap();
		src.set_looping(true);
		if let Some(ref mut slot) = slot {
			src.set_aux_send(0, slot).unwrap();
		}

		println!("Playing static 440hz sine wave...");
		src.play();

		std::thread::sleep(std::time::Duration::new(2, 0));
	}

	std::thread::sleep(std::time::Duration::new(1, 0));

	{
		let mut wave = SinWave::new(44_000 / 220, 0.25);

		let mut src = ctx.new_streaming_source().unwrap();
		if let Some(ref mut slot) = slot {
			src.set_aux_send(0, slot).unwrap();
		}
		for _ in 0 .. 5 {
			let buf = ctx.new_buffer(wave.render().take(44_000 / 10).collect::<Vec<_>>(), 44_000).unwrap();
			src.queue_buffer(buf).unwrap();
		}

		println!("Playing streaming 220hz sine wave...");
		src.play();

		for _ in 0 .. 15 {
			while src.buffers_processed() == 0 { }

			let mut buf = src.unqueue_buffer().unwrap();
			buf.set_data(wave.render().take(44_000 / 10).collect::<Vec<_>>(), 44_000).unwrap();
			src.queue_buffer(buf).unwrap();
		}

		while src.buffers_processed() < 5 { }
	}

	std::thread::sleep(std::time::Duration::new(1, 0));
}


struct SinWave {
	len: i32,
	vol: f32,
	cursor: i32,
}

struct SinWaveRenderer<'w>(&'w mut SinWave);


impl SinWave {
	pub fn new(len: i32, vol: f32) -> SinWave {
		SinWave{len: len, vol: vol, cursor: 0}
	}


	pub fn render(&mut self) -> SinWaveRenderer {
		SinWaveRenderer(self)
	}
}


impl<'w> Iterator for SinWaveRenderer<'w> {
	type Item = Mono<i16>;

	fn next(&mut self) -> Option<Mono<i16>> {
		let cursor = self.0.cursor;
		self.0.cursor += 1;
		if self.0.cursor == self.0.len { self.0.cursor = 0 }

		Some(Mono{center: ((cursor as f32 / self.0.len as f32 * 2.0 * std::f32::consts::PI).sin() * self.0.vol * std::i16::MAX as f32) as i16})
	}
}