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::sample::{Spec, Format};
|
||||
|
||||
use crate::Args;
|
||||
use crate::{Args, source::{PulseAudioSimple, DataSource}};
|
||||
use crate::config::{ChartNames, ChartBounds, ChartReferences, AppConfig, Dimension};
|
||||
use crate::parser::{SampleParser, Signed16PCM};
|
||||
|
||||
pub fn run_app<T : Backend>(args: Args, terminal: &mut Terminal<T>) -> Result<(), io::Error> {
|
||||
// prepare globals
|
||||
let mut buffer : Vec<u8> = vec![0; args.buffer as usize];
|
||||
let mut app = App::from(&args);
|
||||
let fmt = Signed16PCM{}; // TODO some way to choose this?
|
||||
|
||||
// setup audio capture
|
||||
let spec = Spec {
|
||||
format: Format::S16NE,
|
||||
channels: args.channels,
|
||||
rate: args.sample_rate,
|
||||
};
|
||||
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 source = PulseAudioSimple::new(
|
||||
args.device.as_deref(),
|
||||
args.channels,
|
||||
args.sample_rate,
|
||||
args.buffer,
|
||||
args.server_buffer
|
||||
).unwrap();
|
||||
|
||||
let mut fps = 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![];
|
||||
|
||||
loop {
|
||||
match s.read(&mut buffer) {
|
||||
Ok(()) => {},
|
||||
Err(e) => {
|
||||
println!("[!] Could not read data from pulseaudio : {:?}", e);
|
||||
return Err(io::Error::new(ErrorKind::Other, "could not read from pulseaudio"));
|
||||
},
|
||||
}
|
||||
|
||||
let data = source.recv().unwrap();
|
||||
|
||||
if !app.cfg.pause {
|
||||
channels = fmt.oscilloscope(&mut buffer, args.channels);
|
||||
channels = fmt.oscilloscope(data, args.channels);
|
||||
}
|
||||
|
||||
let mut trigger_offset = 0;
|
||||
|
|
|
@ -2,6 +2,7 @@ mod parser;
|
|||
mod app;
|
||||
mod config;
|
||||
mod music;
|
||||
mod source;
|
||||
|
||||
use tui::{
|
||||
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