Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updates #29

Merged
merged 8 commits into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ indent_size = 4
trim_trailing_whitespace = true
max_line_length = 80

[*.yml]
[{*.nix,*.yml}]
indent_size = 2
20 changes: 10 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,35 +44,35 @@ name = "general"
harness = false

[[example]]
name = "minimal-live-input"
name = "live-input-minimal"
required-features = ["recording"]

[[example]]
name = "minimal-live-input-gui"
name = "live-input-visualize"
required-features = ["recording"]

[dependencies]
# +++ NOSTD DEPENDENCIES +++

biquad = "0.4" # lowpass filter
libm = "0.2"# floating point operations
biquad = { version = "0.4", default-features = false } # lowpass filter
libm = { version = "0.2.8", default-features = false }
log = { version = "0.4", default-features = false }
ringbuffer = "0.15.0"
ringbuffer = { version = "0.15.0", default-features = false }

# +++ STD DEPENDENCIES +++
cpal = { version = "0.15", optional = true }
cpal = { version = "0.15", default-features = false, features = [], optional = true }


[dev-dependencies]
assert2 = "0.3.14"
ctrlc = { version = "3.4", features = ["termination"] }
criterion = { version = "0.5", features = [] }
float-cmp = "0.9.0"
float-cmp = "0.10.0"
hound = "3.5.1"
itertools = "0.13.0"
simple_logger = "5.0"
minifb = "0.25.0"
minifb = "0.27.0"
rand = "0.8.5"
wav = "1.0"


