summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
authorGraham Northup <grissess@nexusg.org>2017-10-01 07:04:21 -0400
committerGraham Northup <grissess@nexusg.org>2017-10-01 07:04:21 -0400
commit145e2771c0d1ad30748da6e6ef1fabbd4cc2478c (patch)
treeb9e96a57df0d515383a7c09e3b2ea71edb31db96 /src/main.rs
parent629d2fa754dcd4bbdbd1e84ea9f7598806abc840 (diff)
It plays network noises now!
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs56
1 files changed, 49 insertions, 7 deletions
diff --git a/src/main.rs b/src/main.rs
index e06d2b1..9b78146 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,28 +1,70 @@
use std::io;
use std::io::*;
use std::net::*;
+use std::sync::*;
+use std::collections::VecDeque;
extern crate synfone;
+extern crate portaudio;
+use portaudio as pa;
+use synfone::*;
use synfone::synth::*;
use synfone::lang::*;
+use synfone::proto::*;
use synfone::client::*;
-const GEN: &'static str = "mul(sine(param('v_freq', 500)), ifelse(rel(param('v_frame'), '<', param('v_deadline')), param('v_amp'), 0.0))";
+const GEN: &'static str = "mul(saw(param('v_freq', 500)), ifelse(rel(param('v_frame'), '<', param('v_deadline')), param('v_amp'), 0.0))";
fn main() {
let env = Environment::default();
- let gen = Parser::new(Tokenizer::new(GEN.chars())).expect("Failed to get first token").parse().expect("Failed to compile generator");
+ let mut gens = Vec::new();
+ for _i in 0..25 {
+ let gen = Parser::new(Tokenizer::new(GEN.chars())).expect("Failed to get first token").parse().expect("Failed to compile generator");
+ gens.push(gen);
+ }
let sock = UdpSocket::bind("0.0.0.0:13676").expect("Failed to bind socket");
- let mut client = Client::new(sock, vec![gen], env).expect("Failed to create client");
- let mut buf: Vec<u8> = Vec::new();
- let mut out = io::stdout();
+ let mut client = Arc::new(Mutex::new(Client::new(sock.try_clone().expect("Failed to clone socket"), gens, env.clone()).expect("Failed to create client")));
+
+ let pa_inst = pa::PortAudio::new().expect("Failed to create PortAudio interface");
+ let settings = pa_inst.default_output_stream_settings(1, env.sample_rate as f64, env.default_buffer_size as u32).expect("Failed to instantiate stream settings");
+ let mut stream;
+ {
+ let client = client.clone();
+ let mut ring: VecDeque<Sample> = VecDeque::new();
+ ring.reserve_exact(2 * env.default_buffer_size);
+ stream = pa_inst.open_non_blocking_stream(settings, move |pa::OutputStreamCallbackArgs { buffer, frames, .. }| {
+ while frames > ring.len() {
+ let mut cli = client.lock().unwrap();
+ cli.next_frames();
+ ring.append(&mut cli.buffer().iter().map(|&x| x).collect());
+ }
+ let samps = ring.drain(..frames).collect::<Vec<f32>>();
+ buffer.copy_from_slice(&samps);
+ pa::Continue
+ }).expect("Failed to create stream");
+ }
+
eprintln!("Starting.");
- while client.pump(&mut buf) {
- out.write_all(&buf).expect("Failed to write samples");
+ stream.start().expect("Failed to start stream");
+
+ let mut buffer: [u8; Command::SIZE] = [0u8; Command::SIZE];
+ loop {
+ let (bytes, sender) = sock.recv_from(&mut buffer).unwrap();
+ if bytes < Command::SIZE {
+ continue;
+ }
+
+ let cmd = Command::from(&buffer);
+ {
+ let mut cli = client.lock().unwrap();
+ if !cli.handle_command(cmd, sender) {
+ break;
+ }
+ }
}
eprintln!("Exiting.");