Просмотр исходного кода

add:提交air8000、air780epm、air780ehm等的fft的demo,修改iconv对应demo中的描述

mw 2 месяцев назад
Родитель
Сommit
e8d610d297

+ 2 - 0
module/Air780EHM_Air780EHV_Air780EGH/demo/iconv/iconv_test.lua

@@ -10,6 +10,8 @@
 2. Unicode大端(ucs2be)与GB2312编码互转
 2. Unicode大端(ucs2be)与GB2312编码互转
 3. Unicode小端(ucs2)与UTF8编码互转
 3. Unicode小端(ucs2)与UTF8编码互转
 4. Unicode大端(ucs2be)与UTF8编码互转
 4. Unicode大端(ucs2be)与UTF8编码互转
+5. GB2312 编码与 UTF-8 编码之间的转换。
+
 
 
 
 
 本文件没有对外接口,直接在main.lua中require "iconv_test"就可以加载运行;
 本文件没有对外接口,直接在main.lua中require "iconv_test"就可以加载运行;

+ 1 - 0
module/Air780EHM_Air780EHV_Air780EGH/demo/iconv/main.lua

@@ -11,6 +11,7 @@
 2. Unicode大端(ucs2be)与GB2312编码互转
 2. Unicode大端(ucs2be)与GB2312编码互转
 3. Unicode小端(ucs2)与UTF8编码互转
 3. Unicode小端(ucs2)与UTF8编码互转
 4. Unicode大端(ucs2be)与UTF8编码互转
 4. Unicode大端(ucs2be)与UTF8编码互转
+5. GB2312 编码与 UTF-8 编码之间的转换。
 
 
 更多说明参考本目录下的readme.md文件
 更多说明参考本目录下的readme.md文件
 
 

+ 1 - 0
module/Air780EHM_Air780EHV_Air780EGH/demo/iconv/readme.md

@@ -13,6 +13,7 @@
 2. Unicode大端(ucs2be)与GB2312编码互转
 2. Unicode大端(ucs2be)与GB2312编码互转
 3. Unicode小端(ucs2)与UTF8编码互转
 3. Unicode小端(ucs2)与UTF8编码互转
 4. Unicode大端(ucs2be)与UTF8编码互转
 4. Unicode大端(ucs2be)与UTF8编码互转
+5. GB2312 编码与 UTF-8 编码之间的转换。
 
 
 
 
 
 

+ 1 - 0
module/Air780EPM/demo/iconv/iconv_test.lua

@@ -10,6 +10,7 @@
 2. Unicode大端(ucs2be)与GB2312编码互转
 2. Unicode大端(ucs2be)与GB2312编码互转
 3. Unicode小端(ucs2)与UTF8编码互转
 3. Unicode小端(ucs2)与UTF8编码互转
 4. Unicode大端(ucs2be)与UTF8编码互转
 4. Unicode大端(ucs2be)与UTF8编码互转
+5. GB2312 编码与 UTF-8 编码之间的转换。
 
 
 
 
 本文件没有对外接口,直接在main.lua中require "iconv_test"就可以加载运行;
 本文件没有对外接口,直接在main.lua中require "iconv_test"就可以加载运行;

+ 1 - 0
module/Air780EPM/demo/iconv/main.lua

@@ -11,6 +11,7 @@
 2. Unicode大端(ucs2be)与GB2312编码互转
 2. Unicode大端(ucs2be)与GB2312编码互转
 3. Unicode小端(ucs2)与UTF8编码互转
 3. Unicode小端(ucs2)与UTF8编码互转
 4. Unicode大端(ucs2be)与UTF8编码互转
 4. Unicode大端(ucs2be)与UTF8编码互转
+5. GB2312 编码与 UTF-8 编码之间的转换。
 
 
 更多说明参考本目录下的readme.md文件
 更多说明参考本目录下的readme.md文件
 
 

+ 1 - 0
module/Air780EPM/demo/iconv/readme.md

@@ -13,6 +13,7 @@
 2. Unicode大端(ucs2be)与GB2312编码互转
 2. Unicode大端(ucs2be)与GB2312编码互转
 3. Unicode小端(ucs2)与UTF8编码互转
 3. Unicode小端(ucs2)与UTF8编码互转
 4. Unicode大端(ucs2be)与UTF8编码互转
 4. Unicode大端(ucs2be)与UTF8编码互转
+5. GB2312 编码与 UTF-8 编码之间的转换。
 
 
 
 
 
 

+ 1 - 0
module/Air8000/demo/iconv/iconv_test.lua

