music_demo.lua 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. --[[
  2. 接线要求:
  3. SPI 使用常规4线解法
  4. Air105开发板 TF模块
  5. PC9 CS
  6. PB12(SPI0_CLK) CLK
  7. PB14(SPI0_MISO) MOSI
  8. PB15(SPI0_MISO) MISO
  9. 5V VCC
  10. GND GND
  11. ]]
  12. audio.on(0, function(id, event_id)
  13. if event_id == audio.MORE_DATA then
  14. sys.publish("moredata")
  15. else
  16. sys.publish("playover")
  17. end
  18. end)
  19. -- music文件夾,可以換成你自己的目录,不用加/sd/,demo里固定用TF卡目录,如果要本地目录,自行修改
  20. local music_dir = "/music/"
  21. sys.taskInit(function()
  22. sys.wait(100) -- 启动延时
  23. local tag_len = 0
  24. local frame_len = 1045
  25. local spiId = 0
  26. local result = spi.setup(
  27. spiId,--串口id
  28. 255, -- 不使用默认CS脚
  29. 0,--CPHA
  30. 0,--CPOL
  31. 8,--数据宽度
  32. 400*1000 -- 初始化时使用较低的频率
  33. )
  34. local TF_CS = pin.PB13
  35. gpio.setup(TF_CS, 1)
  36. -- fatfs.debug(1) -- 若挂载失败,可以尝试打开调试信息,查找原因
  37. fatfs.mount("SD", 0, TF_CS, 24000000)
  38. -- fatfs.mount("SD", 0, TF_CS, 24000000)
  39. local data, err = fatfs.getfree("SD")
  40. -- usbapp.udisk_attach_sdhc(0)
  41. -- usbapp.start(0)
  42. -- sys.wait(600000)
  43. local buff = zbuff.create(1024)
  44. local in_buff = zbuff.create(8 * 1024 + 512)
  45. local play_list = {}
  46. if data then
  47. log.info("fatfs", "getfree", json.encode(data))
  48. local dir_nums, dir_info = fatfs.lsdir(music_dir)
  49. for k,v in pairs(dir_info) do
  50. log.info("find",k)
  51. play_list[v.size] = "/sd".. music_dir .. k
  52. end
  53. while true do
  54. for k,v in pairs(play_list) do
  55. log.info('play',v)
  56. log.info(rtos.meminfo("sys"))
  57. log.info(rtos.meminfo("lua"))
  58. if v:find(".mp3") or v:find(".MP3") then
  59. f = io.open(v, "rb")
  60. if f then
  61. -- log.debug("find mp3")
  62. in_buff:del()
  63. data = f:read(10)
  64. if data:sub(1, 3) == 'ID3' then
  65. in_buff:copy(nil, data)
  66. tag_len = ((in_buff:query(6, 1, true) & 0x7f) << 21) + ((in_buff:query(7, 1, true) & 0x7f) << 14) + ((in_buff:query(8, 1, true) & 0x7f) << 7) + (in_buff:query(9, 1, true) & 0x7f)
  67. log.info("jump head", tag_len)
  68. f:seek(SEEK_SET, tag_len)
  69. end
  70. in_buff:del()
  71. data = f:read(2048)
  72. codecr = codec.create(codec.MP3)
  73. local result, AudioFormat, NumChannels, SampleRate, BitsPerSample, is_signed = codec.get_audio_info(codecr, data)
  74. if result then
  75. log.info("mp3 info", NumChannels, SampleRate, BitsPerSample)
  76. buff:resize(65536)
  77. in_buff:copy(nil, data)
  78. result, frame_len = codec.get_audio_data(codecr, in_buff, buff)
  79. log.debug("frame_len",frame_len)
  80. in_buff:resize(frame_len * 8 + 512)
  81. log.debug("start", audio.start(0, AudioFormat, NumChannels, SampleRate, BitsPerSample, is_signed))
  82. audio.write(0, buff)
  83. --local tick1,_ = mcu.tick64()
  84. data = f:read(frame_len * 4)
  85. in_buff:copy(nil, data)
  86. result,_ = codec.get_audio_data(codecr, in_buff, buff)
  87. --local tick2,_ = mcu.tick64()
  88. --log.debug(mcu.dtick64(tick2, tick1)/_)
  89. audio.write(0, buff)
  90. data = f:read(frame_len * 4)
  91. while result and data and #data > 0 do
  92. sys.waitUntil("moredata", 2000)
  93. in_buff:copy(nil, data)
  94. result,_= codec.get_audio_data(codecr, in_buff, buff)
  95. if result then
  96. audio.write(0, buff)
  97. data = f:read(frame_len * 4)
  98. else
  99. log.info("解码结束")
  100. end
  101. end
  102. sys.waitUntil("playover", 2000)
  103. f:close()
  104. audio.stop(0)
  105. else
  106. log.debug("mp3 decode fail!")
  107. f:close()
  108. end
  109. codec.release(codecr)
  110. end
  111. end
  112. if v:find(".wav") or v:find(".WAV") then
  113. data = nil
  114. f = io.open(v, "rb")
  115. if f then
  116. buff:del()
  117. buff:copy(0, f:read(12))
  118. if buff:query(0, 4) == 'RIFF' and buff:query(8, 4) == 'WAVE' then
  119. local total = buff:query(4, 4, false)
  120. buff:copy(0, f:read(8))
  121. if buff:query(0, 4) == 'fmt ' then
  122. buff:copy(0, f:read(16))
  123. buff:seek(0, zbuff.SEEK_SET)
  124. local _, AudioFormat, NumChannels, SampleRate, ByteRate, BlockAlign, BitsPerSample = buff:unpack("<HHIIHH")
  125. log.debug("find fmt info", AudioFormat, NumChannels, SampleRate, ByteRate, BlockAlign, BitsPerSample)
  126. buff:copy(0, f:read(8))
  127. if buff:query(0, 4) ~= 'data' then
  128. buff:copy(0, buff:query(4, 4, false))
  129. buff:copy(0, f:read(8))
  130. end
  131. log.debug("start", audio.start(0, AudioFormat, NumChannels, SampleRate, BitsPerSample))
  132. SampleRate = (SampleRate * BlockAlign / 8) & ~(3)
  133. log.info("size", SampleRate)
  134. data = f:read(SampleRate)
  135. audio.write(0, data)
  136. data = f:read(SampleRate)
  137. audio.write(0, data)
  138. data = f:read(SampleRate)
  139. while data and #data > 0 do
  140. sys.waitUntil("moredata", 2000)
  141. audio.write(0, data)
  142. data = f:read(SampleRate)
  143. end
  144. sys.waitUntil("playover", 2000)
  145. audio.stop(0)
  146. end
  147. else
  148. log.debug(buff:query(0, 4), buff:query(8, 4))
  149. end
  150. f:close()
  151. end
  152. end
  153. log.info(rtos.meminfo("sys"))
  154. log.info(rtos.meminfo("lua"))
  155. end
  156. end
  157. else
  158. log.info("fatfs", "err", err)
  159. end
  160. end)