this repo has no description
at main 3.9 kB view raw
1// https://gist.github.com/phaze-the-dumb/634daacb5141eae2f846e20987dba7a8 2use std::net::UdpSocket; 3 4use crossbeam_channel::Sender; 5use serde::Serialize; 6 7use crate::structs::parameter_types::ParameterType; 8 9#[derive(Debug, Clone, Serialize)] 10pub struct OSCMessage { 11 pub address: String, 12 pub values: Vec<ParameterType>, 13} 14 15impl PartialEq for OSCMessage { 16 // Technically this isn't exactly equal, but the only time i'm checking if OSCMessage's are equal 17 // Is when i'm checking for the "address" value 18 19 fn eq(&self, other: &Self) -> bool { 20 self.address == other.address 21 } 22 23 fn ne(&self, other: &Self) -> bool { 24 self.address != other.address 25 } 26} 27 28// TODO: Implement osc bundles 29pub fn start_server(sender: Sender<OSCMessage>, addr: &str) { 30 let socket = UdpSocket::bind(addr).unwrap(); 31 32 loop { 33 let mut buf = [0; 1024]; 34 let (amt, _src) = socket.recv_from(&mut buf).unwrap(); 35 36 let buf = &mut buf[..amt]; 37 if buf[0] != 0x2F { 38 panic!("Packet is not an OSC Message"); 39 } 40 41 let mut addr: Vec<u8> = Vec::new(); 42 let mut value_start = 0; 43 44 loop { 45 let byte = buf[value_start]; 46 if byte == 0x00 { 47 break; 48 } 49 50 value_start += 1; 51 addr.push(byte); 52 } 53 54 loop { 55 let byte = buf[value_start]; 56 value_start += 1; 57 58 if byte == 0x2C { 59 break; 60 } 61 } 62 63 let mut types: Vec<u8> = Vec::new(); 64 65 loop { 66 let byte = buf[value_start]; 67 if byte == 0x00 { 68 break; 69 } 70 71 types.push(byte); 72 value_start += 1; 73 } 74 75 value_start = ((value_start as f32 / 4.0).ceil() * 4.0) as usize; 76 let mut values = Vec::new(); 77 78 for tp in types { 79 match tp { 80 0x69 => { 81 let val_buf = &buf[value_start..value_start + 4]; 82 83 let bytes = <&[u8; 4]>::try_from(val_buf).unwrap().clone(); 84 let int = i32::from_be_bytes(bytes); 85 86 values.push(ParameterType::Int(int)); 87 value_start += 4; 88 } 89 0x66 => { 90 let val_buf = &buf[value_start..value_start + 4]; 91 92 let bytes = <&[u8; 4]>::try_from(val_buf).unwrap().clone(); 93 let float = f32::from_be_bytes(bytes); 94 95 values.push(ParameterType::Float(float)); 96 value_start += 4; 97 } 98 0x54 => values.push(ParameterType::Boolean(true)), 99 0x46 => values.push(ParameterType::Boolean(false)), 100 _ => {} 101 } 102 } 103 104 let message = OSCMessage { 105 address: String::from_utf8(addr.clone()).unwrap(), 106 values: values, 107 }; 108 109 sender.send(message).unwrap(); 110 } 111} 112 113pub fn send_message(address: &str, values: Vec<ParameterType>, ip_addr: &str) { 114 let socket = UdpSocket::bind("127.0.0.1:0").unwrap(); 115 let mut buf: Vec<u8> = Vec::new(); 116 117 buf.append(&mut address.as_bytes().to_vec()); 118 119 let rounded_len = ((((buf.len() as f64) + 1.0) / 4.0).ceil() * 4.0) as usize; 120 let original_len = buf.len(); 121 122 for _i in original_len..rounded_len { 123 buf.push(0); 124 } 125 126 buf.push(0x2C); 127 128 let mut value_count = 1; 129 for value in values.clone() { 130 match value { 131 ParameterType::Boolean(val) => buf.push(if val { 0x54 } else { 0x46 }), 132 ParameterType::Float(_) => buf.push(0x66), 133 ParameterType::Int(_) => buf.push(0x69), 134 ParameterType::String(_) => buf.push(0x73), 135 _ => {} 136 }; 137 138 value_count += 1; 139 } 140 141 for _i in 0..4 - (value_count % 4) { 142 buf.push(0); 143 } 144 145 for value in values { 146 match value { 147 ParameterType::Float(val) => buf.append(&mut val.to_be_bytes().to_vec()), 148 ParameterType::Int(val) => buf.append(&mut val.to_be_bytes().to_vec()), 149 ParameterType::String(val) => { 150 let mut str_buf = val.as_bytes().to_vec(); 151 let buf_len = str_buf.len().clone(); 152 153 buf.append(&mut str_buf); 154 155 for _i in 0..4 - (buf_len % 4) { 156 buf.push(0); 157 } 158 } 159 _ => {} 160 } 161 } 162 163 socket.send_to(&buf, ip_addr).unwrap(); 164}