---
name: matlab/matlab-extract-signal-features
source: https://app.decimal.ai/s/matlab-matlab-extract-signal-features@1/SKILL.md
source_sha256: 07ede4a1671f
---

# Extract Signal Features

Per-frame feature extraction for 1D signals using the three Signal Processing Toolbox extractor objects. Picks the right extractor, configures it with real parameters only, and adds a GPU code path when one is available.

## When to Use

- The user has a 1D signal and wants per-frame features for analysis or ML.
- The user names specific features from any of the three extractor domains (time, frequency, time-frequency).
- The user asks for a feature table or feature matrix to feed `fitcecoc`, `fitcnet`, or any classifier / regressor.
- The user asks for per-frame statistics over a windowed signal.

## When NOT to Use

- **Filter design or signal preprocessing** — out of scope. Filtering before feature extraction is a separate concern.
- **Audio-specific features** (MFCC, mel-spectrogram, pitch, chroma, gammatone). Audio Toolbox's `audioFeatureExtractor` covers those — out of scope here.
- **Batch / dataset orchestration** — `signalDatastore`, `labeledSignalSet`, `tall` arrays. The per-file extraction is in scope; building the pipeline around it is not.
- **2D, image, or multivariate features** — out of scope by signal-type boundary.

## Workflow

0. **(Recommended) Run a quick preliminary analysis.** Check *spectral* stationarity — does the frequency content drift over time? — on a representative subset using Signal Processing Toolbox alone: a `pspectrum(x, fs, "spectrogram")` look plus a per-frame `MeanFrequency` drift ratio (no Econometrics Toolbox needed; `adftest`/`kpsstest` are an optional supplement only). Use the verdict to pick the *primary* extractor — non-stationary signals favour `signalTimeFrequencyFeatureExtractor`; spectrally stationary signals lean on the frequency extractor. See `references/preliminary-analysis.md`. Then write down a ranked candidate feature list, spanning **more than one domain** for a classifier/regressor feature table, with one-line justifications tying each feature to an observed signal characteristic, *before* configuring the extractors. The verdict picks the primary extractor, not the only one — a set that collapses onto a single extractor is the most common cause of a weak downstream classifier. Example: *"MeanFrequency — stationary harmonic, energy localized at known frequencies."* See `references/feature-ranking.md`.
1. **Pick the extractor** based on what the user wants. See "Choosing the right extractor" below.
2. **Configure** with `SampleRate`, `FrameSize`, and either `FrameRate` or `FrameOverlapLength` (not both). Enable feature flags as name-value pairs.
3. **(Optional) Set per-feature or per-transform parameters** via `setExtractorParameters` for features/transforms that have them. Only `signalFrequencyFeatureExtractor` and `signalTimeFrequencyFeatureExtractor` support this method. The second argument can be a feature name OR a transform name. **Before writing any `setExtractorParameters` call, open the matching reference file and copy the parameter name verbatim.** Parameter names are not what you'd guess. The references are the source of truth.
4. **(Optional) Move to GPU** using the guard pattern in `references/gpu-patterns.md`.
5. **Run `extract(sFE, x)`** on the signal. Output shape depends on `FeatureFormat` (matrix or table). `src` may also be a `signalDatastore` / `audioDatastore`, in which case `extract` returns one result per file (a cell array) and accepts `UseParallel=true` to process files on a parallel pool — use it whenever extracting over many files. For the input contract, the per-extractor output shape, datastore/parallel extraction, and how to combine outputs across extractors, see `references/extract-function.md`.
6. **Decide output shape.** Do NOT aggregate per-frame results by default. The per-frame table is a valid final output. Aggregate (mean/std across frames) only if the user's downstream model requires one fixed-length vector per signal (e.g., `fitcecoc`, `fitcsvm`, tree ensembles). If the model consumes sequences (LSTM, 1-D CNN, transformer), keep the per-frame table as-is. If the user has variable-length signals and the downstream task is unclear, ask rather than assuming aggregation. See `references/post-extraction-patterns.md`.

**Stop and check the matching per-extractor reference before:**
- Enabling any feature on `signalTimeFrequencyFeatureExtractor` — each `Transform` supports a different subset.
- Calling `setExtractorParameters` — parameter names differ per feature and per transform.
- Using any feature flag, parameter, or `Transform` value not already shown in this file's patterns. If it isn't in the per-extractor reference, it doesn't exist on the object.

## Choosing the right extractor

| User wants | Use |
|---|---|
| Time-domain features (amplitude, energy, shape factors) | `signalTimeFeatureExtractor` |
| Frequency-domain features (spectral location, power, bandwidth, PSD) | `signalFrequencyFeatureExtractor` |
| Time-frequency features (spectral shape, instantaneous, ridges, wavelet, EMD-derived) | `signalTimeFrequencyFeatureExtractor` |
| Multiple of the above | Use multiple extractors; concatenate the resulting tables |

For the time-frequency extractor, the `Transform` property gates which features are valid. See the compatibility matrix in `references/signal-time-frequency-feature-extractor.md`.

## Key Functions

| Function | Purpose | Toolbox | Available From |
|---|---|---|---|
| `signalTimeFeatureExtractor` | Time-domain feature extractor object | Signal Processing Toolbox | R2021a |
| `signalFrequencyFeatureExtractor` | Frequency-domain feature extractor object | Signal Processing Toolbox | R2021b |
| `signalTimeFrequencyFeatureExtractor` | Time-frequency feature extractor object | Signal Processing Toolbox | R2024a |
| `extract` | Run a configured extractor on a signal | Signal Processing Toolbox | R2021a |
| `getExtractorParameters` / `setExtractorParameters` | Read/write per-feature or per-transform parameters (frequency and time-frequency only) | Signal Processing Toolbox | R2021b |
| `timeFrequencyFeatureTransformOptions` | Create transform options object for `signalTimeFrequencyFeatureExtractor` (replaces string `Transform=`) | Signal Processing Toolbox | R2026a |
| `generateMATLABFunction` | Emit a codegen-compatible MATLAB function from an extractor | Signal Processing Toolbox | R2021a |
| `canUseGPU`, `gather` | GPU availability check and data transfer (core MATLAB, no toolbox) | MATLAB | R2020b |
| `gpuArray` | Move array to GPU memory | Parallel Computing Toolbox | R2012a |

**`gpuArray` input to `extract` is available per extractor from:** `signalTimeFeatureExtractor` R2023a, `signalFrequencyFeatureExtractor` R2023a, `signalTimeFrequencyFeatureExtractor` **R2024b** (one release after the object itself). Requires Parallel Computing Toolbox. See [`references/gpu-patterns.md`](references/gpu-patterns.md) for per-transform limitations.

`generateMATLABFunction` exists for codegen workflows. Mention it when relevant; full codegen guidance is out of scope for this skill.

## Patterns

### Time-domain features per frame

```matlab
function featureTable = extractTimeFeaturesExample(x, fs)
%extractTimeFeaturesExample Per-frame time-domain features as a table.
    arguments
        x  (:, 1) double {mustBeFinite}
        fs (1, 1) double {mustBePositive}
    end

    sFE = signalTimeFeatureExtractor( ...
        SampleRate=fs, ...
        FrameSize=round(0.1 * fs), ...
        FrameOverlapLength=round(0.05 * fs), ...
        RMS=true, ...
        CrestFactor=true, ...
        PeakValue=true, ...
        FeatureFormat="table");

    featureTable = extract(sFE, x);
end
```

For valid time-feature flags, see `references/signal-time-feature-extractor.md`.

### Frequency-domain features with per-feature parameters

```matlab
function featureTable = extractBandPowerExample(x, fs)
%extractBandPowerExample Band power and occupied bandwidth per frame.
    arguments
        x  (:, 1) double {mustBeFinite}
        fs (1, 1) double {mustBePositive}
    end

    sFE = signalFrequencyFeatureExtractor( ...
        SampleRate=fs, ...
        FrameSize=round(0.1 * fs), ...
        FrameOverlapLength=round(0.05 * fs), ...
        BandPower=true, ...
        OccupiedBandwidth=true, ...
        FeatureFormat="table");

    setExtractorParameters(sFE, "OccupiedBandwidth", Percentage=95);

    featureTable = extract(sFE, x);
end
```

For per-feature parameter tables (including the trap that `PowerBandwidth` takes `RelativeAmplitude` not `Power`), see `references/signal-frequency-feature-extractor.md`.

### Time-frequency features (spectrogram transform)

