changeset 1:9a493071e98f

Move lib source into a subdir Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Wed, 20 May 2020 23:15:44 -0400
parents e15b331f3209
children 72faa753b634
files Cargo.toml src/fmt.rs src/fmt/cf32.rs src/fmt/cu8.rs src/io.rs src/io/cf32.rs src/io/cu8.rs src/lib.rs src/lib/fmt.rs src/lib/fmt/cf32.rs src/lib/fmt/cu8.rs src/lib/io.rs src/lib/io/cf32.rs src/lib/io/cu8.rs src/lib/lib.rs
diffstat 15 files changed, 441 insertions(+), 437 deletions(-) [+]
line wrap: on
line diff
--- a/Cargo.toml	Sat May 09 11:17:08 2020 -0400
+++ b/Cargo.toml	Wed May 20 23:15:44 2020 -0400
@@ -5,6 +5,10 @@
 edition = "2018"
 license = "MIT"
 
+[lib]
+name = "rdsp"
+path = "src/lib/lib.rs"
+
 [dependencies]
 num-complex = "*"
 num-traits = "*"
--- a/src/fmt.rs	Sat May 09 11:17:08 2020 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-pub mod cf32;
-pub mod cu8;
--- a/src/fmt/cf32.rs	Sat May 09 11:17:08 2020 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-use std::convert::TryInto;
-use super::super::IQSample;
-
-pub const SAMPLE_SIZE: usize = std::mem::size_of::<f32>() * 2;
-
-pub fn raw_to_iqsample(sample: &[u8; SAMPLE_SIZE]) -> IQSample {
-        IQSample::new(f32::from_le_bytes(sample[..4].try_into().unwrap()) as f64,
-                      f32::from_le_bytes(sample[4..].try_into().unwrap()) as f64)
-}
--- a/src/fmt/cu8.rs	Sat May 09 11:17:08 2020 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-use super::super::IQSample;
-
-pub const SAMPLE_SIZE: usize = std::mem::size_of::<u8>() * 2;
-
-pub fn raw_to_iqsample(sample: &[u8; SAMPLE_SIZE]) -> IQSample {
-        let i = (((sample[0] ^ 0x80) as i8) as f64) / 128.;
-        let q = (((sample[1] ^ 0x80) as i8) as f64) / 128.;
-
-        IQSample::new(i, q)
-}
-
-#[cfg(test)]
-mod tests {
-    use super::super::super::IQSample;
-
-    /*
-     * minimum and maximum values we should ever encouter
-     *
-     * This is not balanced because we have an even number of possible input values (256) one of
-     * which must represent 0.  This leaves 255 values which cannot be divided in half between
-     * positive and negative "sides".
-     */
-    const MIN: f64 = -128. / 128.;
-    const MAX: f64 = 127. / 128.;
-
-    #[test]
-    fn test_raw_to_iqsample_specific() {
-        let test_cases = vec![
-            ([ 0x80, 0x80 ], IQSample::new(0., 0.)),
-            ([ 0x00, 0xff ], IQSample::new(MIN, MAX)),
-            ([ 0xff, 0x00 ], IQSample::new(MAX, MIN)),
-        ];
-
-        for (input, expected) in test_cases.iter() {
-            let got = super::raw_to_iqsample(input);
-
-            assert_eq!(got, *expected);
-        }
-    }
-
-    #[test]
-    fn test_raw_to_iqsample_auto() {
-        /* convert an i8 to u8 */
-        fn cvt(v: i8) -> u8 {
-            ((v as i16) + 128) as u8
-        }
-
-        for i in -128..127 {
-            for q in -128..127 {
-                let input = [ cvt(i), cvt(q) ];
-                println!("{} {} => {:?}", i,q,input);
-                let i = (i as f64) / 128.;
-                let q = (q as f64) / 128.;
-
-                let got = super::raw_to_iqsample(&input);
-
-                assert_eq!(got, IQSample::new(i, q));
-            }
-        }
-    }
-}
--- a/src/io.rs	Sat May 09 11:17:08 2020 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-mod cf32;
-mod cu8;
-
-use std::iter::Iterator;
-use std::fs::File;
-use std::io::BufReader;
-use std::path::Path;
-use num_traits::identities::Zero;
-
-pub use self::cf32::CF32File;
-pub use self::cu8::CU8File;
-
-use super::IQSample;
-
-pub trait IQFile {
-    type SamplesIter : IQSampleIter + Iterator<Item=IQSample> + Sized;
-
-    fn path(&self) -> &Path;
-
-    /* how many bytes we need for 1 second of data */
-    fn capacity(&self, secs: usize) -> usize;
-
-    fn buffered_reader(&self) -> Result<BufReader<File>, std::io::Error> {
-        let f = File::open(self.path())?;
-
-        Ok(BufReader::with_capacity(self.capacity(1), f))
-    }
-
-    fn chunks(&self, chunk_size: usize) -> Result<IQChunkIter<Self::SamplesIter>, std::io::Error> {
-        Ok(IQChunkIter::new(self.samples()?, chunk_size))
-    }
-
-    fn samples(&self) -> Result<Self::SamplesIter, std::io::Error>;
-}
-
-pub trait IQSampleIter : Iterator { }
-
-pub struct IQChunkIter<T: IQSampleIter<Item=IQSample>> {
-    samples: T,
-    chunk: Vec<IQSample>,
-}
-
-impl<T: IQSampleIter<Item=IQSample>> IQChunkIter<T> {
-    fn new(samples: T, chunk_size: usize) -> IQChunkIter<T> {
-        let mut chunk = Vec::<IQSample>::with_capacity(chunk_size);
-        chunk.resize(chunk_size, IQSample::zero());
-
-        IQChunkIter {
-            samples: samples,
-            chunk: chunk,
-        }
-    }
-}
-
-impl<T: IQSampleIter<Item=IQSample>> Iterator for IQChunkIter<T> {
-    type Item = Vec<IQSample>;
-
-    fn next(&mut self) -> Option<Vec<IQSample>> {
-        let len = self.chunk.len();
-
-        for i in 0..len {
-            match self.samples.next() {
-                None => { return None; },
-                Some(v) => { self.chunk[i] = v; },
-            }
-        }
-
-        /* FIXME: ideally we could return a reference to the buffer to avoid a memory allocation copy */
-        return Some(self.chunk.clone())
-    }
-}
--- a/src/io/cf32.rs	Sat May 09 11:17:08 2020 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-use std::path::{Path, PathBuf};
-use std::fs::File;
-use std::io::BufReader;
-use std::io::Read;
-
-use super::super::fmt::cf32::{SAMPLE_SIZE, raw_to_iqsample};
-use super::super::IQSample;
-use super::IQFile;
-use super::IQSampleIter;
-
-pub struct CF32File {
-    _freq: u64,
-    rate: u64,
-    path: PathBuf,
-}
-
-impl CF32File {
-    pub fn new<P: AsRef<Path>>(fname: P, freq: u64, rate: u64) -> Result<CF32File, std::io::Error> {
-        let mut path = PathBuf::new();
-        path.push(fname);
-
-        Ok(CF32File {
-            _freq: freq,
-            rate: rate,
-            path: path,
-        })
-    }
-}
-
-impl IQFile for CF32File {
-    type SamplesIter = CF32SampleIter;
-
-    fn path(&self) -> &Path {
-        self.path.as_path()
-    }
-
-    fn capacity(&self, secs: usize) -> usize {
-        (self.rate as usize) * SAMPLE_SIZE * secs
-    }
-
-    fn samples(&self) -> Result<Self::SamplesIter, std::io::Error> {
-        let reader = self.buffered_reader()?;
-
-        Ok(CF32SampleIter {
-            reader: reader,
-        })
-    }
-}
-
-pub struct CF32SampleIter {
-    reader: BufReader<File>,
-}
-
-impl Iterator for CF32SampleIter {
-    type Item = IQSample;
-
-    fn next(&mut self) -> Option<IQSample> {
-        let mut buffer = [0u8; SAMPLE_SIZE];
-
-        if self.reader.read_exact(&mut buffer).is_err() {
-            return None;
-        }
-
-        Some(raw_to_iqsample(&buffer))
-    }
-}
-
-impl IQSampleIter for CF32SampleIter { }
--- a/src/io/cu8.rs	Sat May 09 11:17:08 2020 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-use std::path::{Path, PathBuf};
-use std::fs::File;
-use std::io::BufReader;
-use std::io::Read;
-
-use super::super::fmt::cu8::{SAMPLE_SIZE, raw_to_iqsample};
-use super::super::IQSample;
-use super::IQFile;
-use super::IQSampleIter;
-
-pub struct CU8File {
-    _freq: u64,
-    rate: u64,
-    path: PathBuf,
-}
-
-impl CU8File {
-    pub fn new<P: AsRef<Path>>(fname: P, freq: u64, rate: u64) -> Result<CU8File, std::io::Error> {
-        let mut path = PathBuf::new();
-        path.push(fname);
-
-        Ok(CU8File {
-            _freq: freq,
-            rate: rate,
-            path: path,
-        })
-    }
-}
-
-impl IQFile for CU8File {
-    type SamplesIter = CU8SampleIter;
-
-    fn path(&self) -> &Path {
-        self.path.as_path()
-    }
-
-    fn capacity(&self, secs: usize) -> usize {
-        (self.rate as usize) * SAMPLE_SIZE * secs
-    }
-
-    fn samples(&self) -> Result<Self::SamplesIter, std::io::Error> {
-        let reader = self.buffered_reader()?;
-
-        Ok(CU8SampleIter {
-            reader: reader,
-        })
-    }
-}
-
-pub struct CU8SampleIter {
-    reader: BufReader<File>,
-}
-
-impl Iterator for CU8SampleIter {
-    type Item = IQSample;
-
-    fn next(&mut self) -> Option<IQSample> {
-        let mut buffer = [0u8; SAMPLE_SIZE];
-
-        if self.reader.read_exact(&mut buffer).is_err() {
-            return None;
-        }
-
-        Some(raw_to_iqsample(&buffer))
-    }
-}
-
-impl IQSampleIter for CU8SampleIter { }
--- a/src/lib.rs	Sat May 09 11:17:08 2020 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-pub mod io;
-pub mod fmt;
-
-pub type IQSample = num_complex::Complex<f64>;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/fmt.rs	Wed May 20 23:15:44 2020 -0400
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+pub mod cf32;
+pub mod cu8;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/fmt/cf32.rs	Wed May 20 23:15:44 2020 -0400
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+use std::convert::TryInto;
+use super::super::IQSample;
+
+pub const SAMPLE_SIZE: usize = std::mem::size_of::<f32>() * 2;
+
+pub fn raw_to_iqsample(sample: &[u8; SAMPLE_SIZE]) -> IQSample {
+        IQSample::new(f32::from_le_bytes(sample[..4].try_into().unwrap()) as f64,
+                      f32::from_le_bytes(sample[4..].try_into().unwrap()) as f64)
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/fmt/cu8.rs	Wed May 20 23:15:44 2020 -0400
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+use super::super::IQSample;
+
+pub const SAMPLE_SIZE: usize = std::mem::size_of::<u8>() * 2;
+
+pub fn raw_to_iqsample(sample: &[u8; SAMPLE_SIZE]) -> IQSample {
+        let i = (((sample[0] ^ 0x80) as i8) as f64) / 128.;
+        let q = (((sample[1] ^ 0x80) as i8) as f64) / 128.;
+
+        IQSample::new(i, q)
+}
+
+#[cfg(test)]
+mod tests {
+    use super::super::super::IQSample;
+
+    /*
+     * minimum and maximum values we should ever encouter
+     *
+     * This is not balanced because we have an even number of possible input values (256) one of
+     * which must represent 0.  This leaves 255 values which cannot be divided in half between
+     * positive and negative "sides".
+     */
+    const MIN: f64 = -128. / 128.;
+    const MAX: f64 = 127. / 128.;
+
+    #[test]
+    fn test_raw_to_iqsample_specific() {
+        let test_cases = vec![
+            ([ 0x80, 0x80 ], IQSample::new(0., 0.)),
+            ([ 0x00, 0xff ], IQSample::new(MIN, MAX)),
+            ([ 0xff, 0x00 ], IQSample::new(MAX, MIN)),
+        ];
+
+        for (input, expected) in test_cases.iter() {
+            let got = super::raw_to_iqsample(input);
+
+            assert_eq!(got, *expected);
+        }
+    }
+
+    #[test]
+    fn test_raw_to_iqsample_auto() {
+        /* convert an i8 to u8 */
+        fn cvt(v: i8) -> u8 {
+            ((v as i16) + 128) as u8
+        }
+
+        for i in -128..127 {
+            for q in -128..127 {
+                let input = [ cvt(i), cvt(q) ];
+                println!("{} {} => {:?}", i,q,input);
+                let i = (i as f64) / 128.;
+                let q = (q as f64) / 128.;
+
+                let got = super::raw_to_iqsample(&input);
+
+                assert_eq!(got, IQSample::new(i, q));
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/io.rs	Wed May 20 23:15:44 2020 -0400
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+mod cf32;
+mod cu8;
+
+use std::iter::Iterator;
+use std::fs::File;
+use std::io::BufReader;
+use std::path::Path;
+use num_traits::identities::Zero;
+
+pub use self::cf32::CF32File;
+pub use self::cu8::CU8File;
+
+use super::IQSample;
+
+pub trait IQFile {
+    type SamplesIter : IQSampleIter + Iterator<Item=IQSample> + Sized;
+
+    fn path(&self) -> &Path;
+
+    /* how many bytes we need for 1 second of data */
+    fn capacity(&self, secs: usize) -> usize;
+
+    fn buffered_reader(&self) -> Result<BufReader<File>, std::io::Error> {
+        let f = File::open(self.path())?;
+
+        Ok(BufReader::with_capacity(self.capacity(1), f))
+    }
+
+    fn chunks(&self, chunk_size: usize) -> Result<IQChunkIter<Self::SamplesIter>, std::io::Error> {
+        Ok(IQChunkIter::new(self.samples()?, chunk_size))
+    }
+
+    fn samples(&self) -> Result<Self::SamplesIter, std::io::Error>;
+}
+
+pub trait IQSampleIter : Iterator { }
+
+pub struct IQChunkIter<T: IQSampleIter<Item=IQSample>> {
+    samples: T,
+    chunk: Vec<IQSample>,
+}
+
+impl<T: IQSampleIter<Item=IQSample>> IQChunkIter<T> {
+    fn new(samples: T, chunk_size: usize) -> IQChunkIter<T> {
+        let mut chunk = Vec::<IQSample>::with_capacity(chunk_size);
+        chunk.resize(chunk_size, IQSample::zero());
+
+        IQChunkIter {
+            samples: samples,
+            chunk: chunk,
+        }
+    }
+}
+
+impl<T: IQSampleIter<Item=IQSample>> Iterator for IQChunkIter<T> {
+    type Item = Vec<IQSample>;
+
+    fn next(&mut self) -> Option<Vec<IQSample>> {
+        let len = self.chunk.len();
+
+        for i in 0..len {
+            match self.samples.next() {
+                None => { return None; },
+                Some(v) => { self.chunk[i] = v; },
+            }
+        }
+
+        /* FIXME: ideally we could return a reference to the buffer to avoid a memory allocation copy */
+        return Some(self.chunk.clone())
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/io/cf32.rs	Wed May 20 23:15:44 2020 -0400
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+use std::path::{Path, PathBuf};
+use std::fs::File;
+use std::io::BufReader;
+use std::io::Read;
+
+use super::super::fmt::cf32::{SAMPLE_SIZE, raw_to_iqsample};
+use super::super::IQSample;
+use super::IQFile;
+use super::IQSampleIter;
+
+pub struct CF32File {
+    _freq: u64,
+    rate: u64,
+    path: PathBuf,
+}
+
+impl CF32File {
+    pub fn new<P: AsRef<Path>>(fname: P, freq: u64, rate: u64) -> Result<CF32File, std::io::Error> {
+        let mut path = PathBuf::new();
+        path.push(fname);
+
+        Ok(CF32File {
+            _freq: freq,
+            rate: rate,
+            path: path,
+        })
+    }
+}
+
+impl IQFile for CF32File {
+    type SamplesIter = CF32SampleIter;
+
+    fn path(&self) -> &Path {
+        self.path.as_path()
+    }
+
+    fn capacity(&self, secs: usize) -> usize {
+        (self.rate as usize) * SAMPLE_SIZE * secs
+    }
+
+    fn samples(&self) -> Result<Self::SamplesIter, std::io::Error> {
+        let reader = self.buffered_reader()?;
+
+        Ok(CF32SampleIter {
+            reader: reader,
+        })
+    }
+}
+
+pub struct CF32SampleIter {
+    reader: BufReader<File>,
+}
+
+impl Iterator for CF32SampleIter {
+    type Item = IQSample;
+
+    fn next(&mut self) -> Option<IQSample> {
+        let mut buffer = [0u8; SAMPLE_SIZE];
+
+        if self.reader.read_exact(&mut buffer).is_err() {
+            return None;
+        }
+
+        Some(raw_to_iqsample(&buffer))
+    }
+}
+
+impl IQSampleIter for CF32SampleIter { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/io/cu8.rs	Wed May 20 23:15:44 2020 -0400
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+use std::path::{Path, PathBuf};
+use std::fs::File;
+use std::io::BufReader;
+use std::io::Read;
+
+use super::super::fmt::cu8::{SAMPLE_SIZE, raw_to_iqsample};
+use super::super::IQSample;
+use super::IQFile;
+use super::IQSampleIter;
+
+pub struct CU8File {
+    _freq: u64,
+    rate: u64,
+    path: PathBuf,
+}
+
+impl CU8File {
+    pub fn new<P: AsRef<Path>>(fname: P, freq: u64, rate: u64) -> Result<CU8File, std::io::Error> {
+        let mut path = PathBuf::new();
+        path.push(fname);
+
+        Ok(CU8File {
+            _freq: freq,
+            rate: rate,
+            path: path,
+        })
+    }
+}
+
+impl IQFile for CU8File {
+    type SamplesIter = CU8SampleIter;
+
+    fn path(&self) -> &Path {
+        self.path.as_path()
+    }
+
+    fn capacity(&self, secs: usize) -> usize {
+        (self.rate as usize) * SAMPLE_SIZE * secs
+    }
+
+    fn samples(&self) -> Result<Self::SamplesIter, std::io::Error> {
+        let reader = self.buffered_reader()?;
+
+        Ok(CU8SampleIter {
+            reader: reader,
+        })
+    }
+}
+
+pub struct CU8SampleIter {
+    reader: BufReader<File>,
+}
+
+impl Iterator for CU8SampleIter {
+    type Item = IQSample;
+
+    fn next(&mut self) -> Option<IQSample> {
+        let mut buffer = [0u8; SAMPLE_SIZE];
+
+        if self.reader.read_exact(&mut buffer).is_err() {
+            return None;
+        }
+
+        Some(raw_to_iqsample(&buffer))
+    }
+}
+
+impl IQSampleIter for CU8SampleIter { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/lib.rs	Wed May 20 23:15:44 2020 -0400
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+pub mod io;
+pub mod fmt;
+
+pub type IQSample = num_complex::Complex<f64>;