added sound generation, this is currently very broken!

This commit is contained in:
Rolf Martin Glomsrud 2023-03-04 23:11:05 +01:00
parent 67090986bb
commit b6c438ae0f
8 changed files with 188 additions and 25 deletions

16
Cargo.lock generated
View file

@ -9,7 +9,6 @@ dependencies = [
"async-trait",
"macroquad",
"tokio-test",
"wav",
]
[[package]]
@ -423,12 +422,6 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "riff"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9b1a3d5f46d53f4a3478e2be4a5a5ce5108ea58b100dcd139830eae7f79a3a1"
[[package]]
name = "smallvec"
version = "0.6.14"
@ -508,15 +501,6 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wav"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a65e199c799848b4f997072aa4d673c034f80f40191f97fe2f0a23f410be1609"
dependencies = [
"riff",
]
[[package]]
name = "winapi"
version = "0.3.9"

View file

@ -9,6 +9,6 @@ edition = "2021"
macroquad = "0.3.25"
async-trait = "0.1.64"
tokio-test = "*"
wav = "1.0.0"
[profile.release]
opt-level=3

View file

@ -1,20 +1,33 @@
use macroquad::audio::PlaySoundParams;
use macroquad::audio::Sound;
use macroquad::audio::play_sound;
use macroquad::audio::play_sound_once;
use macroquad::color;
use macroquad::color_u8;
use macroquad::rand;
use crate::soundGenerator;
#[derive(Debug, Clone, Copy)]
pub struct Bar {
pub position:usize,
pub color:color::Color
pub color:color::Color,
sound:Sound,
}
impl Bar{
pub fn new(position:usize, hsl_color:f32) -> Self{
pub async fn new(position:usize, hsl_color:f32, frequency:f32) -> Self{
Bar{
position,
color: color::hsl_to_rgb((hsl_color as f32) , 1.0, 0.5),
sound:soundGenerator::generateTone(frequency, 0.1).await
}
}
pub fn playSound(&self ){
play_sound(self.sound, PlaySoundParams::default());
}
}

View file

@ -34,7 +34,7 @@ pub struct GuiVec{
#[async_trait]
pub trait SortingList{
fn new(length:usize, delay:f32) -> Self;
async fn new(length:usize, delay:f32) -> Self;
fn len(&self) -> usize;
@ -64,11 +64,13 @@ pub trait SortingList{
#[async_trait]
impl SortingList for GuiVec{
fn new(length:usize, delay:f32) -> Self {
async fn new(length:usize, delay:f32) -> Self {
let colorStep = 360./length as f32;
let mut list:Vec<Bar> = vec!();
let freqStep = 50. + ((2000.-50.)/length as f32);
for i in 1..length+1 {
list.push(Bar::new(i, (colorStep*i as f32)/360.));
let frequency = i as f32 * freqStep;
list.push(Bar::new(i, (colorStep*i as f32)/360., frequency).await);
}
GuiVec{
list,
@ -161,6 +163,8 @@ impl SortingList for GuiVec{
self.writes += 2;
self.reads += 2;
self.list.swap(index1, index2);
self.list[index1].playSound();
//self.list[index2].playSound();
self.lastTouched.clear();
self.lastTouched.push(index1);
self.lastTouched.push(index2);
@ -236,10 +240,10 @@ pub struct NonGuiVec{
}
#[async_trait]
impl SortingList for NonGuiVec{
fn new(length:usize, delay:f32) -> Self{
async fn new(length:usize, delay:f32) -> Self{
let mut list = Vec::new();
for i in 0..(length as usize){
list.push(Bar::new(i, i as f32))
list.push(Bar::new(i, i as f32, 0.0).await)
}
NonGuiVec { list: list }
}

View file

@ -32,7 +32,7 @@ impl Algorithm{
] }
}
pub async fn run(length:usize, delay:f32, functionName:String){
let mut list:GuiVec = SortingList::new(length, delay);
let mut list:GuiVec = SortingList::new(length, delay).await;
list.randomize();

69
src/main.rs Normal file
View file

@ -0,0 +1,69 @@
mod BarPlugin;
mod GuiHookVec;
mod algorithm;
mod dropdown;
mod soundGenerator;
use std::f32::consts::PI;
use std::fs::File;
use std::path::Path;
use dropdown::ButtonDropDown;
use macroquad::audio::PlaySoundParams;
use macroquad::audio::play_sound;
use macroquad::audio::play_sound_once;
use macroquad::prelude::*;
use macroquad::hash;
use macroquad::ui::root_ui;
#[macroquad::main("BeepSort")]
async fn main() {
let mut length = 1_usize;
let mut lengthString = "100".to_owned();
let mut delayText = "1".to_owned();
let mut algorithm = algorithm::Algorithm::new();
let mut buttonDropDown = ButtonDropDown::new(&algorithm.getAlgorithms());
let sound = soundGenerator::generateTone(50., 0.05).await;
loop{
clear_background(WHITE);
length = match lengthString.parse::<usize>(){
Ok(a) => a,
Err(_)=> {100}
};
let mut centerX = screen_width()/2.0;
draw_text("Sorting!", centerX-170.0, screen_height()*0.1, 100.0, BLACK);
draw_text(&get_fps().to_string(), centerX + 300., 30.0, 20.0, BLACK);
root_ui().window(hash!(), Vec2::new(centerX - 150.0, 150.), Vec2::new(300., 45.), |ui|{
ui.input_text(hash!(), "Delay (ms)", &mut delayText);
ui.input_text(hash!(), "Length Of Array!", &mut lengthString);
});
let mut algo = buttonDropDown.render();
if algo != ""{
algorithm::Algorithm::run(length, 1.0, algo.to_string()).await;
}
next_frame().await
}
}

93
src/soundGenerator.rs Normal file
View file

@ -0,0 +1,93 @@
use std::f32::consts::PI;
use macroquad::audio::{Sound, load_sound_from_bytes};
const CHUNK_ID:&str = "RIFF";
const CHUNK_SIZE:&str = "----";
const FORMAT:&str = "WAVE";
//FMT sub-chunk
const SUBCHUNK_1_ID:&str = "fmt ";
const SUBCHUNK_1_SIZE:usize = 16;
const AUDIO_FORMAT:usize = 1;
const NUM_CHANNELS:usize = 1;
const SAMPLE_RATE:usize = 44100;
const BYTE_RATE:usize = SAMPLE_RATE * NUM_CHANNELS * (SUBCHUNK_1_SIZE / 8);
const BLOACK_ALIGN:usize = NUM_CHANNELS * (SUBCHUNK_1_SIZE / 8);
const BITS_PR_SAMPLE:usize = 16;
//Data sub-chunk
const SUBCHUNK_2_ID:&str = "data";
const SUBCHUNK_2_SIZE:&str = "----";
const MAX_AMPLITUDE:usize = 32760;
fn write_as_bytes(vec:&mut Vec<u8>, value:usize, byte_size:u8){
let mut bytes = value.to_le_bytes();
vec.append(&mut bytes[0..byte_size as usize].to_vec());
}
pub async fn generateTone(frequency: f32, duration:f32) -> Sound{
let mut soundFileBytes = Vec::new();
soundFileBytes.append(&mut CHUNK_ID.clone().as_bytes().to_vec());
soundFileBytes.append(&mut CHUNK_SIZE.clone().as_bytes().to_vec());
soundFileBytes.append(&mut FORMAT.clone().as_bytes().to_vec());
soundFileBytes.append(&mut SUBCHUNK_1_ID.clone().as_bytes().to_vec());
write_as_bytes(&mut soundFileBytes, SUBCHUNK_1_SIZE, 4);
write_as_bytes(&mut soundFileBytes, AUDIO_FORMAT, 2) ;
write_as_bytes(&mut soundFileBytes, NUM_CHANNELS, 2);
write_as_bytes(&mut soundFileBytes, SAMPLE_RATE, 4);
write_as_bytes(&mut soundFileBytes, BYTE_RATE, 4);
write_as_bytes(&mut soundFileBytes, BLOACK_ALIGN, 2);
write_as_bytes(&mut soundFileBytes, BITS_PR_SAMPLE, 2);
soundFileBytes.append(&mut SUBCHUNK_2_ID.clone().as_bytes().to_vec());
soundFileBytes.append(&mut SUBCHUNK_2_SIZE.clone().as_bytes().to_vec());
let startAudio = soundFileBytes.len();
let mut collect = Vec::new();
for i in 0..((SAMPLE_RATE as f32 * duration) as usize){
let amplitude = 10000./ SAMPLE_RATE as f32 * MAX_AMPLITUDE as f32;
let value = f32::sin((2. * PI * (i as f32) * (frequency as f32)) / SAMPLE_RATE as f32);
let channel = (amplitude * value);
collect.push(channel);
soundFileBytes.append(&mut (channel as i16).to_le_bytes().to_vec())
}
let endAudio = soundFileBytes.len();
let mut holder = Vec::new();
write_as_bytes(&mut holder, endAudio-startAudio, 4);
for i in 0..4{
soundFileBytes[(startAudio-4)+i] = holder[i];
}
holder.clear();
write_as_bytes(&mut holder, 36+endAudio-startAudio, 4);
for i in 0..4{
soundFileBytes[4+i] = holder[i];
}
let sound = load_sound_from_bytes(&soundFileBytes).await.expect("Failed to load");
sound
}

Binary file not shown.