@@ -10,6 +10,7 @@
 2. Unicode大端(ucs2be)与GB2312编码互转
 2. Unicode大端(ucs2be)与GB2312编码互转
 3. Unicode小端(ucs2)与UTF8编码互转
 3. Unicode小端(ucs2)与UTF8编码互转
 4. Unicode大端(ucs2be)与UTF8编码互转
 4. Unicode大端(ucs2be)与UTF8编码互转
+5. GB2312 编码与 UTF-8 编码之间的转换。
 
 
 
 
 本文件没有对外接口,直接在main.lua中require "iconv_test"就可以加载运行;
 本文件没有对外接口,直接在main.lua中require "iconv_test"就可以加载运行;

+ 1 - 0
module/Air8000/demo/iconv/main.lua

@@ -11,6 +11,7 @@
 2. Unicode大端(ucs2be)与GB2312编码互转
 2. Unicode大端(ucs2be)与GB2312编码互转
 3. Unicode小端(ucs2)与UTF8编码互转
 3. Unicode小端(ucs2)与UTF8编码互转
 4. Unicode大端(ucs2be)与UTF8编码互转
 4. Unicode大端(ucs2be)与UTF8编码互转
+5. GB2312 编码与 UTF-8 编码之间的转换。
 
 
 更多说明参考本目录下的readme.md文件
 更多说明参考本目录下的readme.md文件
 
 

+ 1 - 1
module/Air8000/demo/iconv/readme.md

@@ -13,7 +13,7 @@
 2. Unicode大端(ucs2be)与GB2312编码互转
 2. Unicode大端(ucs2be)与GB2312编码互转
 3. Unicode小端(ucs2)与UTF8编码互转
 3. Unicode小端(ucs2)与UTF8编码互转
 4. Unicode大端(ucs2be)与UTF8编码互转
 4. Unicode大端(ucs2be)与UTF8编码互转
-
+5. GB2312 编码与 UTF-8 编码之间的转换。
 
 
 
 
 ## 演示硬件环境
 ## 演示硬件环境

+ 57 - 194
module/Air8101/demo/iconv/main.lua

@@ -1,213 +1,76 @@
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "iconv_demo"
-VERSION = "1.0"
-
---- unicode小端编码 转化为 gb2312编码
--- @string ucs2s unicode小端编码数据
--- @return string data,gb2312编码数据
--- @usage local data = common.ucs2ToGb2312(ucs2s)
-function ucs2ToGb2312(ucs2s)
-    local cd = iconv.open("gb2312", "ucs2")
-    return cd:iconv(ucs2s)
-end
-
---- gb2312编码 转化为 unicode小端编码
--- @string gb2312s gb2312编码数据
--- @return string data,unicode小端编码数据
--- @usage local data = common.gb2312ToUcs2(gb2312s)
-function gb2312ToUcs2(gb2312s)
-    local cd = iconv.open("ucs2", "gb2312")
-    return cd:iconv(gb2312s)
-end
-
---- unicode大端编码 转化为 gb2312编码
--- @string ucs2s unicode大端编码数据
--- @return string data,gb2312编码数据
--- @usage data = common.ucs2beToGb2312(ucs2s)
-function ucs2beToGb2312(ucs2s)
-    local cd = iconv.open("gb2312", "ucs2be")
-    return cd:iconv(ucs2s)
-end
-
---- gb2312编码 转化为 unicode大端编码
--- @string gb2312s gb2312编码数据
--- @return string data,unicode大端编码数据
--- @usage local data = common.gb2312ToUcs2be(gb2312s)
-function gb2312ToUcs2be(gb2312s)
-    local cd = iconv.open("ucs2be", "gb2312")
-    return cd:iconv(gb2312s)
-end
-
---- unicode小端编码 转化为 utf8编码
--- @string ucs2s unicode小端编码数据
--- @return string data,utf8编码数据
--- @usage data = common.ucs2ToUtf8(ucs2s)
-function ucs2ToUtf8(ucs2s)
-    local cd = iconv.open("utf8", "ucs2")
-    return cd:iconv(ucs2s)
-end
-
---- utf8编码 转化为 unicode小端编码
--- @string utf8s utf8编码数据
--- @return string data,unicode小端编码数据
--- @usage local data = common.utf8ToUcs2(utf8s)
-function utf8ToUcs2(utf8s)
-    local cd = iconv.open("ucs2", "utf8")
-    return cd:iconv(utf8s)
-end
-
---- unicode大端编码 转化为 utf8编码
--- @string ucs2s unicode大端编码数据
--- @return string data,utf8编码数据
--- @usage data = common.ucs2beToUtf8(ucs2s)
-function ucs2beToUtf8(ucs2s)
-    local cd = iconv.open("utf8", "ucs2be")
-    return cd:iconv(ucs2s)
-end
-
---- utf8编码 转化为 unicode大端编码
--- @string utf8s utf8编码数据
--- @return string data,unicode大端编码数据
--- @usage local data = common.utf8ToUcs2be(utf8s)
-function utf8ToUcs2be(utf8s)
-    local cd = iconv.open("ucs2be", "utf8")
-    return cd:iconv(utf8s)
-end
-
---- utf8编码 转化为 gb2312编码
--- @string utf8s utf8编码数据
--- @return string data,gb2312编码数据
--- @usage local data = common.utf8ToGb2312(utf8s)
-function utf8ToGb2312(utf8s)
-    local cd = iconv.open("ucs2", "utf8")
-    local ucs2s = cd:iconv(utf8s)
-    cd = iconv.open("gb2312", "ucs2")
-    return cd:iconv(ucs2s)
-end
+--[[
+@module  main
+@summary LuatOS用户应用脚本文件入口,总体调度应用逻辑
+@version 1.0
+@date    2025.10.27
+@author  孟伟
+@usage
+本demo演示的功能为:
+提供多种字符编码之间的相互转换功能,支持以下编码转换:
+1. Unicode小端(ucs2)与GB2312编码互转
+2. Unicode大端(ucs2be)与GB2312编码互转
+3. Unicode小端(ucs2)与UTF8编码互转
+4. Unicode大端(ucs2be)与UTF8编码互转
+5. GB2312 编码与 UTF-8 编码之间的转换。
+
+更多说明参考本目录下的readme.md文件
 
 
---- gb2312编码 转化为 utf8编码
--- @string gb2312s gb2312编码数据
--- @return string data,utf8编码数据
--- @usage local data = common.gb2312ToUtf8(gb2312s)
-function gb2312ToUtf8(gb2312s)
-    local cd = iconv.open("ucs2", "gb2312")
-    local ucs2s = cd:iconv(gb2312s)
-    cd = iconv.open("utf8", "ucs2")
-    return cd:iconv(ucs2s)
-end
 
 
---------------------------------------------------------------------------------------------------------
---[[
-函数名:ucs2ToGb2312
-功能  :unicode小端编码 转化为 gb2312编码,并打印出gb2312编码数据
-参数  :
-        ucs2s:unicode小端编码数据,注意输入参数的字节数
-返回值:
 ]]
 ]]
