Initial commit. Reacording and grabbing samples for vu meter works

This commit is contained in:
Sebastian 2017-09-10 16:31:32 +02:00
commit 9a328a9ba2
6 changed files with 260 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
target/
**/*.rs.bk

101
Cargo.lock generated Normal file
View File

@ -0,0 +1,101 @@
[root]
name = "rascam"
version = "0.1.0"
dependencies = [
"gstreamer 0.7.2 (git+https://github.com/arturoc/gstreamer1.0-rs.git)",
"itertools 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "either"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "gstreamer"
version = "0.7.2"
source = "git+https://github.com/arturoc/gstreamer1.0-rs.git#1b7eaf024130520922c4f98f4ada135f58cfc315"
[[package]]
name = "itertools"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quote"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_derive"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_derive_internals"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
"synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "0.11.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "synom"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "toml"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-xid"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a"
"checksum gstreamer 0.7.2 (git+https://github.com/arturoc/gstreamer1.0-rs.git)" = "<none>"
"checksum itertools 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22c285d60139cf413244894189ca52debcfd70b57966feed060da76802e415a0"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum serde 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "7f61b753dd58ec5d4c735f794dbddde1f28b977f652afbcde89d75bc77902216"
"checksum serde_derive 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "2a169fa5384d751ada1da9f3992b81830151a03c875e40dcb37c9fb31aafc68f"
"checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a"
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
"checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e"
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"

11
Cargo.toml Normal file
View File

@ -0,0 +1,11 @@
[package]
name = "rascam"
version = "0.1.0"
authors = ["LongHairedHacker <sebastian@sebastians-site.de>"]
[dependencies]
itertools = "*"
serde = "*"
serde_derive = "*"
toml = "*"
gstreamer = { git = "https://github.com/arturoc/gstreamer1.0-rs.git" }

7
rascam.toml Normal file
View File

@ -0,0 +1,7 @@
[audio]
alsa_device = "hw:1,0"
rate = 96000
[output]
prefix = "test"
directory = "./output/"

138
src/main.rs Normal file
View File

@ -0,0 +1,138 @@
extern crate toml;
#[macro_use]
extern crate serde_derive;
extern crate gst;
extern crate itertools;
use std::fs::File;
use std::io::prelude::*;
use std::thread;
use std::time::Duration;
use itertools::Itertools;
#[derive(Debug, Deserialize)]
struct Config {
audio: AudioConfig,
output: OutputConfig,
}
#[derive(Debug, Deserialize)]
struct AudioConfig {
alsa_device: String,
rate: u32,
}
#[derive(Debug, Deserialize)]
struct OutputConfig {
directory: String,
prefix: String,
}
fn read_config(path: &str) -> Config {
let mut config_toml = String::new();
let mut file = match File::open(path) {
Ok(file) => file,
Err(_) => panic!("Could not find config file!"),
};
file.read_to_string(&mut config_toml)
.unwrap_or_else(|err| panic!("Error while reading config: [{}]", err));
let config: Config =
toml::from_str(&config_toml).unwrap_or_else(|err| {
panic!("Error while parsing config: [{}]",
err)
});
return config;
}
fn main() {
gst::init();
let config = read_config("rascam.toml");
let pipeline_str = format!("alsasrc device={} ! audio/x-raw,rate={},channels=2 ! queue ! tee name=apptee ! audioconvert ! flacenc ! filesink location={}/{}.flac apptee. ! queue ! audioconvert ! appsink name=appsink0 caps=\"audio/x-raw,format=F32LE,channels=2\"",
config.audio.alsa_device,
config.audio.rate,
config.output.directory,
config.output.prefix);
let mut pipeline = gst::Pipeline::new_from_str(&pipeline_str).unwrap();
let mut mainloop = gst::MainLoop::new();
let mut bus = pipeline.bus().expect("Couldn't get bus from pipeline");
let bus_receiver = bus.receiver();
let appsink = pipeline
.get_by_name("appsink0")
.expect("Couldn't get appsink from pipeline");
let appsink = gst::AppSink::new_from_element(appsink);
mainloop.spawn();
pipeline.play();
loop {
let mut exit = false;
while let Ok(msg) = bus_receiver.try_recv() {
match msg.parse() {
gst::Message::StateChangedParsed { ref old, ref new, .. } => {
println!("element `{}` changed from {:?} to {:?}",
msg.src_name(),
old,
new);
}
gst::Message::ErrorParsed {ref error, ref debug, .. } => {
println!("error msg from element `{}`: {}, {}. Quitting",
msg.src_name(),
error.message(),
debug);
exit = true;
break;
}
_ => {
println!("msg of type `{}` from element `{}`",
msg.type_name(),
msg.src_name());
}
}
}
if exit {
break;
}
match appsink.recv(){
Ok(gst::appsink::Message::NewSample(sample)) | Ok(gst::appsink::Message::NewPreroll(sample)) => {
if let Some(buffer) = sample.buffer() {
let (max0, max1) = buffer.map_read(|mapping| {
mapping.iter::<f32>().tuples().fold((0.0f32, 0.0f32), |(acc0, acc1), (sample0, sample1)| {
(acc0.max(sample0.abs()), acc1.max(sample1.abs()))
})
}).unwrap();
println!("{} | {}", max0, max1);
}
}
Ok(gst::appsink::Message::Eos) => {
println!("Got no sample when polling. EOS");
break;
}
Err(_) => {
println!("Error, exiting");
break;
}
}
}
mainloop.quit();
}

1
testpipeline.txt Normal file
View File

@ -0,0 +1 @@
gst-launch-1.0 -v alsasrc device=hw:1,0 ! queue ! audio/x-raw,rate=96000 ! audioconvert ! flacenc ! filesink location=test.flac