diff --git a/examples/etherdream.rs b/examples/etherdream.rs index e174a88..75d888c 100644 --- a/examples/etherdream.rs +++ b/examples/etherdream.rs @@ -3,148 +3,149 @@ 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 - ); - }); + err + ); + }); + eprintln!("Stream dac{:?}", stream.dac()); - // 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/src/device/etherdream.rs b/src/device/etherdream.rs index 86b6a6b..6d1e626 100644 --- a/src/device/etherdream.rs +++ b/src/device/etherdream.rs @@ -71,6 +71,7 @@ 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)) @@ -87,18 +88,29 @@ impl EtherdreamDevice { Err(err) => warn!("err occurred when submitting PREPARE_STREAM command and listening for response: {}",err), Ok(_) => info!("Prepared Stream.") } - let begin_list = vec![ - DacPoint { control: 0, x: 0, y: 0, i: 255, r: 0, g: 0, b: 0, u1: 0, u2: 0 }, - ]; + // 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; + + let mut sine_wave = SineWave { + point: 0, + points_per_frame, + frames_per_second, + }; + match stream .queue_commands() - .data(begin_list.into_iter().take(1 as usize)) + .data(sine_wave.by_ref().take(400)) + // .data(begin_list.into_iter().take(400 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) } @@ -130,9 +142,9 @@ impl Device for EtherdreamDevice { capacity: self.points_capacity(), lack: self.dac_response.to_string(), }; - // info!("Dac Status: {:?} ", status ); - // info!("Etherdream Dac {:?} ", self.dac ); - // info!("Stream dac{:?}", self.stream.dac()); + // debug!("Dac Status: {:?} ", status ); + // debug!("Etherdream Dac {:?} ", self.dac ); + debug!("Stream dac{:?}", self.stream.dac()); status } @@ -143,6 +155,17 @@ impl Device for EtherdreamDevice { let n_points = self.points_capacity(); // let n_points = &line.len(); debug!("Etherdream::device draw Generating {:?} points", n_points); + let frames_per_second = 60.0; + // Lets use the DAC at an eighth the maximum scan rate. + let points_per_second = self.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 self.stream .queue_commands() .data( @@ -151,6 +174,8 @@ impl Device for EtherdreamDevice { // .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 @@ -170,7 +195,6 @@ impl Device for EtherdreamDevice { err.response.response } }; - } Ok(_) => { self.dac_response = DacResponse::ACK; @@ -220,3 +244,53 @@ impl Device for EtherdreamDevice { ] } } + +// 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 +} + +// 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/point.rs b/src/point.rs index 1298905..9f88f43 100644 --- a/src/point.rs +++ b/src/point.rs @@ -1,4 +1,5 @@ use ether_dream::protocol::DacPoint; +use log::debug; fn clamp(val: f32, min: f32, max: f32) -> f32 { if val < min { @@ -67,9 +68,9 @@ impl From for DacPoint { x: x as i16, y: y as i16, i, - r: pt.color.r.into(), - g: pt.color.g.into(), - b: pt.color.b.into(), + r: (pt.color.r as u16) * 255, + g: (pt.color.g as u16) * 255, + b: (pt.color.b as u16) * 255, u1, u2, }