main.lua 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. -- LuaTools需要PROJECT和VERSION这两个信息
  2. PROJECT = "i2sdemo"
  3. VERSION = "1.0.0"
  4. --[[
  5. 本demo暂时只在air101/103/601测试过
  6. 对于EC618系列的模块,例如Air780E/Air700E,请使用audio库进行快捷播放
  7. 本demo需要外挂ES8311 codec芯片, 可使用海凌科的w800音频开发板进行测试
  8. https://detail.tmall.com/item.htm?abbucket=2&id=670202333872
  9. ]]
  10. -- sys库是标配
  11. sys = require("sys")
  12. if wdt then
  13. --添加硬狗防止程序卡死,在支持的设备上启用这个功能
  14. wdt.init(9000)--初始化watchdog设置为9s
  15. sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
  16. end
  17. sys.taskInit(function()
  18. sys.wait(500)
  19. local multimedia_id = 0
  20. local i2c_id = 0
  21. local i2s_id = 0
  22. local i2s_mode = 0
  23. local i2s_sample_rate = 44100
  24. local i2s_bits_per_sample = 16
  25. local i2s_channel_format = 0
  26. local i2s_communication_format = 0
  27. local i2s_channel_bits = 32
  28. local pa_pin = 20
  29. local pa_on_level = 1
  30. local pa_delay = 20
  31. local power_pin = 255
  32. local power_delay = 0
  33. local voice_vol = 70
  34. i2c.setup(i2c_id,i2c.FAST)
  35. i2s.setup(i2s_id, i2s_mode, i2s_sample_rate, i2s_bits_per_sample, i2s_channel_format, i2s_communication_format,i2s_channel_bits)
  36. audio.config(multimedia_id, pa_pin, pa_on_level, power_delay, pa_delay, power_pin)
  37. audio.setBus(multimedia_id, audio.BUS_I2S,{chip = "es8311",i2cid = i2c_id , i2sid = i2s_id}) --通道0的硬件输出通道设置为I2S
  38. -- 播放参数设置
  39. audio.start(multimedia_id, audio.PCM, 1, 16000, 16)
  40. -- 音量设置
  41. audio.vol(multimedia_id, 50)
  42. audio.pm(multimedia_id,audio.RESUME)
  43. -- PCM播放演示, 16k采样率, 16bit采样深度
  44. local file_size = fs.fsize("/luadb/test.pcm")
  45. -- print("/luadb/test.pcm size",file_size)
  46. local f = io.open("/luadb/test.pcm", "rb")
  47. if f then
  48. while 1 do
  49. local data = f:read(4096)
  50. -- print("-------------")
  51. if not data or #data == 0 then
  52. break
  53. end
  54. audio.write(0, data)
  55. sys.wait(100)
  56. end
  57. f:close()
  58. end
  59. -- mp3测试
  60. -- 推荐使用ffmpeg对mp3文件进行预处理, 必须转成单声道
  61. -- ffmpeg -i abc.mp3 -ac 1 -map_metadata -1 -y out.mp3
  62. -- Air101/Air103/Air601支持采样率 8~44.1k, 深度8-16bit, 以下是转成16k采样率
  63. -- ffmpeg -i abc.mp3 -ac 1 -map_metadata -1 -ar 16000 -y out.mp3
  64. local path = "/luadb/out.mp3"
  65. local decoder = codec.create(codec.MP3)
  66. log.info("decoder", decoder)
  67. local result, audio_format, num_channels, sample_rate, bits_per_sample, is_signed= codec.info(decoder, path)
  68. log.info("info", result, audio_format, num_channels, sample_rate, bits_per_sample, is_signed)
  69. if result then
  70. -- 按mp3实际情况切换采样率和采样深度
  71. audio.start(0, audio.PCM, 1, sample_rate, bits_per_sample)
  72. -- 音频数据缓存区大小
  73. local buff = zbuff.create(8*1024)
  74. -- log.info("sys", rtos.meminfo("sys"))
  75. -- log.info("buff", buff)
  76. while 1 do
  77. -- log.info("尝试解码")
  78. local result = codec.data(decoder, buff, 4096)
  79. -- log.info("解析结果", result)
  80. if result then
  81. while 1 do
  82. -- 判断底层缓冲区是否空闲, 不空闲就需要等待
  83. local max, remain = i2s.txStat(0)
  84. if max == 0 then
  85. sys.wait(120)
  86. break
  87. end
  88. if remain > (max / 2) then
  89. sys.wait(10) -- sys.waitUntil("AUDIO_INC", 10)
  90. else
  91. break -- 已经足够空闲,写入数据就好
  92. end
  93. end
  94. audio.write(0, buff)
  95. -- log.info("音频数据已写入", buff:used())
  96. else
  97. break
  98. end
  99. end
  100. end
  101. -- 释放解码器资源
  102. codec.release(decoder)
  103. end)
  104. -- sys.taskInit(function()
  105. -- while 1 do
  106. -- -- 打印内存状态, 调试用
  107. -- sys.wait(1000)
  108. -- log.info("lua", rtos.meminfo())
  109. -- log.info("sys", rtos.meminfo("sys"))
  110. -- end
  111. -- end)
  112. -- 用户代码已结束---------------------------------------------
  113. -- 结尾总是这一句
  114. sys.run()
  115. -- sys.run()之后后面不要加任何语句!!!!!