-local function testucs2ToGb2312(ucs2s)
-    print("ucs2ToGb2312")
-    local gb2312num = ucs2ToGb2312(ucs2s)--调用的是common.ucs2ToGb2312,返回的是编码所对应的字符串
-    -- print("gb2312  code:",string.toHex(gb2312num))
-    print("gb2312  code:" .. string.toHex(gb2312num))
-end
 
 
 --[[
 --[[
-函数名:gb2312ToUcs2
-功能  :gb2312编码 转化为 unicode十六进制小端编码数据并打印
-参数  :
-        gb2312s:gb2312编码数据,注意输入参数的字节数
-返回值:
+必须定义PROJECT和VERSION变量,Luatools工具会用到这两个变量,远程升级功能也会用到这两个变量
+PROJECT:项目名,ascii string类型
+        可以随便定义,只要不使用,就行
+VERSION:项目版本号,ascii string类型
+        如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
+            X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
+            因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
+        如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
 ]]
 ]]
-local function testgb2312ToUcs2(gb2312s)
-    print("gb2312ToUcs2")
-    local ucs2num = gb2312ToUcs2(gb2312s)
-    print("unicode little-endian code:" .. string.toHex(ucs2num)) -- 要将二进制转换为十六进制,否则无法输出
-end
+PROJECT = "iconv_test"
+VERSION = "001.000.000"
 
 
---[[
-函数名:ucs2beToGb2312
-功能  :unicode大端编码 转化为 gb2312编码,并打印出gb2312编码数据,
-大端编码数据是与小端编码数据位置调换
-参数  :
-        ucs2s:unicode大端编码数据,注意输入参数的字节数
-返回值:
-]]
-local function testucs2beToGb2312(ucs2s)
-    print("ucs2beToGb2312")
-    local gb2312num = ucs2beToGb2312(ucs2s) -- 转化后的数据直接变成字符可以直接输出
-    print("gb2312 code :" .. string.toHex(gb2312num))
-end
 
 
---[[
-函数名:gb2312ToUcs2be
-功能  :gb2312编码 转化为 unicode大端编码,并打印出unicode大端编码
-参数  :
-        gb2312s:gb2312编码数据,注意输入参数的字节数
-返回值:unicode大端编码数据
-]]
-function testgb2312ToUcs2be(gb2312s)
-    print("gb2312ToUcs2be")
-    local ucs2benum = gb2312ToUcs2be(gb2312s)
-    print("unicode big-endian code :" .. string.toHex(ucs2benum))
-end
+-- 在日志中打印项目名和项目版本号
+log.info("main", PROJECT, VERSION)
 
 
---[[
-函数名:ucs2ToUtf8
-功能  :unicode小端编码 转化为 utf8编码,并打印出utf8十六进制编码数据
-参数  :
-        ucs2s:unicode小端编码数据,注意输入参数的字节数
-返回值:
-]]
-local function testucs2ToUtf8(ucs2s)
-    print("ucs2ToUtf8")
-    local utf8num = ucs2ToUtf8(ucs2s)
-    print("utf8  code:" .. string.toHex(utf8num))
 
 
+-- 如果内核固件支持wdt看门狗功能,此处对看门狗进行初始化和定时喂狗处理
+-- 如果脚本程序死循环卡死,就会无法及时喂狗,最终会自动重启
+if wdt then
+    --配置喂狗超时时间为9秒钟
+    wdt.init(9000)
+    --启动一个循环定时器,每隔3秒钟喂一次狗
+    sys.timerLoopStart(wdt.feed, 3000)
 end
 end
 
 
