main.lua 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. -- LuaTools需要PROJECT和VERSION这两个信息
  2. PROJECT = "record"
  3. VERSION = "1.0.0"
  4. -- sys库是标配
  5. _G.sys = require("sys")
  6. _G.sysplus = require("sysplus")
  7. gpio.setup(24, 1, gpio.PULLUP) -- i2c工作的电压域
  8. local taskName = "task_audio"
  9. local MSG_MD = "moreData" -- 播放缓存有空余
  10. local MSG_PD = "playDone" -- 播放完成所有数据
  11. -- amr数据存放buffer,尽可能地给大一些
  12. amr_buff = zbuff.create(20 * 1024)
  13. --创建一个amr的encoder
  14. encoder = nil
  15. pcm_buff0 = zbuff.create(16000)
  16. pcm_buff1 = zbuff.create(16000)
  17. audio.on(0, function(id, event, point)
  18. --使用play来播放文件时只有播放完成回调
  19. if event == audio.RECORD_DATA then -- 录音数据
  20. if point == 0 then
  21. log.info("buff", point, pcm_buff0:used())
  22. codec.encode(encoder, pcm_buff0, amr_buff)
  23. else
  24. log.info("buff", point, pcm_buff1:used())
  25. codec.encode(encoder, pcm_buff1, amr_buff)
  26. end
  27. elseif event == audio.RECORD_DONE then -- 录音完成
  28. sys.publish("AUDIO_RECORD_DONE")
  29. else
  30. local succ,stop,file_cnt = audio.getError(0)
  31. if not succ then
  32. if stop then
  33. log.info("用户停止播放")
  34. else
  35. log.info("第", file_cnt, "个文件解码失败")
  36. end
  37. end
  38. -- log.info("播放完成一个音频")
  39. sysplus.sendMsg(taskName, MSG_PD)
  40. end
  41. end)
  42. ---- MultipartForm上传文件
  43. -- url string 请求URL地址
  44. -- filename string 上传服务器的文件名
  45. -- filePath string 待上传文件的路径
  46. local function postMultipartFormData(url, filename, filePath)
  47. local boundary = "----WebKitFormBoundary"..os.time()
  48. local req_headers = {
  49. ["Content-Type"] = "multipart/form-data; boundary=" .. boundary,
  50. }
  51. local body = {}
  52. table.insert(body, "--"..boundary.."\r\nContent-Disposition: form-data; name=\"file\"; filename=\"".. filename .."\"\r\n\r\n")
  53. table.insert(body, io.readFile(filePath))
  54. table.insert(body, "\r\n")
  55. table.insert(body, "--"..boundary.."--\r\n")
  56. body = table.concat(body)
  57. log.info("headers: ", "\r\n" .. json.encode(req_headers), type(body))
  58. log.info("body: " .. body:len() .. "\r\n" .. body)
  59. local code, headers, body = http.request("POST",url,
  60. req_headers,
  61. body
  62. ).wait()
  63. log.info("http.post", code, headers, body)
  64. end
  65. function audio_setup()
  66. local i2c_id = 0 -- i2c_id 0
  67. local pa_pin = 162 -- 喇叭pa功放脚
  68. local power_pin = 164 -- es8311电源脚
  69. local i2s_id = 0 -- i2s_id 0
  70. local i2s_mode = 0 -- i2s模式 0 主机 1 从机
  71. local i2s_sample_rate = 16000 -- 采样率
  72. local i2s_bits_per_sample = 16 -- 数据位数
  73. local i2s_channel_format = i2s.MONO_R -- 声道, 0 左声道, 1 右声道, 2 立体声
  74. local i2s_communication_format = i2s.MODE_LSB -- 格式, 可选MODE_I2S, MODE_LSB, MODE_MSB
  75. local i2s_channel_bits = 16 -- 声道的BCLK数量
  76. local multimedia_id = 0 -- 音频通道 0
  77. local pa_on_level = 1 -- PA打开电平 1 高电平 0 低电平
  78. local power_delay = 3 -- 在DAC启动前插入的冗余时间,单位100ms
  79. local pa_delay = 100 -- 在DAC启动后,延迟多长时间打开PA,单位1ms
  80. local power_on_level = 1 -- 电源控制IO的电平,默认拉高
  81. local power_time_delay = 100 -- 音频播放完毕时,PA与DAC关闭的时间间隔,单位1ms
  82. local voice_vol = 70 -- 喇叭音量
  83. local mic_vol = 80 -- 麦克风音量
  84. gpio.setup(power_pin, 1, gpio.PULLUP)
  85. gpio.setup(pa_pin, 1, gpio.PULLUP)
  86. pm.power(pm.LDO_CTL, false) --开发板上ES8311由LDO_CTL控制上下电
  87. sys.wait(100)
  88. pm.power(pm.LDO_CTL, true) --开发板上ES8311由LDO_CTL控制上下电
  89. gpio.setup(8, 1)
  90. i2c.setup(i2c_id,i2c.FAST) --设置i2c
  91. i2s.setup(i2s_id, i2s_mode, i2s_sample_rate, i2s_bits_per_sample, i2s_channel_format, i2s_communication_format,i2s_channel_bits) --设置i2s
  92. audio.config(multimedia_id, pa_pin, pa_on_level, power_delay, pa_delay, power_pin, power_on_level, power_time_delay)
  93. audio.setBus(multimedia_id, audio.BUS_I2S,{chip = "es8311",i2cid = i2c_id , i2sid = i2s_id, voltage = audio.VOLTAGE_1800}) --通道0的硬件输出通道设置为I2S
  94. audio.vol(multimedia_id, voice_vol)
  95. audio.micVol(multimedia_id, mic_vol)
  96. sys.publish("AUDIO_READY")
  97. end
  98. -- 配置好audio外设
  99. sys.taskInit(audio_setup)
  100. local function audio_task()
  101. sys.waitUntil("AUDIO_READY")
  102. sys.wait(5000)
  103. local result
  104. --下面为录音demo,根据适配情况选择性开启
  105. local recordPath = "/record.amr"
  106. -- -- 直接录音到文件
  107. -- err = audio.record(0, audio.AMR, 5, 7, recordPath)
  108. -- sys.waitUntil("AUDIO_RECORD_DONE")
  109. -- log.info("record","录音结束")
  110. -- result = audio.play(0, {recordPath})
  111. -- if result then
  112. -- --等待音频通道的回调消息,或者切换歌曲的消息
  113. -- while true do
  114. -- msg = sysplus.waitMsg(taskName, nil)
  115. -- if type(msg) == 'table' then
  116. -- if msg[1] == MSG_PD then
  117. -- log.info("播放结束")
  118. -- break
  119. -- end
  120. -- else
  121. -- log.error(type(msg), msg)
  122. -- end
  123. -- end
  124. -- else
  125. -- log.debug("解码失败!")
  126. -- sys.wait(1000)
  127. -- end
  128. -- -- 录音到内存自行编码
  129. encoder = codec.create(codec.AMR, false, 7)
  130. log.info("encoder",encoder)
  131. log.info("开始录音")
  132. err = audio.record(0, audio.AMR, 5, 7, nil,nil, pcm_buff0, pcm_buff1)
  133. sys.waitUntil("AUDIO_RECORD_DONE")
  134. log.info("record","录音结束")
  135. os.remove(recordPath)
  136. io.writeFile(recordPath, "#!AMR\n")
  137. io.writeFile(recordPath, amr_buff:query(), "a+b")
  138. result = audio.play(0, {recordPath})
  139. if result then
  140. --等待音频通道的回调消息,或者切换歌曲的消息
  141. while true do
  142. msg = sysplus.waitMsg(taskName, nil)
  143. if type(msg) == 'table' then
  144. if msg[1] == MSG_PD then
  145. log.info("播放结束")
  146. break
  147. end
  148. else
  149. log.error(type(msg), msg)
  150. end
  151. end
  152. else
  153. log.debug("解码失败!")
  154. sys.wait(1000)
  155. end
  156. -- 下面的演示是将音频文件发送到服务器上,如有需要,可以将下面代码注释打开,这里的url是合宙的文件上传测试服务器,上传的文件到http://tools.openluat.com/tools/device-upload-test查看
  157. --[[
  158. local timeTable = os.date("*t", os.time())
  159. local nowTime = string.format("%4d%02d%02d_%02d%02d%02d", timeTable.year, timeTable.month, timeTable.day, timeTable.hour, timeTable.min, timeTable.sec)
  160. local filename = mobile.imei() .. "_" .. nowTime .. ".amr"
  161. postMultipartFormData("http://tools.openluat.com/api/site/device_upload_file", filename, recordPath)
  162. ]]
  163. --该方法为从串口1,把录音数据传给串口1
  164. -- uart.setup(1, 115200) -- 开启串口1
  165. -- uart.write(1, io.readFile(recordPath)) -- 向串口发送录音文件
  166. end
  167. sysplus.taskInitEx(audio_task, taskName)
  168. -- 用户代码已结束---------------------------------------------
  169. -- 结尾总是这一句
  170. sys.run()
  171. -- sys.run()之后后面不要加任何语句!!!!!