| |
| |
| |
| |
| |
| |
| function bufferToWave(abuffer, len) { |
| let numOfChan = abuffer.numberOfChannels, |
| length = len * numOfChan * 2 + 44, |
| buffer = new ArrayBuffer(length), |
| view = new DataView(buffer), |
| channels = [], |
| i, |
| sample, |
| offset = 0, |
| pos = 0; |
| |
| |
| |
| setUint32(0x46464952); |
| |
| setUint32(length - 8); |
| |
| setUint32(0x45564157); |
| |
| setUint32(0x20746d66); |
| |
| setUint32(16); |
| |
| setUint16(1); |
| setUint16(numOfChan); |
| setUint32(abuffer.sampleRate); |
| |
| setUint32(abuffer.sampleRate * 2 * numOfChan); |
| |
| setUint16(numOfChan * 2); |
| |
| setUint16(16); |
| |
| setUint32(0x61746164); |
| |
| setUint32(length - pos - 4); |
| |
| |
| for (i = 0; i < abuffer.numberOfChannels; i++) { |
| channels.push(abuffer.getChannelData(i)); |
| } |
| |
| while (pos < length) { |
| |
| for (i = 0; i < numOfChan; i++) { |
| |
| sample = Math.max(-1, Math.min(1, channels[i][offset])); |
| |
| sample = (0.5 + sample < 0 ? sample * 32768 : sample * 32767) | 0; |
| |
| view.setInt16(pos, sample, true); |
| pos += 2; |
| } |
| |
| offset++; |
| } |
| |
| |
| return new Blob([buffer], { type: 'audio/wav' }); |
| |
| function setUint16(data) { |
| view.setUint16(pos, data, true); |
| pos += 2; |
| } |
| |
| function setUint32(data) { |
| view.setUint32(pos, data, true); |
| pos += 4; |
| } |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2020-05-27 动态获取深层次的对象的属性值