---[[
-函数名:utf8ToGb2312
-功能  :utf8编码 转化为 gb2312编码,并打印出gb2312编码数据
-参数  :
-        utf8s:utf8编码数据,注意输入参数的字节数
-返回值:
-]]
-local function testutf8ToGb2312(utf8s)
-    print("utf8ToGb2312")
-    local gb2312num = utf8ToGb2312(utf8s)
-    print("gb2312 code:" .. string.toHex(gb2312num))
 
 
-end
+-- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
+-- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息,可以初步分析一些设备运行异常的问题
+-- 以下代码是最基本的用法,更复杂的用法可以详细阅读API说明文档
+-- 启动errDump日志存储并且上传功能,600秒上传一次
+-- if errDump then
+--     errDump.config(true, 600)
+-- end
 
 
---[[
-函数名:gb2312ToUtf8
-功能  :gb2312编码 转化为 utf8编码,并打印出utf8编码数据
-参数  :
-        gb2312s:gb2312s编码数据,注意输入参数的字节数
-返回值:
-]]
-local function testgb2312ToUtf8(gb2312s)
-    print("gb2312ToUtf8")
-    local utf8s = gb2312ToUtf8(gb2312s)
-    print("utf8s code:" .. utf8s)
 
 
-end
+-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
+-- 可以使用合宙的iot.openluat.com平台进行远程升级
+-- 也可以使用客户自己搭建的平台进行远程升级
+-- 远程升级的详细用法,可以参考fota的demo进行使用
+
+
+-- 启动一个循环定时器
+-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
+-- 方便分析内存使用是否有异常
+-- sys.timerLoopStart(function()
+--     log.info("mem.lua", rtos.meminfo())
+--     log.info("mem.sys", rtos.meminfo("sys"))
+-- end, 3000)
 
 
-sys.taskInit(function()
-
-    log.info("iconv", PROJECT, VERSION)
-
-    while 1 do
-        sys.wait(1000)
-        testucs2ToGb2312(string.fromHex("1162")) -- "1162"是"我"字的ucs2编码
-        testgb2312ToUcs2(string.fromHex("CED2")) -- "CED2"是"我"字的gb2312编码
-        testucs2beToGb2312(string.fromHex("6211")) -- "6211"是"我"字的ucs2be编码
-        testgb2312ToUcs2be(string.fromHex("CED2"))
-        testucs2ToUtf8(string.fromHex("1162"))
-        testutf8ToGb2312(string.fromHex("E68891")) -- "E68891"是"我"字的utf8编码
-        testgb2312ToUtf8(string.fromHex("CED2"))
-    end
-end)
+-- 加载iconv功能测试模块
+require("iconv_test")
 
 
 -- 用户代码已结束---------------------------------------------
 -- 用户代码已结束---------------------------------------------
 -- 结尾总是这一句
 -- 结尾总是这一句

+ 0 - 107
olddemo/fft/tcp_test.lua

