2024-04-27 19:48:13 +03:00
|
|
|
use iced::{
|
2024-04-28 18:58:01 +03:00
|
|
|
widget::{container, row, Container},
|
2024-04-27 19:48:13 +03:00
|
|
|
Command,
|
|
|
|
};
|
2024-04-27 15:36:28 +03:00
|
|
|
use tokio::sync::broadcast::{channel, Sender};
|
|
|
|
|
2024-04-28 18:58:01 +03:00
|
|
|
use crate::{
|
|
|
|
gui_utils::button_with_centered_text, recording, streaming, utils::get_config, Config, BUFFER_LENGTH
|
|
|
|
};
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub enum Event {
|
|
|
|
Connect,
|
|
|
|
Disconnect,
|
|
|
|
Record,
|
|
|
|
StopRecord,
|
|
|
|
PlayAudio,
|
|
|
|
StopAudio,
|
|
|
|
LoadConfig(Config),
|
|
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
|
|
|
pub enum State {
|
|
|
|
Connected,
|
|
|
|
Disconnected,
|
|
|
|
Recording,
|
|
|
|
StopRecording,
|
|
|
|
PlayingAudio,
|
|
|
|
StopAudio,
|
|
|
|
}
|
2024-04-27 15:36:28 +03:00
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub enum Message {
|
2024-04-28 18:58:01 +03:00
|
|
|
Event(Event),
|
|
|
|
State(State),
|
|
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
|
|
struct DataChannel {
|
|
|
|
sound_stream_sender: Sender<f32>,
|
|
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
|
|
struct CommunicationChannel {
|
|
|
|
base_to_streaming: Sender<bool>,
|
|
|
|
streaming_to_base: Sender<bool>,
|
|
|
|
base_to_recording: Sender<bool>,
|
|
|
|
recording_to_base: Sender<bool>,
|
|
|
|
base_to_playing: Sender<bool>,
|
|
|
|
playing_to_base: Sender<bool>,
|
|
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
|
|
enum Condition {
|
|
|
|
Active,
|
|
|
|
Loading,
|
|
|
|
Passive,
|
2024-04-27 15:36:28 +03:00
|
|
|
}
|
|
|
|
|
2024-04-28 18:58:01 +03:00
|
|
|
#[derive(Debug)]
|
|
|
|
struct GUIStatus {
|
|
|
|
are_we_connect: Condition,
|
|
|
|
are_we_record: Condition,
|
|
|
|
are_we_play_audio: Condition,
|
|
|
|
}
|
2024-04-27 15:36:28 +03:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Streamer {
|
|
|
|
config: Option<Config>,
|
2024-04-28 18:58:01 +03:00
|
|
|
data_channel: DataChannel,
|
|
|
|
communication_channel: CommunicationChannel,
|
|
|
|
gui_status: GUIStatus,
|
2024-04-27 15:36:28 +03:00
|
|
|
}
|
|
|
|
impl Default for Streamer {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self::new()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Streamer {
|
|
|
|
fn new() -> Self {
|
|
|
|
Self {
|
|
|
|
config: None,
|
2024-04-28 18:58:01 +03:00
|
|
|
data_channel: DataChannel {
|
|
|
|
sound_stream_sender: channel(BUFFER_LENGTH).0,
|
|
|
|
},
|
|
|
|
communication_channel: CommunicationChannel {
|
|
|
|
base_to_streaming: channel(1).0,
|
|
|
|
streaming_to_base: channel(1).0,
|
|
|
|
base_to_recording: channel(1).0,
|
|
|
|
recording_to_base: channel(1).0,
|
|
|
|
base_to_playing: channel(1).0,
|
|
|
|
playing_to_base: channel(1).0,
|
|
|
|
},
|
|
|
|
gui_status: GUIStatus {
|
|
|
|
are_we_connect: Condition::Passive,
|
|
|
|
are_we_record: Condition::Passive,
|
|
|
|
are_we_play_audio: Condition::Passive,
|
|
|
|
},
|
2024-04-27 15:36:28 +03:00
|
|
|
}
|
|
|
|
}
|
2024-04-28 18:58:01 +03:00
|
|
|
pub fn update(&mut self, message: Message) -> Command<Message> {
|
2024-04-27 15:36:28 +03:00
|
|
|
match message {
|
2024-04-28 18:58:01 +03:00
|
|
|
Message::Event(event) => match event {
|
|
|
|
Event::Connect => {
|
|
|
|
println!("Connect");
|
|
|
|
self.gui_status.are_we_connect = Condition::Loading;
|
|
|
|
let mut streaming_to_base_receiver =
|
|
|
|
self.communication_channel.streaming_to_base.subscribe();
|
2024-04-27 22:14:50 +03:00
|
|
|
tokio::spawn(streaming::connect(
|
2024-04-28 18:58:01 +03:00
|
|
|
self.data_channel.sound_stream_sender.subscribe(),
|
2024-04-27 22:14:50 +03:00
|
|
|
self.config.clone().unwrap(),
|
2024-04-28 18:58:01 +03:00
|
|
|
self.communication_channel.base_to_streaming.subscribe(),
|
|
|
|
self.communication_channel.streaming_to_base.clone(),
|
2024-04-27 22:14:50 +03:00
|
|
|
));
|
2024-04-28 18:58:01 +03:00
|
|
|
Command::perform(
|
|
|
|
async move {
|
|
|
|
match streaming_to_base_receiver.recv().await {
|
|
|
|
Ok(_) => State::Connected,
|
|
|
|
Err(err_val) => {
|
|
|
|
eprintln!("Error: Communication | {}", err_val);
|
|
|
|
State::Disconnected
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Message::State,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
Event::Disconnect => {
|
|
|
|
println!("Disconnect");
|
|
|
|
self.gui_status.are_we_connect = Condition::Loading;
|
|
|
|
let mut streaming_to_base_receiver =
|
|
|
|
self.communication_channel.streaming_to_base.subscribe();
|
|
|
|
let _ = self.communication_channel.base_to_streaming.send(false);
|
|
|
|
Command::perform(
|
|
|
|
async move {
|
|
|
|
match streaming_to_base_receiver.recv().await {
|
|
|
|
Ok(_) => State::Disconnected,
|
|
|
|
Err(err_val) => {
|
|
|
|
eprintln!("Error: Communication | {}", err_val);
|
|
|
|
State::Connected
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Message::State,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
Event::Record => {
|
|
|
|
println!("Record");
|
|
|
|
self.gui_status.are_we_record = Condition::Loading;
|
|
|
|
let mut recording_to_base_receiver =
|
|
|
|
self.communication_channel.recording_to_base.subscribe();
|
2024-04-27 22:14:50 +03:00
|
|
|
tokio::spawn(recording::record(
|
2024-04-28 18:58:01 +03:00
|
|
|
self.data_channel.sound_stream_sender.clone(),
|
|
|
|
self.communication_channel.base_to_recording.subscribe(),
|
|
|
|
self.communication_channel.recording_to_base.clone(),
|
2024-04-27 22:14:50 +03:00
|
|
|
));
|
2024-04-28 18:58:01 +03:00
|
|
|
Command::perform(
|
|
|
|
async move {
|
|
|
|
match recording_to_base_receiver.recv().await {
|
|
|
|
Ok(_) => State::Recording,
|
|
|
|
Err(err_val) => {
|
|
|
|
eprintln!("Error: Communication | Streaming | {}", err_val);
|
|
|
|
State::StopRecording
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Message::State,
|
|
|
|
)
|
2024-04-27 22:14:50 +03:00
|
|
|
}
|
2024-04-28 18:58:01 +03:00
|
|
|
Event::StopRecord => {
|
|
|
|
println!("Stop Record");
|
|
|
|
self.gui_status.are_we_record = Condition::Loading;
|
|
|
|
let mut recording_to_base_receiver =
|
|
|
|
self.communication_channel.recording_to_base.subscribe();
|
|
|
|
let _ = self.communication_channel.base_to_recording.send(false);
|
|
|
|
Command::perform(
|
|
|
|
async move {
|
|
|
|
match recording_to_base_receiver.recv().await {
|
|
|
|
Ok(_) => State::StopRecording,
|
|
|
|
Err(err_val) => {
|
|
|
|
eprintln!("Error: Communication | Recording | {}", err_val);
|
|
|
|
State::Recording
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Message::State,
|
|
|
|
)
|
2024-04-27 22:14:50 +03:00
|
|
|
}
|
2024-04-28 18:58:01 +03:00
|
|
|
Event::PlayAudio => {
|
|
|
|
println!("Play Audio");
|
|
|
|
self.gui_status.are_we_play_audio = Condition::Loading;
|
|
|
|
let mut playing_to_base_receiver =
|
|
|
|
self.communication_channel.playing_to_base.subscribe();
|
|
|
|
//tokio::spawn(future);
|
|
|
|
Command::perform(
|
|
|
|
async move {
|
|
|
|
match playing_to_base_receiver.recv().await {
|
|
|
|
Ok(_) => State::PlayingAudio,
|
|
|
|
Err(err_val) => {
|
|
|
|
eprint!("Error: Communication | Playing | {}", err_val);
|
|
|
|
State::StopAudio
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Message::State,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
Event::StopAudio => {
|
|
|
|
println!("Stop Audio");
|
|
|
|
self.gui_status.are_we_play_audio = Condition::Loading;
|
|
|
|
let mut playing_to_base_receiver =
|
|
|
|
self.communication_channel.playing_to_base.subscribe();
|
|
|
|
let _ = self.communication_channel.base_to_playing.send(false);
|
|
|
|
Command::perform(
|
|
|
|
async move {
|
|
|
|
match playing_to_base_receiver.recv().await {
|
|
|
|
Ok(_) => State::StopAudio,
|
|
|
|
Err(err_val) => {
|
|
|
|
eprint!("Error: Communication | Playing | {}", err_val);
|
|
|
|
State::PlayingAudio
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Message::State,
|
|
|
|
)
|
2024-04-27 22:14:50 +03:00
|
|
|
}
|
2024-04-28 18:58:01 +03:00
|
|
|
Event::LoadConfig(config) => {
|
|
|
|
self.config = Some(config);
|
|
|
|
Command::none()
|
2024-04-27 22:14:50 +03:00
|
|
|
}
|
|
|
|
},
|
2024-04-28 18:58:01 +03:00
|
|
|
Message::State(state) => match state {
|
|
|
|
State::Connected => {
|
|
|
|
self.gui_status.are_we_connect = Condition::Active;
|
|
|
|
Command::none()
|
|
|
|
}
|
|
|
|
State::Disconnected => {
|
|
|
|
self.gui_status.are_we_connect = Condition::Passive;
|
|
|
|
Command::none()
|
2024-04-27 22:14:50 +03:00
|
|
|
}
|
2024-04-28 18:58:01 +03:00
|
|
|
State::Recording => {
|
|
|
|
self.gui_status.are_we_record = Condition::Active;
|
|
|
|
Command::none()
|
|
|
|
}
|
|
|
|
State::StopRecording => {
|
|
|
|
self.gui_status.are_we_record = Condition::Passive;
|
|
|
|
Command::none()
|
|
|
|
}
|
|
|
|
State::PlayingAudio => {
|
|
|
|
self.gui_status.are_we_play_audio = Condition::Active;
|
|
|
|
Command::none()
|
|
|
|
}
|
|
|
|
State::StopAudio => {
|
|
|
|
self.gui_status.are_we_play_audio = Condition::Passive;
|
|
|
|
Command::none()
|
2024-04-27 22:14:50 +03:00
|
|
|
}
|
|
|
|
},
|
2024-04-28 18:58:01 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
pub fn view(&self) -> Container<Message> {
|
|
|
|
let connect_button = match self.gui_status.are_we_connect {
|
|
|
|
Condition::Active => {
|
|
|
|
button_with_centered_text("Disconnect").on_press(Message::Event(Event::Disconnect))
|
|
|
|
}
|
|
|
|
Condition::Loading => button_with_centered_text("Processing"),
|
|
|
|
Condition::Passive => {
|
|
|
|
button_with_centered_text("Connect").on_press(Message::Event(Event::Connect))
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let record_button = match self.gui_status.are_we_record {
|
|
|
|
Condition::Active => {
|
|
|
|
button_with_centered_text("Stop Record").on_press(Message::Event(Event::StopRecord))
|
|
|
|
}
|
|
|
|
Condition::Loading => button_with_centered_text("Processing"),
|
|
|
|
Condition::Passive => {
|
|
|
|
button_with_centered_text("Record").on_press(Message::Event(Event::Record))
|
|
|
|
}
|
2024-04-27 22:14:50 +03:00
|
|
|
};
|
2024-04-28 18:58:01 +03:00
|
|
|
|
|
|
|
let play_audio_button =
|
|
|
|
match self.gui_status.are_we_play_audio {
|
|
|
|
Condition::Active => button_with_centered_text("Stop Audio")
|
|
|
|
.on_press(Message::Event(Event::StopAudio)),
|
|
|
|
Condition::Loading => button_with_centered_text("Processing"),
|
|
|
|
Condition::Passive => button_with_centered_text("Play Audio")
|
|
|
|
.on_press(Message::Event(Event::PlayAudio)),
|
|
|
|
};
|
|
|
|
|
|
|
|
let content = row![connect_button, record_button, play_audio_button]
|
|
|
|
.spacing(20)
|
|
|
|
.width(400)
|
|
|
|
.height(35);
|
|
|
|
container(content).height(300).center_x().center_y()
|
2024-04-27 15:36:28 +03:00
|
|
|
}
|
|
|
|
pub fn load_config() -> Command<Message> {
|
2024-04-28 18:58:01 +03:00
|
|
|
Command::perform(
|
|
|
|
async move {
|
|
|
|
let config = get_config().await;
|
|
|
|
Event::LoadConfig(config)
|
|
|
|
},
|
|
|
|
Message::Event,
|
|
|
|
)
|
2024-04-27 15:36:28 +03:00
|
|
|
}
|
|
|
|
}
|