]> OzVa Git service - rust_fft/commitdiff
Added build sript and started working on c++ perspective transformer
authorwill <greenwoodw50@gmail.com>
Sat, 26 Oct 2024 14:07:58 +0000 (15:07 +0100)
committerwill <greenwoodw50@gmail.com>
Sat, 26 Oct 2024 14:07:58 +0000 (15:07 +0100)
.gitignore
Cargo.lock
Cargo.toml
src/build.rs [new file with mode: 0644]
src/camera.cpp [new file with mode: 0644]
src/main.rs

index ea8c4bf7f35f6f77f75d92ad8ce8349f6e81ddba..96804589f64a93b4d781badac893005c79caf765 100644 (file)
@@ -1 +1,2 @@
 /target
+camera.a
index 4e4b4f321983112a04f805fed610fbd5fa3c2fac..ba08d99ae763dfdea02cbbeaecd08e21210228ce 100644 (file)
@@ -267,9 +267,9 @@ dependencies = [
 
 [[package]]
 name = "cc"
-version = "1.1.18"
+version = "1.1.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476"
+checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f"
 dependencies = [
  "jobserver",
  "libc",
@@ -1503,6 +1503,7 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
 name = "rust_fft"
 version = "0.1.0"
 dependencies = [
+ "cc",
  "cpal",
  "hound",
  "rustfft",
index 42c75ef602210b488ff5d0539e22edbca247e20d..83fab88cae716e0436b79243556d5af50624e5ad 100644 (file)
@@ -2,9 +2,14 @@
 name = "rust_fft"
 version = "0.1.0"
 edition = "2021"
+build = "src/build.rs"
+include = ["src/camera.cpp"]
 
 [dependencies]
 rustfft = "6.2.0"
 show-image = "0.14.0"
 hound = "3.5.1"
 cpal = "0.15.3"
+
+[build-dependencies]
+cc = "1.0"
diff --git a/src/build.rs b/src/build.rs
new file mode 100644 (file)
index 0000000..0f5bf50
--- /dev/null
@@ -0,0 +1,7 @@
+fn main() {
+       cc::Build::new()
+               .cpp(true)
+               .file("src/camera.cpp")
+               .compile("camera.a");
+       println!("cargo:rerun-if-changed=src/camera.cpp");
+}
diff --git a/src/camera.cpp b/src/camera.cpp
new file mode 100644 (file)
index 0000000..74233cf
--- /dev/null
@@ -0,0 +1,21 @@
+#include <iostream>
+#include <string>
+
+using std::size_t;
+using std::uint8_t;
+
+const size_t WINDOW_SIZE = 128;
+const size_t CHUNK_SIZE = 72;
+const size_t SPECTOGRAM_AREA = WINDOW_SIZE * CHUNK_SIZE;
+
+extern "C" {
+       uint8_t GetData(size_t *ptr) {
+               uint8_t image[SPECTOGRAM_AREA * 3];
+               for (uint8_t i : image) {
+                       i = *ptr;
+                       ptr++;
+               }
+               uint8_t value = image[1];
+               return value;
+       }
+}
index d74aa90768c66c9c388271cd2c7c2ad907fdbb0e..f9e048caa037b94c0aca6321ef070b8afc7065bc 100644 (file)
@@ -25,12 +25,6 @@ const VOLUME_MAX: f32 = 100.0; // 60 - 65
 const VOLUME_MIN: f32 = -40.0;
 const VOLUME_REL: f32 = VOLUME_MAX - VOLUME_MIN;
 
-// have 2 image arrays that are read from and process line by line when neccicary
-// increece the buffer size of the audio output to make it work
-// mutex counter for the row that is currently to process
-// when it reaches the last row it locks both images and switches them over
-// then sends a message to the main thread to process -> show -> capture a new image
-
 struct ImageArray {
        data: [u8; SPECTOGRAM_AREA * 3],
        chunks: usize
@@ -100,126 +94,116 @@ impl ImageArray {
        }
 }
 
-struct SwitchSpace {
-       write_zone: Arc<Mutex<Vec<Complex<f32>>>>,
-       read_zone: Arc<Mutex<Vec<Complex<f32>>>>,
-       storage: [i16; WINDOW_SIZE*2],
-       inverse_transform: Radix4::<f32>,
-       scratch: Vec<Complex<f32>>,
-       counter: Arc<Mutex<usize>>,
+struct SampleBuffer {
+       buffer: Arc<Mutex<[i16; 2 * SPECTOGRAM_AREA]>>,
+       index: usize,
        tx: Sender<bool>
 }
 
-impl SwitchSpace {
-       fn new (write_zone: Arc<Mutex<Vec<Complex<f32>>>>, tx: Sender<bool>) -> Self {
+impl SampleBuffer {
+       fn new(buffer: Arc<Mutex<[i16; 2 * SPECTOGRAM_AREA]>>, tx: Sender<bool>) -> Self {
                Self {
-                       write_zone,
-                       read_zone: Arc::new(Mutex::new(vec![Complex{re: 0f32, im: 0f32}; SPECTOGRAM_AREA])),
-                       storage: [0i16; WINDOW_SIZE*2],
-
-                       inverse_transform: Radix4::<f32>::new(WINDOW_SIZE, FftDirection::Inverse),
-
-                       scratch: vec![
-                               Complex{re: 0f32, im: 0f32};
-                               Radix4::<f32>::new(
-                                       WINDOW_SIZE,
-                                       FftDirection::Inverse
-                               ).get_inplace_scratch_len()
-                       ],
-
-                       counter: Arc::new(Mutex::new(0usize)),
+                       buffer,
+                       index: 0,
                        tx
                }
        }
 
-       fn get_data(&mut self, data: &mut [i16], _: &cpal::OutputCallbackInfo) {
-               let mut counter = self.counter.lock().unwrap();
-
-               {
-                       let mut read_chunk = self.read_zone.lock().unwrap();
-
-                       self.inverse_transform.process_with_scratch(&mut read_chunk[*counter..*counter+WINDOW_SIZE], &mut self.scratch);
+       fn get_data(&mut self, data: &mut [i16]) {
+               let mut buffer = self.buffer.lock().unwrap();
+               let length = data.len()/2;
 
-                       println!("Writing {} data points...", data.len());
-                       for (i, x) in data.chunks_mut(2).enumerate() {
-                               let value = read_chunk[*counter + i].re as i16;
-                               for sample in x.iter_mut() {
-                                       *sample = value;
-                               }
-                       }
+               for i in 0..length {
+                       data[i*2] = buffer[i + self.index];
                }
 
-               if *counter == CHUNK_SIZE {
-                       println!("Read space empty... Running switch...");
-                       let origional_write = self.write_zone.clone();
-                       self.write_zone = self.read_zone.clone();
-                       self.read_zone = origional_write.clone();
+               self.index += length;
+               if self.index > SPECTOGRAM_AREA {
+                       for i in 0..SPECTOGRAM_AREA {
+                               buffer[i] = buffer[i + SPECTOGRAM_AREA];
+                       }
+                       self.index -= SPECTOGRAM_AREA;
 
-                       *counter = 0;
                        let _ = self.tx.send(true);
-               } else {
-                       *counter += 1;
                }
        }
 }
 
+extern "C" {
+  fn GetData(ptr: usize) -> usize;
+}
+
 #[show_image::main]
 fn main () -> Result<(), Box<dyn std::error::Error>> {
 
        let forward_transform = Radix4::<f32>::new(WINDOW_SIZE, FftDirection::Forward);
+       let inverse_transform = Radix4::<f32>::new(WINDOW_SIZE, FftDirection::Inverse);
        let scratch_size = forward_transform.get_inplace_scratch_len();
 
-       let write_space = Arc::new(Mutex::new(vec![Complex{re: 0f32, im: 0f32}; SPECTOGRAM_AREA]));
+       let mut buffer = vec![Complex{re: 0f32, im: 0f32}; SPECTOGRAM_AREA];
        let mut scratch = vec![Complex{re: 0f32, im: 0f32}; scratch_size];
+
        let (tx, rx) = mpsc::channel();
-       let mut switch = SwitchSpace::new(write_space.clone(), tx);
+       let sample_buffer = Arc::new(Mutex::new([0i16; 2*SPECTOGRAM_AREA]));
+       let mut samples = SampleBuffer::new(sample_buffer.clone(), tx);
 
        let mut image_array = ImageArray::new();
 
        let window = create_window("image", Default::default())?;
 
+       let mut reader = hound::WavReader::open("/home/will/Downloads/Adducci - Around the Horn.wav").unwrap();
+       let file_rate = reader.spec().sample_rate;
+
        let host = cpal::default_host();
        let device = host.default_output_device().expect("No output device available");
 
        let stream = device.build_output_stream(
                &StreamConfig{
                        channels: 2,
-                       sample_rate: SampleRate{0: 22_050},
+                       sample_rate: SampleRate{0: file_rate},
                        buffer_size: BufferSize::Fixed(WINDOW_SIZE as u32)
                },
-               move |data: &mut [i16], info: &cpal::OutputCallbackInfo| {
-                       switch.get_data(data, info);
+               move |data: &mut [i16], _: &cpal::OutputCallbackInfo| {
+                       samples.get_data(data);
                },
                move |err| {
                        eprintln!("an error occurred on the output audio stream: {}", err);
                },
                None
        ).unwrap();
-
        stream.play().expect("Stream pay failed");
 
-       let mut reader = hound::WavReader::open("/home/will/Downloads/Adducci - Around the Horn.wav").unwrap();
        let mut i = 0;
        for sample in reader.samples::<i16>() {
-               let mut buffer = write_space.lock().unwrap();
                if i == SPECTOGRAM_AREA {
 
-                       forward_transform.process_with_scratch(&mut *buffer, &mut scratch);
+                       forward_transform.process_with_scratch(&mut buffer, &mut scratch);
                        for x in buffer.iter_mut() {
                                *x *= 1f32 / WINDOW_SIZE as f32;
                        }
-                       image_array.from_buffer(&*buffer);
+                       image_array.from_buffer(&mut buffer);
 
                        let image = ImageView::new(ImageInfo::rgb8(WINDOW_SIZE as u32, CHUNK_SIZE as u32), &image_array.data);
                        window.set_image ("image", image)?;
 
-                       image_array.to_buffer(&mut *buffer);
+                       unsafe{
+                               println!("First value: {}", image_array.data[1]);
+                               println!("Origional: {}", image_array.data.as_ptr() as usize);
+                               println!("Read first value: {}", GetData(image_array.data.as_ptr() as usize));
+                       }
 
-                       i = 0;
+                       image_array.to_buffer(&mut buffer);
 
-                       println!("Waiting for signal...");
-                       if rx.recv().unwrap() {()}
-                       println!("Signal recevied!");
+                       inverse_transform.process_with_scratch(&mut *buffer, &mut scratch);
+
+                       if rx.recv().unwrap() {
+                               let mut write_buffer = sample_buffer.lock().unwrap();
+                               for (i, x) in write_buffer[SPECTOGRAM_AREA..].iter_mut().enumerate() {
+                                       *x = buffer[i].re as i16;
+                               }
+                       }
+
+                       i = 0;
                }
                let value = match sample {
                        Ok(t) => t,