main.lua 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. -- LuaTools需要PROJECT和VERSION这两个信息
  2. PROJECT = "audiotest"
  3. VERSION = "2.0.1"
  4. -- sys库是标配
  5. _G.sys = require("sys")
  6. _G.sysplus = require("sysplus")
  7. -- Air780E的AT固件默认会为开机键防抖, 导致部分用户刷机很麻烦
  8. if rtos.bsp() == "EC618" and pm and pm.PWK_MODE then
  9. pm.power(pm.PWK_MODE, false)
  10. end
  11. log.style(1)
  12. local taskName = "task_audio"
  13. local MSG_MD = "moreData" -- 播放缓存有空余
  14. local MSG_PD = "playDone" -- 播放完成所有数据
  15. -- amr数据存放buffer,尽可能地给大一些
  16. amr_buff = zbuff.create(20 * 1024)
  17. --创建一个amr的encoder
  18. encoder = nil
  19. audio.on(0, function(id, event,buff)
  20. --使用play来播放文件时只有播放完成回调
  21. if event == audio.RECORD_DATA then -- 录音数据
  22. codec.encode(encoder, buff, amr_buff)
  23. elseif event == audio.RECORD_DONE then -- 录音完成
  24. sys.publish("AUDIO_RECORD_DONE")
  25. else
  26. local succ,stop,file_cnt = audio.getError(0)
  27. if not succ then
  28. if stop then
  29. log.info("用户停止播放")
  30. else
  31. log.info("第", file_cnt, "个文件解码失败")
  32. end
  33. end
  34. -- log.info("播放完成一个音频")
  35. sysplus.sendMsg(taskName, MSG_PD)
  36. end
  37. end)
  38. function audio_setup()
  39. local bsp = rtos.bsp()
  40. if bsp == "EC618" then
  41. --Air780E开发板配套+音频扩展板. ES7149
  42. --由于音频扩展板的PA是长供电的,有塔塔声音是正常的,做产品的话有额外的参考设计
  43. i2s.setup(0, 0, 0, 0, 0, i2s.MODE_I2S)
  44. --如果用TM8211,打开下面的注释
  45. -- i2s.setup(0, 0, 0, 0, 0, i2s.MODE_MSB)
  46. --如果用软件DAC,打开下面的注释
  47. -- if audio.setBus then
  48. -- audio.setBus(0, audio.BUS_SOFT_DAC)
  49. -- end
  50. audio.config(0, 25, 1, 3, 100)
  51. elseif bsp == "EC718P" then
  52. -- CORE+音频小板是这个配置/云喇叭开发板同为这个配置
  53. local multimedia_id = 0
  54. local i2c_id = 0 --云喇叭开发版是1
  55. local i2s_id = 0
  56. local i2s_mode = 0
  57. local i2s_sample_rate = 16000
  58. local i2s_bits_per_sample = 16
  59. local i2s_channel_format = i2s.MONO_R
  60. local i2s_communication_format = i2s.MODE_LSB
  61. local i2s_channel_bits = 16
  62. local pa_pin = 25
  63. local pa_on_level = 1
  64. local pa_delay = 100
  65. local power_pin = 16 -- Air780EPVH 请修改成17
  66. local power_on_level = 1
  67. local power_delay = 3
  68. local power_time_delay = 100
  69. local voice_vol = 70
  70. local mic_vol = 80
  71. local find_es8311 = false
  72. --自适应开发板,如果明确是I2C几就不用了
  73. i2c.setup(0, i2c.FAST)
  74. i2c.setup(1, i2c.FAST)
  75. pm.power(pm.LDO_CTL, false) --开发板上ES8311由LDO_CTL控制上下电
  76. sys.wait(10)
  77. pm.power(pm.LDO_CTL, true) --开发板上ES8311由LDO_CTL控制上下电
  78. sys.wait(10)
  79. if i2c.send(0, 0x18, 0xfd) == true then
  80. log.info("音频小板", "codec on i2c0")
  81. i2c_id = 0
  82. find_es8311 = true
  83. else
  84. if i2c.send(1, 0x18, 0xfd) == true then
  85. log.info("云喇叭开发板", "codec on i2c1")
  86. find_es8311 = true
  87. power_pin = nil
  88. i2c_id = 1
  89. end
  90. end
  91. if not find_es8311 then
  92. while true do
  93. log.info("not find es8311")
  94. sys.wait(1000)
  95. end
  96. end
  97. i2s.setup(i2s_id, i2s_mode, i2s_sample_rate, i2s_bits_per_sample, i2s_channel_format, i2s_communication_format,i2s_channel_bits)
  98. audio.config(multimedia_id, pa_pin, pa_on_level, power_delay, pa_delay, power_pin, power_on_level, power_time_delay)
  99. audio.setBus(multimedia_id, audio.BUS_I2S,{chip = "es8311",i2cid = i2c_id , i2sid = i2s_id}) --通道0的硬件输出通道设置为I2S
  100. audio.vol(multimedia_id, voice_vol)
  101. audio.micVol(multimedia_id, mic_vol)
  102. -- audio.debug(true)
  103. --带TM8211的云喇叭开发板参考下面的配置
  104. --[[
  105. local multimedia_id = 0
  106. local i2s_id = 0
  107. local i2s_mode = 0
  108. local i2s_sample_rate = 0
  109. local i2s_bits_per_sample = 16
  110. local i2s_channel_format = i2s.STEREO
  111. local i2s_communication_format = i2s.MODE_MSB
  112. local i2s_channel_bits = 16
  113. local pa_pin = 25
  114. local pa_on_level = 1
  115. local pa_delay = 100
  116. local power_pin = nil
  117. local power_on_level = 1
  118. local power_delay = 3
  119. local power_time_delay = 0
  120. local voice_vol = 100
  121. -- local voice_vol = 200 --默认就不放大了
  122. i2s.setup(i2s_id, i2s_mode, i2s_sample_rate, i2s_bits_per_sample, i2s_channel_format, i2s_communication_format,i2s_channel_bits)
  123. audio.config(multimedia_id, pa_pin, pa_on_level, power_delay, pa_delay, power_pin, power_on_level, power_time_delay)
  124. audio.setBus(multimedia_id, audio.BUS_I2S,{chip = "tm8211", i2sid = i2s_id}) --通道0的硬件输出通道设置为I2S
  125. -- audio.vol(multimedia_id, voice_vol)
  126. ]]
  127. elseif bsp == "AIR105" then
  128. -- Air105开发板支持DAC直接输出
  129. audio.config(0, 25, 1, 3, 100)
  130. else
  131. -- 其他板子未支持
  132. while 1 do
  133. log.info("audio", "尚未支持的BSP")
  134. sys.wait(1000)
  135. end
  136. end
  137. sys.publish("AUDIO_READY")
  138. end
  139. -- 配置好audio外设
  140. sys.taskInit(audio_setup)
  141. local function audio_task()
  142. sys.waitUntil("AUDIO_READY")
  143. local result
  144. --下面为录音demo,根据适配情况选择性开启
  145. -- local recordPath = "/record.amr"
  146. -- -- 直接录音到文件
  147. -- err = audio.record(0, audio.AMR, 5, 7, recordPath)
  148. -- sys.waitUntil("AUDIO_RECORD_DONE")
  149. -- log.info("record","录音结束")
  150. -- result = audio.play(0, {recordPath})
  151. -- while true do
  152. -- msg = sysplus.waitMsg(taskName, nil)
  153. -- if type(msg) == 'table' then
  154. -- if msg[1] == MSG_PD then
  155. -- log.info("播放结束")
  156. -- break
  157. -- end
  158. -- else
  159. -- log.error(type(msg), msg)
  160. -- end
  161. -- end
  162. -- -- 录音到内存自行编码
  163. -- encoder = codec.create(codec.AMR, false, 7)
  164. -- print("encoder",encoder)
  165. -- err = audio.record(0, audio.AMR, 5, 7)
  166. -- sys.waitUntil("AUDIO_RECORD_DONE")
  167. -- log.info("record","录音结束")
  168. -- os.remove(recordPath)
  169. -- io.writeFile(recordPath, "#!AMR\n")
  170. -- io.writeFile(recordPath, amr_buff:query(), "a+b")
  171. -- result = audio.play(0, {recordPath})
  172. -- while true do
  173. -- msg = sysplus.waitMsg(taskName, nil)
  174. -- if type(msg) == 'table' then
  175. -- if msg[1] == MSG_PD then
  176. -- log.info("播放结束")
  177. -- break
  178. -- end
  179. -- else
  180. -- log.error(type(msg), msg)
  181. -- end
  182. -- end
  183. -- amr 可播放采样率 8k/16k
  184. local amrs = {"/luadb/alipay.amr", "/luadb/2.amr", "/luadb/10.amr", "/luadb/yuan.amr"}
  185. -- 如需在同一个table内混播, 需要使用相同的采样率
  186. -- 此mp3为自由文件,无版权问题,合宙自录音频,若测试音质请使用其他高清mp3
  187. -- local mp3s = {"/luadb/test_32k.mp3"}
  188. -- ec618的固件需要用非full版本才能放下44k的MP3
  189. local mp3s = {"/luadb/test_44k.mp3"}
  190. local counter = 0
  191. while true do
  192. log.info("开始播放")
  193. -- 两个列表前后播放
  194. if rtos.bsp() == "AIR105" then
  195. result = audio.play(0, "/luadb/test_32k.mp3")
  196. else
  197. result = audio.play(0, counter % 2 == 1 and amrs or mp3s)
  198. end
  199. counter = counter + 1
  200. if result then
  201. --等待音频通道的回调消息,或者切换歌曲的消息
  202. while true do
  203. msg = sysplus.waitMsg(taskName, nil)
  204. if type(msg) == 'table' then
  205. if msg[1] == MSG_PD then
  206. log.info("播放结束")
  207. break
  208. end
  209. else
  210. log.error(type(msg), msg)
  211. end
  212. end
  213. else
  214. log.debug("解码失败!")
  215. sys.wait(1000)
  216. end
  217. if not audio.isEnd(0) then
  218. log.info("手动关闭")
  219. audio.playStop(0)
  220. end
  221. audio.pm(0,audio.SHUTDOWN)
  222. --低功耗测试打开下面的代码
  223. --[[
  224. audio.pm(0,audio.POWEROFF) --低功耗可以选择SHUTDOWN或者POWEROFF,如果codec无法断电用SHUTDOWN
  225. pm.power(pm.USB, false)
  226. mobile.flymode(0, true)
  227. pm.request(pm.LIGHT)
  228. sys.wait(20000)
  229. mobile.flymode(0, false)
  230. ]]
  231. log.info(rtos.meminfo("sys"))
  232. log.info(rtos.meminfo("lua"))
  233. sys.wait(1000)
  234. end
  235. sysplus.taskDel(taskName)
  236. end
  237. sysplus.taskInitEx(audio_task, taskName, task_cb)
  238. -- 用户代码已结束---------------------------------------------
  239. -- 结尾总是这一句
  240. sys.run()
  241. -- sys.run()之后后面不要加任何语句!!!!!