diff options
Diffstat (limited to 'doc/archive/MQ_EXTRACTION_IMPROVEMENTS.md')
| -rw-r--r-- | doc/archive/MQ_EXTRACTION_IMPROVEMENTS.md | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/doc/archive/MQ_EXTRACTION_IMPROVEMENTS.md b/doc/archive/MQ_EXTRACTION_IMPROVEMENTS.md new file mode 100644 index 0000000..7bc5c5d --- /dev/null +++ b/doc/archive/MQ_EXTRACTION_IMPROVEMENTS.md @@ -0,0 +1,42 @@ +# MQ Extraction Improvements + +This document outlines three enhancements to the partial extraction algorithm (`mq_extract.js`) to improve tracking accuracy and the quality of the resulting sinusoidal model. + +## 1. Proposal: Predictive Kinematic Tracking + +- **Problem**: The original tracking algorithm assumes a partial's frequency is relatively static between frames. It can fail to track partials with significant, rapid frequency changes (e.g., fast vibrato or glissando) if the change exceeds the fixed frequency tolerance (`trackingRatio`). + +- **Solution**: A simple kinematic model has been added to the tracking logic. + - For each active partial, we now estimate its frequency "velocity" (the rate of change between the last two frames). + - When searching for a matching peak in the next frame, the search is centered around a *predicted* frequency: `predicted_freq = last_freq + velocity`. + - This allows the tracker to anticipate movement and maintain lock on partials that are undergoing rapid, continuous change. + +- **Implementation**: + - The `trackPartials` function now stores a `velocity` property on active partial objects. + - This velocity is updated each time a new peak is added to the partial. + - The core matching logic now uses the predicted frequency as its reference. + +## 2. Proposal: Peak Prominence Pruning + +- **Problem**: The original peak detection algorithm identified any local maximum within a 5-bin window. This could lead to the detection of many small, noisy, or spurious peaks that are not musically significant, creating a large number of short, irrelevant partials for the tracker to process. + +- **Solution**: The `detectPeaks` function has been enhanced with a "prominence" filter. + - A peak's prominence is its height in decibels relative to the lowest "valley" between it and the next higher peak on either side. This measures how much a peak "stands out" from the surrounding spectral landscape. + - A new **Prominence (dB)** parameter is available in the UI. Only peaks that exceed this prominence threshold are passed to the tracking stage. + +- **Implementation**: + - After a local maximum is found, a new algorithm searches left and right to find the lowest point (the valley floor) before encountering a bin with a higher magnitude than the peak itself. + - The prominence is calculated as `peak_magnitude - valley_floor_magnitude`. + - If this value is below the user-defined threshold, the peak is discarded. This effectively prunes insignificant peaks, cleaning the data for the tracker. + +## 3. Proposal: Least-Squares Bezier Fitting + +- **Problem**: The original `fitBezier` function used a simple heuristic. It forced the Bezier curve to pass exactly through four points (start, end, and two internal points at 1/3 and 2/3 of the duration). For noisy or complex partials, this could result in a curve that did not accurately represent the partial's overall trajectory. + +- **Solution**: The heuristic has been replaced with a proper **least-squares fitting algorithm**. + - This method calculates the cubic Bezier curve that minimizes the overall error across *all* points in the partial's trajectory. + - The start and end points of the curve are fixed to match the partial's birth and death, but the two intermediate control points are mathematically optimized to produce the best possible fit to the data. + +- **Implementation**: + - A new `fitBezier` function implements the normal equations to solve the 2x2 linear system for the optimal `v1` and `v2` control point values. + - This results in a smoother, more representative curve that is less sensitive to individual noisy points within the partial. |
