Matlab Analyze Time Frequency Content
MathWorksOfficialCreated by MathWorks
- Skill
- Tool integration
- Science and research
- BSD-2-Clause
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a comprehensive framework for analyzing how frequency content evolves over time using MATLAB. It covers a wide range of analytical techniques including Short-Time Fourier Transform (STFT), Continuous Wavelet Transform (CWT), synchrosqueezing, reassignment, and adaptive signal decomposition (EMD/VMD). The skill is designed to help users select the appropriate method based on their specific signal characteristics and research goals, offering guidance on visualization, mode extraction, and cross-signal analysis.
What it does
- Visualizes time-frequency content using spectrograms and scalograms.
- Supports advanced signal decomposition via EMD, VMD, and multiresolution analysis.
- Enables mode extraction and signal reconstruction from time-frequency representations.
- Computes time-varying coherence and cross-spectra between two signals.
- Provides diagnostic tools to assess signal properties before analysis.
- Offers a decision logic for choosing between STFT, CWT, and other transform methods.
When to use it
- When you need to analyze the evolution of frequency content over time.
- When choosing between different time-frequency representations like STFT or CWT.
- When you need to extract and reconstruct individual signal components.
- When comparing two signals using time-varying coherence or cross-spectrum analysis.
- When decomposing signals into additive time-domain components.
Advantages
- Provides a structured decision tree for selecting the optimal analysis method.
- Includes diagnostic scripts to assess signal length, bandwidth, and nonstationarity.
- Supports both interactive exploration and programmatic data analysis.
- Clearly distinguishes between invertible and non-invertible analysis techniques.
- Offers specific guidance on handling boundary effects and frequency resolution.
Usage examples
- “How do I visualize the time-frequency content of a non-stationary signal?”
- The agent will recommend using signalAnalyzer for interactive exploration or cwt for multi-resolution visualization, depending on the signal's bandwidth.
- “I need to extract a specific mode from my signal using synchrosqueezing.”
- The agent will guide you through the fsst or wsst workflow, including ridge extraction and subsequent signal reconstruction.
- “How can I compare the time-varying coherence of two signals?”
- The agent will provide the wcoherence syntax and explain how to interpret the phase arrows and coherence magnitude.
- “What is the best way to decompose a signal into adaptive components?”
- The agent will recommend emd or vmd based on whether the number of components is known and provide the necessary function calls.
Install
1 of its files are not mirrored here, so install it from its source:
https://github.com/matlab/matlab-agentic-toolkit/tree/2a7f215e965597acf6ed495beb9e7b8aff45a3be/skills-catalog/signal-processing/matlab-analyze-time-frequency-content
Documentation by MathWorks
Time-Frequency Analysis in MATLAB
Analyze how frequency content evolves over time using STFT, CWT, synchrosqueezing, reassignment, cross-signal methods, and data-adaptive decomposition.
Agent directive: Consult the reference guides in
references/before answering. Each guide covers a specific domain with syntax, gotchas, and common mistakes.
When To Use
Analyzing how frequency content evolves over time (spectrogram, scalogram)
Choosing between STFT, CWT, synchrosqueezing, reassignment, or EMD/VMD
Extracting and reconstructing individual signal components from a TF representation
Computing time-varying coherence or cross-spectrum between two signals
Decomposing signals into additive time-domain components (wavelet MRA, EMD, VMD)
Estimating instantaneous frequency or Hilbert spectrum
When Not To Use
Designing or applying classical FIR/IIR filters — use
matlab-design-digital-filterExtracting scalar features for ML classification — use
matlab-extract-signal-featuresSignal preprocessing (resampling, detrending, gap filling) — use
matlab-prepare-signal-dataQuadratic/bilinear TFDs (Wigner-Ville) — not supported in MATLAB toolboxes
Audio-specific representations (mel spectrogram, MFCC) — use Audio Toolbox
Method Selection
Choose the analysis method based on the user's goal and signal characteristics:
| Goal | Method | Guide |
|---|---|---|
| Interactive TF exploration (spectrogram + scalogram) | signalAnalyzer | — |
| General TF visualization (uniform freq resolution) | stft, spectrogram, pspectrum | references/stft-guide.md |
| TF visualization (multi-resolution, constant-Q) | cwt, cwtfilterbank | references/cwt-guide.md |
| Sharpest TF picture (non-invertible) | spectrogram("reassigned"), pspectrum(Reassigned=true) | references/reassignment-guide.md |
| Remove specific TF regions (mask-based filtering) | tffilt with binary mask | references/stft-guide.md |
| Mode extraction + reconstruction (STFT domain) | fsst → tfridge → ifsst | references/reassignment-guide.md |
| Mode extraction + reconstruction (CWT domain) | wsst → wsstridge → iwsst | references/reassignment-guide.md |
| Signal reconstruction from CWT | icwt (exact or approximate) | references/cwt-guide.md |
| Additive decomposition (octave bands) | modwt + modwtmra | references/multiresolution-guide.md |
| Additive decomposition (uniform bands) | modwptdetails | references/multiresolution-guide.md |
| Adaptive decomposition (unknown components) | emd | references/multiresolution-guide.md |
| Adaptive decomposition (known mode count) | vmd | references/multiresolution-guide.md |
| Hilbert spectrum / instantaneous frequency | hht, instfreq | references/multiresolution-guide.md |
| Time-varying coherence between two signals | wcoherence | references/cross-analysis-guide.md |
| Cross spectrogram between two signals | xspectrogram | references/cross-analysis-guide.md |
| Global coherence (no time axis) | mscohere, cpsd | references/cross-analysis-guide.md |
For detailed decision logic, see references/method-selection-guide.md.
Quick Decision Tree
What is the primary goal?
│
├── Interactive exploration (adjust parameters, compare views)
│ └── signalAnalyzer — supports spectrogram + scalogram (CWT) side by side
│
├── Visualize one signal's TF content
│ ├── Need uniform frequency resolution? → stft / spectrogram / pspectrum
│ ├── Need multi-resolution (better low-freq)? → cwt
│ └── Need sharpest picture (no reconstruction)? → spectrogram("reassigned")
│
├── Remove unwanted content visible in spectrogram
│ └── Define binary mask over TF plane → tffilt (Gabor domain)
│
├── Extract and reconstruct individual components
│ ├── From TF representation (invertible)?
│ │ ├── STFT domain → fsst → tfridge → ifsst
│ │ └── CWT domain → wsst → wsstridge → iwsst
│ ├── Additive time-domain components?
│ │ ├── Octave bands → modwt + modwtmra
│ │ ├── Uniform bands → modwptdetails
│ │ └── Data-adaptive → emd or vmd
│ └── From CWT directly? → icwt (see references/cwt-guide.md)
│
├── Compare two signals
│ ├── Time-varying coherence? → wcoherence
│ ├── Time-varying cross-spectrum? → xspectrogram
│ └── Global relationship? → mscohere / cpsd
│
└── Estimate instantaneous frequency
├── Single monocomponent signal? → instfreq(x, fs)
├── Multicomponent (want per-mode IF)? → emd → instfreq(imf, fs)
└── Multicomponent (want single average)? → instfreq(x, fs, Method="tfmoment")Critical Rules
stfthas no reassignment option. Usefsstfor invertible synchrosqueezing orspectrogram("reassigned")for non-invertible visualization.wsstridgeargument order differs fromtfridge:wsstridge(sst, penalty, f, ...)— penalty is 2nd positional argtfridge(tfm, f, penalty, ...)— penalty is 3rd positional arg
wsstsubtracts the signal mean internally.iwsstdoes NOT restore it. Addmean(x)back manually if DC matters.ifsstis machine-precision;iwsstis approximate (Morlet single-integral formula).xspectrogramfirst output is real (cross-spectrogram magnitude). For phase, use the 4th outputP. This differs fromspectrogramwhose first output is complex STFT.wcoherencehas noParentoption. For App Designer, compute outputs and plot manually.wcoherencephase arrows show the phase lag of Y relative to X:↑ = Y lags X by π/2
↓ = Y leads X by π/2
→ = in-phase
← = anti-phase
PhaseDisplayThreshold(default 0.5) is plot-only — it controls which arrows are drawn but has no effect on returned numeric outputs.
hhttakes IMFs, not raw signal. Always decompose first:imf = emd(x); hht(imf, fs).instfreqHilbert method is meaningless for multicomponent signals. Decompose first, or useMethod="tfmoment"for a single average curve.Synchrosqueezing is precision-sensitive. Use double-precision data with
fsst/wsstfor reproducible results across MATLAB, codegen, and GPU.
Signal Assessment Workflow
When the user provides a signal and asks "what should I use?", run the assessment script then apply agent-side interpretation:
Step 1: Run MATLAB assessment
report = assessSignalForTF(x, fs);
disp(report)
disp(report.recommendations)The script returns: signal length, occupied bandwidth, number of spectral peaks (with frequencies), nonstationarity indicator, DC content, precision, and auto-generated recommendations.
Step 2: Agent-side interpretation (combine script output with user goals)
| User Goal | Key Report Fields | Recommendation Logic |
|---|---|---|
| "Explore / I'm not sure what I need" | — | Suggest signalAnalyzer for interactive exploration (spectrogram + scalogram views, adjustable parameters) |
| "Visualize frequency content over time" | likelyNonstationary, fractionalBandwidth | If wideband (>2 octaves): cwt. If narrowband or uniform resolution needed: stft/spectrogram |
| "Separate/extract components" | numSpectralPeaks, peakFrequenciesHz | 2–3 peaks: synchrosqueezing (fsst/wsst). Many peaks: emd/vmd. Closely-spaced: modwptdetails or fsst |
| "Reconstruct after filtering" | hasDC, precision | fsst/ifsst for exact. wsst/iwsst for CWT-domain (warn about mean). icwt for CWT bandpass |
| "Compare two signals" | (run on both) | wcoherence for coherence. xspectrogram for cross-spectrum |
| "Detect transients/events" | signalLength, occupiedBandHz | cwt with low TimeBandwidth. Or short-window stft |
Step 3: Refine with follow-up questions if ambiguous
"Do you need to reconstruct the signal, or just visualize?"
"Do you need uniform frequency resolution, or is multi-resolution acceptable?"
"Are you comparing this signal to another?"
Reference Guides
| File | Coverage |
|---|---|
references/stft-guide.md | stft/istft, spectrogram, pspectrum, stftmag2sig, length preservation, COLA |
references/cwt-guide.md | cwt, cwtfilterbank, icwt, dlicwt/icwtLayer, boundary, constant-Q |
references/reassignment-guide.md | fsst/ifsst, wsst/iwsst, spectrogram("reassigned"), pspectrum(Reassigned=true), ridge extraction, penalty |
references/cross-analysis-guide.md | wcoherence, xspectrogram, cpsd, mscohere, phase arrows, unsmoothed cross-spectrum |
references/multiresolution-guide.md | modwt/modwtmra, modwpt/modwptdetails, emd, vmd, hht, instfreq, instbw |
references/method-selection-guide.md | Decision logic for choosing among all methods |
Toolbox Requirements
| Toolbox | Functions |
|---|---|
| Signal Processing | stft, istft, spectrogram, pspectrum, fsst, ifsst, tfridge, xspectrogram, instfreq, instbw, stftmag2sig, cpsd, mscohere |
| Wavelet | cwt, cwtfilterbank, icwt, wsst, iwsst, wsstridge, wcoherence, modwt, modwtmra, modwpt, modwptdetails, emd, vmd, hht, tffilt, dgt |
| Function | Available From | Note |
|---|---|---|
tffilt | R2025a | TF mask-based filtering; all other functions available in R2024b |
Documentation References
| Topic | Link |
|---|---|
| Time-frequency gallery | https://www.mathworks.com/help/signal/time-frequency-analysis.html |
| Wavelet time-frequency | https://www.mathworks.com/help/wavelet/time-frequency-analysis.html |
| CWT reference | https://www.mathworks.com/help/wavelet/ref/cwt.html |
| STFT reference | https://www.mathworks.com/help/signal/ref/stft.html |
| Synchrosqueezing example | https://www.mathworks.com/help/wavelet/ug/time-frequency-reassignment-and-mode-extraction-with-synchrosqueezing.html |
| Wavelet coherence example | https://www.mathworks.com/help/wavelet/ug/compare-time-frequency-content-in-signals-with-wavelet-coherence.html |
Copyright 2026 The MathWorks, Inc.
Files
- ATTRIBUTION.mdAdded by AutoGineer1.1 KiB
- LICENSELicence file added by AutoGineer1.4 KiB
- SKILL.md10.7 KiB
- manifest.yaml517 B
- references/cross-analysis-guide.md11.7 KiB
- references/cwt-guide.md22.3 KiB
- references/method-selection-guide.md6.2 KiB
- references/multiresolution-guide.md17.9 KiB
- references/reassignment-guide.md11.8 KiB
- references/stft-guide.md16.4 KiB
- scripts/assessBoundary.m3.1 KiB
- scripts/assessSignalForTF.m4.8 KiB
- scripts/assessSpectralEnergy.m3.4 KiB
- scripts/boundaryExDisjointSine.mat(opens on GitHub)Not mirrored: opens on GitHub7.6 KiB
- scripts/illustrateBoundary.m902 B
- scripts/illustrateTransientLocalization.m1.3 KiB
- scripts/plotAntiAnalyticScalogram.m831 B
references/stft-guide.md
STFT Reference Guide
Function Roles
| Function | Purpose | Inverse | Use when |
|---|---|---|---|
stft | Complex-valued STFT coefficients | istft | Analysis-modify-resynthesize workflows |
spectrogram | Power/magnitude spectrogram | None built-in | Visualization, exploratory analysis, PSD estimation |
pspectrum | Calibrated power spectrum | None | Measurements, reassigned spectrograms |
Key differences between spectrogram, stft, and pspectrum
| Aspect | spectrogram / stft | pspectrum |
|---|---|---|
| Window choice | Any user-specified window vector | Always Kaiser (Leakage 0–1; maps to beta = 40*(1-leakage)) |
| Resolution control | Window length in samples (user computes M ≥ fs/Δf) | FrequencyResolution or TimeResolution in Hz/seconds |
| Output normalization | 'psd' or 'power' flag (spectrogram) | Power only; Type selects mode ("power", "spectrogram", "persistence") |
| Underlying transform | FFT (user-specified nfft) | CZT (Chirp Z-Transform) — can zoom into arbitrary [f1, f2] range |
| Overlap specification | Samples (noverlap) | Percentage (OverlapPercent) |
| Frequency zoom | Manual (user crops after computing full spectrum) | Built-in via FrequencyLimits — evaluates only the requested range |
| Edge handling | Truncates incomplete frames | Zero-pads to create extra segment |
| Invertible | stft → istft (yes); spectrogram (no) | No |
| Multichannel | Supported | Not supported for "spectrogram" or "persistence" types |
| Reassignment | Not available | Built-in (Reassign=true) |
spectrogram and stft offer much more control than pspectrum — the user specifies the exact window, number of DFT points, and overlap in samples. pspectrum abstracts these away (always Kaiser, internally computed window length, overlap as percentage), trading control for convenience.
pspectrum's advantage is its CZT-based engine: it can efficiently zoom into a narrow frequency band via FrequencyLimits without computing the full-band spectrum, and it derives the window length automatically from the user's FrequencyResolution target.
When to use which:
stft/istft: User needs to invert (modify spectrum and reconstruct the signal)stftorspectrogram: User needs full control over the STFT (specific window, nfft, overlap, PSD normalization)pspectrum: User just needs a quick analysis of the signal (auto-selects parameters, gives power directly, supports frequency zoom and reassignment)
Analysis-Modify-Resynthesize with stft/istft
CRITICAL: Check Length Preservation FIRST
Before writing any stft→istft code, always check this condition:
The ratio (Nx - L) / (M - L) must be an integer for istft to return the same length as the input, where:
Nx= signal length (samples)L= overlap lengthM= window length
If this ratio is not an integer, adjust M or L until it is. Do not rely on padding or truncation as the primary fix — choose parameters that satisfy the condition.
% FIRST: Check the integer-ratio condition
Nx = length(x);
M = 256; L = 128;
hop = M - L;
ratio = (Nx - L) / hop;
if ratio ~= floor(ratio)
error("(Nx-L)/(M-L) = %.4f — not integer. Adjust M or L.", ratio)
endExample — signal of 1000 samples:
% BAD: (1000-128)/(256-128) = 6.8125 — not integer → length mismatch
% GOOD: (1000-100)/(200-100) = 9 — integer → same length, perfect reconstructionThis is separate from the COLA condition. A window can satisfy COLA but still produce a length mismatch if this integer ratio is not met.
COLA Condition
For perfect reconstruction (when the STFT is unmodified), the window and overlap must satisfy the Constant Overlap-Add constraint:
tf = iscola(win, noverlap); % verify before committing to parametersRequired Workflow for stft→istft
Choose window length
Mand overlapLbased on resolution needsCheck
(Nx - L) / (M - L)is an integer — adjust M or L if not (preferred over padding)Verify
iscola(win, noverlap)is trueUse identical
Window,OverlapLength,FFTLengthin bothstftandistft
If adjusting parameters is not possible (e.g., M is fixed by resolution requirements), then pad the signal to make Nx satisfy the condition and trim after istft.
Inversion: Which Function to Use
| Situation | Function | Notes |
|---|---|---|
| Have full complex STFT (magnitude + phase) | istft | Exact, one-shot overlap-add reconstruction |
| Have only STFT magnitude (no phase) | stftmag2sig | Iterative phase recovery (Griffin-Lim and variants) |
Used spectrogram | Switch to stft/istft | spectrogram is not invertible |
Phaseless Reconstruction with stftmag2sig
When the user only has the STFT magnitude — e.g., "phaseless reconstruction", "I only have the magnitude", "how can I recover the phase" — use stftmag2sig:
% Reconstruct signal from STFT magnitude only
[x, t, info] = stftmag2sig(S_mag, nfft, fs, ...
Window=win, OverlapLength=noverlap, ...
Method="fgla", MaxIterations=200);
% Check convergence
fprintf("Inconsistency: %.2e (after %d iterations)\n", ...
info.Inconsistency(end), info.NumIterations);Methods: "gla" (Griffin-Lim, default), "fgla" (fast variant), "legla" (Le Roux), "gd" (gradient descent, requires Deep Learning Toolbox)
Key requirements:
WindowandOverlapLengthmust match the original STFT computationThe same integer-ratio length condition
(Nx - L)/(M - L)appliesResult is approximate (phase is estimated, not exact)
Interpreting Spectral Values Across Functions
Users often compare values from different functions at the same frequency and get confused because the numbers don't match. Here's how to reconcile them.
For a sine wave of amplitude A at frequency f₀, true average power = A²/2.
What each function returns at f₀
| Function | Value at f₀ | Depends on window? | Physical meaning |
|---|---|---|---|
pspectrum (power or spectrogram) | A²/2 | No — normalized internally | True average power (V²) |
pwelch(...,'power') | A²/2 | No — normalized internally | True average power (V²) |
pwelch(...,'psd') | A²/(2×ENBW) | Yes — via ENBW | Power spectral density (V²/Hz) |
stft | (A/2) × sum(win) | Yes — scales with window | Raw complex coefficient |
Converting stft output to physical values
stft values scale directly with the window sum — changing window length changes the numbers:
% stft values are window-dependent:
% hann(256): sum(win) = 127.5 → |S| = 63.75
% hann(512): sum(win) = 255.5 → |S| ≈ 127.75
% hann(1024): sum(win) = 511.5 → |S| ≈ 255.75
% To get physical values from stft:
amplitude = 2 * abs(S) / sum(win); % one-sided amplitude
power = 2 * abs(S).^2 / sum(win)^2; % one-sided power (matches pspectrum)Converting PSD to power
For windowed PSD estimates (pwelch with 'psd'), power = PSD × ENBW (not PSD × df):
ENBW = fs * sum(win.^2) / sum(win)^2; % effective noise bandwidth
power = psd_value * ENBW; % matches pwelch 'power' outputThe ENBW accounts for the window's spectral spreading. For Hann(256) at fs=1000: ENBW ≈ 5.88 Hz (wider than the 1 Hz bin width).
Summary
pspectrumandpwelch(...,'power')give true power directly — no conversion neededpwelch(...,'psd')gives density — multiply by ENBW for powerstftgives window-scaled coefficients — divide by sum(win) for amplitude, or use2×|S|²/sum(win)²for power
Time-Frequency Filtering with tffilt (R2025a+)
tffilt applies a binary mask to the discrete Gabor transform (DGT) of a signal, then reconstructs the filtered result. It enables "paint-and-remove" workflows: identify unwanted regions in the time-frequency plane, mask them, and get a clean signal back.
Syntax
y = tffilt(bmask, x);
y = tffilt(bmask, x, WindowLength=128, HopLength=32, NumFrequencyBins=256, Method="igm");Creating the Binary Mask
The mask is a logical matrix (nFreqBins × nTimeSteps) where true = remove that TF bin. The mask dimensions must match the DGT of x with the same HopLength, NumFrequencyBins, and FrequencyRange.
% Compute DGT to see the TF plane
c = dgt(x, WindowLength=128, HopLength=32, NumFrequencyBins=256);
f = (0:size(c,1)-1) * fs / 256;
t = (0:size(c,2)-1) * 32 / fs;
% Create mask — example: remove a frequency band between 200-300 Hz
bmask = false(size(c));
bmask(f >= 200 & f <= 300, :) = true;
% Or: remove energy above a threshold in a time range
bmask = abs(c) > threshold & t_grid > t1 & t_grid < t2;
% Apply mask and reconstruct
y = tffilt(bmask, x, WindowLength=128, HopLength=32, NumFrequencyBins=256);Reconstruction Methods
| Method | Algorithm | Quality | Speed | Use when |
|---|---|---|---|---|
"gm" | Direct mask × DGT → IDGT | Artifacts at mask edges | Fast | Quick preview; large masks |
"igm" (default) | Inverse Gabor multiplier (PCG solver) | Good | Moderate | General use |
"rigm" | Regularized optimization (Nyström eigendecomposition) | Best | Slow | Critical quality; complex mask shapes |
Name-Value Options
| Option | Default | Purpose |
|---|---|---|
WindowLength | 128 | Gaussian window length (determines time-freq tradeoff) |
HopLength | 32 | Hop size (must match mask creation) |
NumFrequencyBins | 256 | Freq bins (must exceed HopLength for redundancy) |
FrequencyRange | "centered" | "centered", "onesided", or "twosided" |
Method | "igm" | Reconstruction method |
When to Use tffilt vs Other Approaches
| Scenario | Use | Why |
|---|---|---|
| Remove a known interferer visible in the spectrogram | tffilt | Define mask by frequency band or TF region |
| Separate harmonic from percussive (audio) | tffilt with ratio-based mask | Mask from abs(Dperc) > 0.5*abs(Dmix) |
| Remove transient at a known time | tffilt | Time-localized mask |
| Extract a single mode/ridge | fsst → tfridge → ifsst | Ridge-following is more precise for narrowband modes |
| Denoise (threshold-based) | stft → soft-threshold → istft | Direct coefficient modification, no mask needed |
Key Constraints
NumFrequencyBinsmust exceedHopLength(ensures redundancy for reconstruction)All DGT parameters must be identical between mask creation and
tffiltcallSignal is zero-padded internally if length is not a multiple of LCM(HopLength, WindowLength)
Supports codegen (MATLAB Coder) and GPU arrays (R2026a+)
Frequency Resolution
The frequency resolution of the STFT is determined by the window length:
df = fs / Mwhere M is the window length in samples. Longer windows give finer frequency resolution at the cost of time resolution (the time-frequency uncertainty tradeoff).
Zero-padding (FFTLength > M) interpolates the spectrum for smoother display but does not improve true frequency resolution.
Parameter Recommendation Workflow
When the user provides a signal and asks for time-frequency analysis via STFT, gather these inputs and compute parameters systematically.
Inputs to gather
| Input | How to determine | Default if unknown |
|---|---|---|
Sample rate fs | User provides or read from data | Required — ask |
Signal length Nx | length(x) | Read from signal |
Minimum frequency separation to resolve Δf | User's goal (e.g., "separate 48 Hz from 50 Hz" → Δf = 2 Hz) | fs/256 |
| Whether istft reconstruction is needed | User mentions filtering, denoising, modification | Assume no |
Parameter computation
% 1. Window length from resolution requirement
% Minimum: M >= fs / delta_f
% Practical (Hann/Hamming mainlobe ~2x wider): M >= 2*fs / delta_f
M_min = ceil(2 * fs / delta_f);
% Round up to a convenient value (power of 2 helps FFT speed, not required)
M = 2^nextpow2(M_min); % or just use M_min directly
% 2. Overlap — 75% is standard for Hann/Hamming (good COLA, smooth time axis)
L = round(0.75 * M);
% 3. If istft is needed, verify length preservation
hop = M - L;
if mod(Nx - L, hop) ~= 0
% Adjust overlap to satisfy integer constraint
% Find largest L < M such that (Nx - L) is divisible by (M - L)
for L_try = L:-1:1
if mod(Nx - L_try, M - L_try) == 0
L = L_try;
break
end
end
end
% 4. Verify COLA
win = hann(M, 'periodic');
assert(iscola(win, L), "Window/overlap do not satisfy COLA")Flag tradeoffs to the user
After computing parameters, report:
Time resolution: each window spans
M/fssecondsFrequency resolution:
df = fs/MHz (true), practical ~2*fs/Mfor HannNumber of time frames:
floor((Nx - L) / (M - L))
If the window spans a large fraction of the signal (M > Nx/4), warn:
"Window length is M samples (T seconds) — you will have very few time frames. Consider whether CWT or synchrosqueezing would better serve your time-frequency localization needs."
When to recommend a different method
| Situation | Recommendation |
|---|---|
| Need both fine frequency AND fine time resolution | CWT (cwt) — multi-resolution, no fixed window |
| Need sharper TF representation of the STFT | Synchrosqueezed STFT (fsst) |
| Transient detection + spectral analysis | CWT or reassigned spectrogram (pspectrum with Reassign=true) |
| Stationary signal, only need spectrum (no time axis) | pwelch or periodogram |
| Log-frequency spacing (music/audio) | Constant-Q transform (cqt/icqt) |
Deep Learning Integration
| Use case | Functions | Notes |
|---|---|---|
| Network layer (standard architecture) | stftLayer / istftLayer | Drop into dlnetwork; TransformMode controls output ("mag", "realimag", etc.) |
| Custom training loop | dlstft / dlistft | Accept dlarray inputs; support automatic differentiation |
stftLayer properties:
TransformMode:"mag","squaremag","logmag","logsquaremag", or"realimag"— controls what representation feeds the next layerWeightLearnRateFactor: default 0 (fixed window). Set > 0 to learn the analysis window during training.Input:
"CBT"(channels, batch, time). Output:"SCBT"(S = frequency).
Gotcha — real/complex data flow between layers and dl-functions:
stftLayeronly outputs real-valued data.istftLayeronly accepts real-valued data. The layer pair usesTransformMode="realimag"to concatenate real and imaginary parts along the channel dimension.dlstftoutputs complex-valueddlarray.dlistftaccepts both complex-valued and real-valued inputs.
dlistft input conventions (can be confusing):
Accepts
"SCBT"or"CBT"formatteddlarray(S = frequency, C = channel, B = batch, T = time)If
"CBT"format: the function unflattens to"SCBT"internally. The"C"dimension must be divisible byfloor(FFTLength/2)+1.If
"SCBT"format: the"S"dimension must equalfloor(FFTLength/2)+1.If the input is real-valued,
dlistftassumes real and imaginary parts are concatenated along the channel dimension (same convention asistftLayer). Therefore the number of channels C must be even — the true number of channels is C/2.If the input is complex-valued, channels are interpreted directly.
Gotcha — formatted vs unformatted dlarray:
dlstft and dlistft produce formatted dlarray outputs only when the input is a formatted dlarray. If the input is an unformatted dlarray, you must specify DataFormat — otherwise the call errors. The output will then also be unformatted.
% Formatted input → formatted output (preferred)
x_fmt = dlarray(x, "CBT");
y = dlstft(x_fmt, fs, Window=win); % output is formatted "SCBT"
% Unformatted input → MUST specify DataFormat, output is unformatted
x_raw = dlarray(x);
y = dlstft(x_raw, fs, Window=win, DataFormat="CBT"); % output is unformatted
% This ERRORS:
% y = dlstft(x_raw, fs, Window=win); % no DataFormat, unformatted input → errorFurther Reading
For a visual comparison of all time-frequency methods (STFT, CWT, Wigner-Ville, synchrosqueezing, constant-Q, data-adaptive MRA), see the Time-Frequency Gallery.
Copyright 2026 The MathWorks, Inc.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- MathWorks
- Publisher
- MathWorks (Official)
- Source
- matlab/matlab-agentic-toolkit · skills-catalog/signal-processing/matlab-analyze-time-frequency-content · commit 2a7f215
- Licence
- BSD 2-Clause License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE.md)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by MathWorks.
Get it from the source
1 of this skill’s files are not mirrored here, so there is no ZIP. Get the complete skill from its source: matlab/matlab-agentic-toolkit