diff --git a/examples/etherdream.rs b/examples/etherdream.rs index 75d888c..e174a88 100644 --- a/examples/etherdream.rs +++ b/examples/etherdream.rs @@ -3,149 +3,148 @@ extern crate ether_dream; use ether_dream::dac; fn main() { - println!("Listening for an Ether Dream DAC..."); + println!("Listening for an Ether Dream DAC..."); - let (dac_broadcast, source_addr) = ether_dream::recv_dac_broadcasts() - .expect("failed to bind to UDP socket") - .filter_map(Result::ok) - .next() - .unwrap(); - let mac_address = dac::MacAddress(dac_broadcast.mac_address); + let (dac_broadcast, source_addr) = ether_dream::recv_dac_broadcasts() + .expect("failed to bind to UDP socket") + .filter_map(Result::ok) + .next() + .unwrap(); + let mac_address = dac::MacAddress(dac_broadcast.mac_address); - println!( - "Discovered DAC \"{}\" at \"{}\"! Connecting...", - mac_address, source_addr - ); + println!( + "Discovered DAC \"{}\" at \"{}\"! Connecting...", + mac_address, source_addr + ); - // Establish the TCP connection. - let mut stream = dac::stream::connect(&dac_broadcast, source_addr.ip().clone()).unwrap(); + // Establish the TCP connection. + let mut stream = dac::stream::connect(&dac_broadcast, source_addr.ip().clone()).unwrap(); - // If we want to create an animation (in our case a moving sine wave) we need a frame rate. - let frames_per_second = 60.0; - // Lets use the DAC at an eighth the maximum scan rate. - let points_per_second = stream.dac().max_point_rate / 32; - // Determine the number of points per frame given our target frame and point rates. - let points_per_frame = (points_per_second as f32 / frames_per_second) as u16; + // If we want to create an animation (in our case a moving sine wave) we need a frame rate. + let frames_per_second = 60.0; + // Lets use the DAC at an eighth the maximum scan rate. + let points_per_second = stream.dac().max_point_rate / 32; + // Determine the number of points per frame given our target frame and point rates. + let points_per_frame = (points_per_second as f32 / frames_per_second) as u16; - println!( - "Preparing for playback:\n\tframe_hz: {}\n\tpoint_hz: {}\n\tpoints_per_frame: {}\n", - frames_per_second, points_per_second, points_per_frame - ); + println!( + "Preparing for playback:\n\tframe_hz: {}\n\tpoint_hz: {}\n\tpoints_per_frame: {}\n", + frames_per_second, points_per_second, points_per_frame + ); - // Prepare the DAC's playback engine and await the repsonse. - stream - .queue_commands() - .prepare_stream() - .submit() - .err() - .map(|err| { - eprintln!( - "err occurred when submitting PREPARE_STREAM \ + // Prepare the DAC's playback engine and await the repsonse. + stream + .queue_commands() + .prepare_stream() + .submit() + .err() + .map(|err| { + eprintln!( + "err occurred when submitting PREPARE_STREAM \ command and listening for response: {}", - err - ); - }); + err + ); + }); - println!("Beginning playback!"); + println!("Beginning playback!"); - // The sine wave used to generate points. - let mut sine_wave = SineWave { - point: 0, - points_per_frame, - frames_per_second, - }; + // The sine wave used to generate points. + let mut sine_wave = SineWave { + point: 0, + points_per_frame, + frames_per_second, + }; - // Queue the initial frame and tell the DAC to begin producing output. - let n_points = points_to_generate(stream.dac()); - stream - .queue_commands() - .data(sine_wave.by_ref().take(n_points)) - .begin(0, points_per_second) - .submit() - .err() - .map(|err| { - eprintln!( - "err occurred when submitting initial DATA and BEGIN \ + // Queue the initial frame and tell the DAC to begin producing output. + let n_points = points_to_generate(stream.dac()); + stream + .queue_commands() + .data(sine_wave.by_ref().take(n_points)) + .begin(0, points_per_second) + .submit() + .err() + .map(|err| { + eprintln!( + "err occurred when submitting initial DATA and BEGIN \ commands and listening for response: {}", - err - ); - }); - eprintln!("Stream dac{:?}", stream.dac()); + err + ); + }); - // Loop and continue to send points forever. - loop { - // Determine how many points the DAC can currently receive. - let n_points = points_to_generate(stream.dac()); - if let Err(err) = stream - .queue_commands() - .data(sine_wave.by_ref().take(n_points)) - .submit() - { - eprintln!( - "err occurred when submitting DATA command and listening \ + // Loop and continue to send points forever. + loop { + // Determine how many points the DAC can currently receive. + let n_points = points_to_generate(stream.dac()); + if let Err(err) = stream + .queue_commands() + .data(sine_wave.by_ref().take(n_points)) + .submit() + { + eprintln!( + "err occurred when submitting DATA command and listening \ for response: {}", - err - ); - break; - } - } + err + ); + break; + } + } - // Tell the DAC to stop producing output and return to idle. Wait for the response. - // - // Note that the DAC is commanded to stop on `Drop` if this is not called and any errors - // produced are ignored. - stream - .queue_commands() - .stop() - .submit() - .expect("err occurred when submitting STOP command and listening for response"); + // Tell the DAC to stop producing output and return to idle. Wait for the response. + // + // Note that the DAC is commanded to stop on `Drop` if this is not called and any errors + // produced are ignored. + stream + .queue_commands() + .stop() + .submit() + .expect("err occurred when submitting STOP command and listening for response"); } // Determine the number of points needed to fill the DAC. fn points_to_generate(dac: ðer_dream::dac::Dac) -> usize { - dac.buffer_capacity as usize - 1 - dac.status.buffer_fullness as usize + dac.buffer_capacity as usize - 1 - dac.status.buffer_fullness as usize } // An iterator that endlessly generates a sine wave of DAC points. // // The sine wave oscillates at a rate of once per second. struct SineWave { - point: u32, - points_per_frame: u16, - frames_per_second: f32, + point: u32, + points_per_frame: u16, + frames_per_second: f32, } impl Iterator for SineWave { - type Item = ether_dream::protocol::DacPoint; - fn next(&mut self) -> Option { - let coloured_points_per_frame = self.points_per_frame - 1; - let i = (self.point % self.points_per_frame as u32) as u16; - let hz = 1.0; - let fract = i as f32 / coloured_points_per_frame as f32; - let phase = (self.point as f32 / coloured_points_per_frame as f32) / self.frames_per_second; - let amp = (hz * (fract + phase) * 2.0 * std::f32::consts::PI).sin(); - let (r, g, b) = match i { - i if i == coloured_points_per_frame || i < 13 => (0, 0, 0), - _ => (std::u16::MAX, std::u16::MAX, std::u16::MAX), - }; - let x_min = std::i16::MIN; - let x_max = std::i16::MAX; - let x = (x_min as f32 + fract * (x_max as f32 - x_min as f32)) as i16; - let y = (amp * x_max as f32) as i16; - let control = 0; - let (u1, u2) = (0, 0); - let p = ether_dream::protocol::DacPoint { - control, - x, - y, - i, - r, - g, - b, - u1, - u2, - }; - self.point += 1; - Some(p) - } + type Item = ether_dream::protocol::DacPoint; + fn next(&mut self) -> Option { + let coloured_points_per_frame = self.points_per_frame - 1; + let i = (self.point % self.points_per_frame as u32) as u16; + let hz = 1.0; + let fract = i as f32 / coloured_points_per_frame as f32; + let phase = (self.point as f32 / coloured_points_per_frame as f32) / self.frames_per_second; + let amp = (hz * (fract + phase) * 2.0 * std::f32::consts::PI).sin(); + let (r, g, b) = match i { + i if i == coloured_points_per_frame || i < 13 => (0, 0, 0), + _ => (std::u16::MAX, std::u16::MAX, std::u16::MAX), + }; + let x_min = std::i16::MIN; + let x_max = std::i16::MAX; + let x = (x_min as f32 + fract * (x_max as f32 - x_min as f32)) as i16; + let y = (amp * x_max as f32) as i16; + let control = 0; + let (u1, u2) = (0, 0); + let p = ether_dream::protocol::DacPoint { + control, + x, + y, + i, + r, + g, + b, + u1, + u2, + }; + self.point += 1; + Some(p) + } } \ No newline at end of file diff --git a/examples/populate_redis.rs b/examples/populate_redis.rs index 307acd6..a1d43fe 100644 --- a/examples/populate_redis.rs +++ b/examples/populate_redis.rs @@ -22,7 +22,7 @@ fn do_something() -> redis::RedisResult<()> { let _ = con.set("/EDH/0", "[[1.0, 0.0, 0.0],\n [ 0.0, 1.0, 0.0],\n [ 0.0, 0.0, 1.0]]")?; let _ = con.set("/kpps/0", "5000")?; let _ = con.set("/intensity/0", "255")?; - let _ = con.set("/pl/0/0", "[(1000, 2000, 0), (1000, 1000, 65535), (2000, 1000, 65535), (2000, 2000, 65535), (1000, 2000, 65535)]")?; + let _ = con.set("/pl/0/0", "[(-300, 300, 0), (-300, -300, 65280), (300, -300, 65280), (300, 300, 65280), (-300, 300, 65280)]")?; Ok(()) } diff --git a/src/device/etherdream.rs b/src/device/etherdream.rs index e4ea6a6..86b6a6b 100644 --- a/src/device/etherdream.rs +++ b/src/device/etherdream.rs @@ -9,7 +9,7 @@ use crate::conf::EtherDreamConf; use crate::device::{Device, Status, PlaybackState}; use crate::errors::{LJError, LJResult}; use crate::point::{Color, Point}; -use ether_dream::protocol::{DacBroadcast, DacResponse}; +use ether_dream::protocol::{DacBroadcast, DacPoint, DacResponse}; use log::{debug, info, warn}; #[warn(dead_code)] @@ -71,7 +71,6 @@ impl EtherdreamDevice { Err(Box::new(LJError::EtherdreamConnectError(err))) } Ok((dac, source_addr)) => { - info!("Trying to open TCP stream..."); let stream = EtherdreamDevice::get_tcp_stream(&dac, &source_addr)?; info!("Finished configuring DAC and TCP stream."); Ok((dac, source_addr, stream)) @@ -88,29 +87,18 @@ impl EtherdreamDevice { Err(err) => warn!("err occurred when submitting PREPARE_STREAM command and listening for response: {}",err), Ok(_) => info!("Prepared Stream.") } - // If we want to create an animation (in our case a moving sine wave) we need a frame rate. - let frames_per_second = 60.0; - // Lets use the DAC at an eighth the maximum scan rate. + let begin_list = vec![ + DacPoint { control: 0, x: 0, y: 0, i: 255, r: 0, g: 0, b: 0, u1: 0, u2: 0 }, + ]; let points_per_second = stream.dac().max_point_rate / 32; - // Determine the number of points per frame given our target frame and point rates. - let points_per_frame = (points_per_second as f32 / frames_per_second) as u16; - - let mut sine_wave = SineWave { - point: 0, - points_per_frame, - frames_per_second, - }; - match stream .queue_commands() - .data(sine_wave.by_ref().take(400)) - // .data(begin_list.into_iter().take(400 as usize)) + .data(begin_list.into_iter().take(1 as usize)) .begin(0, points_per_second) .submit() { Err(err) => warn!("err occurred when submitting first data: {}",err), Ok(_) => info!("Sent first data to Etherdream.") } - Ok(stream) } @@ -142,9 +130,9 @@ impl Device for EtherdreamDevice { capacity: self.points_capacity(), lack: self.dac_response.to_string(), }; - // debug!("Dac Status: {:?} ", status ); - // debug!("Etherdream Dac {:?} ", self.dac ); - debug!("Stream dac{:?}", self.stream.dac()); + // info!("Dac Status: {:?} ", status ); + // info!("Etherdream Dac {:?} ", self.dac ); + // info!("Stream dac{:?}", self.stream.dac()); status } @@ -155,17 +143,14 @@ impl Device for EtherdreamDevice { let n_points = self.points_capacity(); // let n_points = &line.len(); debug!("Etherdream::device draw Generating {:?} points", n_points); - - match self.stream .queue_commands() .data( line.into_iter() .map(|point| point.into()) + // .take(line.len() as usize) .take(n_points as usize) ) - // .data(sine_wave.by_ref().take(n_points as usize)) - .submit() { Err(err) => { // We should account for @@ -185,6 +170,7 @@ impl Device for EtherdreamDevice { err.response.response } }; + } Ok(_) => { self.dac_response = DacResponse::ACK; @@ -234,48 +220,3 @@ impl Device for EtherdreamDevice { ] } } - -// An iterator that endlessly generates a sine wave of DAC points. -// -// The sine wave oscillates at a rate of once per second. -struct SineWave { - point: u32, - points_per_frame: u16, - frames_per_second: f32, -} - -impl Iterator for SineWave { - type Item = ether_dream::protocol::DacPoint; - fn next(&mut self) -> Option { - let coloured_points_per_frame = self.points_per_frame - 1; - let i = (self.point % self.points_per_frame as u32) as u16; - let hz = 1.0; - let fract = i as f32 / coloured_points_per_frame as f32; - let phase = (self.point as f32 / coloured_points_per_frame as f32) / self.frames_per_second; - let amp = (hz * (fract + phase) * 2.0 * std::f32::consts::PI).sin(); - let (r, g, b) = match i { - i if i == coloured_points_per_frame || i < 13 => (0, 0, 0), - _ => (std::u16::MAX, std::u16::MAX, std::u16::MAX), - }; - let x_min = std::i16::MIN; - let x_max = std::i16::MAX; - let x = (x_min as f32 + fract * (x_max as f32 - x_min as f32)) as i16; - let y = (amp * x_max as f32) as i16; - let control = 0; - let (u1, u2) = (0, 0); - let p = ether_dream::protocol::DacPoint { - control, - x, - y, - i, - r, - g, - b, - u1, - u2, - }; - debug!("{:?}",p); - self.point += 1; - Some(p) - } -} \ No newline at end of file diff --git a/src/device/helios.rs b/src/device/helios.rs index 0971aeb..19a346c 100644 --- a/src/device/helios.rs +++ b/src/device/helios.rs @@ -1,4 +1,3 @@ -use std::time::SystemTime; /// /// Configure udev: /// https://github.com/Grix/helios_dac/blob/master/docs/udev_rules_for_linux.md @@ -15,7 +14,7 @@ use crate::conf::HeliosConf; use crate::device::{Device, Status, PlaybackState}; use crate::errors::{LJError, LJResult}; use crate::point::{Color, Point}; -use chrono::{DateTime, Utc}; +use chrono::Utc; pub struct HeliosDevice { pub conf: HeliosConf, @@ -35,17 +34,13 @@ impl HeliosDevice { return Err(Box::new(LJError::HeliosDeviceMissing)); }; let dac = device.open()?; - let now = SystemTime::now(); - let now: DateTime = now.into(); - let last_traced_at = now.to_rfc3339(); - Ok(Self { conf: (*conf).clone(), dac, sent_points: 0, state: PlaybackState::PREPARE, lack: "".to_string(), - last_traced_at, + last_traced_at: "1985-04-12T23:20:50.52Z".to_string(), }) } } diff --git a/src/point.rs b/src/point.rs index 6ce6268..1298905 100644 --- a/src/point.rs +++ b/src/point.rs @@ -1,5 +1,15 @@ use ether_dream::protocol::DacPoint; +fn clamp(val: f32, min: f32, max: f32) -> f32 { + if val < min { + return min; + } + if val > max { + return max; + } + val +} + #[derive(Debug, Clone, Copy, Default, PartialEq)] pub struct Point { pub x: f32, @@ -45,20 +55,21 @@ impl From for helios_dac::Point { } impl From for DacPoint { + fn from(pt: Point) -> DacPoint { let control = 0; let (u1, u2) = (0, 0); let i = 255; - let x = pt.x.clamp(-32000.0, 32000.0); - let y = pt.y.clamp(-32000.0, 32000.0); + let x = clamp(pt.x, -32000 as f32, 32000 as f32); + let y = clamp(pt.y, -32000 as f32, 32000 as f32); DacPoint { control, x: x as i16, y: y as i16, i, - r: (pt.color.r as u16) * 255, - g: (pt.color.g as u16) * 255, - b: (pt.color.b as u16) * 255, + r: pt.color.r.into(), + g: pt.color.g.into(), + b: pt.color.b.into(), u1, u2, } diff --git a/src/redis_ctrl.rs b/src/redis_ctrl.rs index 03d7cba..9b4bb4a 100644 --- a/src/redis_ctrl.rs +++ b/src/redis_ctrl.rs @@ -17,7 +17,6 @@ pub enum Order { Intensity, Kpps, ColorBalance, - PowerOff } impl TryFrom for Order { @@ -40,14 +39,13 @@ impl TryFrom for Order { 6 => Intensity, 7 => Kpps, 8 => ColorBalance, - 9 => PowerOff, _ => unreachable!() }) } } pub type Line = Vec<(f32, f32, u32)>; -pub type Resampler = Vec>; +pub type Resampler = Vec<(f32,f32)>; pub struct RedisCtrl { pub client: Client,