mirror of
https://github.com/alemidev/scope-tui.git
synced 2024-11-23 14:14:48 +01:00
chore: modularized source backend code
This commit is contained in:
parent
c4960cf571
commit
ba0174961a
3 changed files with 64 additions and 45 deletions
55
src/app.rs
55
src/app.rs
|
@ -12,49 +12,21 @@ use libpulse_simple_binding::Simple;
|
||||||
use libpulse_binding::{stream::Direction, def::BufferAttr};
|
use libpulse_binding::{stream::Direction, def::BufferAttr};
|
||||||
use libpulse_binding::sample::{Spec, Format};
|
use libpulse_binding::sample::{Spec, Format};
|
||||||
|
|
||||||
use crate::Args;
|
use crate::{Args, source::{PulseAudioSimple, DataSource}};
|
||||||
use crate::config::{ChartNames, ChartBounds, ChartReferences, AppConfig, Dimension};
|
use crate::config::{ChartNames, ChartBounds, ChartReferences, AppConfig, Dimension};
|
||||||
use crate::parser::{SampleParser, Signed16PCM};
|
use crate::parser::{SampleParser, Signed16PCM};
|
||||||
|
|
||||||
pub fn run_app<T : Backend>(args: Args, terminal: &mut Terminal<T>) -> Result<(), io::Error> {
|
pub fn run_app<T : Backend>(args: Args, terminal: &mut Terminal<T>) -> Result<(), io::Error> {
|
||||||
// prepare globals
|
// prepare globals
|
||||||
let mut buffer : Vec<u8> = vec![0; args.buffer as usize];
|
|
||||||
let mut app = App::from(&args);
|
let mut app = App::from(&args);
|
||||||
let fmt = Signed16PCM{}; // TODO some way to choose this?
|
let fmt = Signed16PCM{}; // TODO some way to choose this?
|
||||||
|
let mut source = PulseAudioSimple::new(
|
||||||
// setup audio capture
|
args.device.as_deref(),
|
||||||
let spec = Spec {
|
args.channels,
|
||||||
format: Format::S16NE,
|
args.sample_rate,
|
||||||
channels: args.channels,
|
args.buffer,
|
||||||
rate: args.sample_rate,
|
args.server_buffer
|
||||||
};
|
).unwrap();
|
||||||
assert!(spec.is_valid());
|
|
||||||
|
|
||||||
let dev = match &args.device {
|
|
||||||
Some(d) => Some(d.as_str()),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let s = match Simple::new(
|
|
||||||
None, // Use the default server
|
|
||||||
"scope-tui", // Our application’s name
|
|
||||||
Direction::Record, // We want a record stream
|
|
||||||
dev, // Use requested device, or default
|
|
||||||
"data", // Description of our stream
|
|
||||||
&spec, // Our sample format
|
|
||||||
None, // Use default channel map
|
|
||||||
Some(&BufferAttr {
|
|
||||||
maxlength: args.server_buffer * args.buffer,
|
|
||||||
fragsize: args.buffer,
|
|
||||||
..Default::default()
|
|
||||||
}),
|
|
||||||
) {
|
|
||||||
Ok(s) => s,
|
|
||||||
Err(e) => {
|
|
||||||
println!("[!] Could not connect to pulseaudio : {:?}", e);
|
|
||||||
return Err(io::Error::new(ErrorKind::Other, "could not connect to pulseaudio"));
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut fps = 0;
|
let mut fps = 0;
|
||||||
let mut framerate = 0;
|
let mut framerate = 0;
|
||||||
|
@ -62,17 +34,10 @@ pub fn run_app<T : Backend>(args: Args, terminal: &mut Terminal<T>) -> Result<()
|
||||||
let mut channels = vec![];
|
let mut channels = vec![];
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match s.read(&mut buffer) {
|
let data = source.recv().unwrap();
|
||||||
Ok(()) => {},
|
|
||||||
Err(e) => {
|
|
||||||
println!("[!] Could not read data from pulseaudio : {:?}", e);
|
|
||||||
return Err(io::Error::new(ErrorKind::Other, "could not read from pulseaudio"));
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if !app.cfg.pause {
|
if !app.cfg.pause {
|
||||||
channels = fmt.oscilloscope(&mut buffer, args.channels);
|
channels = fmt.oscilloscope(data, args.channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut trigger_offset = 0;
|
let mut trigger_offset = 0;
|
||||||
|
|
|
@ -2,6 +2,7 @@ mod parser;
|
||||||
mod app;
|
mod app;
|
||||||
mod config;
|
mod config;
|
||||||
mod music;
|
mod music;
|
||||||
|
mod source;
|
||||||
|
|
||||||
use tui::{
|
use tui::{
|
||||||
backend::CrosstermBackend,
|
backend::CrosstermBackend,
|
||||||
|
|
53
src/source.rs
Normal file
53
src/source.rs
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
use libpulse_binding::{stream::Direction, sample::{Spec, Format}, def::BufferAttr, error::{PAErr, Code}};
|
||||||
|
use libpulse_simple_binding::Simple;
|
||||||
|
|
||||||
|
pub trait DataSource {
|
||||||
|
fn recv(&mut self) -> Option<&[u8]>; // TODO convert in Result and make generic error
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PulseAudioSimple {
|
||||||
|
simple: Simple,
|
||||||
|
buffer: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PulseAudioSimple {
|
||||||
|
pub fn new(
|
||||||
|
device: Option<&str>, channels: u8, rate: u32, buffer: u32, server_buffer: u32
|
||||||
|
) -> Result<Self, PAErr> {
|
||||||
|
let spec = Spec {
|
||||||
|
format: Format::S16NE, // TODO allow more formats?
|
||||||
|
channels, rate,
|
||||||
|
};
|
||||||
|
if !spec.is_valid() {
|
||||||
|
return Err(PAErr(0)); // TODO what error number should we throw?
|
||||||
|
}
|
||||||
|
let attrs = BufferAttr {
|
||||||
|
maxlength: server_buffer * buffer,
|
||||||
|
fragsize: buffer,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let simple = Simple::new(
|
||||||
|
None, // Use the default server
|
||||||
|
"scope-tui", // Our application’s name
|
||||||
|
Direction::Record, // We want a record stream
|
||||||
|
device, // Use requested device, or default
|
||||||
|
"data", // Description of our stream
|
||||||
|
&spec, // Our sample format
|
||||||
|
None, // Use default channel map
|
||||||
|
Some(&attrs), // Our hints on how to handle client/server buffers
|
||||||
|
)?;
|
||||||
|
Ok(Self { simple, buffer: vec![0; buffer as usize] })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DataSource for PulseAudioSimple {
|
||||||
|
fn recv(&mut self) -> Option<&[u8]> {
|
||||||
|
match self.simple.read(&mut self.buffer) {
|
||||||
|
Ok(()) => Some(&self.buffer),
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("[!] could not receive from pulseaudio: {}", e);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue