clippy on popgen
This commit is contained in:
parent
cc7fcd6761
commit
90da82a8ec
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,3 +7,4 @@ code/project/music/
|
|||||||
code/project/neopixel/
|
code/project/neopixel/
|
||||||
code/project/radio/
|
code/project/radio/
|
||||||
code/project/speech/
|
code/project/speech/
|
||||||
|
*lock
|
@ -4,7 +4,6 @@
|
|||||||
// https://github.com/pdx-cs-sound/popgen/blob/main/popgen.py
|
// https://github.com/pdx-cs-sound/popgen/blob/main/popgen.py
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use hound;
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rodio::{buffer::SamplesBuffer, OutputStream, Sink};
|
use rodio::{buffer::SamplesBuffer, OutputStream, Sink};
|
||||||
@ -33,12 +32,12 @@ const CHORD_LOOP: [u8; 4] = [8, 5, 6, 4];
|
|||||||
// Given a MIDI key number and an optional number of beats of
|
// Given a MIDI key number and an optional number of beats of
|
||||||
// note duration, return a sine wave for that note.
|
// note duration, return a sine wave for that note.
|
||||||
fn make_note(key: i8, n: Option<u8>, beat_samples: u32, samplerate: u16) -> Vec<f32> {
|
fn make_note(key: i8, n: Option<u8>, beat_samples: u32, samplerate: u16) -> Vec<f32> {
|
||||||
let num_beats: f32 = n.unwrap_or(1).try_into().unwrap();
|
let num_beats: f32 = n.unwrap_or(1).into();
|
||||||
let samplerate_f: f32 = samplerate.try_into().unwrap();
|
let samplerate_f: f32 = samplerate.into();
|
||||||
let beatsamples_f: f32 = beat_samples as f32;
|
let beatsamples_f: f32 = beat_samples as f32;
|
||||||
let key_f: f32 = key.try_into().unwrap();
|
let key_f: f32 = key.into();
|
||||||
let f: f32 = 440f32 * (2f32).powf((key_f - 69f32) / 12f32);
|
let f: f32 = 440f32 * (2f32).powf((key_f - 69f32) / 12f32);
|
||||||
let b: u32 = (beat_samples as u32) * (n.unwrap_or(1) as u32);
|
let b: u32 = (beat_samples) * (n.unwrap_or(1) as u32);
|
||||||
let b_f: f32 = beatsamples_f * num_beats;
|
let b_f: f32 = beatsamples_f * num_beats;
|
||||||
|
|
||||||
let cycles: f32 = 2f32 * PI * f * b_f / samplerate_f;
|
let cycles: f32 = 2f32 * PI * f * b_f / samplerate_f;
|
||||||
@ -103,9 +102,9 @@ fn pick_notes(chord_root: u8, position: &mut i8, rng: &mut rand::prelude::Thread
|
|||||||
let chord_note: i8 = note_to_key_offset((chord_root as i8) + chord_note_offset);
|
let chord_note: i8 = note_to_key_offset((chord_root as i8) + chord_note_offset);
|
||||||
*note = chord_note;
|
*note = chord_note;
|
||||||
if rng.gen::<f32>() > 0.5 {
|
if rng.gen::<f32>() > 0.5 {
|
||||||
p = p + 1;
|
p += 1;
|
||||||
} else {
|
} else {
|
||||||
p = p - 1;
|
p = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,29 +130,23 @@ fn parse_note(note_str: &str, regex: Regex) -> u32 {
|
|||||||
let base_note: char = it.next().unwrap();
|
let base_note: char = it.next().unwrap();
|
||||||
let mut flat: bool = false;
|
let mut flat: bool = false;
|
||||||
// Logic to Handle all valid cases, like C, C[4], Db, Db[6], etc.
|
// Logic to Handle all valid cases, like C, C[4], Db, Db[6], etc.
|
||||||
match it.next() {
|
if let Some(c) = it.next() {
|
||||||
Some(c) => {
|
if c == 'b' {
|
||||||
if c == 'b' {
|
flat = true;
|
||||||
flat = true;
|
if let Some(c) = it.next() {
|
||||||
match it.next() {
|
if c == '[' {
|
||||||
Some(c) => {
|
octave = it.next().unwrap().to_digit(10).unwrap();
|
||||||
if c == '[' {
|
} else {
|
||||||
octave = it.next().unwrap().to_digit(10).unwrap();
|
eprintln!("Invalid Notation: {}", note_str);
|
||||||
} else {
|
std::process::exit(1)
|
||||||
eprintln!("Invalid Notation: {}", note_str);
|
|
||||||
std::process::exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
} else if c == '[' {
|
|
||||||
octave = it.next().unwrap().to_digit(10).unwrap();
|
|
||||||
} else {
|
|
||||||
eprintln!("Invalid Notation: {}", note_str);
|
|
||||||
std::process::exit(1)
|
|
||||||
}
|
}
|
||||||
|
} else if c == '[' {
|
||||||
|
octave = it.next().unwrap().to_digit(10).unwrap();
|
||||||
|
} else {
|
||||||
|
eprintln!("Invalid Notation: {}", note_str);
|
||||||
|
std::process::exit(1)
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Different string format for flat vs not
|
// Different string format for flat vs not
|
||||||
@ -164,7 +157,7 @@ fn parse_note(note_str: &str, regex: Regex) -> u32 {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let index_32: u32 = index as u32;
|
let index_32: u32 = index as u32;
|
||||||
let r: u32 = index_32 + (12 * octave);
|
let r: u32 = index_32 + (12 * octave);
|
||||||
return r;
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
@ -188,13 +181,14 @@ struct Args {
|
|||||||
#[arg(short, long, default_value_t = -3)]
|
#[arg(short, long, default_value_t = -3)]
|
||||||
gain: i8,
|
gain: i8,
|
||||||
|
|
||||||
#[arg(short, long, default_value_t = NO_OUTPUT.to_string())] // Ideally there is a better way than this
|
// Ideally there would be a better way than this
|
||||||
|
#[arg(short, long, default_value_t = NO_OUTPUT.to_string())]
|
||||||
output: String,
|
output: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rodio example https://github.com/RustAudio/rodio/blob/master/examples/basic.rs
|
// Rodio example https://github.com/RustAudio/rodio/blob/master/examples/basic.rs
|
||||||
fn play(samples: Vec<f32>, samplerate: u16, gain: i8) {
|
fn play(samples: Vec<f32>, samplerate: u16, _gain: i8) {
|
||||||
// TODO: apply gain
|
// TODO: apply gain correctly
|
||||||
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
|
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
|
||||||
let source: SamplesBuffer<f32> = SamplesBuffer::new(1, samplerate as u32, samples);
|
let source: SamplesBuffer<f32> = SamplesBuffer::new(1, samplerate as u32, samples);
|
||||||
let sink: Sink = Sink::try_new(&stream_handle).unwrap(); //sink makes it easy to keep the program asleep so the whole song plays
|
let sink: Sink = Sink::try_new(&stream_handle).unwrap(); //sink makes it easy to keep the program asleep so the whole song plays
|
||||||
@ -202,8 +196,8 @@ fn play(samples: Vec<f32>, samplerate: u16, gain: i8) {
|
|||||||
sink.sleep_until_end();
|
sink.sleep_until_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save(samples: Vec<f32>, samplerate: u16, output: &str, gain: i8) {
|
fn save(samples: Vec<f32>, samplerate: u16, output: &str, _gain: i8) {
|
||||||
// TODO: apply gain
|
// TODO: apply gain correctly
|
||||||
let spec: hound::WavSpec = hound::WavSpec {
|
let spec: hound::WavSpec = hound::WavSpec {
|
||||||
channels: 1,
|
channels: 1,
|
||||||
sample_rate: samplerate as u32,
|
sample_rate: samplerate as u32,
|
||||||
@ -362,12 +356,7 @@ fn test() {
|
|||||||
Some(1),
|
Some(1),
|
||||||
288000,
|
288000,
|
||||||
48_000,
|
48_000,
|
||||||
[
|
[0.0, 0.017122516431822686, 0.034240012506541136, 0.051347464],
|
||||||
0.0,
|
|
||||||
0.017122516431822686,
|
|
||||||
0.034240012506541136,
|
|
||||||
0.05134746933903016,
|
|
||||||
],
|
|
||||||
)];
|
)];
|
||||||
for (i, (key, n, beat_samples, samplerate, results)) in make_notes_tests.iter().enumerate() {
|
for (i, (key, n, beat_samples, samplerate, results)) in make_notes_tests.iter().enumerate() {
|
||||||
let wave = make_note(*key, *n, *beat_samples, *samplerate);
|
let wave = make_note(*key, *n, *beat_samples, *samplerate);
|
||||||
|
Reference in New Issue
Block a user