Skip to content

[Feature]: Add COLA constraint utility function is_cola #19

Description

@gabyfle

Initial Checklist

  • I have searched the existing issues to ensure this feature has not already been requested.

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

  • A new public function SoundML.Utils..is_cola is available in the library's utility module.
  • Comprehensive documentation (using odoc) is provided for the function. The documentation must detail each parameter, the return value, potential exceptions, and explicitly state the conditions required for perfect reconstruction.

Core Functionality & Correctness

  • The function correctly implements a check for the weak COLA constraint, which is sufficient for perfect reconstruction of unmodified spectra.
  • The function supports two distinct checking methods, specified by a method parameter:
    • 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.
  • The function returns true for a comprehensive set of known COLA-compliant combinations.
  • The function returns false for parameter combinations known to violate the COLA constraint.

Parameter Handling & Validation

  • The function correctly infers the window length from the input window array.
  • The function raises an appropriate, clearly-defined exception for invalid inputs, such as a hop_length that is less than or equal to zero, or an empty window array.

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.

  1. Parameter Validation: Check that hop_length > 0 and the window is not empty.
  2. 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.
  3. 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.
  4. 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

Metadata

Metadata

Assignees

Labels

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions