Time signature, data structure tweaks
Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
66
src/main.rs
66
src/main.rs
@@ -1,5 +1,5 @@
|
|||||||
use anyhow::{Result, anyhow};
|
use anyhow::{Result, anyhow};
|
||||||
use macroquad::prelude::*;
|
use macroquad::color::*;
|
||||||
use serialport::SerialPortType;
|
use serialport::SerialPortType;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
@@ -12,7 +12,6 @@ pub enum Instruction {
|
|||||||
|
|
||||||
pub struct SerialDevice {
|
pub struct SerialDevice {
|
||||||
port: Box<dyn serialport::SerialPort>,
|
port: Box<dyn serialport::SerialPort>,
|
||||||
ready: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const CHANNEL_COUNT: u8 = 4;
|
const CHANNEL_COUNT: u8 = 4;
|
||||||
@@ -26,18 +25,16 @@ impl SerialDevice {
|
|||||||
SerialPortType::UsbPort(_) => {
|
SerialPortType::UsbPort(_) => {
|
||||||
this = Ok(Self {
|
this = Ok(Self {
|
||||||
port: serialport::new(port.port_name, 115200).open()?,
|
port: serialport::new(port.port_name, 115200).open()?,
|
||||||
ready: true,
|
|
||||||
});
|
});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
fn note_off(&mut self, ch: u8) -> Result<()> {
|
fn note_off(&mut self, ch: u8) -> Result<()> {
|
||||||
assert!(self.ready);
|
|
||||||
assert!((0..CHANNEL_COUNT).contains(&ch));
|
assert!((0..CHANNEL_COUNT).contains(&ch));
|
||||||
let bytes: Vec<u8> = vec![0x80 + ch];
|
let bytes: Vec<u8> = vec![0x80 + ch];
|
||||||
self.port.write(&bytes)?;
|
self.port.write(&bytes)?;
|
||||||
@@ -45,7 +42,6 @@ impl SerialDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn note_on(&mut self, ch: u8, note: u8) -> Result<()> {
|
fn note_on(&mut self, ch: u8, note: u8) -> Result<()> {
|
||||||
assert!(self.ready);
|
|
||||||
assert!((0..CHANNEL_COUNT).contains(&ch));
|
assert!((0..CHANNEL_COUNT).contains(&ch));
|
||||||
assert!((0..=127).contains(¬e));
|
assert!((0..=127).contains(¬e));
|
||||||
let bytes: Vec<u8> = vec![0x90 + ch, note];
|
let bytes: Vec<u8> = vec![0x90 + ch, note];
|
||||||
@@ -54,19 +50,16 @@ impl SerialDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn modulation(&mut self, ch: u8, depth: u8, rate: u8) -> Result<()> {
|
fn modulation(&mut self, ch: u8, depth: u8, rate: u8) -> Result<()> {
|
||||||
assert!(self.ready);
|
|
||||||
assert!((0..CHANNEL_COUNT).contains(&ch));
|
assert!((0..CHANNEL_COUNT).contains(&ch));
|
||||||
assert!((0..=127).contains(&depth));
|
assert!((0..=127).contains(&depth));
|
||||||
assert!((0..=255).contains(&rate));
|
|
||||||
let bytes: Vec<u8> = vec![0xA0 + ch, depth, rate];
|
let bytes: Vec<u8> = vec![0xA0 + ch, depth, rate];
|
||||||
self.port.write(&bytes)?;
|
self.port.write(&bytes)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn frequency_on(&mut self, ch: u8, freq: u16) -> Result<()> {
|
fn frequency_on(&mut self, ch: u8, freq: u16) -> Result<()> {
|
||||||
assert!(self.ready);
|
|
||||||
assert!((0..CHANNEL_COUNT).contains(&ch));
|
assert!((0..CHANNEL_COUNT).contains(&ch));
|
||||||
let bytes: Vec<u8> = vec![0xB0 + ch, (freq & 0xff) as u8, (freq & 0xff00 >> 8) as u8];
|
let bytes: Vec<u8> = vec![0xB0 + ch, (freq & 0xff) as u8, (freq >> 8) as u8];
|
||||||
self.port.write(&bytes)?;
|
self.port.write(&bytes)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -87,28 +80,55 @@ impl SerialDevice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const INSTRUCTIONS_PATTERN: usize = 1024;
|
|
||||||
|
|
||||||
pub struct Pattern {
|
pub struct Pattern {
|
||||||
pub channels: [[Option<Instruction>; INSTRUCTIONS_PATTERN]; CHANNEL_COUNT as usize],
|
pub rows: Vec<[Option<Instruction>; CHANNEL_COUNT as usize]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pattern {
|
impl Pattern {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
let mut rows = Vec::new();
|
||||||
|
rows.resize_with(256, || [None; CHANNEL_COUNT as usize]);
|
||||||
|
Self { rows }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TimeSignature {
|
||||||
|
pub numerator: u8,
|
||||||
|
pub denominator: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for TimeSignature {
|
||||||
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
channels: [[None; INSTRUCTIONS_PATTERN]; CHANNEL_COUNT as usize],
|
numerator: 4,
|
||||||
|
denominator: 4,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Song {
|
pub struct Song {
|
||||||
|
pub bpm: f64,
|
||||||
|
pub time_signature: TimeSignature,
|
||||||
pub patterns: Vec<Pattern>,
|
pub patterns: Vec<Pattern>,
|
||||||
pub pattern_order: Vec<usize>, // index into patterns
|
pub pattern_order: Vec<usize>, // index into patterns
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Song {
|
impl Song {
|
||||||
pub fn new() -> Self {
|
const DEFAULT_BPM: f64 = 120.0;
|
||||||
|
|
||||||
|
pub fn new(bpm: Option<f64>, time_signature: Option<TimeSignature>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
bpm: bpm.unwrap_or(Self::DEFAULT_BPM),
|
||||||
|
time_signature: time_signature.unwrap_or_default(),
|
||||||
|
patterns: vec![Pattern::new()],
|
||||||
|
pattern_order: vec![0],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn empty(bpm: Option<f64>, time_signature: Option<TimeSignature>) -> Self {
|
||||||
|
Self {
|
||||||
|
bpm: bpm.unwrap_or(Self::DEFAULT_BPM),
|
||||||
|
time_signature: time_signature.unwrap_or_default(),
|
||||||
patterns: Vec::new(),
|
patterns: Vec::new(),
|
||||||
pattern_order: Vec::new(),
|
pattern_order: Vec::new(),
|
||||||
}
|
}
|
||||||
@@ -130,14 +150,20 @@ impl App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn update(&self) {
|
async fn update(&self) {
|
||||||
clear_background(RED);
|
macroquad::window::clear_background(WHITE);
|
||||||
|
|
||||||
draw_line(40.0, 40.0, 100.0, 200.0, 15.0, BLUE);
|
macroquad::shapes::draw_line(40.0, 40.0, 100.0, 200.0, 15.0, BLUE);
|
||||||
draw_rectangle(screen_width() / 2.0 - 60.0, 100.0, 120.0, 60.0, GREEN);
|
macroquad::shapes::draw_rectangle(
|
||||||
|
macroquad::window::screen_width() / 2.0 - 60.0,
|
||||||
|
100.0,
|
||||||
|
120.0,
|
||||||
|
60.0,
|
||||||
|
GREEN,
|
||||||
|
);
|
||||||
|
|
||||||
draw_text("Hello, Macroquad!", 20.0, 20.0, 30.0, DARKGRAY);
|
macroquad::text::draw_text("Hello, Macroquad!", 20.0, 20.0, 30.0, DARKGRAY);
|
||||||
|
|
||||||
next_frame().await
|
macroquad::window::next_frame().await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user