summaryrefslogtreecommitdiff
path: root/src/main.rs
blob: fb98dfb52414a6743b2118debb7776d48666dfd1 (plain)
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
use std::{io, env};
use std::io::*;
use std::fs::*;
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::*;

fn main() {
    let env = Environment::default();

    let mut genfile = File::open(env::args_os().nth(1).expect("Need first argument to be a file with a generator vector")).expect("Failed to open file");
    let mut genstr = String::new();
    genfile.read_to_string(&mut genstr);

    let gens = Parser::new(Tokenizer::new(genstr.chars()), env.clone()).expect("Failed to get first token").parse_gen_vec().expect("Failed to compile generators");
    let sock = UdpSocket::bind("0.0.0.0:13676").expect("Failed to bind socket");

    eprintln!("Parsed {} generator definitions", gens.len());

    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.");

    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.");
}