Flutter信号处理插件smart_signal_processing的使用
Smart Signal Processing
这个插件能为你做什么?
该插件提供了信号处理中常用的函数:
- 计算均值、方差和标准差。
- 对数组应用窗口函数(窗函数),例如指数或高斯形状。
- 对数组应用快速傅里叶变换(FFT)。
- 计算复数数组的功率或幅值。
- 对复数数组进行相位旋转(在复平面上旋转)。
示例
你可以直接通过以下链接运行示例代码:
或者下载插件并在浏览器中运行以下文件:
example/example.html
插件的主要API功能
该插件包含以下主要类:
Sigma
:用于计算统计量。BaseLine
:用于基线校正。WinFunc
:用于窗口函数。FFT
:用于快速傅里叶变换。Phase
:用于计算相位。
示例代码片段
// 应用指数衰减
WinFunc.expMult(array, decayFactor, false, "0");
// 计算傅里叶变换
FFT.transform(reals, imags);
// 计算幅值
Phase.magnitude(reals, imags, true);
// 计算特定区域的方差
Sigma.variance(array, ixstart, ixend);
完整示例代码
以下是一个完整的示例代码,展示如何使用 smart_signal_processing
插件来生成一个衰减的余弦波,并对其进行傅里叶变换。
// Copyright (c) 2019, Dr. Bruno Guigas. All rights reserved. Use of this source
// code is governed by a BSD-style license that can be found in the LICENSE file.
import 'dart:html';
import 'dart:typed_data';
import 'dart:convert';
import 'dart:math' as math;
import 'package:smart_arrays_plot_polyline/smart_arrays_plot_polyline.dart';
import 'package:smart_arrays_sample_data/smart_arrays_sample_data.dart';
import 'package:smart_signal_processing/smart_signal_processing.dart';
/// Signal processing example:
/// - Computes NPERIODS periods of a cosine shape with NPOINTS data points.
/// - Applies an exponential function, resulting in a decaying oscillation.
/// - Applies a real Fourier transform, resulting in a complex-valued line shape
/// whose real part is an absorption mode Lorentzian, and whose imaginary
/// part is a dispersion mode Lorentzian. The real part's maximum is at the
/// index defined by the number of cosine periods (NPERIODS).
/// - Plots the real and imaginary parts and the cosine in the browser.
main() {
// 生成一个余弦波
Sine1D sine1d = Sine1D(NPOINTS, 100.0, math.pi / 2, NPERIODS, 0.0, 0.0);
Float64List reals = sine1d.array;
Float64List imags = Float64List(reals.length); // 原始为零
// 使余弦波呈指数衰减
double decayFactor = -3.0 / (reals.length - 1);
WinFunc.expMult(reals, decayFactor, false, "0");
Float64List decayingCosine = Float64List.fromList(reals); // 保存以供绘图
// 在原地进行傅里叶变换:初始时 [imags] 全为零。变换后,
// [reals] 包含吸收模式的洛伦兹线型,[imags] 包含分散模式的洛伦兹线型。
FFT.transform(reals, imags);
// 绘制结果:由于FFT的对称性,只绘制前半部分。
// 第二部分包含相同的信息(对应于“负频率”)。为了使x轴适用于所有三条曲线,
// 只绘制余弦波的一半。
plotArrays([
reals.sublist(0, reals.length ~/ 2), // 实部
imags.sublist(0, imags.length ~/ 2), // 虚部
decayingCosine.sublist(0, decayingCosine.length ~/ 2), // 衰减的余弦波
]);
}
final int NPOINTS = 512, NPERIODS = 50;
/// 显示由 [main] 计算的数组 [arrays],使用包 'smart_arrays_plot_polyline' 在浏览器中绘制。
void plotArrays(List<Float64List> arrays) {
// 获取来自 'example.html' 的 div 容器
DivElement appDiv = (querySelector("#app_div") as DivElement);
DivElement plotDiv = (querySelector("#plot_div") as DivElement);
// 设置绘图区域大小
plotDiv.style
..width = "${appDiv.clientWidth}px"
..height = "${appDiv.clientHeight}px";
// 设置折线图属性
List<Map<PyA, String>> plotAttr = [
{PyA.YPOSITION_ZERO: "0.6"}, // 实部位置
{PyA.YPOSITION_ZERO: "0.6"}, // 虚部位置
{PyA.YPOSITION_ZERO: "0.895", PyA.YSCALE: "5"} // 缩放并下移余弦波
];
// 设置x轴标签
Map<AxA, String> xaxisAttr = {
AxA.PHYS_X_START: "0",
AxA.PHYS_X_WIDTH: "${arrays[0].length}", // 来自实部
AxA.LEGENDTEXT: "Number of points"
};
// 设置y轴标签
Map<AxA, String> yaxisAttr = {AxA.LEGENDTEXT: "Relative units"};
// 设置图例文本和位置
Map<LegA, String> legendAttr = {
LegA.TOP_TITLE:
"Fourier Transform of a decaying cosine with $NPERIODS periods",
LegA.SUB_TITLES: json.encode([
"Real part after transform",
"Imaginary part after transform",
"Decaying cosine (first half, vertically expanded and shifted down)"
]),
LegA.X: "45",
LegA.Y: "15"
};
// 将数组绘制到 [plotDiv]
SimplePlot(arrays, plotDiv, plotAttr, xaxisAttr, yaxisAttr, legendAttr, null);
}
更多关于Flutter信号处理插件smart_signal_processing的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter信号处理插件smart_signal_processing的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
smart_signal_processing
是一个用于 Flutter 的信号处理插件,它可以帮助你在 Flutter 应用中执行各种信号处理任务,如滤波、傅里叶变换、信号生成等。以下是如何在 Flutter 项目中使用 smart_signal_processing
插件的基本步骤。
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 smart_signal_processing
插件的依赖。
dependencies:
flutter:
sdk: flutter
smart_signal_processing: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来获取依赖。
2. 导入插件
在你的 Dart 文件中导入 smart_signal_processing
插件。
import 'package:smart_signal_processing/smart_signal_processing.dart';
3. 使用插件功能
smart_signal_processing
插件提供了多种信号处理功能。以下是一些常见的使用示例。
3.1 信号生成
你可以使用插件生成各种信号,如正弦波、方波等。
void generateSignal() {
// 生成一个正弦波信号
List<double> sineWave = SmartSignalProcessing.generateSineWave(
frequency: 440.0, // 频率
amplitude: 1.0, // 振幅
sampleRate: 44100, // 采样率
duration: 1.0, // 持续时间(秒)
);
print(sineWave);
}
3.2 傅里叶变换
你可以使用插件对信号进行傅里叶变换。
void performFFT() {
List<double> signal = [1.0, 0.0, -1.0, 0.0]; // 示例信号
// 执行傅里叶变换
List<Complex> fftResult = SmartSignalProcessing.fft(signal);
print(fftResult);
}
3.3 滤波
你可以使用插件对信号进行滤波。
void applyFilter() {
List<double> signal = [1.0, 2.0, 3.0, 4.0, 5.0]; // 示例信号
// 应用低通滤波器
List<double> filteredSignal = SmartSignalProcessing.lowPassFilter(
signal: signal,
cutoffFrequency: 0.1, // 截止频率
sampleRate: 44100, // 采样率
);
print(filteredSignal);
}
4. 处理结果
你可以将处理后的信号用于进一步的分析、可视化或播放。
5. 示例应用
以下是一个简单的 Flutter 应用示例,展示了如何使用 smart_signal_processing
插件生成信号并显示其波形。
import 'package:flutter/material.dart';
import 'package:smart_signal_processing/smart_signal_processing.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: SignalProcessingDemo(),
);
}
}
class SignalProcessingDemo extends StatefulWidget {
[@override](/user/override)
_SignalProcessingDemoState createState() => _SignalProcessingDemoState();
}
class _SignalProcessingDemoState extends State<SignalProcessingDemo> {
List<double> signal = [];
[@override](/user/override)
void initState() {
super.initState();
generateSignal();
}
void generateSignal() {
setState(() {
signal = SmartSignalProcessing.generateSineWave(
frequency: 440.0,
amplitude: 1.0,
sampleRate: 44100,
duration: 1.0,
);
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Signal Processing Demo'),
),
body: Center(
child: CustomPaint(
size: Size(300, 150),
painter: SignalPainter(signal),
),
),
);
}
}
class SignalPainter extends CustomPainter {
final List<double> signal;
SignalPainter(this.signal);
[@override](/user/override)
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.blue
..strokeWidth = 2.0
..style = PaintingStyle.stroke;
final path = Path();
final xStep = size.width / (signal.length - 1);
for (int i = 0; i < signal.length; i++) {
final x = i * xStep;
final y = size.height / 2 - signal[i] * size.height / 4;
if (i == 0) {
path.moveTo(x, y);
} else {
path.lineTo(x, y);
}
}
canvas.drawPath(path, paint);
}
[@override](/user/override)
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}