{"id":11124,"date":"2024-02-29T22:22:22","date_gmt":"2024-02-29T14:22:22","guid":{"rendered":"https:\/\/www.zhangxinxu.com\/wordpress\/?p=11124"},"modified":"2024-02-29T22:22:22","modified_gmt":"2024-02-29T14:22:22","slug":"js-audioencoder-backplayrate-audiobuffer","status":"publish","type":"post","link":"https:\/\/www.zhangxinxu.com\/wordpress\/2024\/02\/js-audioencoder-backplayrate-audiobuffer\/","title":{"rendered":"\u4e0d\u6539\u53d8\u97f3\u8c03\u60c5\u51b5\u4e0bAudio\u97f3\u9891\u7684\u500d\u901f\u5408\u6210JS\u5b9e\u73b0"},"content":{"rendered":"<p>by <a href=\"https:\/\/www.zhangxinxu.com\/\">zhangxinxu<\/a> from <a href=\"https:\/\/www.zhangxinxu.com\/wordpress\/?p=11124\">https:\/\/www.zhangxinxu.com\/wordpress\/?p=11124<\/a> \u946b\u7a7a\u95f4-\u946b\u751f\u6d3b<br \/>\n\u672c\u6587\u6b22\u8fce\u5206\u4eab\u4e0e\u805a\u5408\uff0c\u5168\u6587\u8f6c\u8f7d\u5c31\u4e0d\u5fc5\u4e86\uff0c\u5c0a\u91cd\u7248\u6743\uff0c\u5708\u5b50\u5c31\u8fd9\u4e48\u5927\uff0c\u82e5\u6025\u7528\u53ef\u4ee5\u8054\u7cfb\u6388\u6743\u3002<\/p>\n<p><script>window.wxShareImgUrl = 'https:\/\/www.zhangxinxu.com\/study\/image\/share\/202402-audio-playrate.png';<\/script><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202402\/audio-pitch-cover.png\" width=\"422\" height=\"265\" alt=\"\u97f3\u9891\u500d\u901f\u97f3\u8c03\u4e0d\u53d8\u5c01\u9762\u56fe\" class=\"alignright clip thumb size-medium\" \/><\/p>\n<h3>\u4e00\u3001\u4ee5\u4e3a\u5f88\u7b80\u5355\uff0c\u7ed3\u679c&#8230;<\/h3>\n<p>\u9047\u5230\u9700\u6c42\uff0c\u9700\u8981\u5bf9\u97f3\u9891\u500d\u901f\u5408\u6210\uff0c\u53ef\u80fd\u662f0.5\u500d\u901f\uff0c\u4e5f\u53ef\u80fd\u662f2\u500d\u901f\u3002<\/p>\n<p>\u8fd9\u8fd8\u4e0d\u7b80\u5355\uff0c0.5\u500d\u901f\u90a3\u5c31\u91c7\u6837\u7684\u65f6\u5019\u4e24\u4e24\u91cd\u590d\uff0c2\u500d\u901f\u95f4\u9694\u53d6\u6837\u5c31\u597d\u4e86\uff0c\u76f8\u5173\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff08\u5047\u8bbe\u97f3\u9891\u5730\u5740\u662furl\uff0c\u64ad\u653e\u901f\u7387\u53d8\u91cf\u662frate\uff09\uff1a<\/p>\n<pre>fetch(url)\r\n    .then(response =&gt; response.arrayBuffer())\r\n    .then(arrayBuffer =&gt; new AudioContext().decodeAudioData(arrayBuffer))\r\n    .then(originAudioBuffer =&gt; {\r\n        \/\/ \u521b\u5efa\u65b0\u7684AudioBuffer\r\n        const audioBuffer = new AudioContext().createBuffer(\r\n            originAudioBuffer.numberOfChannels,\r\n            originAudioBuffer.length \/ rate,\r\n            originAudioBuffer.sampleRate\r\n        );\r\n\r\n        \/\/ \u590d\u5236\u539f\u59cb\u97f3\u9891\u7684\u6570\u636e\u5230\u65b0\u7684AudioBuffer\r\n        for (let channel = 0; channel &lt; originAudioBuffer.numberOfChannels; channel++) {\r\n            const originChannelData = originAudioBuffer.getChannelData(channel);\r\n            const newChannelData = audioBuffer.getChannelData(channel);\r\n            for (let i = 0; i &lt; audioBuffer.length; i += 1) {\r\n                 newChannelData[i] = originChannelData[Math.floor(i * rate)] || 0;\r\n            }\r\n        }\r\n\r\n        \/\/ \u6b64\u65f6 audioBuffer \u5c31\u662f\u53d8\u901f\u540e\u7684\u97f3\u9891\u6570\u636e\r\n        \/\/ \u4f60\u53ef\u4ee5\u7528\u6765\u64ad\u653e\uff0c\u6216\u8005\u4e0a\u4f20\uff0c\u6216\u8005\u4e0b\u8f7d\r\n    });\r\n<\/pre>\n<p>\u4e0a\u9762\u4ee3\u7801\u4e2d\u7684audioBuffer\u5c31\u662f\u5c31\u662f\u53d8\u901f\u540e\u7684\u97f3\u9891\u6570\u636e\uff0c\u4f60\u53ef\u4ee5\u7528\u6765\u64ad\u653e\uff0c\u6216\u8005\u4e0a\u4f20\uff0c\u6216\u8005\u4e0b\u8f7d\uff0c\u5177\u4f53\u5982\u4f55\u5b9e\u73b0\uff0c\u53ef\u53c2\u89c1\u4e4b\u524d\u201c<a href=\"https:\/\/www.zhangxinxu.com\/wordpress\/2023\/10\/js-audio-audiobuffer-concat-merge\/\" rel=\"noopener\">\u7eafJS\u5b9e\u73b0\u591a\u4e2a\u97f3\u9891\u7684\u62fc\u63a5\u6216\u8005\u5408\u5e76<\/a>\u201d\u4e00\u6587\u3002<\/p>\n<p>\u4ee3\u7801\u4e00\u8dd1\uff0c\u563f\u563f\uff0c\u65f6\u957f\u7b26\u5408\u9884\u671f\uff0c\u4f46\u662f\u7ad6\u8d77\u8033\u6735\u4e00\u542c\uff0c\u4e0d\u5bf9\u52b2\uff0c\u5f88\u4e0d\u5bf9\u52b2\uff0c\u8fd9\u58f0\u97f3\u7684\u97f3\u8c03\u600e\u4e48\u53d8\u4e86\u3002<\/p>\n<p>\u6162\u901f\u7684\u65f6\u5019\u58f0\u97f3\u53d8\u5f97\u7279\u522b\u7684\u4f4e\u6c89\uff0c\u5feb\u901f\u7684\u65f6\u5019\u97f3\u8c03\u975e\u5e38\u9ad8\u3002<\/p>\n<p>\u5927\u5bb6\u4e5f\u53ef\u4ee5\u6765\u611f\u53d7\u4e0b\uff0c\u60a8\u53ef\u4ee5\u72e0\u72e0\u5730\u70b9\u51fb\u8fd9\u91cc\uff1a<a href=\"https:\/\/www.zhangxinxu.com\/study\/202402\/js-audio-playbackrate-pitch-demo.php\" rel=\"noopener\" target=\"_blank\">JS\u97f3\u9891\u500d\u901f\u540e\u97f3\u8c03\u53d1\u751f\u53d8\u5316demo<\/a><\/p>\n<p>\u6bd4\u65b9\u8bf4demo\u9875\u9762\u4e2d\u8fd9\u6bb5\u201c\u6597\u6c14\u5316\u9a6c\u201d\u7684\u5f55\u97f3\uff0c\u4e24\u500d\u901f\u540e\uff0c\u58f0\u97f3\u542c\u8d77\u6765\u5c31\u50cf\u662f\u634f\u7740\u55d3\u5b50\u7684\u5b69\u7ae5\u97f3\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202402\/2024-02-27_231218.png\" width=\"431\" height=\"376\" alt=\"\u58f0\u97f3\u53d8\u8c03\u622a\u56fe\" class=\"alignnone size-medium\" \/><\/p>\n<p>\u600e\u4e48\u56de\u4e8b\uff0c\u96be\u9053\u662f\u4ee3\u7801\u903b\u8f91\u6709\u95ee\u9898\u3002<\/p>\n<p>\u4e8e\u662f\u82b1\u65f6\u95f4\u7814\u7a76\u4e86\u4e00\u756a\uff0c\u53d1\u73b0\u4e8b\u60c5\u4e0d\u7b80\u5355\u3002<\/p>\n<h3>\u4e8c\u3001\u53d8\u901f\u53d8\u97f3\u8c03\u7684\u539f\u56e0\u89e3\u5bc6<\/h3>\n<p>\u4f17\u6240\u5468\u77e5\uff0c\u58f0\u97f3\u5176\u5b9e\u5c31\u662f\u4e00\u79cd\u6ce2\uff0c\u5728\u6570\u5b66\u4e0a\u5e38\u5e38\u7528\u4e09\u89d2\u51fd\u6570\u8868\u793a\u3002<\/p>\n<p>\u64ad\u653e\u901f\u7387\u53d8\u5feb\uff0c\u4e5f\u5c31\u610f\u5473\u7740\u6ce2\u5f62\u8d8a\u9661\u5ced\uff0c\u81ea\u7136\u97f3\u8c03\u4e5f\u5c31\u8d8a\u9ad8\u3002<\/p>\n<p>\u4e0b\u9762\u8fd9\u4e2aGIF\u52a8\u56fe\u5f88\u597d\u5730\u793a\u610f\u4e86\u8fd9\u4e00\u70b9\uff08\u539f\u56fe<a href=\"https:\/\/blog.crimx.com\/img\/wave-2.gif\" rel=\"noopener\" target=\"_blank\">\u8bbf\u95ee\u8fd9\u91cc<\/a>\uff09\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202402\/Wave-small.gif\" width=\"300\" height=\"220\" alt=\"GIF\u4e0e\u97f3\u8c03\u539f\u7406\u793a\u610f\" class=\"alignnone size-medium\" \/><\/p>\n<p>\u6b64\u56fe\u6e90\u81ea\u975e\u5e38\u4f18\u8d28\u7684\u4e00\u7247\u5916\u6587\u201c<a href=\"https:\/\/waitbutwhy.com\/2016\/03\/sound.html\" rel=\"noopener\" target=\"_blank\">Everything You Should Know About Sound<\/a>\u201d\uff0c\u53ef\u4ee5\u52a0\u6df1\u5927\u5bb6\u5bf9\u97f3\u9891\u672c\u8d28\u7684\u4e86\u89e3\u3002<\/p>\n<h4>\u5982\u4f55\u89e3\u51b3\uff1f<\/h4>\n<p>\u97f3\u9891\u62c9\u4f38\u5f71\u54cd\u97f3\u8c03\u5176\u5b9e\u662f\u4e1a\u754c\u6bd4\u8f83\u77e5\u540d\u7684\u4e00\u4e2a\u95ee\u9898\u4e86\uff0c\u975e\u5e38\u8003\u9a8c\u7b97\u6cd5\u529f\u529b\uff0c\u6240\u4ee5\u5404\u8def\u5927\u795e\u5206\u5206\u51fa\u9a6c\uff0c\u8bde\u751f\u4e86\u5f88\u591a\u7ecf\u5178\u7684\u7b97\u6cd5\u3002<\/p>\n<p>\u4f8b\u5982\u9897\u7c92\u5408\u6210\uff08<a href=\"http:\/\/pd-tutorial.com\/english\/ch03s07.html\" rel=\"noopener\" target=\"_blank\">Granular synthesis<\/a>\uff09\u7b97\u6cd5\uff0c\u5927\u81f4\u539f\u7406\u662f\u8fd9\u6837\u7684\u3002<\/p>\n<p>\u97f3\u9891\u91c7\u6837\u662f\u4e00\u4e2a\u4e00\u4e2a\u7684\u70b9\uff0c\u8fd9\u4e9b\u70b9\u8fde\u5728\u4e00\u8d77\uff0c\u5c31\u4f1a\u6784\u6210\u6ce2\u5cf0\u6216\u66f2\u7ebf\uff0c\u4e3a\u4e86\u65b9\u4fbf\u793a\u610f\uff0c\u6211\u4eec\u7528\u4e00\u6761\u76f4\u7ebf\u4ee3\u66ff\uff0c\u5982\u4e0b\u6240\u793a\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202402\/3-7b.png\" width=\"209\" height=\"147\" alt=\"\u91c7\u6837\u70b9\u66f2\u7ebf\" class=\"alignnone size-medium\" \/><\/p>\n<p>\u73b0\u5728\u7f29\u77ed\u97f3\u9891\u64ad\u653e\u65f6\u957f\uff0c\u4e5f\u5c31\u662f\u52a0\u5feb\u97f3\u9891\u7684\u64ad\u653e\u901f\u7387\uff0c\u90a3\u4e48\u91c7\u6837\u70b9\u66f2\u7ebf\u5c31\u4f1a\u53d8\u5f97\u66f4\u52a0\u9661\u5ced\uff0c\u5c31\u4f1a\u662f\u8fd9\u6837\u5b50\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202402\/3-7c.png\" width=\"222\" height=\"164\" alt=\"\u66f2\u7ebf\u9661\u5ced\" class=\"alignnone size-medium\" \/><\/p>\n<p>\u9661\u5ced\u4e5f\u5c31\u610f\u5473\u7740\u97f3\u8c03\u53d8\u9ad8\u4e86\uff0c\u663e\u7136\u4e0d\u662f\u6211\u4eec\u60f3\u8981\u7684\uff0c\u6240\u4ee5\u9700\u8981\u4fdd\u6301\u901f\u7387\u7684\u540c\u65f6\u8ba9\u66f2\u7ebf\u4e0d\u9661\u5ced\uff0c\u53ef\u4ee5\u8fd9\u4e48\u5904\u7406\uff0c\u628a\u66f2\u7ebf\u622a\u6210\u4e00\u6bb5\u4e00\u6bb5\u7684\u9897\u7c92\uff0c\u8ba9\u8fd9\u6bb5\u9897\u7c92\u7684\u66f2\u5ea6\u548c\u9ed8\u8ba4\u64ad\u653e\u66f2\u7ebf\u4e00\u81f4\uff0c\u7136\u540e\u8fd9\u4e9b\u9897\u7c92\u7684\u8d77\u70b9\u4f4d\u7f6e\u504f\u79fb\uff0c\u4fdd\u6301\u8bbe\u5b9a\u7684\u64ad\u653e\u901f\u7387\uff0c\u5c31\u50cf\u4e0b\u56fe\u8fd9\u6837\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202402\/3-7d.png\" width=\"212\" height=\"152\" alt=\"\u9897\u7c92\u7b97\u6cd5\u8bf4\u660e\" class=\"alignnone size-medium\" \/><\/p>\n<p>\u4e8e\u662f\uff0c\u7528\u6237\u542c\u8d77\u6765\u64ad\u653e\u901f\u5ea6\u5feb\u4e86\uff0c\u540c\u65f6\u97f3\u8c03\u5e76\u672a\u53d1\u751f\u53d8\u5316\u3002<\/p>\n<p>\u5f53\u7136\uff0c\u8fd8\u6709\u5f88\u591a\u5176\u4ed6\u7684\u7b97\u6cd5\uff0c\u6211\u5e76\u672a\u53bb\u6df1\u7a76\u3002<\/p>\n<p>\u8fd9\u4e9b\u7b97\u6cd5\u672c\u8d28\u4e0a\u662f\u6570\u5b66\u8ba1\u7b97\uff0c\u6709\u4e9b\u8fd8\u7275\u626f\u5230\u5085\u91cc\u53f6\u53d8\u6362\uff0c\u800c\u8fd9\u4e9b\u77e5\u8bc6\uff0c\u6211\u65e9\u5df2\u7ecf\u8fd8\u7ed9\u6559\u6388\u4e86\uff0c\u6240\u4ee5\uff0c\u5f53\u673a\u7acb\u65ad\uff0c\u627e\u522b\u4eba\u5199\u597d\u7684\u7b97\u6cd5\uff0c\u76f4\u63a5\u5957\u7528\u5b9e\u73b0\u3002<\/p>\n<h3>\u4e09\u3001\u67d0\u4e2a\u7b80\u5355\u7684\u7b97\u6cd5\u5b9e\u73b0<\/h3>\n<p>\u4e00\u5f00\u59cb\u627e\u7684\u662f\u8fd9\u4e2a\u9879\u76ee\uff0c\u539f\u56e0\u65e0\u4ed6\uff0c\u4ee3\u7801\u5c11\uff0c\u5982\u4f55\u4f7f\u7528\u4e00\u76ee\u4e86\u7136\uff0c\u53c2\u89c1\uff1a<a href=\"https:\/\/github.com\/danigb\/timestretch\" rel=\"noopener\" target=\"_blank\">https:\/\/github.com\/danigb\/timestretch<\/a><\/p>\n<p>\u5176\u7b97\u6cd5\u4ee3\u7801\u4e0d\u591a\uff0c\u76f4\u63a5\u7c98\u8d34\u51fa\u6765\u90fd\u53ef\u4ee5\uff1a<\/p>\n<pre>\/**\r\n * https:\/\/github.com\/danigb\/timestretch\/blob\/master\/lib\/index.js\r\n * Copy `len` bytes generated by a function to `array` starting at `pos`\r\n *\/\r\nfunction copy (len, array, pos, fn) {\r\n  for (var i = 0; i &lt; len; i++) {\r\n    array[pos + i] = fn(i)\r\n  }\r\n}\r\n\r\nfunction stretch (ac, input, scale, options) {\r\n  \/\/ OPTIONS\r\n  var opts = options || {}\r\n  \/\/ Processing sequence size (100 msec with 44100Hz sample rate)\r\n  var seqSize = opts.seqSize || 4410\r\n  \/\/ Overlapping size (20 msec)\r\n  var overlap = opts.overlap || 882\r\n  \/\/ Best overlap offset seeking window (15 msec)\r\n  \/\/ var seekWindow = opts.seekWindow || 662\r\n\r\n  \/\/ The theoretical start of the next sequence\r\n  var nextOffset = Math.round(seqSize \/ scale)\r\n\r\n  \/\/ Setup the buffers\r\n  var numSamples = input.length\r\n  var output = ac.createBuffer(1, numSamples * scale, input.sampleRate)\r\n  var inL = input.getChannelData(0)\r\n  var outL = output.getChannelData(0)\r\n\r\n  \/\/ STATE\r\n  \/\/ where to read then next sequence\r\n  var read = 0\r\n  \/\/ where to write the next sequence\r\n  var write = 0\r\n  \/\/ where to read the next fadeout\r\n  var readOverlap = 0\r\n\r\n  while (numSamples - read &gt; seqSize) {\r\n    \/\/ write the first overlap\r\n    copy(overlap, outL, write, function (i) {\r\n      var fadeIn = i \/ overlap\r\n      var fadeOut = 1 - fadeIn\r\n      \/\/ Mix the begin of the new sequence with the tail of the sequence last\r\n      return (inL[read + i] * fadeIn + inL[readOverlap + i] * fadeOut) \/ 2\r\n    })\r\n    copy(seqSize - overlap, outL, write + overlap, function (i) {\r\n      \/\/ Copy the tail of the sequence\r\n      return inL[read + overlap + i]\r\n    })\r\n    \/\/ the next overlap is after this sequence\r\n    readOverlap += read + seqSize\r\n    \/\/ the next sequence is after the nextOffset\r\n    read += nextOffset\r\n    \/\/ we wrote a complete sequence\r\n    write += seqSize\r\n  }\r\n\r\n  return output\r\n}<\/pre>\n<p>\u4f7f\u7528\u975e\u5e38\u7b80\u5355\uff0c\u51e0\u884c\u4ee3\u7801\u7684\u4e8b\u60c5\uff0c\u793a\u610f\u5982\u4e0b\uff08\u5047\u8bbe\u539f\u97f3\u9891\u6570\u636e\u5bf9\u8c61\u662f audioBuffer\uff0c\u64ad\u653e\u901f\u7387\u662frate\uff09\uff1a<\/p>\n<pre>\/\/ \u500d\u901f\u53d8\u5316\uff0c\u8fd4\u56de\u65b0\u7684AudioBuffer\r\nconst newAudioBuffer = stretch(new AudioContext(), audioBuffer, 1 \/ rate, {\r\n    seqSize: audioBuffer.sampleRate \/ 10,\r\n    overlap: audioBuffer.sampleRate \/ 100\r\n});<\/pre>\n<p>\u4e0a\u9762\u4ee3\u7801\u8fd4\u56de\u7684newAudioBuffer\u5c31\u662f\u500d\u901f\u5904\u7406\u540e\u7684\u65b0\u7684\u97f3\u9891\u3002<\/p>\n<p>\u6211\u4eec\u6765\u770b\u770b\u8fd9\u6bb5\u4ee3\u7801\u771f\u5b9e\u5e94\u7528\u540e\u7684\u6548\u679c\uff0c\u60a8\u53ef\u4ee5\u72e0\u72e0\u5730\u70b9\u51fb\u8fd9\u91cc\uff1a<a href=\"https:\/\/www.zhangxinxu.com\/study\/202402\/js-audiobuffer-speed-pitch-keep-demo.php\" rel=\"noopener\" target=\"_blank\">JS\u97f3\u9891\u500d\u901f\u91c7\u7528\u97f3\u8c03\u4fdd\u6301\u4e0d\u53d8\u7b80\u6613\u7b97\u6cd5demo<\/a><\/p>\n<p>\u8fd8\u662f\u6597\u6c14\u5316\u9a6c\u7684\u97f3\u9891\uff0c2\u500d\u901f\uff0c\u7ec6\u7ec6\u542c\u4e00\u4e0b\uff0c\u53ef\u4ee5\u542c\u51fa\u662f\u6211\u7684\u58f0\u97f3\uff0c\u53ef\u5374\u6709\u5f88\u591a\u566a\u70b9\u6742\u97f3\uff0c\u542c\u8d77\u6765\u5e76\u4e0d\u8212\u670d\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202402\/2024-02-28_233059.png\" width=\"454\" height=\"334\" alt=\"\u566a\u58f0\u660e\u663e\" class=\"alignnone size-medium\" \/><\/p>\n<p>\u8dd1\u4e86\u4e0b\u97f3\u9891\u6ce2\u5f62\u56fe\uff0c\u8bf8\u591a\u7ec6\u8282\u4e22\u5931\uff0c\u5f88\u591a\u5730\u65b9\u8fc7\u4e8e\u5e73\u6ed1\uff0c\u611f\u89c9\u50cf\u662f\u6709\u4e9b\u9ad8\u97f3\u8c03\u7684\u91c7\u6837\u6570\u636e\u6ca1\u80fd\u8c03\u597d\uff0c\u6df7\u5728\u4e00\u8d77\uff0c\u5c31\u597d\u4f3c\u566a\u70b9\u8fd9\u822c\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202402\/2024-02-28_233411.png\" width=\"418\" height=\"136\" alt=\"\u6ce2\u5f62\u56fe\u7ec6\u8282\" class=\"alignnone size-medium\" \/><\/p>\n<p>\u6211\u7422\u78e8\u7740\uff0c\u4f1a\u4e0d\u4f1a\u662f\u56e0\u4e3a\u6211\u5f55\u97f3\u7684\u65f6\u5019\uff0c\u672c\u8eab\u5c31\u6709\u80cc\u666f\u566a\u97f3\u5bfc\u81f4\uff0c\u4e8e\u662f\uff0c\u5c31\u4f7f\u7528\u751f\u4ea7\u73af\u5883\u7684AI\u8bed\u97f3\u8fdb\u884c\u6d4b\u8bd5\u3002<\/p>\n<p>\u6211\u561e\u4e2a\u64e6\uff0c\u6b63\u5e38\u58f0\u97f3\u7684\u80cc\u540e\u8fd8\u6709\u4e00\u9053\u8fde\u7eed\u4e0d\u65ad\u7684\u523a\u8033\u7684\u91cd\u91d1\u5c5e\u566a\u97f3\u3002<\/p>\n<p>\u7ed3\u8bba\u5f88\u660e\u663e\uff0c\u867d\u7136\u6b64\u9879\u76ee\u7b97\u6cd5\u7b80\u5355\uff0c\u4f46\u662f\u6548\u679c\u771f\u7684\u662f\u5dee\uff0c\u4e0d\u80fd\u7528\u5728\u771f\u5b9e\u7684\u9879\u76ee\u4e2d\u3002<\/p>\n<p>\u4f5c\u8005\u4f3c\u4e4e\u4e5f\u610f\u8bc6\u5230\u81ea\u5df1\u8fd9\u6bb5\u4ee3\u7801\u7684\u7b97\u6cd5\u4e0d\u662f\u5f88\u725b\u903c\u7684\u90a3\u79cd\uff0c\u4e8e\u662f\u6709\u8bf4\uff1a<\/p>\n<blockquote><p>This is not the best implementation if you&#8217;re looking for sound quality and\/or performance (see FAQ).<\/p>\n<p>\u5982\u679c\u60a8\u6b63\u5728\u5bfb\u627e\u97f3\u8d28\u548c\/\u6216\u6027\u80fd\uff0c\u8fd9\u4e0d\u662f\u6700\u597d\u7684\u5b9e\u73b0\uff08\u8bf7\u53c2\u9605FAQ\uff09\u3002<\/p><\/blockquote>\n<p>\u800c\u6b64\u9879\u76ee\u7684FAQ\u6b63\u597d\u6536\u7f57\u4e86\u8bf8\u591a\u97f3\u9891\u65f6\u95f4\u62c9\u4f38\u7b97\u6cd5\uff0c\u6211\u5dee\u4e0d\u591a\u90fd\u7814\u7a76\u4e86\u4e0b\uff0c\u968f\u540e\u51b3\u5b9a\u4f7f\u7528 OLA-TS.js \u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202402\/2024-02-28_233932.png\" width=\"420\" height=\"360\" alt=\"\u97f3\u9891\u65f6\u95f4\u62c9\u4f38\u7b97\u6cd5\u622a\u56fe\" class=\"alignnone size-medium\" \/><\/p>\n<h3>\u56db\u3001\u58f0\u97f3\u8d28\u91cf\u66f4\u597dOLA\u7b97\u6cd5\u5b9e\u73b0<\/h3>\n<p>\u9879\u76ee\u5730\u5740\uff1a<a href=\"https:\/\/github.com\/echo66\/OLA-TS.js\" rel=\"noopener\" target=\"_blank\">https:\/\/github.com\/echo66\/OLA-TS.js<\/a><\/p>\n<p>\u4f5c\u8005\u662f\u8fd9\u4e48\u63cf\u8ff0\u7684\uff1a<\/p>\n<blockquote><p>OLA-TS.js\u662f\u4e00\u79cd\u6539\u8fdb\u7684\u91cd\u53e0\u548c\u6dfb\u52a0\uff08OLA\uff09\u7b97\u6cd5\u7684\u97f3\u9891\u65f6\u95f4\u62c9\u4f38\u5b9e\u73b0\u3002<\/p><\/blockquote>\n<p>\u4e00\u756a\u4f7f\u7528\u4e0b\u6765\uff0c\u6548\u679c\u786e\u5b9e\u597d\u3002<\/p>\n<h4>\u5982\u4f55\u4f7f\u7528\uff1f<\/h4>\n<p>\u6b64\u9879\u76ee\u975e\u5e38\u8001\uff0c\u5e74\u4e45\u5931\u4fee\uff0c\u8981\u662f\u65e0\u4eba\u6307\u5f15\uff0c\u60f3\u8981\u4e0a\u624b\u8fd8\u662f\u8981\u8d39\u4e00\u756a\u529f\u592b\u7684\u3002<\/p>\n<p>\u7ecf\u8fc7\u6211\u7684\u4e00\u756a\u6574\u5408\uff0c\u8c03\u8bd5\uff0c\u7ec8\u4e8e\u5f04\u4e86\u4e2a\u53ef\u7528\u7684\u7248\u672c\uff08\u539f\u672c\u7684\u5b9e\u73b0\u53ea\u652f\u6301\u591a\u901a\u9053\u97f3\u9891\uff09\u3002<\/p>\n<p>\u5f88\u7b80\u5355\uff0c\u9996\u5148\uff0c\u5f15\u5165bufferedOla.js\uff1a<\/p>\n<pre>import BufferedOLA from '.\/bufferedOla.js';<\/pre>\n<p>\u7136\u540e\uff0c\u901a\u7528\u4e0b\u9762\u7684\u8bed\u6cd5\u8fdb\u884c\u97f3\u9891\u62c9\u4f38\u5904\u7406\uff08\u5047\u8bbe\u539f\u97f3\u9891\u6570\u636e\u5bf9\u8c61\u662f audioBuffer\uff0c\u64ad\u653e\u901f\u7387\u662frate\uff09\uff1a<\/p>\n<pre>\/\/ \u521b\u5efa\u65b0\u7684audiobuffer\r\nconst newAudioBuffer = new AudioContext().createBuffer(\r\n  audioBuffer.numberOfChannels,\r\n  audioBuffer.length \/ rate,\r\n  audioBuffer.sampleRate,\r\n);\r\nconst myOLATS = new BufferedOLA();\r\nmyOLATS.set_audio_buffer(audioBuffer);\r\nmyOLATS.alpha = 1 \/ rate;\r\n\r\nmyOLATS.process(newAudioBuffer);<\/pre>\n<p>\u6267\u884c\u5b8c\u4e0a\u9762\u7684\u4ee3\u7801\u540e\uff0cnewAudioBuffer\u5c31\u662f\u5904\u7406\u540e\u7684\u500d\u901f\u97f3\u9891AudioBuffer\u6570\u636e\u4e86\u3002<\/p>\n<p>\u773c\u89c1\u4e3a\u5b9e\uff0c\u60a8\u53ef\u4ee5\u72e0\u72e0\u5730\u70b9\u51fb\u8fd9\u91cc\uff1a<a href=\"https:\/\/www.zhangxinxu.com\/study\/202402\/js-audiobuffer-ola-algorithm-demo.php\" rel=\"noopener\" target=\"_blank\">JS\u97f3\u9891\u65f6\u95f4\u62c9\u4f38\u6539\u8fdb\u7b97\u6cd5demo<\/a><\/p>\n<p>\u6b64\u65f6\uff0c\u518d\u53bb2\u500d\u901f\u542c\u201c\u6597\u6c14\u5316\u9a6c\u201d\uff0c\u5594\u5662\uff0c\u6ca1\u6709\u4efb\u4f55\u6742\u97f3\uff0c\u975e\u5e38\u6d41\u7545\uff0c\u975e\u5e38\u5b8c\u7f8e\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202402\/2024-02-28_235050.png\" width=\"426\" height=\"349\" alt=\"\u5b8c\u7f8e\u6548\u679c\u4f7f\u7528\u793a\u610f\" class=\"alignnone size-medium\" \/><\/p>\n<h3>\u4e94\u3001\u7ed3\u675f\u8bf4\u660e<\/h3>\n<p>\u770b\u770b\u65f6\u95f4\uff0c12\u70b9\u4e4b\u524d\u5199\u4e0d\u5b8c\u4e86\uff0c\u524d\u6bb5\u65f6\u95f4\u611f\u5192\u53d1\u70e7\uff0c\u5bb6\u91cc\u9886\u5bfc\u89c4\u5b9a\u5fc5\u987b12\u70b9\u4e4b\u524d\u5173\u673a\u4f11\u606f\uff0c\u5199\u5230\u8fd9\u91cc23:53\uff0c\u52a0\u4e0a\u8fd8\u8981\u914d\u56fe\uff0c\u5199\u6458\u8981\uff0c\u5199\u5173\u952e\u5b57\uff0c\u793e\u4ea4\u8d26\u53f7\u5199\u5468\u77e5\u6d88\u606f\uff0c12\u70b9\u4e4b\u524d\u5b9a\u662f\u6765\u4e0d\u53ca\u4e86\u3002<\/p>\n<p>\u4fdd\u5b58\u8349\u7a3f\uff0c\u660e\u5929\u53d1\u5e03\uff0c\u65ad\u66f4\u5c31\u65ad\u66f4\u5427\uff0c\u8eab\u4f53\u8981\u7d27\u3002<\/p>\n<p>\u6700\u540e\uff0c\u9644\u4e0a\u90a3\u4e9b\u4e0e\u97f3\u9891\u65f6\u95f4\u901f\u7387\u97f3\u8c03\u76f8\u5173\u7684\u9879\u76ee\uff1a<\/p>\n<ul dir=\"auto\">\n<li><a href=\"https:\/\/github.com\/sebpiq\/paulstretch.js\">https:\/\/github.com\/sebpiq\/paulstretch.js<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/echo66\/OLA-TS.js\">https:\/\/github.com\/echo66\/OLA-TS.js<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/echo66\/PhaseVocoderJS\">https:\/\/github.com\/echo66\/PhaseVocoderJS<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Infinity\/Kali\">https:\/\/github.com\/Infinity\/Kali<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/0xfe\/vexwarp\">https:\/\/github.com\/0xfe\/vexwarp<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/mikolalysenko\/pitch-shift\">https:\/\/github.com\/mikolalysenko\/pitch-shift<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/GTCMT\/pitchshiftjs\">https:\/\/github.com\/GTCMT\/pitchshiftjs<\/a><\/li>\n<\/ul>\n<p>\u5168\u90fd\u662f\u5f88\u591a\u5e74\u4e4b\u524d\u7684\u9879\u76ee\u4e86\uff0c\u5c31\u8fd9\u6837\uff0c\u6211\u4eec\u4e0b\u7bc7\u6587\u7ae0\u518d\u89c1\u3002<\/p>\n<p>??<br \/>\n??<br \/>\n??<\/p>\n<p>\u672c\u6587\u4e3a\u539f\u521b\u6587\u7ae0\uff0c\u6b22\u8fce\u5206\u4eab\uff0c\u52ff\u5168\u6587\u8f6c\u8f7d\uff0c\u5982\u679c\u5b9e\u5728\u559c\u6b22\uff0c\u53ef\u6536\u85cf\uff0c\u6c38\u4e0d\u8fc7\u671f\uff0c\u4e14\u4f1a\u53ca\u65f6\u66f4\u65b0\u77e5\u8bc6\u70b9\u53ca\u4fee\u6b63\u9519\u8bef\uff0c\u9605\u8bfb\u4f53\u9a8c\u4e5f\u66f4\u597d\u3002<br \/>\n\u672c\u6587\u5730\u5740\uff1a<a href=\"https:\/\/www.zhangxinxu.com\/wordpress\/?p=11124\">https:\/\/www.zhangxinxu.com\/wordpress\/?p=11124<\/a><\/p>\n<p>\uff08\u672c\u7bc7\u5b8c\uff09<\/p>\n","protected":false},"excerpt":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/image.zhangxinxu.com\/image\/blog\/202402\/audio-pitch-cover.png\" width=\"160\" height=\"100\" alt=\"\u97f3\u9891\u500d\u901f\u97f3\u8c03\u4e0d\u53d8\u5c01\u9762\u56fe\" class=\"alignright size-medium\" loading=\"lazy\" \/><\/p>\n<p>\u97f3\u89c6\u9891\u5408\u6210\u7684\u65f6\u5019\uff0c\u6709\u500d\u901f\u5408\u6210\u7684\u9700\u6c42\uff0c\u8d77\u521d\uff0c\u6211\u4ee5\u4e3a\u8fd9\u53ea\u662f\u4e2a\u624b\u5230\u64d2\u6765\u7684\u5c0f\u9700\u6c42\uff0c\u7ec6\u7a76\u4e4b\u4e0b\u53d1\u73b0\u95ee\u9898\u5e76\u4e0d\u7b80\u5355\u2026\u2026<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[180],"tags":[874,489,1638,1137,1279,1096,1750],"_links":{"self":[{"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/posts\/11124"}],"collection":[{"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/comments?post=11124"}],"version-history":[{"count":0,"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/posts\/11124\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/media?parent=11124"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/categories?post=11124"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/tags?post=11124"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}