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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use std::{sync::{Arc, Mutex}, net::TcpStream, io::{Write, Read}, thread};

use crate::{common::audiobuffer::AudioBuffer, config::BUFFER_SIZE};

pub struct ResonatorClient {
    send_port: u16,                                  //The port which is used for sending outbound audio buffers
    receive_port: u16,                               //The port which is used for receiving inbound audio buffers
    outgoing_buffers: Arc<Mutex<Vec<AudioBuffer>>>, //The buffers which are to be sent to the server
    incoming_buffers: Arc<Mutex<Vec<AudioBuffer>>>,  //The buffers which have been received from the server, but not yet processed
    id: i32,                                         //The id of this client
    reciever_id: i32                                 //The id of the client which this client is sending audio to
}

impl ResonatorClient {
    /**
     * Constructs a new ResonatorClient using the specified ports
     * If external_buffer_input is provided then the client will use that buffer as the audio source
     * If external_buffer_output is provided then the client will use that buffer as the audio output
     */
    pub fn new(send_port: u16, receive_port: u16, id: i32, reciever_id: i32, external_buffer_input: Option<Arc<Mutex<Vec<AudioBuffer>>>>, external_buffer_output: Option<Arc<Mutex<Vec<AudioBuffer>>>>) -> ResonatorClient {
        ResonatorClient {
            send_port,
            receive_port,
            outgoing_buffers: external_buffer_input.unwrap_or(Arc::new(Mutex::new(Vec::new()))), //Outgoing buffers will be pulled from the input buffer
            incoming_buffers: external_buffer_output.unwrap_or(Arc::new(Mutex::new(Vec::new()))), //Incoming buffers will be pushed to the output buffer
            id,
            reciever_id
        }
    }

    //Getter function for returning the vector of recieved audio buffers
    pub fn get_incoming_buffers(&self) -> Arc<Mutex<Vec<AudioBuffer>>> {
        self.incoming_buffers.clone()
    }

    //Returns the first buffer in the incoming buffers vec, and removes it
    pub fn process_buffer(&self) -> Option<AudioBuffer> {
        if self.incoming_buffers.lock().unwrap().len() > 0 {
            return Some(self.incoming_buffers.lock().unwrap().remove(0));
        }

        None
    }

    //Pushes a buffer to the outgoing buffers vec to be sent to the server
    pub fn push_buffer(&self, audio_buffer: AudioBuffer) {
        self.outgoing_buffers.lock().unwrap().push(audio_buffer);
    }

    //Begins the client, spawning the reciever and sender threads
    pub fn begin(&self) {
        println!("Starting client on ports {} and {}", self.send_port, self.receive_port);

        {
            let receive_port = self.receive_port.clone();
            let incoming_buffers = self.incoming_buffers.clone();
            let id = self.id.clone();
            thread::spawn(move || {
                ResonatorClient::_reciever_thread(receive_port.clone(), incoming_buffers.clone(), id.clone());
                loop {}
            });
        }

        {
            let send_port = self.send_port.clone();
            let outgoning_buffers = self.outgoing_buffers.clone();
            let id = self.id.clone();
            let receiver_id = self.reciever_id.clone();

            thread::spawn(move || {
                ResonatorClient::_sender_thread(send_port.clone(), outgoning_buffers.clone(), id.clone(), receiver_id.clone());
                loop {}
            });
        }
    }

    fn _reciever_thread(port: u16, incoming_buffers: Arc<Mutex<Vec<AudioBuffer>>>, id: i32) {
        let mut stream = TcpStream::connect(format!("127.0.0.1:{}", port)).unwrap();
        stream.write_all(&id.to_le_bytes()).unwrap();

        let mut buffer = [0; BUFFER_SIZE];
        loop {
            match stream.read(&mut buffer) {
                Ok(size) if size == 0 => {
                    println!("Client closed connection");
                    break;
                }
                Ok(size) => size,
                Err(_) => {
                    println!("Client error");
                    break;
                }
            };

            //Parsed buffer ready to be played
            let audio_buffer = AudioBuffer::from_bytes(&buffer);
            incoming_buffers.lock().unwrap().push(audio_buffer.clone());
            println!("Received buffer!");
            //println!("{:?}", audio_buffer);
        }
    }

    fn _sender_thread(port: u16, outgoning_buffers: Arc<Mutex<Vec<AudioBuffer>>>, id: i32, reciever_id: i32) {
        let mut stream = TcpStream::connect(format!("127.0.0.1:{}", port)).unwrap();

        //Send buffer every 10 secs
        loop {
            //If no outgoing buffers in the queue, skip
            if outgoning_buffers.lock().unwrap().len() == 0 {
                continue;
            }

            //Otherwise send the first buffer in the outgoing buffers vec
            println!("Sending buffer from client");
            let audio_buffer = outgoning_buffers.lock().unwrap().remove(0);
            let raw_buffer = audio_buffer.as_buffer().unwrap().raw_buffer_with_header(id, reciever_id);
            stream.write_all(&raw_buffer).unwrap();
        }
    }
}