Initial Checklist
Problem Statement & User Value
As a DSP Engineer, I want to programmatically verify if my chosen window function and hop length will result in perfect reconstruction, so that I can confidently select STFT parameters and debug my audio processing pipelines without performing a full, computationally expensive STFT/iSTFT round-trip.
Acceptance Criteria (Definition of Done)
API Definition
Core Functionality & Correctness
Parameter Handling & Validation
Proposed Solution or Technical Approach (Optional)
1. The COLA Principle
The Constant Overlap-Add (COLA) constraint ensures that the sum of overlapping windows is a non-zero constant.
- For the standard Overlap-Add (OLA) method, the condition is:
$\sum_{m=-\infty}^{\infty} w[n - mH] = C \neq 0$
- For the Weighted Overlap-Add (WOLA) method, which underpins the least-squares iSTFT algorithm, the condition applies to the squared window:
$\sum_{m=-\infty}^{\infty} w^2[n - mH] = C \neq 0$
where $w$ is the window, $H$ is the hop size (hop_length), and $C$ is a constant. The is_cola function will numerically test if this sum is constant over one period.
2. Proposed API Design for SoundML.is_cola
OCaml Signature:
type cola_method: Ola | Wola
val is_cola :
window:('a, 'b, 'dev) Rune.t ->
hop_length:int ->
?method:cola_method ->
bool
3. Implementation Strategy
The check can be implemented directly without complex transforms.
- Parameter Validation: Check that
hop_length > 0 and the window is not empty.
- Determine Window for Summation:
- Get the window length
win_length from window.
- If
method is Ola, use w = window.
- If
method is Wola, compute w = Rune.sqrt window.
- Simulate Overlap-Add:
- The periodicity of the sum is
gcd(win_length, hop_length). A simpler, sufficient approach is to check over a buffer of length 2 * win_length.
- Initialize a summation buffer
win_sum of this length to all zeros.
- Iterate through window positions
m = 0, 1, 2,... such that m * hop_length covers the buffer. For each position, add w to the corresponding slice of win_sum.
- Check for Constant Value:
- Extract a stable, central portion of the
win_sum buffer to analyze, avoiding edge effects (e.g., from win_length to win_length + hop_length - 1).
- Check if all values in this stable region are equal to the first value within a small floating-point tolerance (e.g.,
1e-7).
- Also, ensure this constant value is not close to zero.
- Return the boolean result of this check.
Additional Context (Mockups, Links, etc.)
No response
References
Code of Conduct
Initial Checklist
Problem Statement & User Value
As a DSP Engineer, I want to programmatically verify if my chosen window function and hop length will result in perfect reconstruction, so that I can confidently select STFT parameters and debug my audio processing pipelines without performing a full, computationally expensive STFT/iSTFT round-trip.
Acceptance Criteria (Definition of Done)
API Definition
SoundML.Utils..is_colais available in the library's utility module.Core Functionality & Correctness
methodparameter:Ola: Checks the standard overlap-add condition:sum_m(w[n - m*H]) = C.'Wola': Checks the weighted overlap-add condition:sum_m(w[n - m*H]^2) = C, which is relevant for least-squares iSTFT implementations.truefor a comprehensive set of known COLA-compliant combinations.falsefor parameter combinations known to violate the COLA constraint.Parameter Handling & Validation
windowarray.hop_lengththat is less than or equal to zero, or an emptywindowarray.Proposed Solution or Technical Approach (Optional)
1. The COLA Principle
The Constant Overlap-Add (COLA) constraint ensures that the sum of overlapping windows is a non-zero constant.
where
hop_length), andis_colafunction will numerically test if this sum is constant over one period.2. Proposed API Design for
SoundML.is_colaOCaml Signature:
3. Implementation Strategy
The check can be implemented directly without complex transforms.
hop_length > 0and the window is not empty.win_lengthfromwindow.methodisOla, usew = window.methodisWola, computew = Rune.sqrt window.gcd(win_length, hop_length). A simpler, sufficient approach is to check over a buffer of length2 * win_length.win_sumof this length to all zeros.m = 0, 1, 2,...such thatm * hop_lengthcovers the buffer. For each position, addwto the corresponding slice ofwin_sum.win_sumbuffer to analyze, avoiding edge effects (e.g., fromwin_lengthtowin_length + hop_length - 1).1e-7).Additional Context (Mockups, Links, etc.)
No response
References
Code of Conduct