1use crate::{types::ConversionRequest, Error};
39use std::collections::HashMap;
40use std::sync::{Arc, Mutex};
41use std::time::{Duration, Instant};
42
43#[derive(Debug, Clone, PartialEq)]
45pub enum OptimizationLevel {
46 None,
48 Basic,
50 Standard,
52 Aggressive,
54 Maximum,
56}
57
58#[derive(Debug, Clone, PartialEq, Eq, Hash)]
60pub enum TargetPlatform {
61 Windows,
63 MacOS,
65 Linux,
67 IOS,
69 Android,
71 WebAssembly,
73 Unix,
75 Unknown,
77}
78
79impl TargetPlatform {
80 pub fn current() -> Self {
82 #[cfg(target_os = "windows")]
83 return TargetPlatform::Windows;
84
85 #[cfg(target_os = "macos")]
86 return TargetPlatform::MacOS;
87
88 #[cfg(target_os = "linux")]
89 return TargetPlatform::Linux;
90
91 #[cfg(target_os = "ios")]
92 return TargetPlatform::IOS;
93
94 #[cfg(target_os = "android")]
95 return TargetPlatform::Android;
96
97 #[cfg(target_arch = "wasm32")]
98 return TargetPlatform::WebAssembly;
99
100 #[cfg(all(
101 unix,
102 not(any(
103 target_os = "macos",
104 target_os = "linux",
105 target_os = "ios",
106 target_os = "android"
107 ))
108 ))]
109 return TargetPlatform::Unix;
110
111 #[cfg(not(any(
112 target_os = "windows",
113 target_os = "macos",
114 target_os = "linux",
115 target_os = "ios",
116 target_os = "android",
117 target_arch = "wasm32",
118 all(
119 unix,
120 not(any(
121 target_os = "macos",
122 target_os = "linux",
123 target_os = "ios",
124 target_os = "android"
125 ))
126 )
127 )))]
128 TargetPlatform::Unknown
129 }
130}
131
132#[derive(Debug, Clone, Default)]
134pub struct CpuFeatures {
135 pub sse: bool,
137 pub sse2: bool,
139 pub sse3: bool,
141 pub sse4_1: bool,
143 pub sse4_2: bool,
145 pub avx: bool,
147 pub avx2: bool,
149 pub fma: bool,
151 pub neon: bool,
153 pub core_count: usize,
155 pub cache_line_size: usize,
157 pub cpu_frequency: u32,
159}
160
161#[derive(Debug, Clone)]
163pub struct PlatformConfig {
164 pub target_platform: Option<TargetPlatform>,
166 pub optimization_level: OptimizationLevel,
168 pub hardware_acceleration: bool,
170 pub realtime_priority: bool,
172 pub memory_optimization: bool,
174 pub power_management: bool,
176 pub thread_affinity: Option<u64>,
178 pub buffer_alignment: usize,
180 pub vectorization: bool,
182}
183
184impl Default for PlatformConfig {
185 fn default() -> Self {
186 Self {
187 target_platform: None, optimization_level: OptimizationLevel::Standard,
189 hardware_acceleration: true,
190 realtime_priority: false,
191 memory_optimization: true,
192 power_management: true,
193 thread_affinity: None,
194 buffer_alignment: 64, vectorization: true,
196 }
197 }
198}
199
200impl PlatformConfig {
201 pub fn with_optimization_level(mut self, level: OptimizationLevel) -> Self {
203 self.optimization_level = level;
204 self
205 }
206
207 pub fn with_hardware_acceleration(mut self, enable: bool) -> Self {
209 self.hardware_acceleration = enable;
210 self
211 }
212
213 pub fn with_realtime_priority(mut self, enable: bool) -> Self {
215 self.realtime_priority = enable;
216 self
217 }
218
219 pub fn with_thread_affinity(mut self, mask: u64) -> Self {
221 self.thread_affinity = Some(mask);
222 self
223 }
224
225 pub fn with_buffer_alignment(mut self, alignment: usize) -> Self {
227 self.buffer_alignment = alignment;
228 self
229 }
230
231 pub fn with_vectorization(mut self, enable: bool) -> Self {
233 self.vectorization = enable;
234 self
235 }
236}
237
238#[derive(Debug, Clone, Default)]
240pub struct PlatformStats {
241 pub simd_ops_per_sec: f64,
243 pub memory_bandwidth: f32,
245 pub cache_hit_rate: f32,
247 pub thread_efficiency: f32,
249 pub power_consumption: f32,
251 pub thermal_throttling: u64,
253 pub page_faults_per_sec: f64,
255 pub context_switches_per_sec: f64,
257}
258
259#[cfg(target_os = "windows")]
261pub mod windows {
262 use super::*;
263
264 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
266 pub enum WindowsAudioAPI {
267 WASAPI,
269 DirectSound,
271 MME,
273 ASIO,
275 }
276
277 #[derive(Debug, Clone)]
279 pub struct WindowsConfig {
280 pub audio_api: WindowsAudioAPI,
282 pub mmcss: bool,
284 pub priority_class: u32,
286 pub large_pages: bool,
288 pub hardware_offloading: bool,
290 }
291
292 impl Default for WindowsConfig {
293 fn default() -> Self {
294 Self {
295 audio_api: WindowsAudioAPI::WASAPI,
296 mmcss: true,
297 priority_class: 0x00000020, large_pages: false,
299 hardware_offloading: true,
300 }
301 }
302 }
303
304 pub fn apply_windows_optimizations(config: &WindowsConfig) -> Result<(), Error> {
306 if config.mmcss {
308 }
310
311 if config.large_pages {
316 }
318
319 Ok(())
320 }
321
322 pub fn detect_windows_audio_capabilities() -> HashMap<WindowsAudioAPI, bool> {
324 let mut capabilities = HashMap::new();
325
326 capabilities.insert(WindowsAudioAPI::WASAPI, true); capabilities.insert(WindowsAudioAPI::DirectSound, true);
331
332 capabilities.insert(WindowsAudioAPI::MME, true);
334
335 capabilities.insert(WindowsAudioAPI::ASIO, false); capabilities
339 }
340}
341
342#[cfg(target_os = "macos")]
344pub mod macos {
345 use super::*;
346
347 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
349 pub enum MacOSAudioFramework {
350 CoreAudio,
352 AudioUnits,
354 AVAudioEngine,
356 }
357
358 #[derive(Debug, Clone)]
360 pub struct MacOSConfig {
361 pub audio_framework: MacOSAudioFramework,
363 pub realtime_scheduling: bool,
365 pub thread_period: u64,
367 pub thread_computation: u64,
369 pub thread_constraint: u64,
371 pub accelerate_framework: bool,
373 }
374
375 impl Default for MacOSConfig {
376 fn default() -> Self {
377 Self {
378 audio_framework: MacOSAudioFramework::CoreAudio,
379 realtime_scheduling: true,
380 thread_period: 2_902_494, thread_computation: 1_451_247, thread_constraint: 2_902_494,
383 accelerate_framework: true,
384 }
385 }
386 }
387
388 pub fn apply_macos_optimizations(config: &MacOSConfig) -> Result<(), Error> {
390 if config.realtime_scheduling {
392 }
394
395 if config.accelerate_framework {
397 }
399
400 Ok(())
401 }
402
403 pub fn detect_macos_audio_capabilities() -> HashMap<MacOSAudioFramework, bool> {
405 let mut capabilities = HashMap::new();
406
407 capabilities.insert(MacOSAudioFramework::CoreAudio, true);
409
410 capabilities.insert(MacOSAudioFramework::AudioUnits, true);
412
413 capabilities.insert(MacOSAudioFramework::AVAudioEngine, true);
415
416 capabilities
417 }
418}
419
420#[cfg(target_os = "linux")]
422pub mod linux {
423 use super::*;
424
425 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
427 pub enum LinuxAudioSystem {
428 ALSA,
430 PulseAudio,
432 JACK,
434 PipeWire,
436 OSS,
438 }
439
440 #[derive(Debug, Clone)]
442 pub struct LinuxConfig {
443 pub audio_system: LinuxAudioSystem,
445 pub realtime_scheduling: bool,
447 pub rt_priority: u8,
449 pub cpu_governor: String,
451 pub memory_locking: bool,
453 pub cpu_affinity: bool,
455 }
456
457 impl Default for LinuxConfig {
458 fn default() -> Self {
459 Self {
460 audio_system: LinuxAudioSystem::PulseAudio,
461 realtime_scheduling: false, rt_priority: 80,
463 cpu_governor: "performance".to_string(),
464 memory_locking: false, cpu_affinity: true,
466 }
467 }
468 }
469
470 pub fn apply_linux_optimizations(config: &LinuxConfig) -> Result<(), Error> {
472 if config.realtime_scheduling {
474 }
476
477 if config.memory_locking {
479 }
481
482 if config.cpu_affinity {
484 }
486
487 Ok(())
488 }
489
490 pub fn detect_linux_audio_capabilities() -> HashMap<LinuxAudioSystem, bool> {
492 let mut capabilities = HashMap::new();
493
494 capabilities.insert(
496 LinuxAudioSystem::ALSA,
497 std::path::Path::new("/proc/asound").exists(),
498 );
499
500 capabilities.insert(
502 LinuxAudioSystem::PulseAudio,
503 std::process::Command::new("pulseaudio")
504 .arg("--check")
505 .status()
506 .map(|s| s.success())
507 .unwrap_or(false),
508 );
509
510 capabilities.insert(
512 LinuxAudioSystem::JACK,
513 std::process::Command::new("jack_lsp")
514 .output()
515 .map(|o| o.status.success())
516 .unwrap_or(false),
517 );
518
519 capabilities.insert(
521 LinuxAudioSystem::PipeWire,
522 std::process::Command::new("pipewire")
523 .arg("--version")
524 .status()
525 .map(|s| s.success())
526 .unwrap_or(false),
527 );
528
529 capabilities.insert(
531 LinuxAudioSystem::OSS,
532 std::path::Path::new("/dev/dsp").exists(),
533 );
534
535 capabilities
536 }
537}
538
539pub struct PlatformOptimizer {
541 config: PlatformConfig,
543 platform: TargetPlatform,
545 cpu_features: CpuFeatures,
547 stats: Arc<Mutex<PlatformStats>>,
549 initialized: bool,
551 #[cfg(target_os = "windows")]
553 windows_config: windows::WindowsConfig,
554 #[cfg(target_os = "macos")]
555 macos_config: macos::MacOSConfig,
556 #[cfg(target_os = "linux")]
557 linux_config: linux::LinuxConfig,
558}
559
560impl PlatformOptimizer {
561 pub fn new(config: PlatformConfig) -> Result<Self, Error> {
563 let platform = config
564 .target_platform
565 .clone()
566 .unwrap_or_else(TargetPlatform::current);
567 let cpu_features = Self::detect_cpu_features();
568
569 Ok(Self {
570 config,
571 platform,
572 cpu_features,
573 stats: Arc::new(Mutex::new(PlatformStats::default())),
574 initialized: false,
575 #[cfg(target_os = "windows")]
576 windows_config: windows::WindowsConfig::default(),
577 #[cfg(target_os = "macos")]
578 macos_config: macos::MacOSConfig::default(),
579 #[cfg(target_os = "linux")]
580 linux_config: linux::LinuxConfig::default(),
581 })
582 }
583
584 pub fn initialize(&mut self) -> Result<(), Error> {
586 if self.initialized {
587 return Ok(());
588 }
589
590 match self.platform {
592 #[cfg(target_os = "windows")]
593 TargetPlatform::Windows => {
594 windows::apply_windows_optimizations(&self.windows_config)?;
595 }
596 #[cfg(target_os = "macos")]
597 TargetPlatform::MacOS => {
598 macos::apply_macos_optimizations(&self.macos_config)?;
599 }
600 #[cfg(target_os = "linux")]
601 TargetPlatform::Linux => {
602 linux::apply_linux_optimizations(&self.linux_config)?;
603 }
604 _ => {
605 self.apply_generic_optimizations()?;
607 }
608 }
609
610 if let Some(affinity) = self.config.thread_affinity {
612 self.set_thread_affinity(affinity)?;
613 }
614
615 if self.config.realtime_priority {
617 self.set_realtime_priority()?;
618 }
619
620 self.initialized = true;
621 Ok(())
622 }
623
624 pub fn optimize_processing(&self, audio: &[f32]) -> Result<Vec<f32>, Error> {
626 if !self.initialized {
627 return Err(Error::validation(
628 "Platform optimizer not initialized".to_string(),
629 ));
630 }
631
632 let start_time = Instant::now();
633 let mut processed = self.allocate_aligned_buffer(audio.len())?;
634
635 match self.config.optimization_level {
637 OptimizationLevel::None => {
638 processed.copy_from_slice(audio);
639 }
640 OptimizationLevel::Basic => {
641 self.apply_basic_optimizations(audio, &mut processed)?;
642 }
643 OptimizationLevel::Standard => {
644 self.apply_standard_optimizations(audio, &mut processed)?;
645 }
646 OptimizationLevel::Aggressive => {
647 self.apply_aggressive_optimizations(audio, &mut processed)?;
648 }
649 OptimizationLevel::Maximum => {
650 self.apply_maximum_optimizations(audio, &mut processed)?;
651 }
652 }
653
654 let processing_time = start_time.elapsed();
656 self.update_performance_stats(audio.len(), processing_time);
657
658 Ok(processed)
659 }
660
661 pub fn get_cpu_features(&self) -> &CpuFeatures {
663 &self.cpu_features
664 }
665
666 pub fn get_platform(&self) -> &TargetPlatform {
668 &self.platform
669 }
670
671 pub fn get_stats(&self) -> PlatformStats {
673 self.stats.lock().expect("Lock poisoned").clone()
674 }
675
676 pub fn is_optimization_available(&self, optimization: &str) -> bool {
678 match optimization {
679 "simd" => self.cpu_features.sse2 || self.cpu_features.neon,
680 "avx" => self.cpu_features.avx,
681 "avx2" => self.cpu_features.avx2,
682 "fma" => self.cpu_features.fma,
683 "neon" => self.cpu_features.neon,
684 "vectorization" => {
685 self.config.vectorization && (self.cpu_features.sse2 || self.cpu_features.neon)
686 }
687 _ => false,
688 }
689 }
690
691 fn detect_cpu_features() -> CpuFeatures {
695 let mut features = CpuFeatures::default();
696
697 features.core_count = std::thread::available_parallelism()
699 .map(|p| p.get())
700 .unwrap_or(1);
701
702 #[cfg(target_arch = "x86_64")]
704 {
705 if is_x86_feature_detected!("sse") {
707 features.sse = true;
708 }
709 if is_x86_feature_detected!("sse2") {
710 features.sse2 = true;
711 }
712 if is_x86_feature_detected!("sse3") {
713 features.sse3 = true;
714 }
715 if is_x86_feature_detected!("sse4.1") {
716 features.sse4_1 = true;
717 }
718 if is_x86_feature_detected!("sse4.2") {
719 features.sse4_2 = true;
720 }
721 if is_x86_feature_detected!("avx") {
722 features.avx = true;
723 }
724 if is_x86_feature_detected!("avx2") {
725 features.avx2 = true;
726 }
727 if is_x86_feature_detected!("fma") {
728 features.fma = true;
729 }
730 }
731
732 #[cfg(target_arch = "aarch64")]
733 {
734 features.neon = true;
736 }
737
738 #[cfg(target_arch = "arm")]
739 {
740 features.neon = std::arch::is_aarch64_feature_detected!("neon");
742 }
743
744 features.cache_line_size = 64; features.cpu_frequency = 2400; features
751 }
752
753 fn allocate_aligned_buffer(&self, size: usize) -> Result<Vec<f32>, Error> {
755 Ok(vec![0.0; size])
758 }
759
760 fn apply_basic_optimizations(&self, input: &[f32], output: &mut [f32]) -> Result<(), Error> {
762 if self.cpu_features.sse2 || self.cpu_features.neon {
763 self.simd_copy(input, output)?;
765 } else {
766 output.copy_from_slice(input);
768 }
769 Ok(())
770 }
771
772 fn apply_standard_optimizations(&self, input: &[f32], output: &mut [f32]) -> Result<(), Error> {
774 self.apply_basic_optimizations(input, output)?;
775
776 if input.len() > 1024 {
778 self.parallel_process(input, output)?;
779 }
780
781 Ok(())
782 }
783
784 fn apply_aggressive_optimizations(
786 &self,
787 input: &[f32],
788 output: &mut [f32],
789 ) -> Result<(), Error> {
790 self.apply_standard_optimizations(input, output)?;
791
792 if self.cpu_features.avx2 {
794 self.avx2_process(input, output)?;
795 } else if self.cpu_features.avx {
796 self.avx_process(input, output)?;
797 }
798
799 Ok(())
800 }
801
802 fn apply_maximum_optimizations(&self, input: &[f32], output: &mut [f32]) -> Result<(), Error> {
804 self.apply_aggressive_optimizations(input, output)?;
805
806 if self.cpu_features.fma {
808 self.fma_process(input, output)?;
809 }
810
811 Ok(())
812 }
813
814 fn simd_copy(&self, input: &[f32], output: &mut [f32]) -> Result<(), Error> {
816 for (inp, out) in input.iter().zip(output.iter_mut()) {
818 *out = *inp * 0.99; }
820 Ok(())
821 }
822
823 fn parallel_process(&self, input: &[f32], output: &mut [f32]) -> Result<(), Error> {
825 let chunk_size = input.len() / self.cpu_features.core_count;
826
827 if chunk_size > 0 {
828 for (inp_chunk, out_chunk) in
831 input.chunks(chunk_size).zip(output.chunks_mut(chunk_size))
832 {
833 for (inp, out) in inp_chunk.iter().zip(out_chunk.iter_mut()) {
834 *out = *inp * 0.98;
835 }
836 }
837 }
838
839 Ok(())
840 }
841
842 #[cfg(target_arch = "x86_64")]
845 #[allow(unsafe_code)]
846 fn avx_process(&self, input: &[f32], output: &mut [f32]) -> Result<(), Error> {
847 if !is_x86_feature_detected!("avx") {
848 return self.scalar_process(input, output);
850 }
851
852 unsafe { self.avx_process_unchecked(input, output) }
853 }
854
855 #[cfg(not(target_arch = "x86_64"))]
856 fn avx_process(&self, input: &[f32], output: &mut [f32]) -> Result<(), Error> {
857 self.scalar_process(input, output)
858 }
859
860 #[cfg(target_arch = "x86_64")]
861 #[target_feature(enable = "avx")]
862 #[allow(unsafe_code)]
863 unsafe fn avx_process_unchecked(&self, input: &[f32], output: &mut [f32]) -> Result<(), Error> {
864 use std::arch::x86_64::*;
865
866 let len = input.len().min(output.len());
867 let mut i = 0;
868
869 while i + 8 <= len {
871 let input_vec = _mm256_loadu_ps(input.as_ptr().add(i));
873
874 let scale = _mm256_set1_ps(0.99); let mut processed = _mm256_mul_ps(input_vec, scale);
877
878 let prev_scale = _mm256_set1_ps(0.995);
881 if i >= 8 {
882 let prev_vec = _mm256_loadu_ps(input.as_ptr().add(i - 1));
883 let dc_offset = _mm256_mul_ps(prev_vec, prev_scale);
884 processed = _mm256_sub_ps(processed, dc_offset);
885 }
886
887 _mm256_storeu_ps(output.as_mut_ptr().add(i), processed);
889
890 i += 8;
891 }
892
893 for j in i..len {
895 output[j] = input[j] * 0.99;
896 if j > 0 {
897 output[j] -= input[j - 1] * 0.995;
898 }
899 }
900
901 Ok(())
902 }
903
904 #[cfg(target_arch = "x86_64")]
907 #[allow(unsafe_code)]
908 fn avx2_process(&self, input: &[f32], output: &mut [f32]) -> Result<(), Error> {
909 if !is_x86_feature_detected!("avx2") {
910 return if is_x86_feature_detected!("avx") {
912 self.avx_process(input, output)
913 } else {
914 self.scalar_process(input, output)
915 };
916 }
917
918 unsafe { self.avx2_process_unchecked(input, output) }
919 }
920
921 #[cfg(not(target_arch = "x86_64"))]
922 fn avx2_process(&self, input: &[f32], output: &mut [f32]) -> Result<(), Error> {
923 self.scalar_process(input, output)
924 }
925
926 #[cfg(target_arch = "x86_64")]
927 #[target_feature(enable = "avx2")]
928 #[allow(unsafe_code)]
929 unsafe fn avx2_process_unchecked(
930 &self,
931 input: &[f32],
932 output: &mut [f32],
933 ) -> Result<(), Error> {
934 use std::arch::x86_64::*;
935
936 let len = input.len().min(output.len());
937 let mut i = 0;
938
939 while i + 16 <= len {
942 let vec1 = _mm256_loadu_ps(input.as_ptr().add(i));
944 let vec2 = _mm256_loadu_ps(input.as_ptr().add(i + 8));
945
946 let coeff0 = _mm256_set1_ps(0.1);
949 let coeff1 = _mm256_set1_ps(0.3);
950 let coeff2 = _mm256_set1_ps(0.4);
951 let coeff3 = _mm256_set1_ps(0.2);
952
953 let mut result1 = _mm256_mul_ps(vec1, coeff0);
955 let mut result2 = _mm256_mul_ps(vec2, coeff0);
956
957 if i >= 1 {
959 let delayed1 = _mm256_loadu_ps(input.as_ptr().add(i - 1));
960 result1 = _mm256_fmadd_ps(delayed1, coeff1, result1);
961 }
962 if i >= 2 {
963 let delayed2 = _mm256_loadu_ps(input.as_ptr().add(i - 2));
964 result1 = _mm256_fmadd_ps(delayed2, coeff2, result1);
965 }
966 if i >= 3 {
967 let delayed3 = _mm256_loadu_ps(input.as_ptr().add(i - 3));
968 result1 = _mm256_fmadd_ps(delayed3, coeff3, result1);
969 }
970
971 if i + 8 >= 1 {
972 let delayed1 = _mm256_loadu_ps(input.as_ptr().add(i + 7));
973 result2 = _mm256_fmadd_ps(delayed1, coeff1, result2);
974 }
975
976 _mm256_storeu_ps(output.as_mut_ptr().add(i), result1);
978 _mm256_storeu_ps(output.as_mut_ptr().add(i + 8), result2);
979
980 i += 16;
981 }
982
983 while i < len {
985 let mut sample = input[i] * 0.1;
986 if i >= 1 {
987 sample += input[i - 1] * 0.3;
988 }
989 if i >= 2 {
990 sample += input[i - 2] * 0.4;
991 }
992 if i >= 3 {
993 sample += input[i - 3] * 0.2;
994 }
995 output[i] = sample;
996 i += 1;
997 }
998
999 Ok(())
1000 }
1001
1002 #[cfg(target_arch = "x86_64")]
1005 #[allow(unsafe_code)]
1006 fn fma_process(&self, input: &[f32], output: &mut [f32]) -> Result<(), Error> {
1007 if !is_x86_feature_detected!("fma") {
1008 return if is_x86_feature_detected!("avx2") {
1010 self.avx2_process(input, output)
1011 } else if is_x86_feature_detected!("avx") {
1012 self.avx_process(input, output)
1013 } else {
1014 self.scalar_process(input, output)
1015 };
1016 }
1017
1018 unsafe { self.fma_process_unchecked(input, output) }
1019 }
1020
1021 #[cfg(not(target_arch = "x86_64"))]
1022 fn fma_process(&self, input: &[f32], output: &mut [f32]) -> Result<(), Error> {
1023 self.scalar_process(input, output)
1024 }
1025
1026 #[cfg(target_arch = "x86_64")]
1027 #[target_feature(enable = "fma")]
1028 #[allow(unsafe_code)]
1029 unsafe fn fma_process_unchecked(&self, input: &[f32], output: &mut [f32]) -> Result<(), Error> {
1030 use std::arch::x86_64::*;
1031
1032 let len = input.len().min(output.len());
1033 let mut i = 0;
1034
1035 let b0 = _mm256_set1_ps(0.0201);
1041 let b1 = _mm256_set1_ps(0.0402);
1042 let b2 = _mm256_set1_ps(0.0201);
1043 let a1 = _mm256_set1_ps(-1.5610);
1044 let a2 = _mm256_set1_ps(0.6414);
1045
1046 let mut x1 = _mm256_setzero_ps();
1048 let mut x2 = _mm256_setzero_ps();
1049 let mut y1 = _mm256_setzero_ps();
1050 let mut y2 = _mm256_setzero_ps();
1051
1052 while i + 8 <= len {
1053 let x0 = _mm256_loadu_ps(input.as_ptr().add(i));
1054
1055 let mut y0 = _mm256_mul_ps(b0, x0);
1060 y0 = _mm256_fmadd_ps(b1, x1, y0); y0 = _mm256_fmadd_ps(b2, x2, y0); y0 = _mm256_fnmadd_ps(a1, y1, y0); y0 = _mm256_fnmadd_ps(a2, y2, y0); _mm256_storeu_ps(output.as_mut_ptr().add(i), y0);
1069
1070 x2 = x1;
1072 x1 = x0;
1073 y2 = y1;
1074 y1 = y0;
1075
1076 i += 8;
1077 }
1078
1079 let b0_scalar = 0.0201;
1081 let b1_scalar = 0.0402;
1082 let b2_scalar = 0.0201;
1083 let a1_scalar = -1.5610;
1084 let a2_scalar = 0.6414;
1085
1086 let mut x1_scalar = if i >= 1 { input[i - 1] } else { 0.0 };
1087 let mut x2_scalar = if i >= 2 { input[i - 2] } else { 0.0 };
1088 let mut y1_scalar = if i >= 1 { output[i - 1] } else { 0.0 };
1089 let mut y2_scalar = if i >= 2 { output[i - 2] } else { 0.0 };
1090
1091 while i < len {
1092 let x0_scalar = input[i];
1093 let y0_scalar = b0_scalar * x0_scalar + b1_scalar * x1_scalar + b2_scalar * x2_scalar
1094 - a1_scalar * y1_scalar
1095 - a2_scalar * y2_scalar;
1096 output[i] = y0_scalar;
1097
1098 x2_scalar = x1_scalar;
1099 x1_scalar = x0_scalar;
1100 y2_scalar = y1_scalar;
1101 y1_scalar = y0_scalar;
1102
1103 i += 1;
1104 }
1105
1106 Ok(())
1107 }
1108
1109 fn scalar_process(&self, input: &[f32], output: &mut [f32]) -> Result<(), Error> {
1111 let len = input.len().min(output.len());
1112 output[..len].copy_from_slice(&input[..len]);
1113 Ok(())
1114 }
1115
1116 fn apply_generic_optimizations(&self) -> Result<(), Error> {
1118 Ok(())
1120 }
1121
1122 fn set_thread_affinity(&self, _affinity: u64) -> Result<(), Error> {
1124 Ok(())
1128 }
1129
1130 fn set_realtime_priority(&self) -> Result<(), Error> {
1132 Ok(())
1136 }
1137
1138 fn update_performance_stats(&self, samples_processed: usize, processing_time: Duration) {
1140 if let Ok(mut stats) = self.stats.lock() {
1141 let samples_per_sec = samples_processed as f64 / processing_time.as_secs_f64();
1142 stats.simd_ops_per_sec = samples_per_sec;
1143
1144 stats.memory_bandwidth = (samples_per_sec / 1_000_000.0) as f32; stats.cache_hit_rate = 0.95; stats.thread_efficiency = 0.85; stats.power_consumption = 15.0; }
1150 }
1151}
1152
1153#[cfg(test)]
1154mod tests {
1155 use super::*;
1156
1157 #[test]
1158 fn test_target_platform_detection() {
1159 let platform = TargetPlatform::current();
1160
1161 assert_ne!(platform, TargetPlatform::Unknown);
1163
1164 #[cfg(target_os = "windows")]
1166 assert_eq!(platform, TargetPlatform::Windows);
1167
1168 #[cfg(target_os = "macos")]
1169 assert_eq!(platform, TargetPlatform::MacOS);
1170
1171 #[cfg(target_os = "linux")]
1172 assert_eq!(platform, TargetPlatform::Linux);
1173 }
1174
1175 #[test]
1176 fn test_cpu_features_detection() {
1177 let features = PlatformOptimizer::detect_cpu_features();
1178
1179 assert!(features.core_count > 0);
1181 assert!(features.cache_line_size > 0);
1182 assert!(features.cpu_frequency > 0);
1183
1184 #[cfg(target_arch = "x86_64")]
1186 assert!(features.sse2);
1187
1188 #[cfg(target_arch = "aarch64")]
1190 assert!(features.neon);
1191
1192 println!("Detected CPU features: {:?}", features);
1193 }
1194
1195 #[test]
1196 fn test_platform_config_creation() {
1197 let config = PlatformConfig::default();
1198
1199 assert_eq!(config.optimization_level, OptimizationLevel::Standard);
1200 assert!(config.hardware_acceleration);
1201 assert!(!config.realtime_priority);
1202 assert!(config.memory_optimization);
1203 assert!(config.power_management);
1204 assert_eq!(config.buffer_alignment, 64);
1205 assert!(config.vectorization);
1206 }
1207
1208 #[test]
1209 fn test_platform_config_builder() {
1210 let config = PlatformConfig::default()
1211 .with_optimization_level(OptimizationLevel::Maximum)
1212 .with_hardware_acceleration(false)
1213 .with_realtime_priority(true)
1214 .with_thread_affinity(0xFF)
1215 .with_buffer_alignment(128)
1216 .with_vectorization(false);
1217
1218 assert_eq!(config.optimization_level, OptimizationLevel::Maximum);
1219 assert!(!config.hardware_acceleration);
1220 assert!(config.realtime_priority);
1221 assert_eq!(config.thread_affinity, Some(0xFF));
1222 assert_eq!(config.buffer_alignment, 128);
1223 assert!(!config.vectorization);
1224 }
1225
1226 #[test]
1227 fn test_optimization_levels() {
1228 let levels = vec![
1229 OptimizationLevel::None,
1230 OptimizationLevel::Basic,
1231 OptimizationLevel::Standard,
1232 OptimizationLevel::Aggressive,
1233 OptimizationLevel::Maximum,
1234 ];
1235
1236 for level in levels {
1237 assert_ne!(format!("{:?}", level), "");
1238 }
1239 }
1240
1241 #[test]
1242 fn test_platform_optimizer_creation() {
1243 let config = PlatformConfig::default();
1244 let optimizer = PlatformOptimizer::new(config);
1245
1246 assert!(optimizer.is_ok());
1247 let optimizer = optimizer.unwrap();
1248 assert!(!optimizer.initialized);
1249 assert!(optimizer.cpu_features.core_count > 0);
1250 }
1251
1252 #[test]
1253 fn test_platform_optimizer_initialization() {
1254 let config = PlatformConfig::default();
1255 let mut optimizer = PlatformOptimizer::new(config).unwrap();
1256
1257 let result = optimizer.initialize();
1258 assert!(result.is_ok());
1259 assert!(optimizer.initialized);
1260 }
1261
1262 #[test]
1263 fn test_optimization_availability() {
1264 let config = PlatformConfig::default();
1265 let optimizer = PlatformOptimizer::new(config).unwrap();
1266
1267 let simd_available = optimizer.is_optimization_available("simd");
1269
1270 #[cfg(target_arch = "x86_64")]
1271 assert!(simd_available); let vectorization_available = optimizer.is_optimization_available("vectorization");
1275 assert_eq!(vectorization_available, simd_available);
1276
1277 println!("SIMD available: {}", simd_available);
1278 println!("Vectorization available: {}", vectorization_available);
1279 }
1280
1281 #[test]
1282 fn test_audio_processing_optimization() {
1283 let config = PlatformConfig::default();
1284 let mut optimizer = PlatformOptimizer::new(config).unwrap();
1285 optimizer.initialize().unwrap();
1286
1287 let audio = vec![0.1, 0.2, -0.1, 0.05, 0.3, -0.2];
1288 let result = optimizer.optimize_processing(&audio);
1289
1290 assert!(result.is_ok());
1291 let processed = result.unwrap();
1292 assert_eq!(processed.len(), audio.len());
1293
1294 for (original, processed) in audio.iter().zip(processed.iter()) {
1296 assert_ne!(*original, *processed);
1297 assert!((*original - *processed).abs() < 0.1);
1298 }
1299 }
1300
1301 #[test]
1302 fn test_performance_stats_update() {
1303 let config = PlatformConfig::default();
1304 let mut optimizer = PlatformOptimizer::new(config).unwrap();
1305 optimizer.initialize().unwrap();
1306
1307 let audio = vec![0.1; 1000];
1308 let _ = optimizer.optimize_processing(&audio);
1309
1310 let stats = optimizer.get_stats();
1311 assert!(stats.simd_ops_per_sec > 0.0);
1312 assert!(stats.memory_bandwidth >= 0.0);
1313 assert!(stats.cache_hit_rate >= 0.0 && stats.cache_hit_rate <= 1.0);
1314 assert!(stats.thread_efficiency >= 0.0 && stats.thread_efficiency <= 1.0);
1315
1316 println!("Performance stats: {:?}", stats);
1317 }
1318
1319 #[test]
1320 fn test_different_optimization_levels() {
1321 let levels = vec![
1322 OptimizationLevel::None,
1323 OptimizationLevel::Basic,
1324 OptimizationLevel::Standard,
1325 OptimizationLevel::Aggressive,
1326 OptimizationLevel::Maximum,
1327 ];
1328
1329 let audio = vec![0.1, 0.2, -0.1, 0.05];
1330
1331 for level in levels {
1332 let config = PlatformConfig::default().with_optimization_level(level.clone());
1333 let mut optimizer = PlatformOptimizer::new(config).unwrap();
1334 optimizer.initialize().unwrap();
1335
1336 let result = optimizer.optimize_processing(&audio);
1337 assert!(
1338 result.is_ok(),
1339 "Failed with optimization level: {:?}",
1340 level
1341 );
1342
1343 let processed = result.unwrap();
1344 assert_eq!(processed.len(), audio.len());
1345
1346 println!(
1347 "Optimization level {:?}: processed {} samples",
1348 level,
1349 processed.len()
1350 );
1351 }
1352 }
1353
1354 #[cfg(target_os = "windows")]
1355 #[test]
1356 fn test_windows_audio_capabilities() {
1357 let capabilities = windows::detect_windows_audio_capabilities();
1358
1359 assert!(!capabilities.is_empty());
1360 assert!(capabilities.contains_key(&windows::WindowsAudioAPI::WASAPI));
1361 assert!(capabilities.contains_key(&windows::WindowsAudioAPI::DirectSound));
1362 assert!(capabilities.contains_key(&windows::WindowsAudioAPI::MME));
1363
1364 println!("Windows audio capabilities: {:?}", capabilities);
1365 }
1366
1367 #[cfg(target_os = "macos")]
1368 #[test]
1369 fn test_macos_audio_capabilities() {
1370 let capabilities = macos::detect_macos_audio_capabilities();
1371
1372 assert!(!capabilities.is_empty());
1373 assert!(capabilities.contains_key(&macos::MacOSAudioFramework::CoreAudio));
1374 assert!(capabilities.contains_key(&macos::MacOSAudioFramework::AudioUnits));
1375
1376 println!("macOS audio capabilities: {:?}", capabilities);
1377 }
1378
1379 #[cfg(target_os = "linux")]
1380 #[test]
1381 fn test_linux_audio_capabilities() {
1382 let capabilities = linux::detect_linux_audio_capabilities();
1383
1384 assert!(!capabilities.is_empty());
1385 let has_audio = capabilities.values().any(|&available| available);
1387 assert!(has_audio, "No audio system detected on Linux");
1388
1389 println!("Linux audio capabilities: {:?}", capabilities);
1390 }
1391
1392 #[test]
1393 fn test_platform_stats_default() {
1394 let stats = PlatformStats::default();
1395
1396 assert_eq!(stats.simd_ops_per_sec, 0.0);
1397 assert_eq!(stats.memory_bandwidth, 0.0);
1398 assert_eq!(stats.cache_hit_rate, 0.0);
1399 assert_eq!(stats.thread_efficiency, 0.0);
1400 assert_eq!(stats.power_consumption, 0.0);
1401 assert_eq!(stats.thermal_throttling, 0);
1402 assert_eq!(stats.page_faults_per_sec, 0.0);
1403 assert_eq!(stats.context_switches_per_sec, 0.0);
1404 }
1405
1406 #[test]
1407 fn test_buffer_alignment() {
1408 let config = PlatformConfig::default().with_buffer_alignment(256);
1409 let mut optimizer = PlatformOptimizer::new(config).unwrap();
1410 optimizer.initialize().unwrap();
1411
1412 let buffer = optimizer.allocate_aligned_buffer(1024);
1413 assert!(buffer.is_ok());
1414
1415 let buffer = buffer.unwrap();
1416 assert_eq!(buffer.len(), 1024);
1417 assert!(buffer.iter().all(|&x| x == 0.0));
1418 }
1419}