app.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. // app.js
  2. App({
  3. data: {//数据
  4. worker: null,//线程句柄
  5. recorder: null,//录音设备句柄
  6. wavFilePath: '',//wav文件路径
  7. readFileTimes: 0,//读取本地文件次数
  8. imuStartTimestamp: 0,//IMU开始时间戳
  9. },
  10. onLaunch() {
  11. },
  12. //创建线程(listener:线程监听服务程序)
  13. createWorker(listener) {
  14. if (this.data.worker == null) {
  15. this.data.worker = wx.createWorker("worker/worker.js")
  16. //设置线程监听服务程序
  17. if (typeof (listener) === 'function') {
  18. this.setWorkerListener(listener)
  19. //发消息给worker,加载wasm
  20. this.data.worker.postMessage({
  21. message: 'MAIN_WORKER_LOAD_WX_WASM',
  22. data: ''
  23. })
  24. }
  25. }
  26. },
  27. //设置线程监听服务程序
  28. setWorkerListener(listener) {
  29. if (this.data.worker != null) {
  30. this.data.worker.onMessage(listener)
  31. }
  32. },
  33. //创建录音设备,并监听录音完成事件
  34. createRecorder() {
  35. const self = this
  36. //获得录音机句柄
  37. this.data.recorder = wx.getRecorderManager()
  38. //注册录音回调函数(录音长度达到设定值后执行)
  39. this.data.recorder.onFrameRecorded((res) => {
  40. //从返回参数res中解构isLastFrame和frameBuffer变量
  41. //其中frameBuffer是二进制数据数组,不能直接读写
  42. const { isLastFrame, frameBuffer } = res
  43. //录音时长达到最大值,则重新开始录音
  44. //微信小程序录音时长最长为10分钟
  45. if (isLastFrame) {
  46. self.startRecord()
  47. }
  48. //将录音数据发送给worker
  49. self.data.worker.postMessage({
  50. message: 'MAIN_WORKER_AUDIO_DATA',
  51. data: frameBuffer
  52. })
  53. })
  54. //延迟1秒后开始录音,以便让录音机稳定
  55. setTimeout(this.startRecord, 1000)
  56. },
  57. //开始录音
  58. startRecord() {
  59. if (this.data.recorder != null) {
  60. let options = {}
  61. //组织录音参数
  62. options.duration = 600000 //最长连续录音10分钟
  63. options.sampleRate = 48000 //采样频率
  64. options.encodeBitRate = 320000 //TODO,编码率,不知道干什么用的
  65. options.numberOfChannels = 1 //单通道采样
  66. options.format = "pcm"
  67. options.frameSize = "22" //单位kB(数据不会太准确,因此需要缓存数据以实施成帧操作)
  68. //开始录音
  69. this.data.recorder.start(options)
  70. }
  71. },
  72. //打开蓝牙适配器
  73. openBleAdapter() {
  74. let self = this
  75. wx.openBluetoothAdapter({
  76. mode: "central",
  77. success: function (res) {//打开成功,开始扫描周边设备
  78. wx.startBluetoothDevicesDiscovery({
  79. allowDuplicatesKey: true,
  80. interval: 2000,//2秒扫描一次
  81. powerLevel: "medium",
  82. success() {
  83. self.monitorBleBtsScanResult()
  84. }
  85. })
  86. },
  87. fail: function (err) {//打开失败
  88. console.log("open ble fail", err)
  89. setTimeout(() => {
  90. self.openBleAdapter()
  91. }, 3000)
  92. }
  93. })
  94. //this.monitorBleBtsScanResult();
  95. // // 监听扫描到新设备事件
  96. // wx.onBluetoothDeviceFound((res) => {
  97. // console.log("扫描到了蓝牙设备")
  98. // res.devices.forEach((device) => {
  99. // console.log('Device Found', device)
  100. // })
  101. // })
  102. },
  103. //开始扫描周边蓝牙设备
  104. startScanNearbyBleBts() {
  105. let self = this
  106. //扫描周边设备
  107. wx.startBluetoothDevicesDiscovery({
  108. allowDuplicatesKey: true,//允许重复上报已扫描到的设备
  109. interval: 3000,//3秒扫描一次
  110. powerLevel: "medium",
  111. success: function () {
  112. self.monitorBleBtsScanResult()//监听蓝牙基站扫描结果
  113. },
  114. fail: function () {
  115. //500毫秒之后重新扫描
  116. setTimeout(self.startScanNearbyBleBts, 500)
  117. }
  118. })
  119. },
  120. //监听蓝牙基站扫描结果
  121. monitorBleBtsScanResult() {
  122. let self = this
  123. wx.onBluetoothDeviceFound((res) => {
  124. let findFlag = 0//发现系统基站标识符
  125. let bleBtsDataList = []//蓝牙基站数据队列
  126. //遍历蓝牙设备队列
  127. res.devices.forEach((element) => {
  128. if (element.name && element.name.length == 23) {
  129. let bleName = element.name
  130. let subName = bleName.slice(-10)
  131. //该设备为本系统设备
  132. if (subName === "IPS8000BLE") {
  133. if (!findFlag) {
  134. findFlag = 1//发现系统基站
  135. }
  136. let macAddress = bleName.substring(0, 12);//BLE的mac地址
  137. let rssi = -10000;
  138. if (element.RSSI) {
  139. rssi = element.RSSI//接收电平强度
  140. }
  141. //保存扫描结果
  142. let item = {}
  143. item['mac'] = macAddress;
  144. item['rssi'] = rssi
  145. bleBtsDataList.push(item)
  146. }
  147. }
  148. })
  149. //成功监听到本系统蓝牙设备
  150. if (findFlag) {
  151. //组织本次监听到的蓝牙基站数据
  152. self.organizeBleBtsData(bleBtsDataList)
  153. }
  154. })
  155. },
  156. //按照wasm模块所需格式组织蓝牙基站数据
  157. organizeBleBtsData(bleBtsList) {
  158. let listLen = 0
  159. let bleBtsDataList = []//蓝牙基站数据队列
  160. let rssi = 0
  161. let strMac = ""
  162. let macLen = 0
  163. let oneHexChar = ""
  164. let oneHexCharValue = 0
  165. //没有蓝牙基站
  166. if (!bleBtsList || bleBtsList.length <= 0) {
  167. return
  168. }
  169. //队列长度
  170. listLen = bleBtsList.length
  171. if (listLen > 9) {
  172. listLen = 9//最多9个蓝牙基站
  173. }
  174. ////按照WASM模块所需数据格式组织蓝牙基站数据
  175. bleBtsDataList.push(1)//蓝牙基站有效标识符置1
  176. bleBtsDataList.push(listLen)//蓝牙基站个数
  177. //组织RSSI和MAC
  178. for (let i = 0; i < listLen; i++) {
  179. rssi = bleBtsList[i].rssi
  180. bleBtsDataList.push(rssi)//RSSI
  181. strMac = bleBtsList[i].mac//mac地址16进制字符串
  182. macLen = strMac.length
  183. if (macLen == 12) {
  184. for (let j = 0; j < macLen; j++) {
  185. oneHexChar = strMac[j]
  186. oneHexCharValue = this.hexCharToValue(oneHexChar)
  187. bleBtsDataList.push(oneHexCharValue)//MAC
  188. }
  189. } else {
  190. console.log("长度错误")
  191. }
  192. }
  193. //把数据发送给worker
  194. if (bleBtsDataList.length > 3) {
  195. if (this.data.worker != null) {
  196. this.data.worker.postMessage({
  197. message: 'MAIN_WORKER_BLE_BTS_DATA',
  198. data: bleBtsDataList
  199. })
  200. }
  201. }
  202. },
  203. hexCharToValue(char) {
  204. // 定义16进制字符到数值的映射
  205. const hexValues = {
  206. '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7,
  207. '8': 8, '9': 9, 'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15,
  208. 'a': 10, 'b': 11, 'c': 12, 'd': 13, 'e': 14, 'f': 15
  209. };
  210. // 查找字符对应的值
  211. return hexValues[char];
  212. },
  213. //停止扫描蓝牙设备
  214. stopScanNearbyBle() {
  215. let self = this
  216. wx.stopBluetoothDevicesDiscovery({
  217. success: function () {
  218. wx.offBluetoothDeviceFound(function () { })
  219. },
  220. fail: function () {
  221. console.log("没有扫描到基站")
  222. setTimeout(self.stopScanNearbyBle, 3000)
  223. }
  224. })
  225. },
  226. //启动加速度计
  227. startImu() {
  228. wx.stopAccelerometer()//停止加速度传感器
  229. //启动加速度传感器,20毫秒采集一次加速度
  230. wx.startAccelerometer({ interval: "game" })
  231. //监听加速度传感器
  232. wx.onAccelerometerChange(this.onAccelerometerChange)
  233. //生成IMU开始时间戳
  234. this.data.imuStartTimestamp = new Date().getTime()
  235. },
  236. //监测三轴加速度计的变化
  237. onAccelerometerChange(res) {
  238. let timestamp = new Date().getTime() - this.data.imuStartTimestamp; //生成时间戳
  239. let item = {}
  240. item.timestamp = timestamp
  241. item.x = res.x
  242. item.y = res.y
  243. item.z = res.z
  244. //把数据发送给线程
  245. if (this.data.worker != null) {
  246. this.data.worker.postMessage({
  247. message: 'MAIN_WORKER_ONE_ACC_DATA',//加速度数据
  248. data: item
  249. })
  250. }
  251. },
  252. ////////////////////////////////////////////////////////////////////////////
  253. ///////////////////////////以下未测试接口,已舍弃/////////////////////////////
  254. ////////////////////////////////////////////////////////////////////////////
  255. //保存音频文件
  256. //buffer:录音数据,为二进制单字节数据数组(byte)
  257. saveAduioDataToBin(buffer) {
  258. console.log("收到保存消息")
  259. let fileSystemManager = wx.getFileSystemManager()
  260. try {
  261. fileSystemManager.appendFileSync(wx.env.USER_DATA_PATH + "/IPS8000.bin", buffer, 'binary')
  262. return { code: 1, data: 'ok' }
  263. } catch (e) {
  264. return { code: 0, data: e }
  265. }
  266. },
  267. })