binaural_beat_generator_cli/
main.rs

1//! This program allows for the user to be able to listen to binaural beat tones on their machine.
2//! ## Binaural beats is the idea that your brainwaves could be changed in a positive way by listening to slightly different tones in each ear.
3//! # Study suggests that binurial beats can help in stress relief, pain relief, anxiety relief as well as help in increased focus and so on.
4//! See the following for more info. [What Are Binaural Beats?](https://www.webmd.com/balance/what-are-binaural-beats)
5
6extern crate cpal;
7use colored::Colorize;
8use crossterm::event::{self, Event, KeyCode, KeyEventKind};
9use std::sync::Arc;
10use std::sync::atomic::{AtomicBool, Ordering};
11
12use anyhow::Error;
13use inquire::Select;
14
15use crate::modules::bb_generator::generate_binaural_beats;
16use crate::modules::duration::duration::duration_list;
17use crate::modules::preset::{BinauralPresetGroup, preset_list};
18
19mod modules;
20
21/// This is the entry point to the program.
22fn main() -> Result<(), Error> {
23    let preset_options = preset_list();
24    let duration_options = duration_list();
25    
26    print_program_info();
27
28    let chosen_preset = Select::new("Choose a preset: ", preset_options)
29        .with_page_size(7)
30        .prompt();
31
32    match chosen_preset {
33        Ok(preset) => {
34            let mut binaural_preset_options = BinauralPresetGroup::from(preset);
35
36            let starting_duration_index = duration_options
37                .iter()
38                .position(|&x| x == binaural_preset_options.duration)
39                .unwrap();
40
41            let chosen_duration = Select::new("Choose a duration: ", duration_options)
42                .with_starting_cursor(starting_duration_index)
43                .prompt();
44
45            match chosen_duration {
46                Ok(duration) => {
47                    //Get the chosen duration if it has changed.
48                    binaural_preset_options.duration = duration;
49                    run_binaural_beat(binaural_preset_options)?;
50                }
51                Err(err) => eprintln!(
52                    "There was an error choosing the duration, please try again. {}",
53                    err
54                ),
55            }
56        }
57        Err(err) => eprintln!("There was an error, please try again. {}", err),
58    }
59
60    Ok(())
61}
62
63/// A helper funciton that sets off the running of the binaural beat tones.
64/// It also spawns a new thread in order to watch for early completion.
65fn run_binaural_beat(preset_options: BinauralPresetGroup) -> Result<(), Error> {
66    let cancel_token = Arc::new(AtomicBool::new(false));
67    let cancel_token_clone = Arc::clone(&cancel_token);
68
69    // 2. Start a separate thread to listen for user input
70    std::thread::spawn(move || {
71        println!("Press Enter to stop playback.");
72
73        loop {
74            match event::read() {
75                Ok(Event::Key(key_event)) => {
76                    if key_event.kind == KeyEventKind::Press && key_event.code == KeyCode::Enter {
77                        cancel_token_clone.store(true, Ordering::Relaxed);
78                    }
79                }
80                Ok(_) => {} // Ignore other events
81                Err(err) => eprintln!("There was an error, please try again. {}", err),
82            }
83        }
84    });
85
86    generate_binaural_beats(preset_options, Arc::clone(&cancel_token))?;
87
88    Ok(())
89}
90
91/// A helper function that just prints out the program name and author.
92fn print_program_info() {
93    let bar = "|" ;
94    println!("\n{:-^50}","Binaural Beat Generator".red().bold().italic());
95    println!("{: <25}{: >25}",bar.blue().bold(), bar.blue().bold());
96    println!("{first_name:-<25}{last_name:->25}\n", 
97        first_name="Chris".blue().bold(), 
98        last_name = "Horton".blue().bold());
99    
100}