[profile.dev]
# otherwise many code is too slow
Expand Down
35 changes: 14 additions & 21 deletions benches/beat_detection_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ fn criterion_benchmark(c: &mut Criterion) {
// to be done.
let slice_of_interest = &samples[28000..28000 + 4096];

let mut detector = BeatDetector::new(header.sampling_rate as f32, true);
let mut detector = BeatDetector::new(header.sample_rate as f32, true);
c.bench_function(
"simulate beat detection (with lowpass) with 4096 samples per invocation",
|b| {
Expand All @@ -21,7 +21,7 @@ fn criterion_benchmark(c: &mut Criterion) {
},
);

let mut detector = BeatDetector::new(header.sampling_rate as f32, false);
let mut detector = BeatDetector::new(header.sample_rate as f32, false);
c.bench_function(
"simulate beat detection (no lowpass) with 4096 samples per invocation",
|b| {
Expand All @@ -44,37 +44,30 @@ mod samples {

/// Returns the mono samples of the holiday sample (long version)
/// together with the sampling rate.
pub fn holiday_long() -> (Vec<i16>, wav::Header) {
pub fn holiday_long() -> (Vec<i16>, hound::WavSpec) {
read_wav_to_mono("res/holiday_lowpassed--long.wav")
}
}

/// Copy and paste from `test_utils.rs`.
mod helpers {
use beat_detector::util::{f32_sample_to_i16, stereo_to_mono};
use beat_detector::util::stereo_to_mono;
use itertools::Itertools;
use std::fs::File;
use std::path::Path;
use wav::BitDepth;

pub fn read_wav_to_mono<T: AsRef<Path>>(file: T) -> (Vec<i16>, wav::Header) {
let mut file = File::open(file).unwrap();
let (header, data) = wav::read(&mut file).unwrap();
pub fn read_wav_to_mono<T: AsRef<Path>>(file: T) -> (Vec<i16>, hound::WavSpec) {
let mut reader = hound::WavReader::open(file).unwrap();
let header = reader.spec();

// owning vector with original data in f32 format
let data = match data {
BitDepth::Sixteen(samples) => samples,
BitDepth::ThirtyTwoFloat(samples) => samples
.into_iter()
.map(f32_sample_to_i16)
.map(Result::unwrap)
.collect::<Vec<_>>(),
_ => todo!("{data:?} not supported yet"),
};
// owning vector with original data in i16 format
let data = reader
.samples::<i16>()
.map(|s| s.unwrap())
.collect::<Vec<_>>();

if header.channel_count == 1 {
if header.channels == 1 {
(data, header)
} else if header.channel_count == 2 {
} else if header.channels == 2 {
let data = data
.into_iter()
.chunks(2)
Expand Down
2 changes: 1 addition & 1 deletion examples/cpal-info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use cpal::traits::DeviceTrait;
mod example_utils;

/// Minimal example to explore the structure of the audio input samples we get
/// from cpal. This example does nothing with the beat detection library.
/// from cpal. This binary does nothing with the beat detection library.
fn main() {
let input_device = example_utils::select_audio_device();
let supported_configs = input_device
Expand Down
57 changes: 0 additions & 57 deletions examples/cpal-minimal.rs

This file was deleted.

File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ fn main() {
panic!("{}", e);
});

// Limit to max ~60 fps update rate
window.limit_update_rate(Some(std::time::Duration::from_secs_f32(1.0 / 60.0)));
window.set_target_fps(60);

let handle = {
let rgb_buffer = rgb_buffer.clone();
Expand Down
18 changes: 12 additions & 6 deletions shell.nix
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
{ pkgs ? import <nixpkgs> { } }:
pkgs.mkShell rec {
packages = with pkgs; [
# Base deps
alsa-lib
pkg-config

let
libDeps = with pkgs; [
# gui examples (minifb)
libxkbcommon
xorg.libXcursor
xorg.libX11
];
in
pkgs.mkShell {
packages = with pkgs; [
# Base deps
alsa-lib
pkg-config

# benchmarks
gnuplot

# Development
nixpkgs-fmt
rustup
];
] ++ libDeps;

LD_LIBRARY_PATH = "${pkgs.lib.makeLibraryPath libDeps}";
}
9 changes: 5 additions & 4 deletions src/audio_history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,10 @@ impl Ord for SampleInfo {
}

/// Accessor over the captured audio history that helps to identify the
/// timestamp of each sample. Users are supposed to add new data in chunks that
/// are less than the buffer size, to slowly fade out old data from the
/// underlying ringbuffer.
/// timestamp of each sample.
///
/// Users are supposed to add new data in chunks that are less than the buffer
/// size, to slowly fade out old data from the underlying ringbuffer.
#[derive(Debug)]
pub struct AudioHistory {
audio_buffer: ConstGenericRingBuffer<i16, DEFAULT_BUFFER_SIZE>,
Expand Down Expand Up @@ -320,7 +321,7 @@ mod tests {
fn audio_history_on_real_data() {
let (samples, header) = crate::test_utils::samples::sample1_long();

let mut history = AudioHistory::new(header.sampling_rate as f32);
let mut history = AudioHistory::new(header.sample_rate as f32);
history.update(samples.iter().copied());

assert_eq!(
Expand Down
16 changes: 8 additions & 8 deletions src/beat_detector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ mod tests {
#[allow(non_snake_case)]
fn detect__static__no_lowpass__holiday_single_beat() {
let (samples, header) = test_utils::samples::holiday_single_beat();
let mut detector = BeatDetector::new(header.sampling_rate as f32, false);
let mut detector = BeatDetector::new(header.sample_rate as f32, false);
assert_eq!(
detector.update_and_detect_beat(samples.iter().copied()),
Some(EnvelopeInfo {
Expand Down Expand Up @@ -230,7 +230,7 @@ mod tests {
#[allow(non_snake_case)]
fn detect__static__lowpass__holiday_single_beat() {
let (samples, header) = test_utils::samples::holiday_single_beat();
let mut detector = BeatDetector::new(header.sampling_rate as f32, true);
let mut detector = BeatDetector::new(header.sample_rate as f32, true);
assert_eq!(
detector
.update_and_detect_beat(samples.iter().copied())
Expand Down Expand Up @@ -265,13 +265,13 @@ mod tests {
fn detect__dynamic__no_lowpass__holiday_single_beat() {
let (samples, header) = test_utils::samples::holiday_single_beat();

let mut detector = BeatDetector::new(header.sampling_rate as f32, false);
let mut detector = BeatDetector::new(header.sample_rate as f32, false);
assert_eq!(
simulate_dynamic_audio_source(256, &samples, &mut detector),
&[829]
);

let mut detector = BeatDetector::new(header.sampling_rate as f32, false);
let mut detector = BeatDetector::new(header.sample_rate as f32, false);
assert_eq!(
simulate_dynamic_audio_source(2048, &samples, &mut detector),
&[829]
Expand All @@ -283,7 +283,7 @@ mod tests {
fn detect__dynamic__no_lowpass__sample1_double_beat() {
let (samples, header) = test_utils::samples::sample1_double_beat();

let mut detector = BeatDetector::new(header.sampling_rate as f32, false);
let mut detector = BeatDetector::new(header.sample_rate as f32, false);
assert_eq!(
simulate_dynamic_audio_source(2048, &samples, &mut detector),
&[1309, 8637]
Expand All @@ -295,7 +295,7 @@ mod tests {
fn detect__dynamic__lowpass__sample1_long() {
let (samples, header) = test_utils::samples::sample1_long();

let mut detector = BeatDetector::new(header.sampling_rate as f32, true);
let mut detector = BeatDetector::new(header.sample_rate as f32, true);
assert_eq!(
simulate_dynamic_audio_source(2048, &samples, &mut detector),
&[12939, 93789, 101457, 189595, 270785, 278473]
Expand All @@ -307,7 +307,7 @@ mod tests {
fn detect__dynamic__no_lowpass__holiday_long() {
let (samples, header) = test_utils::samples::holiday_long();

let mut detector = BeatDetector::new(header.sampling_rate as f32, false);
let mut detector = BeatDetector::new(header.sample_rate as f32, false);
assert_eq!(
simulate_dynamic_audio_source(2048, &samples, &mut detector),
&[29077, 31225, 47053, 65811, 83773, 101995, 120137, 138131]
Expand All @@ -319,7 +319,7 @@ mod tests {
fn detect__dynamic__lowpass__holiday_long() {
let (samples, header) = test_utils::samples::holiday_long();

let mut detector = BeatDetector::new(header.sampling_rate as f32, true);
let mut detector = BeatDetector::new(header.sample_rate as f32, true);
assert_eq!(
simulate_dynamic_audio_source(2048, &samples, &mut detector),
&[31335, 47163, 65921, 84223, 102105, 120247, 138559]
Expand Down
12 changes: 6 additions & 6 deletions src/envelope_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ mod tests {
// sample1: single beat
{
let (samples, header) = test_utils::samples::sample1_single_beat();
let mut history = AudioHistory::new(header.sampling_rate as f32);
let mut history = AudioHistory::new(header.sample_rate as f32);
history.update(samples.iter().copied());

// Taken from waveform in Audacity.
Expand All @@ -349,7 +349,7 @@ mod tests {
// sample1: double beat
{
let (samples, header) = test_utils::samples::sample1_double_beat();
let mut history = AudioHistory::new(header.sampling_rate as f32);
let mut history = AudioHistory::new(header.sample_rate as f32);
history.update(samples.iter().copied());

// Taken from waveform in Audacity.
Expand All @@ -372,7 +372,7 @@ mod tests {
// good enough.
{
let (samples, header) = test_utils::samples::holiday_single_beat();
let mut history = AudioHistory::new(header.sampling_rate as f32);
let mut history = AudioHistory::new(header.sample_rate as f32);
history.update(samples.iter().copied());

// Taken from waveform in Audacity.
Expand All @@ -387,7 +387,7 @@ mod tests {
#[test]
fn find_envelopes_sample1_single_beat() {
let (samples, header) = test_utils::samples::sample1_single_beat();
let mut history = AudioHistory::new(header.sampling_rate as f32);
let mut history = AudioHistory::new(header.sample_rate as f32);
history.update(samples.iter().copied());

let envelopes = EnvelopeIterator::new(&history, None)
Expand All @@ -400,7 +400,7 @@ mod tests {
#[test]
fn find_envelopes_sample1_double_beat() {
let (samples, header) = test_utils::samples::sample1_double_beat();
let mut history = AudioHistory::new(header.sampling_rate as f32);
let mut history = AudioHistory::new(header.sample_rate as f32);
history.update(samples.iter().copied());

let envelopes = EnvelopeIterator::new(&history, None)
Expand All @@ -419,7 +419,7 @@ mod tests {
#[test]
fn find_envelopes_holiday_single_beat() {
let (samples, header) = test_utils::samples::holiday_single_beat();
let mut history = AudioHistory::new(header.sampling_rate as f32);
let mut history = AudioHistory::new(header.sample_rate as f32);
history.update(samples.iter().copied());

let envelopes = EnvelopeIterator::new(&history, None)
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ mod tests {
use crate::test_utils;
use std::vec::Vec;

fn _print_sample_stats((samples, header): (Vec<i16>, wav::Header)) {
let mut history = AudioHistory::new(header.sampling_rate as f32);
fn _print_sample_stats((samples, header): (Vec<i16>, hound::WavSpec)) {
let mut history = AudioHistory::new(header.sample_rate as f32);
history.update(samples.iter().copied());

let all_peaks = MaxMinIterator::new(&history, None).collect::<Vec<_>>();
Expand Down
Loading