@@ -1,107 +0,0 @@
-local libnet = require "libnet"
-
--- 下面演示用阻塞方式做串口透传远程服务器,简单的串口DTU
-local d1Online = false
-local com_buff = zbuff.create(4096)
-local d1Name = "D1_TASK"
-local function netCB(msg)
-    log.info("未处理消息", msg[1], msg[2], msg[3], msg[4])
-end
-local filename = "/spectrum.json"
-local function dtuTask(uart_id, ip, port)
-    sys.wait(5000)
-    d1Online = false
-    local tx_buff = zbuff.create(1024)
-    local rx_buff = zbuff.create(1024)
-    local netc
-    local result, param, is_err
-    -- result = uart.setup(uart_id, 115200, 8, 1)
-    -- uart.on(uart_id, "receive", function(id, len)
-    --     uart.rx(id, com_buff)
-    --     if d1Online then -- 如果已经在线了,则发送socket.EVENT消息来打断任务里的阻塞等待状态,让任务循环继续
-    --         sysplus.sendMsg(d1Name, socket.EVENT, 0)
-    --     end
-    -- end)
-    netc = socket.create(nil, d1Name)
-    socket.debug(netc, true)
-    socket.config(netc, nil, nil, nil)
-    -- socket.config(netc, nil, true)
-    while true do
-        log.info(rtos.meminfo("sys"))
-        result = libnet.waitLink(d1Name, 0, netc)
-        result = libnet.connect(d1Name, 15000, netc, ip, port)
-        -- result = libnet.connect(d1Name, 5000, netc, "112.125.89.8",34607)
-        d1Online = result
-        if result then
-            log.info("服务器连上了")
-            libnet.tx(d1Name, 0, netc, "helloworld")
-            if not io.exists(filename) then
-                log.error("文件", "频谱文件不存在: " .. filename)
-                return nil
-            end
-
-            local file = io.open(filename, "r")
-            if not file then
-                log.error("文件", "无法打开文件: " .. filename)
-                return nil
-            end
-
-            local content = file:read("*a")
-            file:close()
-
-            if not content or #content == 0 then
-                log.error("文件", "文件内容为空")
-                return nil
-            end
-
-            log.info("文件", string.format("读取了 %d 字节", #content))
-            rx_buff:del()
-            libnet.tx(d1Name, 0, netc, content)
-        end
-        while result do
-            succ, param, _, _ = socket.rx(netc, rx_buff)
-            if not succ then
-                log.info("服务器断开了", succ, param, ip, port)
-                break
-            end
-            if rx_buff:used() > 0 then
-                log.info("收到服务器数据,长度", rx_buff:used())
-                -- uart.tx(uart_id, rx_buff)
-            end
-            tx_buff:copy(nil, com_buff)
-            com_buff:del()
-            if tx_buff:used() > 0 then
-                result, param = libnet.tx(d1Name, 15000, netc, tx_buff)
-            end
-            if not result then
-                log.info("发送失败了", result, param)
-                break
-            end
-            tx_buff:del()
-            if com_buff:len() > 4096 then
-                com_buff:resize(4096)
-            end
-            if tx_buff:len() > 1024 then
-                tx_buff:resize(1024)
-            end
-            if rx_buff:len() > 1024 then
-                rx_buff:resize(1024)
-            end
-            log.info(rtos.meminfo("sys"))
-            -- 阻塞等待新的消息到来,比如服务器下发,串口接收到数据
-            result, param = libnet.wait(d1Name, 15000, netc)
-            if not result then
-                log.info("服务器断开了", result, param)
-                break
-            end
-        end
-        d1Online = false
-        libnet.close(d1Name, 5000, netc)
-        log.info(rtos.meminfo("sys"))
-        sys.wait(1000)
-    end
-end
-
-function dtuDemo(uart_id, ip, port)
-    sysplus.taskInitEx(dtuTask, d1Name, netCB, uart_id, ip, port)
-end

+ 0 - 401
olddemo/fft/test.lua

@@ -1,401 +0,0 @@
-PROJECT = "pcm32_spectrum"
-VERSION = "1.0.0"
-_G.sys = require("sys")
-
--- 32bit PCM频谱分析
-function generate_32bit_spectrum(pcm_filename, output_filename)
-    local sample_rate = 24000
-    local fft_points = 256 -- 使用较小的FFT点数节省内存
-    local df = sample_rate / fft_points
-
-    log.info("分析", "32bit PCM频谱分析")
-    log.info("参数", string.format("采样率: %dHz, FFT点数: %d", sample_rate, fft_points))
-
-    -- 检查文件是否存在
-    if not io.exists(pcm_filename) then
-        log.error("文件", "PCM文件不存在: " .. pcm_filename)
-        return false
-    end
-
-    -- 获取文件大小
-    local file_size = io.fileSize(pcm_filename)
-    if not file_size then
-        log.error("文件", "无法获取文件大小")
-        return false
-    end
-
-    log.info("文件", string.format("文件大小: %d 字节", file_size))
-    log.info("文件", string.format("约 %d 个32bit样本", file_size // 4))
-
-    -- 准备FFT缓冲区
-    local real_buf = zbuff.create(fft_points * 2)
-    local imag_buf = zbuff.create(fft_points * 2)
-
-    local Wc = zbuff.create((fft_points // 2) * 2)
-    local Ws = zbuff.create((fft_points // 2) * 2)
-    fft.generate_twiddles_q15_to_zbuff(fft_points, Wc, Ws)
-
-    -- 读取文件
-    local file = io.open(pcm_filename, "rb")
-    if not file then
-        log.error("文件", "无法打开PCM文件")
-        return false
-    end
-
-    -- 读取一个片段(32bit = 4字节 per sample)
-    local bytes_to_read = fft_points * 4
-    local chunk = file:read(bytes_to_read)
-    file:close()
-
-    if not chunk or #chunk < 4 then
-        log.error("读取", "文件数据不足")
-        return false
-    end
-
-    log.info("读取", string.format("读取了 %d 字节", #chunk))
-
-    -- 处理32bit PCM数据
-    local samples_processed = 0
-    for i = 1, math.floor(#chunk / 4) do
-        local byte_pos = (i - 1) * 4 + 1
-
-        -- 32bit小端序解析
-        local b1 = chunk:byte(byte_pos) -- 最低字节
-        local b2 = chunk:byte(byte_pos + 1)
-        local b3 = chunk:byte(byte_pos + 2)
-        local b4 = chunk:byte(byte_pos + 3) -- 最高字节
-
-        -- 组合成32位整数
-        local sample = b1 + b2 * 256 + b3 * 65536 + b4 * 16777216
-
-        -- 32bit有符号转换 (范围: -2147483648 到 2147483647)
-        if sample >= 2147483648 then
-            sample = sample - 4294967296
-        end
-
-        -- 32bit转U12格式
-        local normalized = (sample / 2147483648.0)                    -- 归一化到 -1.0 到 1.0
-        local u12_val = math.floor((normalized + 1.0) * 2047.5 + 0.5) -- 转到 0-4095
-
-        if u12_val < 0 then u12_val = 0 end
-        if u12_val > 4095 then u12_val = 4095 end
-
-        real_buf:seek((i - 1) * 2, zbuff.SEEK_SET)
-        real_buf:writeU16(u12_val)
-        imag_buf:seek((i - 1) * 2, zbuff.SEEK_SET)
-        imag_buf:writeU16(0)
-
-        samples_processed = samples_processed + 1
-
-        -- 每处理64个样本输出一次进度
-        if i % 64 == 0 then
-            log.info("处理", string.format("已处理 %d/%d 样本", i, math.floor(#chunk / 4)))
-        end
-    end
-
-    -- 如果数据不足,用0填充
-    for i = samples_processed + 1, fft_points do
-        real_buf:seek((i - 1) * 2, zbuff.SEEK_SET)
-        real_buf:writeU16(2048) -- 中间值
-        imag_buf:seek((i - 1) * 2, zbuff.SEEK_SET)
-        imag_buf:writeU16(0)
-    end
-
-    log.info("FFT", "开始执行FFT计算...")
-
-    -- 执行FFT
-    fft.run(real_buf, imag_buf, fft_points, Wc, Ws, {
-        core = "q15",
-        input_format = "u12"
-    })
-
-    -- 生成输出文件
-    local out_file = io.open(output_filename, "w")
-    if not out_file then
-        log.error("文件", "无法创建输出文件")
-        return false
-    end
-
-    -- 写入文件头
-    local ret, err = out_file:write('{\n')
-    if not ret then
-        log.error("写入", "写入文件头失败:", err)
-        out_file:close()
-        return false
-    end
-
-    out_file:write('  "sample_rate": 24000,\n')
-    out_file:write('  "fft_points": 256,\n')
-    out_file:write('  "frequency_resolution": ' .. df .. ',\n')
-    out_file:write('  "max_frequency": 12000,\n')
-    out_file:write('  "bit_depth": 32,\n')
-    out_file:write('  "spectrum_data": [\n')
-
-    -- 收集频谱数据
-    local freq_data = {}
-    local max_magnitude = 0
-
-    -- 先扫描找到最大值用于归一化
-    for k = 1, fft_points // 2 do
-        real_buf:seek(k * 2, zbuff.SEEK_SET)
-        imag_buf:seek(k * 2, zbuff.SEEK_SET)
-        local r = real_buf:readI16()
-        local i = imag_buf:readI16()
-        local magnitude = math.sqrt(r * r + i * i)
-        if magnitude > max_magnitude then
-            max_magnitude = magnitude
-        end
-    end
-
-    -- 生成归一化的频谱数据
-    for k = 1, fft_points // 2 do
-        real_buf:seek(k * 2, zbuff.SEEK_SET)
-        imag_buf:seek(k * 2, zbuff.SEEK_SET)
-        local r = real_buf:readI16()
-        local i = imag_buf:readI16()
-        local magnitude = math.sqrt(r * r + i * i)
-
-        -- 归一化到0-100范围
-        local normalized = 0
-        if max_magnitude > 0 then
-            normalized = (magnitude / max_magnitude) * 100
-        end
-
-        table.insert(freq_data, string.format("%.2f", normalized))
-
-        -- 输出主要频点信息
-        if normalized > 10 then -- 只显示能量大于10%的频点
-            local freq = (k - 1) * df
-            log.info("频点", string.format("%.0fHz: %.1f%%", freq, normalized))
-        end
-    end
-
-    -- 写入频谱数据
-    out_file:write('    { "time": 0.0, "freq": [')
-    out_file:write(table.concat(freq_data, ", "))
-    out_file:write('] }\n')
-    out_file:write('  ]\n')
-    out_file:write('}\n')
-
-    out_file:close()
-
-    log.info("完成", "32bit PCM频谱分析完成")
-    log.info("文件", "频谱数据已保存到: " .. output_filename)
-
-    return true
-end
-
--- 快速测试版本(不生成文件,直接输出)
-function quick_32bit_test(pcm_filename)
-    local sample_rate = 24000
-    local fft_points = 128
-
-    log.info("快速测试", "32bit PCM快速频谱分析")
-
-    -- 检查文件是否存在
-    if not io.exists(pcm_filename) then
-        log.error("文件", "PCM文件不存在")
-        return false
-    end
-
-    -- 最小内存分配
-    local real_buf = zbuff.create(fft_points * 2)
-    local imag_buf = zbuff.create(fft_points * 2)
-    local Wc = zbuff.create((fft_points // 2) * 2)
-    local Ws = zbuff.create((fft_points // 2) * 2)
-
-    fft.generate_twiddles_q15_to_zbuff(fft_points, Wc, Ws)
-
-    local file = io.open(pcm_filename, "rb")
-    if not file then
-        log.error("文件", "无法打开文件")
-        return false
-    end
-
-    local chunk = file:read(512) -- 只读512字节
-    file:close()
-
-    if not chunk then
-        log.error("读取", "读取文件失败")
-        return false
-    end
-
-    log.info("读取", string.format("读取了 %d 字节", #chunk))
-
-    -- 处理32bit数据
-    local samples_processed = 0
-    for i = 1, math.min(fft_points, math.floor(#chunk / 4)) do
-        local byte_pos = (i - 1) * 4 + 1
-        if byte_pos + 3 <= #chunk then
-            local b1 = chunk:byte(byte_pos)
-            local b2 = chunk:byte(byte_pos + 1)
-            local b3 = chunk:byte(byte_pos + 2)
-            local b4 = chunk:byte(byte_pos + 3)
-
-            local sample = b1 + b2 * 256 + b3 * 65536 + b4 * 16777216
-            if sample >= 2147483648 then sample = sample - 4294967296 end
-
-            -- 简化转换
-            local normalized = sample / 2147483648.0
-            local u12_val = math.floor((normalized + 1.0) * 2047.5)
-            if u12_val < 0 then u12_val = 0 end
-            if u12_val > 4095 then u12_val = 4095 end
-
-            real_buf:seek((i - 1) * 2, zbuff.SEEK_SET)
-            real_buf:writeU16(u12_val)
-            imag_buf:seek((i - 1) * 2, zbuff.SEEK_SET)
-            imag_buf:writeU16(0)
-
-            samples_processed = samples_processed + 1
-        end
-    end
-
-    -- 填充剩余数据
-    for i = samples_processed + 1, fft_points do
-        real_buf:seek((i - 1) * 2, zbuff.SEEK_SET)
-        real_buf:writeU16(2048)
-        imag_buf:seek((i - 1) * 2, zbuff.SEEK_SET)
-        imag_buf:writeU16(0)
-    end
-
-    -- FFT计算
-    fft.run(real_buf, imag_buf, fft_points, Wc, Ws, {
-        core = "q15",
-        input_format = "u12"
-    })
-
-    -- 直接输出结果
-    log.info("=== 频谱结果 ===")
-    local df = sample_rate / fft_points
-    local peaks = {}
-
-    for k = 2, fft_points // 2 do -- 跳过直流分量
-        real_buf:seek(k * 2, zbuff.SEEK_SET)
-        imag_buf:seek(k * 2, zbuff.SEEK_SET)
-        local r = real_buf:readI16()
-        local i = imag_buf:readI16()
-        local magnitude = math.sqrt(r * r + i * i)
-        local freq = (k - 1) * df
-
-        if magnitude > 100 then
-            table.insert(peaks, { freq = freq, mag = magnitude })
-        end
-    end
-
-    -- 按幅度排序,显示前10个
-    table.sort(peaks, function(a, b) return a.mag > b.mag end)
-
-    for i = 1, math.min(10, #peaks) do
-        log.info("峰值" .. i, string.format("%.0fHz (%.1f)", peaks[i].freq, peaks[i].mag))
-    end
-
-    if #peaks == 0 then
-        log.info("结果", "未检测到明显频率峰值")
-    end
-
-    return true
-end
-
--- 极简版本:只分析前几个样本
-function minimal_32bit_test(pcm_filename)
-    log.info("极简测试", "32bit PCM极简分析")
-
-    if not io.exists(pcm_filename) then
-        log.error("文件", "文件不存在")
-        return false
-    end
-
-    local file_size = io.fileSize(pcm_filename)
-    if not file_size or file_size < 16 then
-        log.error("文件", "文件太小")
-        return false
-    end
-
-    log.info("文件", string.format("文件大小: %d 字节", file_size))
-
-    -- 只读取前16个字节(4个样本)
-    local data = io.readFile(pcm_filename, "rb", 0, 16)
-    if not data then
-        log.error("读取", "读取文件失败")
-        return false
-    end
-
-    log.info("数据", string.format("读取了 %d 字节", #data))
-
-    -- 分析前4个样本
-    for i = 1, math.min(4, math.floor(#data / 4)) do
-        local byte_pos = (i - 1) * 4 + 1
-        if byte_pos + 3 <= #data then
-            local b1 = data:byte(byte_pos)
-            local b2 = data:byte(byte_pos + 1)
-            local b3 = data:byte(byte_pos + 2)
-            local b4 = data:byte(byte_pos + 3)
-
-            local sample = b1 + b2 * 256 + b3 * 65536 + b4 * 16777216
-            if sample >= 2147483648 then sample = sample - 4294967296 end
-
-            local normalized = sample / 2147483648.0
-            log.info("样本" .. i, string.format("原始值: %d, 归一化: %.6f", sample, normalized))
-        end
-    end
-
-    return true
-end
-
--- 主程序
-sys.taskInit(function()
-    if not fft then
-        log.error("FFT", "不支持FFT库")
-        return
-    end
-
-    sys.wait(3000) -- 等待系统稳定
-
-    local pcm_file = "/luadb/qlx_13sec.pcm"
-    local spectrum_file = "/spectrum.json"
-
-    if not io.exists(pcm_file) then
-        log.warn("文件", "PCM文件不存在: " .. pcm_file)
-        log.info("提示", "请将32bit PCM文件命名为 audio.pcm 并放入文件系统")
-        return
-    end
-
-    log.info("开始", "32bit PCM频谱分析...")
-
-    -- 先尝试极简测试
-    if minimal_32bit_test(pcm_file) then
-        log.info("成功", "极简测试完成")
-
-        -- 然后尝试快速测试
-        sys.wait(1000)
-        if quick_32bit_test(pcm_file) then
-            log.info("成功", "快速测试完成")
-
-            -- 最后进行完整分析
-            sys.wait(1000)
-            if generate_32bit_spectrum(pcm_file, spectrum_file) then
-                log.info("完成", "完整频谱分析完成!")
-
-                -- 检查输出文件
-                if io.exists(spectrum_file) then
-                    local out_size = io.fileSize(spectrum_file)
-                    if out_size then
-                        log.info("输出", string.format("频谱文件大小: %d 字节", out_size))
-                    end
-                end
-            else
-                log.error("失败", "完整频谱分析失败")
-            end
-        else
-            log.error("失败", "快速测试失败")
-        end
-    else
-        log.error("失败", "极简测试失败")
-    end
-
-    log.info("程序", "分析流程结束")
-    require("tcp_test")
-    dtuDemo(1, "112.125.89.8", 32062)
-end)
-
-require("test")