```matlab
function featureTable = extractTFFeaturesExample(x, fs)
%extractTFFeaturesExample Spectral entropy and instantaneous frequency per frame.
    arguments
        x  (:, 1) double {mustBeFinite}
        fs (1, 1) double {mustBePositive}
    end

    % R2026a+ (preferred): use timeFrequencyFeatureTransformOptions.
    % Constructor is name-value only, keyed by FEATURE name -> transform.
    % There is no positional-string form: timeFrequencyFeatureTransformOptions("spectrogram") errors.
    tfOpts = timeFrequencyFeatureTransformOptions( ...
        SpectralEntropy="spectrogram", ...
        InstantaneousFrequency="spectrogram");
    sFE = signalTimeFrequencyFeatureExtractor( ...
        Transform=tfOpts, ...
        SampleRate=fs, ...
        FrameSize=256, ...
        FrameOverlapLength=128, ...
        SpectralEntropy=true, ...
        InstantaneousFrequency=true, ...
        FeatureFormat="table");

    % R2024a–R2025b: use string directly (deprecated from R2026a)
    % sFE = signalTimeFrequencyFeatureExtractor( ...
    %     Transform="spectrogram", ...
    %     SampleRate=fs, ...
    %     FrameSize=256, ...
    %     FrameOverlapLength=128, ...
    %     SpectralEntropy=true, ...
    %     InstantaneousFrequency=true, ...
    %     FeatureFormat="table");

    setExtractorParameters(sFE, "spectrogram", Leakage=0.9, OverlapPercent=85);

    featureTable = extract(sFE, x);
end
```

Each `Transform` supports a different subset of features, and per-feature parameters depend on `(transform, feature)`. Always check `references/signal-time-frequency-feature-extractor.md` before enabling a feature or calling `setExtractorParameters`.

**Multi-transform routing (R2026a+):** A single extractor can route different features to different transforms — you do NOT need separate extractors. Use `timeFrequencyFeatureTransformOptions` with per-feature properties (e.g., `SpectralKurtosis="synchrosqueezedspectrogram"`, `SpectralEntropy="spectrogram"`). See the full example and valid-transform table in `references/signal-time-frequency-feature-extractor.md`.

### GPU-accelerated extraction

> **Toolbox note:** The GPU path (`gpuArray`) and the `UseParallel=true` datastore path both require **Parallel Computing Toolbox**. It is *not* required for core feature extraction — the skill runs fully on CPU without it, because the `canUseGPU()` guard skips the GPU branch and `UseParallel` defaults to `false`. Enable these paths only when Parallel Computing Toolbox is installed.

```matlab
function featureTable = extractWithGPU(x, fs)
%extractWithGPU Run feature extraction on GPU when available, CPU otherwise.
    arguments
        x  (:, 1) double {mustBeFinite}
        fs (1, 1) double {mustBePositive}
    end

    sFE = signalTimeFeatureExtractor( ...
        SampleRate=fs, ...
        FrameSize=round(0.1 * fs), ...
        FrameOverlapLength=round(0.05 * fs), ...
        RMS=true, ...
        StandardDeviation=true, ...
        FeatureFormat="table");

    if canUseGPU()
        x = gpuArray(x);
    end
    featureTable = extract(sFE, x);
end
```

The feature table may contain gpuArray columns. Downstream code (ML training, plotting) often accepts these directly. Call `gather` only when a specific consumer requires it (e.g., `save` to .mat, `writetable` to CSV).

See `references/gpu-patterns.md` for the rationale behind the `canUseGPU` guard and why unconditional `gpuArray` calls are wrong. If the GPU path unexpectedly falls back to CPU or `gpuArray` errors, the `matlab-setup-gpu` skill diagnoses GPU availability problems (unlicensed PCT, outdated driver, compute mode).

### Post-extraction: aggregation and reproducibility

Do not aggregate unless the user's workflow explicitly requires one feature vector per signal. The per-frame table is the default output. Two optional patterns that run after `extract`:

- **Per-frame → per-signal aggregation** — only when the downstream model requires a fixed-length vector per example (tree ensembles, SVM, etc.). Collapse with `varfun(@mean, ...)` / `varfun(@std, ...)`, dropping `FrameStartTime` / `FrameEndTime` first. Skip aggregation for sequence models (LSTM, 1-D CNN) that consume the frame sequence directly. For scalar summaries of vector-valued features, use `setScalarizationMethods` at extraction time instead.
- **Save extractor + data card** — `save("featureConfig.mat", "sFE", "dataCard")` where `dataCard` records `SampleRate`, `FrameSize`, `FrameOverlapLength`, `class(sFE)`, and `version("-release")`. Minimum sidecar to reproduce the extraction on new data.

See `references/post-extraction-patterns.md` for the worked code blocks and edge cases (vector-valued columns, label-column handling, alternative scalarization route).

## Conventions (apply to all three extractors)

- **Always set `SampleRate`.** Frequency-derived features interpret the signal as `fs = 1` if `SampleRate` is omitted.
- **Pick `FrameRate` or `FrameOverlapLength`, not both.** They control the same thing two different ways. Setting both raises an error.
- **`FrameOverlapLength` must be `< FrameSize`.**
- **Set `FrameSize` and `FrameOverlapLength` in samples**, not seconds. Convert: `FrameSize = round(durationSeconds * fs)`.
- **Prefer `FeatureFormat="table"`** when the extractor produces a mix of scalar and vector features.
- **`FrameStartTime` / `FrameEndTime` are 1-indexed sample positions**, not seconds. Convert: `tSec = (T.FrameStartTime - 1) / fs`. Strip them before training a classifier.
- **Vector-valued feature columns are numeric matrices when per-frame length is fixed, cells when it varies.** Check with `iscell(T.(colName))` before indexing.
- **Don't guess feature names or parameters.** Read the relevant per-extractor reference. Anything not in the reference does not exist on the object.

## Common cross-cutting pitfalls

| What you tried | Fix |
|---|---|
| Hand-rolled per-frame statistics over a windowed signal (e.g. RMS / crest factor loop on a buffered signal) | Use the extractor object — composes with `extract`, has a codegen path. |
| `FrameLength=N` instead of `FrameSize=N` | Property is `FrameSize` on all three extractors. |
| Set both `FrameRate` and `FrameOverlapLength` | Pick one. |
| `gpuArray(x)` without `canUseGPU()` guard | Hard-errors on CPU-only machines. Wrap in `if canUseGPU(); x = gpuArray(x); end`. |

For extractor-specific pitfalls (e.g., `Skewness=true` on the time extractor, `MeanEnvelopeEnergy` on a non-EMD transform, the `PowerBandwidth` parameter being `RelativeAmplitude` rather than guessed from the feature name), see the per-extractor references.

## References

- [`references/preliminary-analysis.md`](references/preliminary-analysis.md) — Signal-Processing-only spectral-stationarity check (`pspectrum` spectrogram + per-frame `MeanFrequency` drift ratio), the optional Econometrics `adftest`/`kpsstest` supplement, and the verdict→extractor decision rules. Read before picking an extractor when the signal character is unclear.
- [`references/feature-ranking.md`](references/feature-ranking.md) — a-priori candidate-feature list pattern and the signal-profile→feature mapping. Read when the user asks for a starting feature set or wants a ranked list.
- [`references/extract-function.md`](references/extract-function.md) — `extract` input/output contract, per-extractor output character, multi-extractor row alignment, and common error modes. Read when debugging shape or alignment issues.
- [`references/signal-time-feature-extractor.md`](references/signal-time-feature-extractor.md) — full property and feature-flag surface for the time extractor. Read when verifying a time-feature name or property.
- [`references/signal-frequency-feature-extractor.md`](references/signal-frequency-feature-extractor.md) — full property surface plus per-feature parameter tables (`OccupiedBandwidth`, `PowerBandwidth`, `WelchPSD`, peak parameters). Read when configuring frequency features.
- [`references/signal-time-frequency-feature-extractor.md`](references/signal-time-frequency-feature-extractor.md) — Transform×feature compatibility matrix and per-transform parameter tables. Read this before enabling any feature on the time-frequency extractor.
- [`references/scalarization-options.md`](references/scalarization-options.md) — the three `*ScalarFeatureOptions` objects and the `setScalarizationMethods` API. Read when adding scalar summary columns to vector-valued features.
- [`references/gpu-patterns.md`](references/gpu-patterns.md) — `canUseGPU` guard pattern and rationale. Read when the user mentions GPU.

----

Copyright 2026 The MathWorks, Inc.

----