Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
akshithio committed Sep 17, 2024
2 parents 5a3db88 + 05c30cf commit aa613be
Show file tree
Hide file tree
Showing 26 changed files with 592 additions and 362 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@ jobs:
- uses: actions/checkout@v3

- name: test
run: cargo test --verbose
run: cargo test --verbose

- name: no-std test
run: cargo test --verbose --no-default-features
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[![MIT](https://img.shields.io/github/license/purdue-orbital/SuperDSP)](../master/LICENSE)
[![Tests](https://img.shields.io/github/actions/workflow/status/purdue-orbital/SuperDSP/test.yml?label=Tests)](https://github.com/purdue-orbital/SuperDSP/actions)

# SuperDSP (WIP)

This library is a very work in progress, and the interface currently is subject to changes.
Expand Down
36 changes: 17 additions & 19 deletions examples/bladerf_waterfall/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
// use superdsp::gui::time_chart_complex::TimeChartComplex;
// //use superdsp::gui::waterfall::Waterfall;
// use superdsp::objects::object::DSPObject;
// use superdsp::radios;
//
//
//
// fn main() {
// let mut src = radios::bladerf::src::BladeRfSrc::new(915000000, 1_000_000, 1_000_000, 1_000_000, 1024);
// let mut chart = TimeChartComplex::new();
// //let mut waterfall = Waterfall::new(1024);
//
// let s = src.get_bus();
//
// waterfall.set_bus(s);
// chart.set_bus(s);
//
// superdsp::objects::GUIExecutor::run(vec![Box::new(waterfall), Box::new(chart)], Box::new(src));
// }
use superdsp::gui::time_chart_complex::TimeChartComplex;
use superdsp::gui::waterfall::Waterfall;
use superdsp::objects::object::DSPObject;
use superdsp::radios;

fn main() {
let mut src = radios::bladerf::src::BladeRfSrc::new(915000000, 1_000_000, 1_000_000, 1_000_000, 1024);
let mut chart = TimeChartComplex::new();
let mut waterfall = Waterfall::new();

let s = src.get_bus();

waterfall.set_bus(s);
chart.set_bus(s);

superdsp::objects::GUIExecutor::run(vec![Box::new(waterfall), Box::new(chart)], Box::new(src));
}
17 changes: 13 additions & 4 deletions examples/wave_generator/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
use superdsp::gui::slider::Slider;
use superdsp::gui::time_chart::TimeChart;
use superdsp::objects::GUIExecutor;
use superdsp::objects::object::DSPObject;
use superdsp::objects::object::{Bus, DSPObject};
use superdsp::objects::wave_gen_time::WaveStepGenTime;

fn main() {
let mut wave_step_gen = WaveStepGenTime::new(440.0, 1.0, 0.0, 44100.0);
let mut chart = TimeChart::new();
let mut frequency = Bus::from_f32(200.0);
let amplitude = Bus::from_f32(1.0);
let phase = Bus::from_f32(0.0);
let sample_rate = Bus::from_f32(441.0);

let mut slider = Slider::new(0.0, 100.0);
slider.set_bus(&mut frequency);

let mut wave_step_gen = WaveStepGenTime::new(frequency, amplitude, phase, sample_rate);
let mut chart = TimeChart::new();

let s = wave_step_gen.get_bus();
chart.set_bus(s);

GUIExecutor::run(vec![Box::new(chart)], Box::new(wave_step_gen));
GUIExecutor::run(vec![Box::new(chart), Box::new(slider)], Box::new(wave_step_gen));
}
21 changes: 14 additions & 7 deletions examples/wave_generator_complex_waterfall/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
#![feature(generic_const_exprs)]

use superdsp::gui::slider::Slider;
use superdsp::gui::waterfall::Waterfall;
use superdsp::objects::GUIExecutor;
use superdsp::objects::object::DSPObject;
use superdsp::objects::object::{Bus, DSPObject};
use superdsp::objects::wave_gen_time_complex::WaveStepGenTimeComplex;
use std::thread;

fn main() {
let mut waterfall:Waterfall<256> = Waterfall::new();
let mut gen = WaveStepGenTimeComplex::new(8.0, 1.0, 0.0, 16.0);
let mut frequency = Bus::from_f32(1.0);
let amplitude = Bus::from_f32(1.0);
let phase = Bus::from_f32(0.0);
let sample_rate = Bus::from_f32(441.0);

let mut waterfall: Waterfall<256> = Waterfall::new();
let mut slider = Slider::new(0.0,100.0);

slider.set_bus(&mut frequency);

let mut gen = WaveStepGenTimeComplex::new(frequency, amplitude, phase, sample_rate);

waterfall.set_bus(gen.get_bus());
GUIExecutor::run(vec![Box::new(waterfall)], Box::new(gen))
GUIExecutor::run(vec![Box::new(waterfall), Box::new(slider)], Box::new(gen))
}
5 changes: 2 additions & 3 deletions src/filters_and_windows/blackman.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
///
/// # Arguments
/// N: usize - Size of the filter
/// l: usize - Filter setting (N, N+1, or N+2)
/// offset: usize - Bin offset
///
/// # Returns
Expand All @@ -20,8 +19,8 @@ pub fn blackman_window<const N: usize>(offset: usize) -> [f32; N] {
let a2 = 0.08;

for n in 0..N {
filter[n] = a0 - a1 * f32::cos((2.0 * std::f32::consts::PI * ((n - offset) as f32) ) / (N as f32))
+ a2 * f32::cos((4.0 * std::f32::consts::PI * ((n - offset) as f32)) / (N as f32));
filter[n] = a0 - a1 * f32::cos((2.0 * core::f32::consts::PI * ((n - offset) as f32) ) / (N as f32))
+ a2 * f32::cos((4.0 * core::f32::consts::PI * ((n - offset) as f32)) / (N as f32));
}

filter
Expand Down
2 changes: 1 addition & 1 deletion src/filters_and_windows/blackman_nuttall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/// # Returns
/// [f32; N] - Blackman-Nuttal window
///
use std::f32;
use core::f32;

pub fn blackman_nuttall<const N: usize>(offset: usize) -> [f32; N] {
let mut filter = [0.0; N];
Expand Down
8 changes: 4 additions & 4 deletions src/filters_and_windows/hamming.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// This function is based on the triangle filter function from wikipedia found here: https://en.wikipedia.org/wiki/Window_function

/// Creates a triangle filter of size N
/// Formula: f(x) = 1 - |((n - o) - (N / 2)) / (L / 2)| for n in 0..N
/// Creates a hamming window of size N
/// Formula: f(x) = (25.0/46.0) - ((1 - (25.0/46.0)) * cos((2*pi*(n - offset))/N)) for n in 0..N
///
/// Where:
/// L can be N, N+1, or N+2
Expand All @@ -14,14 +14,14 @@
///
/// # Returns
/// [f32; N] - Triangle window\
pub fn triangle_window<const N: usize>(l: usize, offset: usize) -> [f32; N] {
pub fn hamming_window<const N: usize>(l: usize, offset: usize) -> [f32; N] {
let mut filter = [0.0; N];

let a_nought: f32 = 25.0/46.0;
let float_large_n: f32 = N as f32;

for n in 0..N {
let float_small_n = n as f32;
let float_small_n = n as f32 - offset as f32;
filter[n] = a_nought - (1.0-a_nought) * libm::cosf((2.0*core::f32::consts::PI*float_small_n)/float_large_n);
}

Expand Down
1 change: 1 addition & 0 deletions src/filters_and_windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pub mod blackman_nuttall;
pub mod gaussian_window;
pub mod hamming;
pub mod triangle;
pub mod sin;
25 changes: 25 additions & 0 deletions src/filters_and_windows/sin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// This function is based on the sin filter function from wikipedia found here: https://en.wikipedia.org/wiki/Window_function
/// Creates a triangle filter of size N
/// Formula: f(x) = sinf(pi*(n-o)/N) for n in 0..N
///
/// Where:
/// o is the bin offset
///
/// # Arguments
/// N: usize - Size of the filter
/// offset: usize - Bin offset
///
/// # Returns
/// [f32; N] - Sin window
///
use std::f32::consts::PI;

pub fn sin_window<const N: usize>(offset: usize) -> [f32; N] {
let mut filter = [0.0; N];

for n in 0..N {
filter[n] = (PI*(n-offset) as f32 /N as f32).sin();
}

filter
}
12 changes: 7 additions & 5 deletions src/filters_and_windows/triangle.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
// This function is based on the triangle filter function from wikipedia found here: https://en.wikipedia.org/wiki/Window_function

use core::f32::consts::PI;

/// Creates a triangle filter of size N
/// Formula: f(x) = 1 - |((n - o) - (N / 2)) / (L / 2)| for n in 0..N
///
///
/// Where:
/// L can be N, N+1, or N+2
/// o is the bin offset
///
///
/// # Arguments
/// N: usize - Size of the filter
/// l: usize - Filter setting (N, N+1, or N+2)
/// offset: usize - Bin offset
///
///
/// # Returns
/// [f32; N] - Triangle window
pub fn triangle_window<const N: usize>(l: usize, offset: usize) -> [f32; N] {
let mut filter = [0.0; N];

for n in 0..N {
filter[n] = 1.0 - (((n - offset) as f32 - (N as f32 / 2.0)) / (l as f32 / 2.0)).abs();
}

filter
}
3 changes: 3 additions & 0 deletions src/gui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ use crate::objects::object::DSPObject;
pub mod time_chart;
pub mod time_chart_complex;
pub mod waterfall;
pub mod slider;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Message {
Tick,
SliderChanged,
}

pub trait DSPChart: DSPChartClone + DSPObject {
Expand Down Expand Up @@ -91,6 +93,7 @@ impl Application for GUI {
let _ = element.update(_message);
});
}
_ => {}
}
Command::none()
}
Expand Down
76 changes: 76 additions & 0 deletions src/gui/slider.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use iced::Command;
use plotters_iced::{Chart, ChartBuilder, DrawingBackend};

use crate::gui::{DSPChart, Message};
use crate::objects::object::{Bus, DSPObject, Type};

#[derive(Clone)]
pub struct Slider {
bus: Bus<'static>,
min: f32,
max: f32,
}

impl Slider {
pub fn new(min: f32, max: f32) -> Slider {
Slider {
bus: Bus::new_complex(),
min,
max,
}
}
}

impl Default for Slider {
fn default() -> Self {
Self::new(0.0, 10.0)
}
}

impl Chart<Message> for Slider {
type State = ();

fn build_chart<DB: DrawingBackend>(&self, state: &Self::State, mut builder: ChartBuilder<DB>) {}
}

impl DSPObject for Slider {
fn return_type(&self) -> Type {
Type::Complex
}

fn input_type(&self) -> Type {
Type::Complex
}

fn get_bus(&mut self) -> &mut Bus<'static> {
&mut self.bus
}

fn set_bus(&mut self, bus: &mut Bus<'static>) {
self.bus = *bus;
bus.subscribe(self);
}

fn start(&mut self) {
panic!("Charts can not be root object");
}

fn process(&mut self) {}
}

impl DSPChart for Slider {
type Message = Message;
type State = ();

fn view(&self) -> iced::Element<Self::Message> {
iced::widget::Slider::new(self.min..=self.max,*self.bus.buffer_f32.unwrap().read(), |value| {
self.bus.trigger_f32(value);
Message::SliderChanged
}).into()
}

fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
Command::none()
}
}

Loading

0 comments on commit aa613be

Please sign in to comment.