Android Kotlin 实时 FFT 和绘图

发布于 2025-01-18 13:06:14 字数 1842 浏览 1 评论 0原文

我正在尝试对通过蓝牙 BLE 连接的传感器数据应用实时 FFT。

有一个 sdk 允许您使用处理程序从 Android 中的传感器接收数据。我使用 ViewModel 在应用程序的各个部分发送传感器数据,以使用 GraphView 绘制数据和执行 FFT。

我正在使用 JTransform 来执行 FFT,但在我使用 JDSP 执行 STFT。

下面是使用 JTransform 对未经过滤的原始传感器数据执行 FFT 的代码

    var t = 0
    var fs  = 512
    var sampleSize = 2*fs
    val windowSize = sampleSize/2
    
    private fun getFFT(sample:DoubleArray): Array<DataPoint>{
        val fft = DoubleFFT_1D(sampleSize.toLong())
        fft.realForward(sample)
        return analysed(sample)
    } 
    
    private fun analysed(sample:DoubleArray): Array<DataPoint> {
        val series:Array<DataPoint> =  Array(sample.size) { i -> DataPoint(0.0,0.0) }
        sample.forEachIndexed { i, y -> 
            val x = i.toDouble()
            series[i] = DataPoint(x, y)
        }
        return series
    }

    
    sensorViewModel.getRaw().observe(this){
        if(t<sampleSize-1){
            sample[t] = it.toDouble()
            t++
        }else{
            sample = sample.takeLast(windowSize).toDoubleArray().plus(DoubleArray(2*windowSize) { i -> 0.0 })
            t = windowSize

            // Plot FFT
            asyncTask.execute(onPreExecute = {
            }, doInBackground = {
                getFFT(sample)
            }, onPostExecute = {
                fftseries.resetData(it)
            })
        }
    }

虽然我的代码运行没有崩溃,但我可以看到该应用程序有很多问题。

  1. 使用滑动窗口创建“样本”来对创建的样本执行 FFT 感觉效率很低。谁能建议我如何通过更好地控制窗口大小来更好地编写它。

  2. 如何快速绘制此 FFT 图?

I am trying to apply Real-time FFT on a sensor data which is connected over the bluetooth BLE.

There is a sdk which allows you to receive the data from the sensor in the Android using handler. I am using ViewModel to send the sensor data in various parts of the app to plot the data using GraphView and perform FFT.

I am using JTransform to perform the FFT but before I was using JDSP to perform STFT.

Below is the code use to perform FFT on a unfiltered raw sensor data using JTransform

    var t = 0
    var fs  = 512
    var sampleSize = 2*fs
    val windowSize = sampleSize/2
    
    private fun getFFT(sample:DoubleArray): Array<DataPoint>{
        val fft = DoubleFFT_1D(sampleSize.toLong())
        fft.realForward(sample)
        return analysed(sample)
    } 
    
    private fun analysed(sample:DoubleArray): Array<DataPoint> {
        val series:Array<DataPoint> =  Array(sample.size) { i -> DataPoint(0.0,0.0) }
        sample.forEachIndexed { i, y -> 
            val x = i.toDouble()
            series[i] = DataPoint(x, y)
        }
        return series
    }

    
    sensorViewModel.getRaw().observe(this){
        if(t<sampleSize-1){
            sample[t] = it.toDouble()
            t++
        }else{
            sample = sample.takeLast(windowSize).toDoubleArray().plus(DoubleArray(2*windowSize) { i -> 0.0 })
            t = windowSize

            // Plot FFT
            asyncTask.execute(onPreExecute = {
            }, doInBackground = {
                getFFT(sample)
            }, onPostExecute = {
                fftseries.resetData(it)
            })
        }
    }

Although my code runs without crash but I can see so many problems with the app.

  1. Using a sliding window to create "sample" to perform FFT on the created sample feels really inefficient. Can anyone please suggest how can I do write it better with the better control of window size.

  2. How to make this FFT plot fast?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文