audio_processor_analysis/transient_detection/stft/markers.rs
1// Augmented Audio: Audio libraries and applications
2// Copyright (c) 2022 Pedro Tacla Yamada
3//
4// The MIT License (MIT)
5//
6// Permission is hereby granted, free of charge, to any person obtaining a copy
7// of this software and associated documentation files (the "Software"), to deal
8// in the Software without restriction, including without limitation the rights
9// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10// copies of the Software, and to permit persons to whom the Software is
11// furnished to do so, subject to the following conditions:
12//
13// The above copyright notice and this permission notice shall be included in
14// all copies or substantial portions of the Software.
15//
16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22// THE SOFTWARE.
23use audio_processor_traits::{AudioBuffer, AudioProcessorSettings};
24
25use super::{find_transients, IterativeTransientDetectionParams};
26
27#[derive(Clone, Debug)]
28pub struct AudioFileMarker {
29 pub position_samples: usize,
30}
31
32/// Helper for extracting vector of transient markers from buffer
33pub fn build_markers(
34 settings: &AudioProcessorSettings,
35 audio_file_buffer: &mut [f32],
36 params: IterativeTransientDetectionParams,
37 gate: f32,
38) -> Vec<AudioFileMarker> {
39 let transients = find_transients(
40 params,
41 &mut AudioBuffer::from_interleaved(1, audio_file_buffer),
42 );
43 let mut peak_detector = crate::peak_detector::PeakDetector::default();
44 let attack_mult = crate::peak_detector::calculate_multiplier(settings.sample_rate, 0.1);
45 let release_mult = crate::peak_detector::calculate_multiplier(settings.sample_rate, 15.0);
46 let transients: Vec<f32> = transients
47 .iter()
48 .map(|f| {
49 peak_detector.accept_frame(attack_mult, release_mult, &[*f]);
50 peak_detector.value()
51 })
52 .collect();
53
54 let markers_from_transients = {
55 let mut markers = vec![];
56 let mut inside_transient = false;
57 for (index, sample) in transients.iter().cloned().enumerate() {
58 if sample >= gate && !inside_transient {
59 inside_transient = true;
60 markers.push(index);
61 } else if sample < gate {
62 inside_transient = false;
63 }
64 }
65 markers
66 };
67
68 markers_from_transients
69 .into_iter()
70 .map(|position_samples| AudioFileMarker { position_samples })
71 .collect()
72}