Skip to content

Commit 476ca73

Browse files
committed
doc: improve documentation and publish rustdoc
1 parent e8bc8d5 commit 476ca73

File tree

16 files changed

+2438
-106
lines changed

16 files changed

+2438
-106
lines changed

.github/workflows/docs.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Rust Documentation
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
workflow_dispatch: # Allows manual triggering from the Actions tab
7+
8+
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
9+
permissions:
10+
contents: read
11+
pages: write
12+
id-token: write
13+
14+
# Allow only one concurrent deployment
15+
concurrency:
16+
group: "pages"
17+
cancel-in-progress: true
18+
19+
jobs:
20+
build:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/checkout@v4
24+
25+
- name: Set up Rust
26+
uses: dtolnay/rust-toolchain@v1
27+
with:
28+
toolchain: 1.86.0
29+
30+
- name: Build documentation
31+
run: |
32+
# Build documentation with all features
33+
cargo doc --no-deps --all-features
34+
35+
# Create an index.html that redirects to the main crate documentation
36+
echo '<meta http-equiv="refresh" content="0; url=rust_photoacoustic">' > target/doc/index.html
37+
38+
# Copy the documentation to the GitHub Pages directory
39+
mkdir -p public
40+
cp -r target/doc/* public/
41+
42+
- name: Setup Pages
43+
uses: actions/configure-pages@v4
44+
45+
- name: Upload artifact
46+
uses: actions/upload-pages-artifact@v3
47+
with:
48+
path: './public'
49+
50+
deploy:
51+
environment:
52+
name: github-pages
53+
url: ${{ steps.deployment.outputs.page_url }}
54+
runs-on: ubuntu-latest
55+
needs: build
56+
steps:
57+
- name: Deploy to GitHub Pages
58+
id: deployment
59+
uses: actions/deploy-pages@v4

src/bin/differential.rs

Lines changed: 118 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,119 @@
11
// Copyright (c) 2025 Ronan LE MEILLAT, SCTG Development
22
// This file is part of the rust-photoacoustic project and is licensed under the
33
// SCTG Development Non-Commercial License v1.0 (see LICENSE.md for details).
4-
//! Differential processor utility
4+
5+
//! # Differential Processor Utility
6+
//!
7+
//! This binary tool processes WAV audio files to create differential signals for photoacoustic analysis.
8+
//! It supports several processing modes to help extract the relevant signal components from raw recordings.
9+
//!
10+
//! ## Features
11+
//!
12+
//! * Process stereo files and output the difference between channels (L-R or R-L)
13+
//! * Process two mono files and output their difference (file1-file2)
14+
//! * Apply gain adjustment to the resulting differential signal
15+
//!
16+
//! ## Usage
17+
//!
18+
//! ```
19+
//! differential --input input.wav --output output.wav --mode LeftMinusRight --gain 1.0
20+
//! ```
21+
//!
22+
//! For File1MinusFile2 mode:
23+
//!
24+
//! ```
25+
//! differential --input file1.wav --input2 file2.wav --output result.wav --mode File1MinusFile2
26+
//! ```
27+
//!
28+
//! ## Applications in Photoacoustic Analysis
29+
//!
30+
//! In photoacoustic spectroscopy, differential signals help isolate the actual acoustic response
31+
//! by removing common mode noise. This is particularly useful when:
532
//!
6-
//! This binary tool processes WAV files to create differential signals.
7-
//! It can:
8-
//! 1. Process a stereo file and output the difference between channels (L-R or R-L)
9-
//! 2. Process two mono files and output their difference (file1-file2)
33+
//! 1. Using stereo recordings where one channel contains the signal+noise and the other contains just noise
34+
//! 2. Comparing before/after recordings to isolate the effect of a stimulus
1035
1136
use clap::{Parser, ValueEnum};
1237
use hound::{SampleFormat, WavReader, WavSpec, WavWriter};
1338
use rust_photoacoustic::preprocessing::differential;
1439
use std::path::PathBuf;
1540

41+
/// Defines the different modes of differential signal processing.
42+
///
43+
/// The mode determines which channels or files are subtracted from each other
44+
/// to create the output signal.
1645
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
1746
enum DifferentialMode {
18-
/// Left minus Right (for stereo files)
47+
/// Left channel minus Right channel (for stereo files).
48+
///
49+
/// This mode is useful when the left channel contains signal+noise and
50+
/// the right channel contains a reference noise recording.
1951
LeftMinusRight,
20-
/// Right minus Left (for stereo files)
52+
53+
/// Right channel minus Left channel (for stereo files).
54+
///
55+
/// This mode is useful when the right channel contains signal+noise and
56+
/// the left channel contains a reference noise recording.
2157
RightMinusLeft,
22-
/// File1 minus File2 (for two mono files)
58+
59+
/// First file minus Second file (for two mono files).
60+
///
61+
/// This mode allows processing two separate recordings, such as with/without
62+
/// stimulus or before/after a treatment.
2363
File1MinusFile2,
2464
}
2565

66+
/// Command line arguments for the differential signal processor.
67+
///
68+
/// This structure defines all the parameters that can be provided via command line
69+
/// to control the differential processing of WAV files.
2670
#[derive(Parser, Debug)]
2771
#[command(name = "differential")]
28-
#[command(author = "Romain Lemeill")]
72+
#[command(author = "Ronan LE MEILLAT")]
2973
#[command(version = "1.0")]
3074
#[command(about = "Create differential signals from WAV files", long_about = None)]
3175
struct Args {
32-
/// Input WAV file (stereo or mono)
76+
/// Input WAV file (stereo or mono).
77+
///
78+
/// This is the primary input file. For LeftMinusRight and RightMinusLeft modes,
79+
/// this must be a stereo file. For File1MinusFile2 mode, this should be a mono file.
3380
#[arg(short = 'i', long)]
3481
input: PathBuf,
3582

36-
/// Second input WAV file (only used in File1MinusFile2 mode)
83+
/// Second input WAV file (only used in File1MinusFile2 mode).
84+
///
85+
/// This file is subtracted from the primary input file. It must be mono
86+
/// and have the same sample rate and bit depth as the primary input.
3787
#[arg(short = '2', long)]
3888
input2: Option<PathBuf>,
3989

40-
/// Output WAV file
90+
/// Output WAV file path where the differential signal will be saved.
91+
///
92+
/// The output will always be a mono WAV file with the same sample rate
93+
/// and bit depth as the input.
4194
#[arg(short, long)]
4295
output: PathBuf,
4396

44-
/// Differential mode
97+
/// Differential mode determining how the signals are combined.
98+
///
99+
/// Specifies which processing method to use: LeftMinusRight (default),
100+
/// RightMinusLeft, or File1MinusFile2.
45101
#[arg(short, long, value_enum, default_value_t = DifferentialMode::LeftMinusRight)]
46102
mode: DifferentialMode,
47103

48-
/// Gain to apply to the output (multiplier)
104+
/// Gain to apply to the output (multiplier).
105+
///
106+
/// This value multiplies each sample of the differential signal.
107+
/// Values greater than 1.0 amplify the signal, values less than 1.0 attenuate it.
108+
/// The result is clamped to prevent digital clipping.
49109
#[arg(short, long, default_value_t = 1.0)]
50110
gain: f32,
51111
}
52112

113+
/// Main entry point for the differential signal processing utility.
114+
///
115+
/// Parses command line arguments and routes processing to the appropriate function
116+
/// based on the selected differential mode.
53117
fn main() -> Result<(), Box<dyn std::error::Error>> {
54118
let args = Args::parse();
55119

@@ -74,6 +138,26 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
74138
Ok(())
75139
}
76140

141+
/// Processes a stereo WAV file to create a differential signal.
142+
///
143+
/// This function handles the LeftMinusRight and RightMinusLeft modes.
144+
/// It reads a stereo file, separates the channels, and creates a mono
145+
/// output file with the difference between the channels.
146+
///
147+
/// # Arguments
148+
///
149+
/// * `args` - Command line arguments containing input/output paths and processing parameters
150+
///
151+
/// # Returns
152+
///
153+
/// * `Result<(), Box<dyn std::error::Error>>` - Success or an error with description
154+
///
155+
/// # Errors
156+
///
157+
/// Will return an error if:
158+
/// - The input file cannot be read
159+
/// - The input file is not stereo
160+
/// - There is an issue writing the output file
77161
fn process_stereo_file(args: &Args) -> Result<(), Box<dyn std::error::Error>> {
78162
println!("Reading stereo file {:?}", args.input);
79163

@@ -139,6 +223,26 @@ fn process_stereo_file(args: &Args) -> Result<(), Box<dyn std::error::Error>> {
139223
Ok(())
140224
}
141225

226+
/// Processes two mono WAV files to create a differential signal.
227+
///
228+
/// This function handles the File1MinusFile2 mode. It reads two mono files,
229+
/// verifies their compatibility, and creates an output file with their difference.
230+
///
231+
/// # Arguments
232+
///
233+
/// * `args` - Command line arguments containing input/output paths and processing parameters
234+
///
235+
/// # Returns
236+
///
237+
/// * `Result<(), Box<dyn std::error::Error>>` - Success or an error with description
238+
///
239+
/// # Errors
240+
///
241+
/// Will return an error if:
242+
/// - Either input file cannot be read
243+
/// - Either input file is not mono
244+
/// - The input files have incompatible sample rates or bit depths
245+
/// - There is an issue writing the output file
142246
fn process_two_mono_files(args: &Args) -> Result<(), Box<dyn std::error::Error>> {
143247
let input2 = args.input2.as_ref().unwrap(); // Safe because we checked earlier
144248

0 commit comments

Comments
 (0)