Add scripts and templates, clean up audio logger
This commit is contained in:
parent
eff8dde098
commit
2dece7dc9d
@ -10,16 +10,7 @@ cpal= { version = "0.13.5", features = ["jack"] }
|
||||
anyhow = "1.0.61"
|
||||
clap = "3.2.17"
|
||||
hound = "3.4.0"
|
||||
|
||||
|
||||
[target.'cfg(target_os = "android")'.dev-dependencies]
|
||||
ndk-glue = "0.7"
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
windows = { version = "0.37", features = ["Win32_Media_Audio", "Win32_Foundation", "Win32_System_Com", "Win32_Devices_Properties", "Win32_Media_KernelStreaming", "Win32_System_Com_StructuredStorage", "Win32_System_Ole", "Win32_System_Threading", "Win32_Security", "Win32_System_SystemServices", "Win32_System_WindowsProgramming", "Win32_Media_Multimedia", "Win32_UI_Shell_PropertiesSystem"]}
|
||||
num-traits = { version = "0.2.6", optional = true }
|
||||
parking_lot = "0.12"
|
||||
once_cell = "1.12"
|
||||
chrono = "0.4.22"
|
||||
|
||||
[target.'cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd"))'.dependencies]
|
||||
alsa = "0.6"
|
||||
@ -27,27 +18,3 @@ nix = "0.23"
|
||||
libc = "0.2.65"
|
||||
parking_lot = "0.12"
|
||||
jack = { version = "0.9", optional = true }
|
||||
|
||||
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies]
|
||||
core-foundation-sys = "0.8.2" # For linking to CoreFoundation.framework and handling device name `CFString`s.
|
||||
mach = "0.3" # For access to mach_timebase type.
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
coreaudio-rs = { version = "0.10", default-features = false, features = ["audio_unit", "core_audio"] }
|
||||
|
||||
[target.'cfg(target_os = "ios")'.dependencies]
|
||||
coreaudio-rs = { version = "0.10", default-features = false, features = ["audio_unit", "core_audio", "audio_toolbox"] }
|
||||
|
||||
[target.'cfg(target_os = "emscripten")'.dependencies]
|
||||
stdweb = { version = "0.1.3", default-features = false }
|
||||
|
||||
[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]
|
||||
wasm-bindgen = { version = "0.2.58", optional = true }
|
||||
js-sys = { version = "0.3.35" }
|
||||
web-sys = { version = "0.3.35", features = [ "AudioContext", "AudioContextOptions", "AudioBuffer", "AudioBufferSourceNode", "AudioNode", "AudioDestinationNode", "Window", "AudioContextState"] }
|
||||
|
||||
[target.'cfg(target_os = "android")'.dependencies]
|
||||
oboe = { version = "0.4", features = [ "java-interface" ] }
|
||||
ndk = "0.7"
|
||||
ndk-context = "0.1"
|
||||
jni = "0.19"
|
@ -2,71 +2,25 @@
|
||||
//!
|
||||
//! The input data is recorded to "$CARGO_MANIFEST_DIR/recorded.wav".
|
||||
|
||||
use clap::arg;
|
||||
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
|
||||
use std::fs::File;
|
||||
use std::io::BufWriter;
|
||||
use std::path::Path;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Opt {
|
||||
#[cfg(all(
|
||||
any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd"),
|
||||
))]
|
||||
jack: bool,
|
||||
|
||||
device: String,
|
||||
}
|
||||
|
||||
impl Opt {
|
||||
fn from_args() -> Self {
|
||||
let app = clap::Command::new("record_wav").arg(arg!([DEVICE] "The audio device to use"));
|
||||
#[cfg(all(
|
||||
any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd"),
|
||||
))]
|
||||
let app = app.arg(arg!(-j --jack "Use the JACK host"));
|
||||
let matches = app.get_matches();
|
||||
let device = matches.value_of("DEVICE").unwrap_or("default").to_string();
|
||||
|
||||
#[cfg(all(
|
||||
any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd"),
|
||||
))]
|
||||
return Opt {
|
||||
jack: matches.is_present("jack"),
|
||||
device,
|
||||
};
|
||||
|
||||
#[cfg(any(
|
||||
not(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd")),
|
||||
))]
|
||||
Opt { device }
|
||||
}
|
||||
}
|
||||
use chrono::prelude::*;
|
||||
|
||||
fn main() -> Result<(), anyhow::Error> {
|
||||
let opt = Opt::from_args();
|
||||
|
||||
// Manually check for flags. Can be passed through cargo with -- e.g.
|
||||
// cargo run --release --example beep --features jack -- --jack
|
||||
let host = if opt.jack {
|
||||
cpal::host_from_id(cpal::available_hosts()
|
||||
.into_iter()
|
||||
.find(|id| *id == cpal::HostId::Jack)
|
||||
.expect(
|
||||
"make sure --features jack is specified. only works on OSes where jack is available",
|
||||
)).expect("jack host unavailable")
|
||||
} else {
|
||||
cpal::default_host()
|
||||
};
|
||||
// Use jack host, requires the jack server to be running
|
||||
let host = cpal::host_from_id(cpal::available_hosts()
|
||||
.into_iter()
|
||||
.find(|id| *id == cpal::HostId::Jack)
|
||||
.expect(
|
||||
"make sure feature jack is specified for cpal. only works on OSes where jack is available",
|
||||
)).expect("jack host unavailable");
|
||||
|
||||
// Set up the input device and stream with the default input config.
|
||||
let device = if opt.device == "default" {
|
||||
host.default_input_device()
|
||||
} else {
|
||||
host.input_devices()?
|
||||
.find(|x| x.name().map(|y| y == opt.device).unwrap_or(false))
|
||||
}
|
||||
.expect("failed to find input device");
|
||||
let device = host.default_input_device()
|
||||
.expect("failed to find input device");
|
||||
|
||||
println!("Input device: {}", device.name()?);
|
||||
|
||||
@ -75,47 +29,55 @@ fn main() -> Result<(), anyhow::Error> {
|
||||
.expect("Failed to get default input config");
|
||||
println!("Default input config: {:?}", config);
|
||||
|
||||
// The WAV file we're recording to.
|
||||
const PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/recorded.wav");
|
||||
// Location where files will be outputted
|
||||
let path = Path::new("/home/shared/logger-raspi-setup/data/audio/");
|
||||
let spec = wav_spec_from_config(&config);
|
||||
let writer = hound::WavWriter::create(PATH, spec)?;
|
||||
let writer = Arc::new(Mutex::new(Some(writer)));
|
||||
|
||||
// A flag to indicate that recording is in progress.
|
||||
println!("Begin recording...");
|
||||
for _ in 0..5 {
|
||||
// The WAV file we're recording to.
|
||||
let ts: String = Utc::now().format("%Y-%m-%dT%H-%M-%S.%f").to_string();
|
||||
let file: String = path.to_str().unwrap().to_owned() + &ts + "_audio_data.wav";
|
||||
|
||||
// Run the input stream on a separate thread.
|
||||
let writer_2 = writer.clone();
|
||||
|
||||
let err_fn = move |err| {
|
||||
eprintln!("an error occurred on stream: {}", err);
|
||||
};
|
||||
|
||||
let stream = match config.sample_format() {
|
||||
cpal::SampleFormat::F32 => device.build_input_stream(
|
||||
&config.into(),
|
||||
move |data, _: &_| write_input_data::<f32, f32>(data, &writer_2),
|
||||
err_fn,
|
||||
)?,
|
||||
cpal::SampleFormat::I16 => device.build_input_stream(
|
||||
&config.into(),
|
||||
move |data, _: &_| write_input_data::<i16, i16>(data, &writer_2),
|
||||
err_fn,
|
||||
)?,
|
||||
cpal::SampleFormat::U16 => device.build_input_stream(
|
||||
&config.into(),
|
||||
move |data, _: &_| write_input_data::<u16, i16>(data, &writer_2),
|
||||
err_fn,
|
||||
)?,
|
||||
};
|
||||
|
||||
stream.play()?;
|
||||
|
||||
// Let recording go for roughly three seconds.
|
||||
std::thread::sleep(std::time::Duration::from_secs(3));
|
||||
drop(stream);
|
||||
writer.lock().unwrap().take().unwrap().finalize()?;
|
||||
println!("Recording {} complete!", PATH);
|
||||
let writer = hound::WavWriter::create(file.clone(), spec)?;
|
||||
let writer = Arc::new(Mutex::new(Some(writer)));
|
||||
|
||||
// Run the input stream on a separate thread.
|
||||
let writer_2 = writer.clone();
|
||||
|
||||
let config_2 = config.clone();
|
||||
|
||||
let err_fn = move |err| {
|
||||
eprintln!("an error occurred on stream: {}", err);
|
||||
};
|
||||
|
||||
let stream = match config.sample_format() {
|
||||
cpal::SampleFormat::F32 => device.build_input_stream(
|
||||
&config_2.into(),
|
||||
move |data, _: &_| write_input_data::<f32, f32>(data, &writer_2),
|
||||
err_fn,
|
||||
)?,
|
||||
cpal::SampleFormat::I16 => device.build_input_stream(
|
||||
&config_2.into(),
|
||||
move |data, _: &_| write_input_data::<i16, i16>(data, &writer_2),
|
||||
err_fn,
|
||||
)?,
|
||||
cpal::SampleFormat::U16 => device.build_input_stream(
|
||||
&config_2.into(),
|
||||
move |data, _: &_| write_input_data::<u16, i16>(data, &writer_2),
|
||||
err_fn,
|
||||
)?,
|
||||
};
|
||||
|
||||
// Start recording
|
||||
println!("Begin recording at {}", Utc::now());
|
||||
stream.play()?;
|
||||
|
||||
// Let recording go for roughly five seconds.
|
||||
std::thread::sleep(std::time::Duration::from_secs(5));
|
||||
drop(stream);
|
||||
writer.lock().unwrap().take().unwrap().finalize()?;
|
||||
println!("Recording {} complete!", file);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
{"rustc_fingerprint":1011063074445675614,"outputs":{"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.62.1 (e092d0b6b 2022-07-16)\nbinary: rustc\ncommit-hash: e092d0b6b43f2de967af0887873151bb1c0b18d3\ncommit-date: 2022-07-16\nhost: x86_64-unknown-linux-gnu\nrelease: 1.62.1\nLLVM version: 14.0.5\n","stderr":""},"15697416045686424142":{"success":false,"status":"exit status: 1","code":1,"stdout":"","stderr":"error: `-Csplit-debuginfo` is unstable on this platform\n\n"},"10376369925670944939":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/julius/.rustup/toolchains/stable-x86_64-unknown-linux-gnu\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""}},"successes":{}}
|
52
depth-logger/record-depth-temp.py
Normal file
52
depth-logger/record-depth-temp.py
Normal file
@ -0,0 +1,52 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import board
|
||||
import time
|
||||
import busio
|
||||
import adafruit_ads1x15.ads1015 as ADS
|
||||
from adafruit_ads1x15.analog_in import AnalogIn
|
||||
from time import sleep, strftime
|
||||
|
||||
# Create the I2C bus
|
||||
i2c = busio.I2C(board.SCL, board.SDA)
|
||||
|
||||
# Create the ADC object using the I2C bus
|
||||
ads = ADS.ADS1015(i2c)
|
||||
|
||||
# Create single-ended input on channel 0
|
||||
tmp36 = AnalogIn(ads, ADS.P0)
|
||||
|
||||
# Attempting to create a single-ended input on channel 1
|
||||
depthS = AnalogIn(ads, ADS.P1)
|
||||
|
||||
# Subtract the offset from the sensor voltage
|
||||
# and convert chan.voltage * (1 degree C / 0.01V) = Degrees Celcius
|
||||
temperatureC = (tmp36.voltage - 0.5) / 0.01
|
||||
|
||||
# Open the file to write down the results
|
||||
timestr = time.strftime("%Y-%m-%dT%H-%M-%S")
|
||||
filename = "/home/shared/logger-raspi-setup/data/depth-temp/" + timestr + "depth_temperature_data.csv"
|
||||
|
||||
#depthM = ((depthS.voltage * 31.848) - 22.93)
|
||||
|
||||
#Attempting to round the figure to a more intelligible figure
|
||||
#rounddepth = round(depthM, ndigits)
|
||||
#psi = depthS.voltage * 104.1666667 - 75
|
||||
|
||||
#bar = psi * 14.503773800722
|
||||
|
||||
with open(filename, "w") as f:
|
||||
f.write("time and date, temperature (C), Voltage of depth sensor (V), Depth (m)\n")
|
||||
|
||||
while True:
|
||||
depthM = ((depthS.voltage * 31.848) - 22.93)
|
||||
rounddepth = round(depthM, 2)
|
||||
roundtemp = round(temperatureC, 2)
|
||||
roundvolts = round(depthS.voltage, 3)
|
||||
|
||||
print((str(roundtemp) + " °C ") + (str(roundvolts) + " V ") + (str(rounddepth) + " m"))
|
||||
|
||||
f.write(time.strftime("%Y-%m-%d %H:%M:%S") + ",")
|
||||
f.write((str(roundtemp) + " °C ") + "," + (str(roundvolts) + " V ") + "," + (str(rounddepth) + " m\n"))
|
||||
|
||||
time.sleep(3)
|
29
gps-logger/record-gps.py
Normal file
29
gps-logger/record-gps.py
Normal file
@ -0,0 +1,29 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
from gps import *
|
||||
from time import sleep, strftime
|
||||
|
||||
filename = "/home/shared/logger-raspi-setup/data/gps/" + time.strftime("%Y-%m-%dT%H-%M-%S") + "_GPS_data.csv"
|
||||
# filename = "/mnt/myssd/GPS_Data" + timestr +".csv"
|
||||
|
||||
with open(filename, "w", 1) as f:
|
||||
gpsd = gps(mode=WATCH_ENABLE|WATCH_NEWSTYLE)
|
||||
f.write("GPStime utc,latitude,longitude,speed,sats in view\n")
|
||||
|
||||
try:
|
||||
while True:
|
||||
report = gpsd.next()
|
||||
if report["class"] == "TPV":
|
||||
GPStime = str(getattr(report,"time",""))
|
||||
lat = str(getattr(report,"lat",0.0))
|
||||
lon = str(getattr(report,"lon",0.0))
|
||||
speed = str(getattr(report,"speed","nan"))
|
||||
sats = str(len(gpsd.satellites))
|
||||
|
||||
f.write(GPStime + "," + lat +"," + lon + "," + speed + "," + sats + "\n")
|
||||
|
||||
time.sleep(5)
|
||||
|
||||
except (KeyboardInterrupt, SystemExit): # when you press ctrl+c
|
||||
print("Done.\nExiting.")
|
||||
f.close()
|
@ -2,4 +2,8 @@
|
||||
|
||||
# Raspberry Pi water pressure sensor
|
||||
|
||||
https://www.circuito.io/app?components=9443,200000,267055
|
||||
https://www.circuito.io/app?components=9443,200000,267055
|
||||
|
||||
# Setting up Jack on Raspberry Pi
|
||||
|
||||
https://wiki.linuxaudio.org/wiki/raspberrypi
|
0
scripts/audio-setup.sh → scripts/audio-setup-utils.sh
Normal file → Executable file
0
scripts/audio-setup.sh → scripts/audio-setup-utils.sh
Normal file → Executable file
12
scripts/list-usb-devices.sh
Executable file
12
scripts/list-usb-devices.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
for sysdevpath in $(find /sys/bus/usb/devices/usb*/ -name dev); do
|
||||
(
|
||||
syspath="${sysdevpath%/dev}"
|
||||
devname="$(udevadm info -q name -p $syspath)"
|
||||
[[ "$devname" == "bus/"* ]] && exit
|
||||
eval "$(udevadm info -q property --export -p $syspath)"
|
||||
[[ -z "$ID_SERIAL" ]] && exit
|
||||
echo "/dev/$devname - $ID_SERIAL"
|
||||
)
|
||||
done
|
5
scripts/setup-audio.sh
Executable file
5
scripts/setup-audio.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Install jackd
|
||||
|
||||
# Audio setup utils
|
16
scripts/setup-gps.sh
Executable file
16
scripts/setup-gps.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
sudo apt-get update && sudo apt-get install -y \
|
||||
gpsd gpsd-clients
|
||||
|
||||
sudo systemctl stop gpsd.socket
|
||||
sudo systemctl disable gpsd.socket
|
||||
|
||||
device="/dev/ttyUSB0"
|
||||
|
||||
sudo gpsd ${device} -F /var/run/gpsd.sock
|
||||
|
||||
sudo sed -i "s|DEVICES=\"\"|DEVICES=\"${device}\"|g" /etc/default/gpsd
|
||||
|
||||
echo "START_DAEMON=\"true\"" | sudo tee -a /etc/default/gpsd
|
||||
|
3
scripts/start-all.sh
Executable file
3
scripts/start-all.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
(trap 'kill 0' SIGINT; ./scripts/start-gps.sh & ./scripts/start-audio.sh)
|
9
scripts/start-audio.sh
Executable file
9
scripts/start-audio.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Start jack server
|
||||
|
||||
sh scripts/start-jack.sh
|
||||
|
||||
# Start recording
|
||||
|
||||
cd audio-logger && cargo run
|
3
scripts/start-gps.sh
Executable file
3
scripts/start-gps.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/usr/bin/sh
|
||||
|
||||
python /home/shared/logger-raspi-setup/gps-logger/record-gps.py
|
7
scripts/start-jack.sh
Executable file
7
scripts/start-jack.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Get soundcard name
|
||||
soundcard=$(grep USB /proc/asound/cards | grep -oe "\[.*]" | tr -d "[] ")
|
||||
|
||||
# Start jack server
|
||||
/usr/bin/jackd -P75 -d alsa -d hw:${soundcard} -r 44100 -p 512 -n 3 &
|
Loading…
Reference in New Issue
Block a user