tidy up
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Build legacy Nix package on Ubuntu / build (push) Successful in 4m37s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Build legacy Nix package on Ubuntu / build (push) Successful in 4m37s
				
			This commit is contained in:
		
							
								
								
									
										7
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										7
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -101,6 +101,7 @@ dependencies = [ | ||||
| name = "audio-reactive-source" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "az", | ||||
|  "bytemuck", | ||||
|  "color-eyre", | ||||
|  "cpal", | ||||
| @@ -116,6 +117,12 @@ version = "1.4.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" | ||||
|  | ||||
| [[package]] | ||||
| name = "az" | ||||
| version = "1.2.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" | ||||
|  | ||||
| [[package]] | ||||
| name = "backtrace" | ||||
| version = "0.3.71" | ||||
|   | ||||
| @@ -16,5 +16,9 @@ cpal = { version = "0.15", features = ["jack"] } | ||||
| realfft = "3.4" | ||||
|  | ||||
| bytemuck = { version = "1.21", features = ["derive"] } | ||||
| az = "1.2" | ||||
|  | ||||
| textplots = "0.8" | ||||
| textplots = { version = "0.8", optional = true } | ||||
|  | ||||
| [features] | ||||
| plot = ["textplots"] | ||||
|   | ||||
							
								
								
									
										50
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								src/main.rs
									
									
									
									
									
								
							| @@ -1,5 +1,6 @@ | ||||
| use std::{cmp::Ordering, net::UdpSocket, sync::mpsc, thread::sleep, time::Duration}; | ||||
| use std::{cmp::Ordering, net::UdpSocket, sync::mpsc}; | ||||
|  | ||||
| use az::{Az, SaturatingAs}; | ||||
| use bytemuck::{Pod, Zeroable}; | ||||
| use color_eyre::eyre::{bail, Result}; | ||||
| use cpal::{ | ||||
| @@ -8,10 +9,11 @@ use cpal::{ | ||||
| }; | ||||
| use log::{debug, error, info, trace}; | ||||
| use realfft::{ | ||||
|     num_complex::{Complex, Complex32, ComplexFloat}, | ||||
|     num_complex::{Complex32, ComplexFloat}, | ||||
|     RealFftPlanner, RealToComplex, | ||||
| }; | ||||
| use textplots::{Chart, LabelBuilder, LabelFormat, Plot, Shape}; | ||||
| #[cfg(feature = "plot")] | ||||
| use textplots::{Chart, Plot, Shape}; | ||||
|  | ||||
| fn main() -> color_eyre::Result<()> { | ||||
|     env_logger::init(); | ||||
| @@ -87,15 +89,18 @@ fn main() -> color_eyre::Result<()> { | ||||
|             error!("Unable to send packet over multicast: {e}"); | ||||
|         } | ||||
|  | ||||
|         // let plot_data: Vec<_> = data | ||||
|         //     .fft_result | ||||
|         //     .iter() | ||||
|         //     .enumerate() | ||||
|         //     .map(|(i, datum)| (i as f32, f32::from(*datum))) | ||||
|         //     .collect(); | ||||
|         // Chart::new_with_y_range(250, 50, 0.0, 16.0, 0.0, 255.0) | ||||
|         //     .lineplot(&Shape::Bars(&plot_data[..])) | ||||
|         //     .display(); | ||||
|         #[cfg(feature = "plot")] | ||||
|         { | ||||
|             let plot_data: Vec<_> = data | ||||
|                 .fft_result | ||||
|                 .iter() | ||||
|                 .enumerate() | ||||
|                 .map(|(i, datum)| (i.az(), f32::from(*datum))) | ||||
|                 .collect(); | ||||
|             Chart::new_with_y_range(250, 50, 0.0, 16.0, 0.0, 255.0) | ||||
|                 .lineplot(&Shape::Bars(&plot_data[..])) | ||||
|                 .display(); | ||||
|         } | ||||
|         let magnitude = data.fft_magnitude; | ||||
|         let sample_raw = data.sample_raw; | ||||
|         let sample_smth = data.sample_smth; | ||||
| @@ -113,9 +118,9 @@ struct AudioSyncPacket { | ||||
|     header: [u8; 6], | ||||
|     /// Optional sound pressure as fixed point (8bit integer, 8bit fractional) | ||||
|     preasure: [u8; 2], | ||||
|     /// either "sample_raw" or "raw_sample_agc" depending on sound_agc setting | ||||
|     /// either `sample_raw` or `raw_sample_agc` depending on `sound_agc` setting | ||||
|     sample_raw: f32, | ||||
|     /// either "sample_avg" or "sample_agc" depending on sound_agc setting | ||||
|     /// either `sample_avg` or `sample_agc` depending on `sound_agc` setting | ||||
|     sample_smth: f32, | ||||
|     /// 0 = no peak, >= 1 = peak detected, In future, this will also provide peak Magnitude | ||||
|     sample_peak: u8, | ||||
| @@ -168,14 +173,14 @@ impl AudioSyncPacket { | ||||
|         let abs_data: Vec<_> = data.iter().map(|sample| sample.abs()).collect(); | ||||
|  | ||||
|         // calculate peak  (raw level and peak level) | ||||
|         let raw_level = abs_data.iter().sum::<f32>() / data.len() as f32 * 256.0; | ||||
|         let raw_level = abs_data.iter().sum::<f32>() / data.len().az::<f32>() * 512.0; | ||||
|         let peak_level = abs_data | ||||
|             .iter() | ||||
|             .max_by(|lhs, rhs| lhs.partial_cmp(rhs).unwrap_or(Ordering::Equal)) | ||||
|             .copied() | ||||
|             .unwrap_or(0.0); | ||||
|         // scale peak level to u8 | ||||
|         let peak_level = (peak_level * f32::from(u8::MAX)) as u8; | ||||
|         let peak_level = (peak_level * f32::from(u8::MAX)).saturating_as(); | ||||
|  | ||||
|         // calculate fft | ||||
|         fft_input[..].copy_from_slice(data); | ||||
| @@ -183,13 +188,14 @@ impl AudioSyncPacket { | ||||
|         let real_fft_output: Vec<_> = fft_output.iter().map(|value| value.abs()).collect(); | ||||
|  | ||||
|         // find dominant frequency | ||||
|         let (peak_index, peak) = real_fft_output | ||||
|         let peak_index = real_fft_output | ||||
|             .iter() | ||||
|             .enumerate() | ||||
|             .max_by(|(_, lhs), (_, rhs)| lhs.partial_cmp(rhs).unwrap_or(Ordering::Equal)) | ||||
|             .map(|(i, value)| (i, *value)) | ||||
|             .map(|(i, _)| i) | ||||
|             .unwrap_or_default(); | ||||
|         let peak_frequency = (peak_index * sample_rate as usize) as f32 / data.len() as f32; | ||||
|         let peak_frequency = | ||||
|             (peak_index * sample_rate.az::<usize>()).az::<f32>() / data.len().az::<f32>(); | ||||
|  | ||||
|         // select 16 [frequency bins](https://github.com/MoonModules/WLED/blob/fc173b3bc00694e59b653ca230133052b5476c05/usermods/audioreactive/audio_reactive.h#L733-L760) | ||||
|         let bins = [ | ||||
| @@ -197,12 +203,12 @@ impl AudioSyncPacket { | ||||
|         ] | ||||
|         .map(|frequency| frequency * data.len() / sample_rate as usize); | ||||
|         let mut fft_values = [0.0; 16]; | ||||
|         fft_values[0] = real_fft_output[1..=bins[0]].iter().sum::<f32>() / (bins[0]) as f32; | ||||
|         fft_values[0] = real_fft_output[1..=bins[0]].iter().sum::<f32>() / (bins[0]).az::<f32>(); | ||||
|         for i in 1..fft_values.len() { | ||||
|             fft_values[i] = real_fft_output[bins[i - 1] + 1..=bins[i]] | ||||
|                 .iter() | ||||
|                 .sum::<f32>() | ||||
|                 / (bins[i] - bins[i - 1] + 1) as f32; | ||||
|                 / (bins[i] - bins[i - 1] + 1).az::<f32>(); | ||||
|         } | ||||
|         fft_values[14] *= 0.88; | ||||
|         fft_values[15] *= 0.7; | ||||
| @@ -218,7 +224,7 @@ impl AudioSyncPacket { | ||||
|             fft_max = 1.0; | ||||
|         } | ||||
|         for i in 0..fft_values.len() { | ||||
|             fft_values_u8[i] = (fft_values[i] * f32::from(u8::MAX) / fft_max) as u8; | ||||
|             fft_values_u8[i] = (fft_values[i] * f32::from(u8::MAX) / fft_max).saturating_as(); | ||||
|         } | ||||
|  | ||||
|         // calculate fft magnitude sum | ||||
|   | ||||
		Reference in New Issue
	
	Block a user