proteus_lib/peaks/mod.rs
1//! Peak extraction and binary peak-file utilities for waveform display.
2
3mod error;
4mod extract;
5mod format;
6
7pub use error::PeaksError;
8
9/// A single peak window with maximum and minimum sample amplitude.
10#[derive(Debug, Clone, Copy)]
11pub struct PeakWindow {
12 pub max: f32,
13 pub min: f32,
14}
15
16/// Peak data for all channels at a fixed window size.
17#[derive(Debug, Clone)]
18pub struct PeaksData {
19 pub sample_rate: u32,
20 pub window_size: u32,
21 pub channels: Vec<Vec<PeakWindow>>,
22}
23
24/// Query options for reading peaks from a binary peaks file.
25#[derive(Debug, Clone, Default)]
26pub struct GetPeaksOptions {
27 /// Start timestamp in seconds (inclusive). If omitted, reads from file start.
28 pub start_seconds: Option<f64>,
29 /// End timestamp in seconds (exclusive). If omitted, reads to file end.
30 pub end_seconds: Option<f64>,
31 /// Maximum number of peak windows to return per channel.
32 ///
33 /// If the range contains fewer peaks than requested, all peaks are returned.
34 pub target_peaks: Option<usize>,
35 /// Maximum number of channels to return.
36 ///
37 /// Channels are selected from index 0 upward.
38 pub channels: Option<usize>,
39}
40
41/// Decode an audio file and write its peaks to a binary file.
42///
43/// # Arguments
44/// * `input_audio_file` - Source audio path.
45/// * `output_peaks_file` - Destination binary peaks file path.
46///
47/// # Errors
48/// Returns an error if audio decode fails or if writing the peaks file fails.
49pub fn write_peaks(input_audio_file: &str, output_peaks_file: &str) -> Result<(), PeaksError> {
50 let peaks = extract::extract_peaks_from_audio(input_audio_file, false)?;
51 format::write_peaks_file(output_peaks_file, &peaks)
52}
53
54/// Read all peaks from a binary peaks file.
55///
56/// # Arguments
57/// * `peaks_file` - Path to a binary peaks file previously written by [`write_peaks`].
58/// * `options` - Query options for range, peak count, and channel count.
59///
60/// # Returns
61/// Per-channel peak data after applying range/channel/downsample options.
62///
63/// # Errors
64/// Returns an error if the file cannot be read or has an invalid peaks format.
65pub fn get_peaks(peaks_file: &str, options: GetPeaksOptions) -> Result<PeaksData, PeaksError> {
66 format::read_peaks_with_options(peaks_file, &options)
67}
68
69/// Read all channels and all peaks from a binary peaks file.
70///
71/// # Arguments
72/// * `peaks_file` - Path to a binary peaks file previously written by [`write_peaks`].
73///
74/// # Returns
75/// Full per-channel peak data.
76///
77/// # Errors
78/// Returns an error if the file cannot be read or has an invalid peaks format.
79pub fn get_all_peaks(peaks_file: &str) -> Result<PeaksData, PeaksError> {
80 get_peaks(peaks_file, GetPeaksOptions::default())
81}
82
83/// Read peaks from a binary peaks file for a specific time range in seconds.
84///
85/// # Arguments
86/// * `peaks_file` - Path to a binary peaks file.
87/// * `start_seconds` - Start timestamp (inclusive).
88/// * `end_seconds` - End timestamp (exclusive).
89///
90/// # Returns
91/// Per-channel peak data for the requested time range.
92///
93/// # Errors
94/// Returns an error if timestamps are invalid, or if file IO/format parsing fails.
95pub fn get_peaks_in_range(
96 peaks_file: &str,
97 start_seconds: f64,
98 end_seconds: f64,
99) -> Result<PeaksData, PeaksError> {
100 get_peaks(
101 peaks_file,
102 GetPeaksOptions {
103 start_seconds: Some(start_seconds),
104 end_seconds: Some(end_seconds),
105 ..Default::default()
106 },
107 )
108}
109
110/// Decode an audio file directly into in-memory peaks.
111///
112/// # Arguments
113/// * `file_path` - Source audio path.
114/// * `limited` - If true, only channel 0 is processed.
115///
116/// # Returns
117/// In-memory per-channel peak data.
118///
119/// # Errors
120/// Returns an error if decoding fails.
121pub fn extract_peaks_from_audio(file_path: &str, limited: bool) -> Result<PeaksData, PeaksError> {
122 extract::extract_peaks_from_audio(file_path, limited)
123}