From 75e50e438ba821928d5a4907199ec79bbef445cf Mon Sep 17 00:00:00 2001 From: Gabriel Bastos Date: Thu, 7 Jul 2022 17:28:42 -0300 Subject: [PATCH] Remove useless threading model --- src/engine/ambient.rs | 105 +++++++--------- src/engine/jazz.rs | 114 ++++++++---------- src/engine/mod.rs | 39 +++--- src/{ => engine}/sample.rs | 0 src/{ => events}/contract.rs | 0 src/events/mod.rs | 11 ++ src/{event_streamer.rs => events/streamer.rs} | 13 +- src/lib.rs | 4 +- src/main.rs | 4 +- 9 files changed, 128 insertions(+), 162 deletions(-) rename src/{ => engine}/sample.rs (100%) rename src/{ => events}/contract.rs (100%) create mode 100644 src/events/mod.rs rename src/{event_streamer.rs => events/streamer.rs} (93%) diff --git a/src/engine/ambient.rs b/src/engine/ambient.rs index 0b36c47..8d1708b 100644 --- a/src/engine/ambient.rs +++ b/src/engine/ambient.rs @@ -1,67 +1,54 @@ -use std::{sync::mpsc::{Receiver, TryRecvError}, thread, time::Duration}; - use anyhow::Context; use rand::prelude::SliceRandom; -use rodio::{OutputStream, Source}; - -use crate::{event_streamer::Event, sample::Samples}; - -pub fn play(events: Receiver) -> anyhow::Result<()> { - let samples = Samples::load()?; - // Get a output stream handle to the default physical sound device - let (_stream, output) = OutputStream::try_default()?; - +use rodio::{Source, OutputStreamHandle}; +use tokio_stream::{Stream, StreamExt}; + +use crate::events::Event; +use super::sample::Samples; + +pub async fn play( + samples: &Samples, + mut events: S, + output: &OutputStreamHandle +) -> anyhow::Result<()> +where + S: Stream + Unpin, +{ let mut rng = rand::thread_rng(); - loop { - let mut ambience = false; - let mut soundscape = false; - let mut synth = false; - let mut pad = false; - let mut badger = false; - loop { - match events.try_recv() { - Ok(Event::Block) => soundscape = true, - Ok(Event::PixCashier) => badger = true, - Ok(Event::SpinMachine) => ambience = true, - Ok(Event::Brlc) => synth = true, - Ok(Event::Compound) => pad = true, - Err(TryRecvError::Empty) => break, - Err(TryRecvError::Disconnected) => return Ok(()), - }; - } - - if ambience { - let ambience = samples.ambiences.choose(&mut rng).context("no ambiances")?; - output.play_raw(ambience.decoder()?.convert_samples())?; - } - - if synth { - log::info!("😌🎹"); - let synth = &samples.synths.choose(&mut rng).context("no synths")?; - output.play_raw(synth.decoder()?.convert_samples())?; + while let Some(event) = events.next().await { + match event { + Event::Block => { + let soundscape = &samples + .soundscapes + .choose(&mut rng) + .context("no soundscape")?; + output.play_raw(soundscape.decoder()?.convert_samples())?; + }, + + Event::PixCashier => { + let badger = samples.badgers.choose(&mut rng).context("no badger")?; + output.play_raw(badger.decoder()?.convert_samples())?; + }, + + Event::SpinMachine => { + let ambience = samples.ambiences.choose(&mut rng).context("no ambiances")?; + output.play_raw(ambience.decoder()?.convert_samples())?; + }, + + Event::Brlc => { + log::info!("😌🎹"); + let synth = &samples.synths.choose(&mut rng).context("no synths")?; + output.play_raw(synth.decoder()?.convert_samples())?; + }, + + Event::Compound => { + let pad = &samples.pads.choose(&mut rng).context("no pads")?; + output.play_raw(pad.decoder()?.convert_samples())?; + }, } - - if soundscape { - let soundscape = &samples - .soundscapes - .choose(&mut rng) - .context("no soundscape")?; - output.play_raw(soundscape.decoder()?.convert_samples())?; - } - - if pad { - let pad = &samples.pads.choose(&mut rng).context("no pads")?; - output.play_raw(pad.decoder()?.convert_samples())?; - } - - if badger { - let badger = samples.badgers.choose(&mut rng).context("no badger")?; - output.play_raw(badger.decoder()?.convert_samples())?; - } - - // sleep to avoid looping too much - thread::sleep(Duration::from_millis(20)); } + + Ok(()) } diff --git a/src/engine/jazz.rs b/src/engine/jazz.rs index b4dcb0c..ab4edf7 100644 --- a/src/engine/jazz.rs +++ b/src/engine/jazz.rs @@ -1,71 +1,55 @@ -use std::{sync::mpsc::{Receiver, TryRecvError}, time::Duration, thread}; - use anyhow::Context; use rand::prelude::SliceRandom; -use rodio::{OutputStream, Source}; - -use crate::{event_streamer::Event, sample::Samples}; - -pub fn play(events: Receiver) -> anyhow::Result<()> { - let samples = Samples::load()?; - // Get a output stream handle to the default physical sound device - let (_stream, output) = OutputStream::try_default()?; - +use rodio::{Source, OutputStreamHandle}; +use tokio_stream::{Stream, StreamExt}; + +use crate::events::Event; +use super::sample::Samples; + +pub async fn play( + samples: &Samples, + mut events: S, + output: &OutputStreamHandle +) -> anyhow::Result<()> +where + S: Stream + Unpin, +{ let mut rng = rand::thread_rng(); - loop { - let mut jazz_loop = false; - let mut piano = false; - let mut sax = false; - let mut percussion = false; - let mut bass = false; - loop { - match events.try_recv() { - Ok(Event::Block) => jazz_loop = true, - Ok(Event::PixCashier) => sax = true, - Ok(Event::SpinMachine) => piano = true, - Ok(Event::Brlc) => bass = true, - Ok(Event::Compound) => percussion = true, - Err(TryRecvError::Empty) => break, - Err(TryRecvError::Disconnected) => return Ok(()), - }; - } - - if jazz_loop { - let jazz_loop = samples - .jazz_loops - .choose(&mut rng) - .context("no jazz loops")?; - - output.play_raw(jazz_loop.decoder()?.convert_samples())?; - } - - if piano { - let piano = &samples.pianos.choose(&mut rng).context("no pianos")?; - output.play_raw(piano.decoder()?.convert_samples())?; - } - - if percussion { - let perc = &samples - .percussions - .choose(&mut rng) - .context("no percussion")?; - output.play_raw(perc.decoder()?.convert_samples())?; - } - - if sax { - log::info!("epic sax guy 🎷"); - let sax = &samples.saxes.choose(&mut rng).context("no saxes")?; - output.play_raw(sax.decoder()?.convert_samples())?; - } - - if bass { - let bass = samples.basses.choose(&mut rng).context("no basses")?; - - output.play_raw(bass.decoder()?.convert_samples())?; - } - - // sleep to avoid looping too much - thread::sleep(Duration::from_millis(20)); + while let Some(event) = events.next().await { + match event { + Event::Block => { + let jazz_loop = samples + .jazz_loops + .choose(&mut rng) + .context("no jazz loops")?; + + output.play_raw(jazz_loop.decoder()?.convert_samples())?; + } + + Event::PixCashier => { + log::info!("epic sax guy 🎷"); + let sax = &samples.saxes.choose(&mut rng).context("no saxes")?; + output.play_raw(sax.decoder()?.convert_samples())?; + } + Event::SpinMachine => { + let piano = &samples.pianos.choose(&mut rng).context("no pianos")?; + output.play_raw(piano.decoder()?.convert_samples())?; + } + Event::Brlc => { + let bass = samples.basses.choose(&mut rng).context("no basses")?; + + output.play_raw(bass.decoder()?.convert_samples())?; + } + Event::Compound => { + let perc = &samples + .percussions + .choose(&mut rng) + .context("no percussion")?; + output.play_raw(perc.decoder()?.convert_samples())?; + } + }; } + + Ok(()) } diff --git a/src/engine/mod.rs b/src/engine/mod.rs index 0091634..bede64f 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -1,11 +1,12 @@ mod ambient; mod jazz; +mod sample; -use std::thread; +use rodio::OutputStream; +use tokio_stream::Stream; -use tokio_stream::{Stream, StreamExt}; - -use crate::event_streamer::Event; +use crate::events::Event; +use self::sample::Samples; #[derive(Debug, Clone, Copy)] pub enum Program { @@ -13,25 +14,19 @@ pub enum Program { Jazz, } -pub async fn play(mut events: S, program: Program) -> anyhow::Result<()> -where - S: Stream + Unpin, -{ - let (sender, receiver) = std::sync::mpsc::channel(); - thread::spawn(move || { - let result = match program { - Program::Jazz => jazz::play(receiver), - Program::Ambient => ambient::play(receiver), - }; - - if let Err(error) = result { - log::error!("{}", error); +impl Program { + pub async fn play(&self, events: S) -> anyhow::Result<()> + where + S: Stream + Unpin, + { + let samples = Samples::load()?; + // Get a output stream handle to the default physical sound device + let (_stream, output) = OutputStream::try_default()?; + + match self { + Program::Jazz => jazz::play(&samples, events, &output).await, + Program::Ambient => ambient::play(&samples, events, &output).await, } - }); - - while let Some(event) = events.next().await { - sender.send(event)?; } - Ok(()) } diff --git a/src/sample.rs b/src/engine/sample.rs similarity index 100% rename from src/sample.rs rename to src/engine/sample.rs diff --git a/src/contract.rs b/src/events/contract.rs similarity index 100% rename from src/contract.rs rename to src/events/contract.rs diff --git a/src/events/mod.rs b/src/events/mod.rs new file mode 100644 index 0000000..21bc254 --- /dev/null +++ b/src/events/mod.rs @@ -0,0 +1,11 @@ +pub mod streamer; +mod contract; + +#[derive(Debug, Copy, Clone)] +pub enum Event { + Block, + Brlc, + PixCashier, + SpinMachine, + Compound, +} diff --git a/src/event_streamer.rs b/src/events/streamer.rs similarity index 93% rename from src/event_streamer.rs rename to src/events/streamer.rs index d74f915..caa785d 100644 --- a/src/event_streamer.rs +++ b/src/events/streamer.rs @@ -1,18 +1,9 @@ -use std::{fmt::Debug, pin::Pin}; +use std::pin::Pin; use hex_literal::hex; use tokio_stream::{Stream, StreamExt, StreamMap}; -use crate::contract::Contract; - -#[derive(Debug, Copy, Clone)] -pub enum Event { - Block, - Brlc, - PixCashier, - SpinMachine, - Compound, -} +use super::{contract::Contract, Event}; pub async fn start() -> anyhow::Result> { let brlc_address = hex!("A9a55a81a4C085EC0C31585Aed4cFB09D78dfD53"); diff --git a/src/lib.rs b/src/lib.rs index 55003d1..0dd0aee 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,3 @@ pub mod args; -mod contract; pub mod engine; -pub mod event_streamer; -mod sample; +pub mod events; diff --git a/src/main.rs b/src/main.rs index da05390..24aa3fa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,6 @@ async fn main() -> anyhow::Result<()> { SimpleLogger::new().with_level(LevelFilter::Info).init()?; let args = Args::parse(); - let stream = chaintrak::event_streamer::start().await?; - chaintrak::engine::play(stream, args.vibe).await + let events = chaintrak::events::streamer::start().await?; + args.vibe.play(events).await }