{"_id":"audio","_rev":"23-e466aba51258153e1b2d795777b25778","name":"audio","dist-tags":{"next":"2.0.0-1","latest":"2.2.0"},"versions":{"0.0.0":{"name":"audio","version":"0.0.0","author":{"name":"Casper Beyer","email":"caspervonb@qup.io"},"license":"MIT","_id":"audio@0.0.0","maintainers":[{"name":"caspervonb","email":"caspervonb@qup.io"}],"dist":{"shasum":"f86ab973a00fe15fd78fcc5e81f92f8bb29dc3cc","tarball":"https://registry.npmjs.org/audio/-/audio-0.0.0.tgz","integrity":"sha512-qu8FFfn3lPjudu4k9qvaTw1t4rJ5yFM5gViFCayoX8t3k/wbLqB3YnlvTyVD6zzogT3xc6E8QKcpQh779lhzkQ==","signatures":[{"sig":"MEUCIQCxB80OWS1/0sm/O/BJSzXKlOHr9B93Cwkf7srUgarOlwIgIgZ2Ee/B8XhM/+VfJVr+nsUxeyhBKaRgtq2seE0LKAg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"f86ab973a00fe15fd78fcc5e81f92f8bb29dc3cc","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"caspervonb","email":"caspervonb@qup.io"},"_npmVersion":"2.4.1","description":"","directories":{},"_nodeVersion":"0.10.33"},"0.0.1":{"name":"audio","version":"0.0.1","license":"MIT","_id":"audio@0.0.1","maintainers":[{"name":"jamen","email":"jamenmarz+npm@gmail.com"}],"contributors":[{"url":"http://jamenmarz.com","name":"Jamen Marzonie","email":"jamenmarz@gmail.com"}],"homepage":"https://github.com/audiojs/audio#readme","bugs":{"url":"https://github.com/audiojs/audio/issues"},"dist":{"shasum":"2c3123b57b0dba106207d58e34b2fbcbc96eb5b2","tarball":"https://registry.npmjs.org/audio/-/audio-0.0.1.tgz","integrity":"sha512-nQPQxVSPQ5YohIS1SVsP8iJBQ/zHzjJ53Rjjcy6ClJiZrjNLcJbJ3LL11Cr7T60k7zrXVLgIHF58SmZBYV5EgQ==","signatures":[{"sig":"MEQCIAdZSocWkAjQrVG40nssoUHAIIFiL9VBo5NR1CeM/Ou5AiBS34UeIPr68N+5gjCso2HRDxQyTVVVtoIzcUTtlK77MA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","files":["index.js"],"_shasum":"2c3123b57b0dba106207d58e34b2fbcbc96eb5b2","gitHead":"1536cf659d88b02b75ee02619a082773b95f8e55","scripts":{"test":"eslint index.js && tape 'test/*.js' | tap-spec"},"_npmUser":{"name":"jamen","email":"jamenmarz+npm@gmail.com"},"repository":{"url":"git+https://github.com/audiojs/audio.git","type":"git"},"_npmVersion":"3.8.9","description":"Digital audio in JavaScript.","directories":{},"_nodeVersion":"6.2.0","devDependencies":{"tape":"^4.5.1","eslint":"^2.11.0","tap-spec":"^4.1.1","eslint-config-google":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/audio-0.0.1.tgz_1464764523543_0.7700171368196607","host":"packages-16-east.internal.npmjs.com"}},"0.1.0":{"name":"audio","version":"0.1.0","license":"MIT","_id":"audio@0.1.0","maintainers":[{"name":"jamen","email":"jamenmarz+npm@gmail.com"}],"contributors":[{"url":"http://jamenmarz.com","name":"Jamen Marzonie","email":"jamenmarz@gmail.com"}],"homepage":"https://github.com/audiojs/audio","bugs":{"url":"https://github.com/audiojs/audio/issues"},"dist":{"shasum":"1521ae1371e619afd8ef4c01d3e34162dcd65a87","tarball":"https://registry.npmjs.org/audio/-/audio-0.1.0.tgz","integrity":"sha512-zbeN6bGXXn7wenG1ph09FJXeKiKSGj3/GLwSVFyGOo4DP3TGm6+NUvbsKkNVfaOsBglgsxr2w2XByU1rX9zeIQ==","signatures":[{"sig":"MEQCICz/L5uHdf0skPR7zWaiAJRxCBdCjtLk1jSl6S/+SbGhAiB37inQgYIXG00ozS/Mr/wkUtpyh6Jzu8JLAfOIzqYqEw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","files":["index.js"],"_shasum":"1521ae1371e619afd8ef4c01d3e34162dcd65a87","engines":{"node":">=0.11"},"gitHead":"5555ed53c8da6ab3aef4e63ebe4aca56d749cda9","scripts":{"test":"eslint index.js test && tape 'test/*.js' | tap-spec"},"_npmUser":{"name":"jamen","email":"jamenmarz+npm@gmail.com"},"repository":{"url":"https://github.com/audiojs/audio","type":"git"},"_npmVersion":"2.3.0","description":"Digital audio in JavaScript.","directories":{},"_nodeVersion":"0.11.16","devDependencies":{"tape":"^4.5.1","eslint":"^2.11.0","tap-spec":"^4.1.1","eslint-config-google":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/audio-0.1.0.tgz_1464928853933_0.923715339275077","host":"packages-16-east.internal.npmjs.com"}},"0.1.1":{"name":"audio","version":"0.1.1","license":"MIT","_id":"audio@0.1.1","maintainers":[{"name":"jamen","email":"jamenmarz+npm@gmail.com"}],"contributors":[{"url":"http://jamenmarz.com","name":"Jamen Marzonie","email":"jamenmarz@gmail.com"}],"homepage":"https://github.com/audiojs/audio#readme","bugs":{"url":"https://github.com/audiojs/audio/issues"},"dist":{"shasum":"b3daeb6437fa867a6516c4664759596e1439a62d","tarball":"https://registry.npmjs.org/audio/-/audio-0.1.1.tgz","integrity":"sha512-aa/SIT+Gc+dzpQbzvjaQh2FAlW2Zva+Ber66rgbzd9JwGYOPCjLhtAZibc//WPAGoI9GWs4TXBvUGx6nlgpvdQ==","signatures":[{"sig":"MEYCIQC+vD1sh1TdpWv5ySEbUbsUNLblqJ8M5Slm6P2ibqXpxgIhAMOkd0C9xtaNpAnJxl5uNSpjCaoVUYaI0b+chEJxnVo0","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","files":["index.js"],"_shasum":"b3daeb6437fa867a6516c4664759596e1439a62d","engines":{"node":">=0.11"},"gitHead":"371c48de20bbd59307bf391dccc0063064605f26","scripts":{"test":"eslint index.js test && tape 'test/*.js' | tap-spec"},"_npmUser":{"name":"jamen","email":"jamenmarz+npm@gmail.com"},"repository":{"url":"git+https://github.com/audiojs/audio.git","type":"git"},"_npmVersion":"3.9.3","description":"Digital audio in JavaScript.","directories":{},"_nodeVersion":"6.2.1","devDependencies":{"tape":"^4.5.1","eslint":"^2.11.0","tap-spec":"^4.1.1","eslint-config-google":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/audio-0.1.1.tgz_1465053573108_0.4342291837092489","host":"packages-12-west.internal.npmjs.com"}},"1.0.0":{"name":"audio","version":"1.0.0","license":"MIT","_id":"audio@1.0.0","maintainers":[{"name":"jamen","email":"jamenmarz+npm@gmail.com"}],"contributors":[{"url":"http://jamenmarz.com","name":"Jamen Marzonie","email":"jamenmarz@gmail.com"}],"homepage":"https://github.com/audiojs/audio#readme","bugs":{"url":"https://github.com/audiojs/audio/issues"},"dist":{"shasum":"6b113daa3453d17b66869baf38779ec9ba6b7d3a","tarball":"https://registry.npmjs.org/audio/-/audio-1.0.0.tgz","integrity":"sha512-njWVGxfTDWU9lJjsToJ4Y2ihoKgYREwvYd3mB+EDcTVIXFDgCB2u8zOvfQfm0wthbtGhb5TfdT5WqepQSTotaA==","signatures":[{"sig":"MEQCIE8KZMIne1FapX6cxm1mZBDUZ8PdH0nc8jRH+LKbEgddAiBWXPev9WZF9NTa/MOgficVWIOUrcPi8Tpv4PVI4vW3tQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","files":["index.js"],"_shasum":"6b113daa3453d17b66869baf38779ec9ba6b7d3a","engines":{"node":">=0.11"},"gitHead":"101dc738ea9e182e75d862c8477834fbd91d697c","scripts":{"test":"eslint index.js test && tape 'test/*.js' | tap-spec"},"_npmUser":{"name":"jamen","email":"jamenmarz+npm@gmail.com"},"deprecated":"Accidently published the old version","repository":{"url":"git+https://github.com/audiojs/audio.git","type":"git"},"_npmVersion":"3.9.3","description":"Digital audio in JavaScript.","directories":{},"_nodeVersion":"6.2.1","devDependencies":{"tape":"^4.5.1","eslint":"^2.11.0","tap-spec":"^4.1.1","eslint-config-google":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/audio-1.0.0.tgz_1465113406712_0.956740127177909","host":"packages-12-west.internal.npmjs.com"}},"1.0.1":{"name":"audio","version":"1.0.1","keywords":["audiojs","audio","javascript","pcm","lpcm"],"license":"MIT","_id":"audio@1.0.1","maintainers":[{"name":"jamen","email":"jamenmarz+npm@gmail.com"}],"contributors":[{"url":"http://jamenmarz.com","name":"Jamen Marzonie","email":"jamenmarz@gmail.com"}],"homepage":"https://github.com/audiojs/audio#readme","bugs":{"url":"https://github.com/audiojs/audio/issues"},"dist":{"shasum":"2393dfc853ccb4438ffdc0d8aa6003604ce3ca68","tarball":"https://registry.npmjs.org/audio/-/audio-1.0.1.tgz","integrity":"sha512-YfdZNBSzdOT9sUXqqhqDAA6Ghs3OHUUEqKSrpL/PPmK1a17lDutCBhLII+sjF80+vqp7PcqJBvUf4lAxDJac8Q==","signatures":[{"sig":"MEQCIEI0uryn25WOesUKoEIgC4hsM8sHjDTZTZ4l8zgXPuPxAiAFobBVGmDiq+aP0blhzObr7ErgyNu+Up40IYtA2B+8rA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","files":["index.js"],"_shasum":"2393dfc853ccb4438ffdc0d8aa6003604ce3ca68","engines":{"node":">=0.11"},"gitHead":"e98e6fe5ccbc82fce29b419cb322a16f04e8a618","scripts":{"test":"eslint index.js test && tape 'test/*.js' | tap-spec"},"_npmUser":{"name":"jamen","email":"jamenmarz+npm@gmail.com"},"repository":{"url":"git+https://github.com/audiojs/audio.git","type":"git"},"_npmVersion":"3.9.3","description":"Digital audio in JavaScript.","directories":{},"_nodeVersion":"6.2.1","dependencies":{"object-assign":"^4.1.0"},"devDependencies":{"tape":"^4.5.1","eslint":"^2.11.0","tap-spec":"^4.1.1","eslint-config-google":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/audio-1.0.1.tgz_1465113465006_0.8826586594805121","host":"packages-12-west.internal.npmjs.com"}},"1.1.0":{"name":"audio","version":"1.1.0","keywords":["audiojs","audio","javascript","pcm","lpcm"],"license":"MIT","_id":"audio@1.1.0","maintainers":[{"name":"jamen","email":"jamenmarz+npm@gmail.com"}],"contributors":[{"url":"http://jamenmarz.com","name":"Jamen Marzonie","email":"jamenmarz@gmail.com"}],"homepage":"https://github.com/jamen/node-audio#readme","bugs":{"url":"https://github.com/jamen/node-audio/issues"},"dist":{"shasum":"4a6720c077bd84c3a2be340c902ca54eb5f20011","tarball":"https://registry.npmjs.org/audio/-/audio-1.1.0.tgz","integrity":"sha512-JvYY01+rv63Nfc91Y+qMNCfF9W4hjO6s3vfF/JQak1ptMxRVM60Ub7U6/J2bpzY7DYSQt04MvGYDVjgJ5z7rpA==","signatures":[{"sig":"MEQCIFiqe8r+3QGYnEviRec4mNmDqPtsnOTere5RyDRHs00xAiA+gzEcxyluIV4kJcbkF2DuIgRp5As9/gCZ/5ktJ9mKrQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","files":["index.js"],"_shasum":"4a6720c077bd84c3a2be340c902ca54eb5f20011","engines":{"node":">=0.11"},"gitHead":"303b324a798bb17212008351d386f389d0517a56","scripts":{"test":"eslint index.js test && tape 'test/*.js' | tap-spec"},"_npmUser":{"name":"jamen","email":"jamenmarz+npm@gmail.com"},"repository":{"url":"git+https://github.com/jamen/node-audio.git","type":"git"},"_npmVersion":"3.9.3","description":"Digital audio in JavaScript.","directories":{},"_nodeVersion":"6.2.1","dependencies":{"object-assign":"^4.1.0"},"devDependencies":{"tape":"^4.5.1","eslint":"^2.11.0","tap-spec":"^4.1.1","eslint-config-google":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/audio-1.1.0.tgz_1465181329271_0.15824570343829691","host":"packages-12-west.internal.npmjs.com"}},"1.2.0":{"name":"audio","version":"1.2.0","keywords":["audiojs","audio","javascript","pcm","lpcm"],"license":"MIT","_id":"audio@1.2.0","maintainers":[{"name":"jamen","email":"jamenmarz+npm@gmail.com"}],"contributors":[{"url":"http://jamenmarz.com","name":"Jamen Marzonie","email":"jamenmarz@gmail.com"}],"homepage":"https://github.com/jamen/node-audio#readme","bugs":{"url":"https://github.com/jamen/node-audio/issues"},"dist":{"shasum":"7bd383fe022cfb1849b5dbc33938714e794126ca","tarball":"https://registry.npmjs.org/audio/-/audio-1.2.0.tgz","integrity":"sha512-rW+atJOIZRqF1RIILxEclaAoNKR4vDQugSPfl/4IKtm+eKMO7CxWQgbCTmTPyu5SbLpX47j0ftHmhmyAIggJtA==","signatures":[{"sig":"MEUCIHkfE7hDXv7Auy9wqLK8i3FPoAtFwDUVET7bbw4V7g4gAiEAunbCGEyid3mLS7UJlvQZRiqcsl9y/jqiNgkqOA6RyL0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","files":["index.js"],"_shasum":"7bd383fe022cfb1849b5dbc33938714e794126ca","engines":{"node":">=0.11"},"gitHead":"a0ec4d34ef65d5d3ede3ef8ea48b3fbd4b422667","scripts":{"test":"eslint index.js test && tape 'test/*.js' | tap-spec"},"_npmUser":{"name":"jamen","email":"jamenmarz+npm@gmail.com"},"repository":{"url":"git+https://github.com/jamen/node-audio.git","type":"git"},"_npmVersion":"3.9.5","description":"Digital audio in JavaScript.","directories":{},"_nodeVersion":"6.2.2","dependencies":{"object-assign":"^4.1.0"},"devDependencies":{"tape":"^4.5.1","eslint":"^2.11.0","tap-spec":"^4.1.1","eslint-config-google":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/audio-1.2.0.tgz_1467009545796_0.7299996472429484","host":"packages-16-east.internal.npmjs.com"}},"2.0.0-0":{"name":"audio","version":"2.0.0-0","keywords":["audiojs","audio","javascript","pcm","lpcm"],"license":"MIT","_id":"audio@2.0.0-0","maintainers":[{"name":"jamen","email":"jamenmarz+npm@gmail.com"}],"contributors":[{"url":"http://jamenmarz.com","name":"Jamen Marzonie","email":"jamenmarz@gmail.com"}],"homepage":"https://github.com/audiojs/audio#readme","bugs":{"url":"https://github.com/audiojs/audio/issues"},"dist":{"shasum":"b03169159d5168e5b50ed9a69a9d25db30c5d327","tarball":"https://registry.npmjs.org/audio/-/audio-2.0.0-0.tgz","integrity":"sha512-mGvUG5cvvzvjhYbI6CTVPVpIPdMs3qJM5/WpH6l+61DLKFViEfNrvKcjyIlWQTvqPZYqKoizODtEobs4kFdjTw==","signatures":[{"sig":"MEUCIQDnGy5bAjTNt+LXuoNPwMH0HRScM5QEZp3MHUznKoTAlwIgHqvuWvrmYQh6o/HhfyTa/dii3P7zNrJxGmtNf6QNv5M=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","files":["index.js"],"_shasum":"b03169159d5168e5b50ed9a69a9d25db30c5d327","engines":{"node":">=0.11"},"gitHead":"2d85f9f68d7487aeba7834b737080299739f2338","scripts":{"test":"eslint index.js test && tape 'test/*.js' | tap-spec"},"_npmUser":{"name":"jamen","email":"jamenmarz+npm@gmail.com"},"repository":{"url":"git+https://github.com/audiojs/audio.git","type":"git"},"_npmVersion":"3.10.5","description":"Digital audio in JavaScript.","directories":{},"_nodeVersion":"6.2.2","devDependencies":{"tape":"^4.5.1","eslint":"^2.11.0","tap-spec":"^4.1.1","eslint-config-google":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/audio-2.0.0-0.tgz_1471253523634_0.7199980134610087","host":"packages-16-east.internal.npmjs.com"}},"2.0.0-1":{"name":"audio","version":"2.0.0-1","keywords":["audiojs","audio","javascript","pcm","lpcm"],"license":"MIT","_id":"audio@2.0.0-1","maintainers":[{"name":"jamen","email":"jamenmarz+npm@gmail.com"}],"contributors":[{"url":"http://jamenmarz.com","name":"Jamen Marzonie","email":"jamenmarz@gmail.com"}],"homepage":"https://github.com/audiojs/audio#readme","bugs":{"url":"https://github.com/audiojs/audio/issues"},"dist":{"shasum":"4c1d8baa6c0dd69c32060350b1ff60c955fdc8d4","tarball":"https://registry.npmjs.org/audio/-/audio-2.0.0-1.tgz","integrity":"sha512-lhqW/xFOdAaxkxhsuy1oj1FZM9jGXVKvDw0EjCcLeWT3+LYtyHS/YOw6oFqcQRw+5DMvKPu7RqCBhCRbKfUIxA==","signatures":[{"sig":"MEQCIHbfjY058lCnT/Y1ZnJGniKWuNBCQ0tt45UgAZLIlo1XAiBHuW26FOhftsIaQ1thRO9Yxx153xm5BUS43+RcyoscCA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","files":["index.js"],"_shasum":"4c1d8baa6c0dd69c32060350b1ff60c955fdc8d4","engines":{"node":">=0.11"},"gitHead":"d6bb8cbac9ec54827442428af743a48cb63b2990","scripts":{"test":"eslint index.js test && tape 'test/*.js' | tap-spec"},"_npmUser":{"name":"jamen","email":"jamenmarz+npm@gmail.com"},"repository":{"url":"git+https://github.com/audiojs/audio.git","type":"git"},"_npmVersion":"3.10.5","description":"Framework for handling audio in JavaScript.","directories":{},"_nodeVersion":"6.2.2","devDependencies":{"tape":"^4.5.1","eslint":"^2.11.0","tap-spec":"^4.1.1","eslint-config-google":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/audio-2.0.0-1.tgz_1471555756988_0.048940891632810235","host":"packages-16-east.internal.npmjs.com"}},"2.0.0":{"name":"audio","version":"2.0.0","keywords":["audiojs","audio","dsp","pcm"],"license":"MIT","_id":"audio@2.0.0","maintainers":[{"name":"dfcreative","email":"df.creative@gmail.com"},{"name":"jamen","email":"jamenmarz@gmail.com"},{"name":"dy","email":"df.creative@gmail.com"}],"homepage":"https://github.com/audiojs/audio#readme","bugs":{"url":"https://github.com/audiojs/audio/issues"},"bin":{"audio":"bin/cli.js"},"dist":{"shasum":"fcd39afadc01a30b432d42e0cb9cda8242bbff03","tarball":"https://registry.npmjs.org/audio/-/audio-2.0.0.tgz","fileCount":39,"integrity":"sha512-3ieH8xRdURNRDNhNa2pwhulTaToNRpMJvEsZrcCkbuz0ARkmpmFRP8eR2zqM/0ACqDNkc2bZd0L+BumaFWGFog==","signatures":[{"sig":"MEYCIQD8DpW/Ndx3rcPVIN1JS15n/U7A/9p8GbWgqCn/UJhKDAIhAOVcDrpfV28zV5CtmbwVylMg4vCoUUiJtX0Fuqian2eu","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":10722031},"main":"audio.js","type":"module","types":"./audio.d.ts","exports":{".":{"browser":"./dist/audio.js","default":"./audio.js"},"./core":"./core.js","./fn/*":"./fn/*","./plan":"./plan.js","./cache":"./cache.js","./stats":"./stats.js"},"gitHead":"6ddd02853e762caa2e024b52b93a9879935b5b90","scripts":{"demo":"vhs player.tape","test":"node test/index.js","build":"node .esbuild.js","serve":"node test/serve.js","version":"node -p \"var s=require('fs'),v=require('./package.json').version;s.writeFileSync('core.js',s.readFileSync('core.js','utf8').replace(/audio\\.version = '[^']+'/,'audio.version = \\''+v+'\\''));''\" && git add core.js","test:all":"CI=1 npm test && CI=1 npm run test:cli && npm run test:browser","test:cli":"TST_PARALLEL=3 node test/cli.js","test:browser":"node test/browser.js","prepublishOnly":"npm run version && npm run test:all"},"_npmUser":{"name":"dy","email":"df.creative@gmail.com"},"repository":{"url":"git+https://github.com/audiojs/audio.git","type":"git"},"_npmVersion":"11.11.0","description":"Audio loading, editing, and rendering for JavaScript","directories":{},"_nodeVersion":"25.8.1","dependencies":{"audio-type":"^2.4.1","a-weighting":"^2.0.1","pcm-convert":"^3.1.1","audio-decode":"^3.8.1","audio-filter":"^2.2.2","encode-audio":"^1.2.2","audio-speaker":"^2.1.1","parse-duration":"^2.1.6","window-function":"^3.0.1","@audio/decode-caf":"^1.1.0","@audio/decode-wav":"^1.1.0","@audio/encode-mp3":"^1.0.1","fourier-transform":"^2.2.0","@audio/decode-aiff":"^1.1.0"},"_hasShrinkwrap":false,"devDependencies":{"tst":"^9.4.0","esbuild":"^0.28.0","audio-lena":"^3.0.0","playwright":"^1.59.1"},"optionalDependencies":{"audio-mic":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/audio_2.0.0_1775795783207_0.06484293253781037","host":"s3://npm-registry-packages-npm-production"}},"2.1.0":{"name":"audio","version":"2.1.0","keywords":["audiojs","audio","dsp","pcm"],"license":"MIT","_id":"audio@2.1.0","maintainers":[{"name":"dfcreative","email":"df.creative@gmail.com"},{"name":"jamen","email":"jamenmarz@gmail.com"},{"name":"dy","email":"df.creative@gmail.com"}],"homepage":"https://github.com/audiojs/audio#readme","bugs":{"url":"https://github.com/audiojs/audio/issues"},"bin":{"audio":"bin/cli.js"},"dist":{"shasum":"8d4d347ea799c05c73ddd0ddd7540b26950512ca","tarball":"https://registry.npmjs.org/audio/-/audio-2.1.0.tgz","fileCount":39,"integrity":"sha512-eb6uJ82SKeiRKMqHZG/QNm3kGDM2QjZH9Nw8E0SOwEOlt3hNMj+czYqSwAE+oVtk2ZN/Rj+0wf9PNPsQWKv7bw==","signatures":[{"sig":"MEUCIC18YyMUeff9T/0RNHjH6hJai8OmF2mJSqN7DNIsF93HAiEAyCak4NmN8ukHeEno+Cqq7mU4nT6F9v9fJmYakO/h52c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":10729600},"main":"audio.js","type":"module","types":"./audio.d.ts","exports":{".":{"browser":"./dist/audio.js","default":"./audio.js"},"./core":"./core.js","./fn/*":"./fn/*","./plan":"./plan.js","./cache":"./cache.js","./stats":"./stats.js"},"gitHead":"6a012cc369d2efd5052c4cfa41a48f4655258920","scripts":{"demo":"vhs player.tape","test":"node test/index.js","build":"node .esbuild.js","serve":"node test/serve.js","version":"node -p \"var s=require('fs'),v=require('./package.json').version;s.writeFileSync('core.js',s.readFileSync('core.js','utf8').replace(/audio\\.version = '[^']+'/,'audio.version = \\''+v+'\\''));''\" && git add core.js","test:all":"CI=1 npm test && CI=1 npm run test:cli && npm run test:browser","test:cli":"TST_PARALLEL=3 node test/cli.js","test:browser":"node test/browser.js","prepublishOnly":"npm run version && npm run test:all"},"_npmUser":{"name":"dy","email":"df.creative@gmail.com"},"repository":{"url":"git+https://github.com/audiojs/audio.git","type":"git"},"_npmVersion":"11.11.0","description":"Audio loading, editing, and rendering for JavaScript","directories":{},"_nodeVersion":"25.8.1","dependencies":{"audio-type":"^2.4.1","a-weighting":"^2.0.1","pcm-convert":"^3.1.1","audio-decode":"^3.8.1","audio-filter":"^2.2.2","encode-audio":"^1.2.2","audio-speaker":"^2.1.1","parse-duration":"^2.1.6","window-function":"^3.0.1","fourier-transform":"^2.2.0"},"_hasShrinkwrap":false,"devDependencies":{"tst":"^9.4.0","esbuild":"^0.28.0","audio-lena":"^3.0.0","playwright":"^1.59.1"},"optionalDependencies":{"audio-mic":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/audio_2.1.0_1775800966359_0.011140688882187666","host":"s3://npm-registry-packages-npm-production"}},"2.1.1":{"name":"audio","version":"2.1.1","keywords":["audiojs","audio","dsp","pcm"],"license":"MIT","_id":"audio@2.1.1","maintainers":[{"name":"dfcreative","email":"df.creative@gmail.com"},{"name":"jamen","email":"jamenmarz@gmail.com"},{"name":"dy","email":"df.creative@gmail.com"}],"homepage":"https://github.com/audiojs/audio#readme","bugs":{"url":"https://github.com/audiojs/audio/issues"},"bin":{"audio":"bin/cli.js"},"dist":{"shasum":"069a45a0c256eb8d964f4761b6d5d6106ed1740a","tarball":"https://registry.npmjs.org/audio/-/audio-2.1.1.tgz","fileCount":38,"integrity":"sha512-a1gDhjUDnHocWI84badsYD69Bx658IJ/m+W3ux+AQkaGMzgyt1MrYGEGg+isYyVcii/RsfIGXp8ZXxG59ahxqQ==","signatures":[{"sig":"MEUCIQCkM9I3zsCYkRH3cVTyuIFtlxgaGI8pU77Gs0CKuGR2OwIgINKEOXzPE7OrrbvDTSes6ZrOzKSiy0S9hYhTeRdopsg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":369424},"main":"audio.js","type":"module","types":"./audio.d.ts","exports":{".":{"browser":"./dist/audio.js","default":"./audio.js"},"./core":"./core.js","./fn/*":"./fn/*","./plan":"./plan.js","./cache":"./cache.js","./stats":"./stats.js"},"gitHead":"7296a9526ba10b55636fc0c3c987d6fbebf096db","scripts":{"demo":"vhs player.tape","test":"node test/index.js","build":"node .esbuild.js","serve":"node test/serve.js","version":"node -p \"var s=require('fs'),v=require('./package.json').version;s.writeFileSync('core.js',s.readFileSync('core.js','utf8').replace(/audio\\.version = '[^']+'/,'audio.version = \\''+v+'\\''));''\" && git add core.js","test:all":"CI=1 npm test && CI=1 npm run test:cli && npm run test:browser","test:cli":"TST_PARALLEL=3 node test/cli.js","test:browser":"node test/browser.js","prepublishOnly":"npm run version && npm run test:all"},"_npmUser":{"name":"dy","email":"df.creative@gmail.com"},"repository":{"url":"git+https://github.com/audiojs/audio.git","type":"git"},"_npmVersion":"11.11.0","description":"Audio loading, editing, and rendering for JavaScript","directories":{},"_nodeVersion":"25.8.1","dependencies":{"audio-type":"^2.4.1","a-weighting":"^2.0.1","pcm-convert":"^3.1.1","audio-decode":"^3.8.1","audio-filter":"^2.2.2","encode-audio":"^1.2.2","audio-speaker":"^2.1.1","parse-duration":"^2.1.6","window-function":"^3.0.1","fourier-transform":"^2.2.0"},"_hasShrinkwrap":false,"devDependencies":{"tst":"^9.4.0","esbuild":"^0.28.0","audio-lena":"^3.0.0","playwright":"^1.59.1"},"optionalDependencies":{"audio-mic":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/audio_2.1.1_1775801865646_0.49733123961151304","host":"s3://npm-registry-packages-npm-production"}},"2.2.0":{"name":"audio","version":"2.2.0","description":"Audio loading, editing, and rendering for JavaScript","type":"module","main":"audio.js","exports":{".":{"browser":"./dist/audio.js","default":"./audio.js"},"./core":"./core.js","./plan":"./plan.js","./stats":"./stats.js","./cache":"./cache.js","./fn/*":"./fn/*"},"types":"./audio.d.ts","bin":{"audio":"bin/cli.js"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/audiojs/audio.git"},"keywords":["audiojs","audio","dsp","pcm"],"scripts":{"build":"node .esbuild.js","test":"node test/index.js","test:cli":"TST_PARALLEL=3 node test/cli.js","test:browser":"node test/browser.js","test:all":"CI=1 npm test && CI=1 npm run test:cli && npm run test:browser","version":"node -p \"var s=require('fs'),v=require('./package.json').version;s.writeFileSync('core.js',s.readFileSync('core.js','utf8').replace(/audio\\.version = '[^']+'/,'audio.version = \\''+v+'\\''));''\" && git add core.js","prepublishOnly":"npm run version && npm run test:all","serve":"node test/serve.js","demo":"vhs player.tape"},"dependencies":{"a-weighting":"^2.0.1","audio-decode":"^3.9.0","audio-filter":"^2.2.2","audio-speaker":"^2.1.1","audio-type":"^2.4.1","encode-audio":"^1.2.2","fourier-transform":"^2.2.0","parse-duration":"^2.1.6","pcm-convert":"^3.1.1","time-stretch":"^1.0.0","window-function":"^3.0.1"},"optionalDependencies":{"audio-mic":"^1.0.0"},"devDependencies":{"audio-lena":"^3.0.0","esbuild":"^0.28.0","playwright":"^1.59.1","tst":"^9.4.0"},"gitHead":"6550a6152ae606b023bb920995f3205e91c3ad57","_id":"audio@2.2.0","bugs":{"url":"https://github.com/audiojs/audio/issues"},"homepage":"https://github.com/audiojs/audio#readme","_nodeVersion":"25.8.1","_npmVersion":"11.11.0","dist":{"integrity":"sha512-7Suud4i2ZiKh29r7aMl9t4jnda/u8QzQh/pcFNrygn1RKPIKc9/MIAjkKIqwlUaAY9VVZ38TlOhZaT65t58i7Q==","shasum":"c2cab1873877388744bec734717befb2339da65f","tarball":"https://registry.npmjs.org/audio/-/audio-2.2.0.tgz","fileCount":40,"unpackedSize":415803,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCqKp6L2HzqEbB8WZTZOELGPf7XENWxhUR7UKQlKj7cbAIhAKgbzvMqRFejXKpLCc2zjdkOLEio1atg1rsbAo7iJy9L"}]},"_npmUser":{"name":"dy","email":"df.creative@gmail.com"},"directories":{},"maintainers":[{"name":"dfcreative","email":"df.creative@gmail.com"},{"name":"jamen","email":"jamenmarz@gmail.com"},{"name":"dy","email":"df.creative@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/audio_2.2.0_1775881917908_0.2998592795549089"},"_hasShrinkwrap":false}},"time":{"created":"2015-02-05T04:39:50.252Z","modified":"2026-04-11T04:31:58.196Z","0.0.0":"2015-02-05T04:39:50.252Z","0.0.1":"2016-06-01T07:02:04.688Z","0.1.0":"2016-06-03T04:40:55.263Z","0.1.1":"2016-06-04T15:19:35.405Z","1.0.0":"2016-06-05T07:56:49.062Z","1.0.1":"2016-06-05T07:57:47.401Z","1.1.0":"2016-06-06T02:48:51.839Z","1.2.0":"2016-06-27T06:39:08.224Z","2.0.0-0":"2016-08-15T09:32:05.280Z","2.0.0-1":"2016-08-18T21:29:17.928Z","2.0.0":"2026-04-10T04:36:23.512Z","2.1.0":"2026-04-10T06:02:46.637Z","2.1.1":"2026-04-10T06:17:45.795Z","2.2.0":"2026-04-11T04:31:58.063Z"},"bugs":{"url":"https://github.com/audiojs/audio/issues"},"license":"MIT","homepage":"https://github.com/audiojs/audio#readme","keywords":["audiojs","audio","dsp","pcm"],"repository":{"type":"git","url":"git+https://github.com/audiojs/audio.git"},"description":"Audio loading, editing, and rendering for JavaScript","maintainers":[{"name":"dfcreative","email":"df.creative@gmail.com"},{"name":"jamen","email":"jamenmarz@gmail.com"},{"name":"dy","email":"df.creative@gmail.com"}],"readme":"# <img src=\"logo.svg\" width=\"20\" height=\"20\" alt=\"audio\"> audio [![test](https://github.com/audiojs/audio/actions/workflows/test.yml/badge.svg)](https://github.com/audiojs/audio/actions/workflows/test.yml) [![npm](https://img.shields.io/npm/v/audio?color=white)](https://npmjs.org/package/audio)\n\n_Audio in JavaScript_\n\n```js\naudio('raw.wav').trim(-30).normalize('podcast').fade(0.3, 0.5).save('clean.mp3')\n```\n\n<!-- <img src=\"preview.svg?v=1\" alt=\"Audiojs demo\" width=\"540\"> -->\n\n* **Any Format** — fast wasm codecs, no ffmpeg.\n* **Streaming** — playback during decode.\n* **Immutable** — safe edits, infinite undo/redo.\n* **Page Cache** — open 10Gb+ files.\n* **Analysis** — loudness, spectrum, and more.\n* **Modular** – pluggable ops, tree-shakable.\n* **CLI** — playback, unix pipes, tab completion.\n* **Isomorphic** — node / browser.\n* **Audio-first** – dB, Hz, LUFS, not bytes and indices.\n\n<!--\n* [Architecture](docs/architecture.md) – stream-first design, pages & blocks, non-destructive editing, plan compilation\n* [Plugins](docs/plugins.md) – custom ops, stats, descriptors (process, plan, resolve, call), persistent ctx\n-->\n\n<div align=\"center\">\n\n#### [Quick Start](#quick-start)&nbsp;&nbsp;&nbsp;[Recipes](#recipes)&nbsp;&nbsp;&nbsp;[API](#api)&nbsp;&nbsp;&nbsp;[CLI](#cli)&nbsp;&nbsp;&nbsp;[FAQ](#faq)&nbsp;&nbsp;&nbsp;<br>[Ecosystem](#ecosystem)&nbsp;&nbsp;&nbsp;[Plugins](docs/plugins.md)&nbsp;&nbsp;&nbsp;[Architecture](docs/architecture.md)&nbsp;&nbsp;&nbsp;\n\n</div>\n\n## Quick Start\n\n### Node\n\n`npm i audio`\n\n```js\nimport audio from 'audio'\nlet a = audio('voice.mp3')\na.trim().normalize('podcast').fade(0.3, 0.5)\nawait a.save('clean.mp3')\n```\n\n### Browser\n\n```html\n<script type=\"module\">\n  import audio from './dist/audio.min.js'\n  let a = audio('./song.mp3')\n  a.trim().normalize().fade(0.5, 2)\n  a.clip({ at: 60, duration: 30 }).play()   // play the chorus\n</script>\n```\n\nCodecs load on demand via `import()` — map them with an import map or your bundler.\n<details>\n<summary><strong>Import map example</strong></summary>\n\n\n```html\n<script type=\"importmap\">\n{\n  \"imports\": {\n    \"@audio/decode-mp3\": \"https://esm.sh/@audio/decode-mp3\",\n    \"@audio/decode-wav\": \"https://esm.sh/@audio/decode-wav\",\n    \"@audio/decode-flac\": \"https://esm.sh/@audio/decode-flac\",\n    \"@audio/decode-opus\": \"https://esm.sh/@audio/decode-opus\",\n    \"@audio/decode-vorbis\": \"https://esm.sh/@audio/decode-vorbis\",\n    \"@audio/decode-aac\": \"https://esm.sh/@audio/decode-aac\",\n    \"@audio/decode-qoa\": \"https://esm.sh/@audio/decode-qoa\",\n    \"@audio/decode-aiff\": \"https://esm.sh/@audio/decode-aiff\",\n    \"@audio/decode-caf\": \"https://esm.sh/@audio/decode-caf\",\n    \"@audio/decode-webm\": \"https://esm.sh/@audio/decode-webm\",\n    \"@audio/decode-amr\": \"https://esm.sh/@audio/decode-amr\",\n    \"@audio/decode-wma\": \"https://esm.sh/@audio/decode-wma\",\n    \"@audio/encode-wav\": \"https://esm.sh/@audio/encode-wav\",\n    \"@audio/encode-mp3\": \"https://esm.sh/@audio/encode-mp3\",\n    \"@audio/encode-flac\": \"https://esm.sh/@audio/encode-flac\",\n    \"@audio/encode-opus\": \"https://esm.sh/@audio/encode-opus\",\n    \"@audio/encode-ogg\": \"https://esm.sh/@audio/encode-ogg\",\n    \"@audio/encode-aiff\": \"https://esm.sh/@audio/encode-aiff\"\n  }\n}\n</script>\n```\n\n</details>\n\n### CLI\n\n```sh\nnpm i -g audio\naudio voice.wav trim normalize podcast fade 0.3s -0.5s -o clean.mp3\n```\n\n## Recipes\n\n### Clean up a recording\n\n```js\nlet a = audio('raw-take.wav')\na.trim(-30).normalize('podcast').fade(0.3, 0.5)\nawait a.save('clean.wav')\n```\n\n### Podcast montage\n\n```js\nlet intro = audio('intro.mp3')\nlet body  = audio('interview.wav')\nlet outro = audio('outro.mp3')\n\nbody.trim().normalize('podcast')\nlet ep = audio([intro, body, outro])\nep.fade(0.5, 2)\nawait ep.save('episode.mp3')\n```\n\n### Render a waveform\n\n```js\nlet a = audio('track.mp3')\nlet [mins, peaks] = await a.stat(['min', 'max'], { bins: canvas.width })\nfor (let i = 0; i < peaks.length; i++)\n  ctx.fillRect(i, h/2 - peaks[i] * h/2, 1, (peaks[i] - mins[i]) * h/2)\n```\n\n### Render as it decodes\n\n```js\nlet a = audio('long.flac')\na.on('data', ({ delta }) => appendBars(delta.max[0], delta.min[0]))\nawait a\n```\n\n### Voiceover on music\n\n```js\nlet music = audio('bg.mp3')\nlet voice = audio('narration.wav')\nmusic.gain(-12).mix(voice, { at: 2 })\nawait music.save('mixed.wav')\n```\n\n### Split a long file\n\n```js\nlet a = audio('audiobook.mp3')\nlet [ch1, ch2, ch3] = a.split(1800, 3600)\nfor (let [i, ch] of [ch1, ch2, ch3].entries())\n  await ch.save(`chapter-${i + 1}.mp3`)\n```\n\n### Record from mic\n\n```js\nlet a = audio()\na.record()\nawait new Promise(r => setTimeout(r, 5000))\na.stop()\na.trim().normalize()\nawait a.save('recording.wav')\n```\n\n### Extract features for ML\n\n```js\nlet a = audio('speech.wav')\nlet mfcc = await a.stat('cepstrum', { bins: 13 })\nlet spec = await a.stat('spectrum', { bins: 128 })\nlet [loud, rms] = await a.stat(['loudness', 'rms'])\n```\n\n### Generate a tone\n\n```js\nlet a = audio.from(t => Math.sin(440 * Math.PI * 2 * t), { duration: 2 })\nawait a.save('440hz.wav')\n```\n\n### Custom op\n\n```js\naudio.op('crush', (chs, ctx) => {\n  let steps = 2 ** (ctx.args[0] ?? 8)\n  return chs.map(ch => ch.map(s => Math.round(s * steps) / steps))\n})\n\na.crush(4)\n```\n\n### Serialize and restore\n\n```js\nlet json = JSON.stringify(a)             // { source, edits, ... }\nlet b = audio(JSON.parse(json))           // re-decode + replay edits\n```\n\n### Remove a section\n\n```js\nlet a = audio('interview.wav')\na.remove({ at: 120, duration: 15 })     // cut 2:00–2:15\na.fade(0.1, { at: 120 })                // smooth the splice\nawait a.save('edited.wav')\n```\n\n### Ringtone from any song\n\n```js\nlet a = audio('song.mp3')\na.crop({ at: 45, duration: 30 }).fade(0.5, 2).normalize()\nawait a.save('ringtone.mp3')\n```\n\n### Detect clipping\n\n```js\nlet a = audio('master.wav')\nlet clips = await a.stat('clipping')\nif (clips.length) console.warn(`${clips.length} clipped blocks`)\n```\n\n### Stream to network\n\n```js\nlet a = audio('2hour-mix.flac')\na.highpass(40).normalize('broadcast')\nfor await (let chunk of a) socket.send(chunk[0].buffer)\n```\n\n### Glitch: stutter + reverse\n\n```js\nlet a = audio('beat.wav')\nlet v = a.clip({ at: 1, duration: 0.25 })\nlet glitch = audio([v, v, v, v])\nglitch.reverse({ at: 0.25, duration: 0.25 })\nawait glitch.save('glitch.wav')\n```\n\n### Tremolo / sidechain\n\n```js\nlet a = audio('pad.wav')\na.gain(t => -12 * (0.5 + 0.5 * Math.cos(t * Math.PI * 4)))  // 2Hz tremolo in dB\nawait a.save('tremolo.wav')\n```\n\n### Sonify data\n\n```js\nlet prices = [100, 102, 98, 105, 110, 95, 88, 92, 101, 107]\nlet a = audio.from(t => {\n  let freq = 200 + (prices[Math.min(Math.floor(t / 0.2), prices.length - 1)] - 80) * 10\n  return Math.sin(freq * Math.PI * 2 * t) * 0.5\n}, { duration: prices.length * 0.2 })\nawait a.save('sonification.wav')\n```\n\n\n## API\n\n### Create\n\n* **`audio(source, opts?)`** – decode from file, URL, or bytes. Returns instantly — decodes in background.\n* **`audio.from(source, opts?)`** – wrap existing PCM, AudioBuffer, silence, or function. Sync, no I/O.\n\n```js\nlet a = audio('voice.mp3')                // file path\nlet b = audio('https://cdn.ex/track.mp3') // URL\nlet c = audio(inputEl.files[0])           // Blob, File, Response, ArrayBuffer\nlet d = audio()                           // empty, ready for .push() or .record()\nlet e = audio([intro, body, outro])       // concat (virtual, no copy)\n// opts: { sampleRate, channels, storage: 'memory' | 'persistent' | 'auto' }\n\nawait a    // await for decode — if you need .duration, full stats etc\n\nlet a = audio.from([left, right])                 // Float32Array[] channels\nlet b = audio.from(3, { channels: 2 })           // 3s silence\nlet c = audio.from(t => Math.sin(440*TAU*t), { duration: 2 })  // generator\nlet d = audio.from(audioBuffer)                   // Web Audio AudioBuffer\nlet e = audio.from(int16arr, { format: 'int16' }) // typed array + format\n```\n\n\n### Properties\n\n```js\n// format\na.duration                // total seconds (reflects edits)\na.channels                // channel count\na.sampleRate              // sample rate\na.length                  // total samples per channel\n\n// playback\na.currentTime             // position in seconds (smooth interpolation during playback)\na.playing                 // true during playback\na.paused                  // true when paused\na.volume = 0.5             // 0..1 linear (settable)\na.muted = true            // mute gate (independent of volume)\na.loop = true             // on/off (settable)\na.ended                   // true when playback ended naturally (not via stop)\na.seeking                 // true during a seek operation\na.played                  // promise, resolves when playback starts\na.recording               // true during mic recording\n\n// state\na.ready                   // promise, resolves when fully decoded\na.source                  // original source reference\na.pages                   // Float32Array page store\na.stats                   // per-block stats (peak, rms, etc.)\na.edits                   // edit list (non-destructive ops)\na.version                 // increments on each edit\n```\n\n### Structure\n\nNon-destructive time/channel rearrangement. All support `{at, duration, channel}`.\n\n* **`.trim(threshold?)`** – strip leading/trailing silence (dB, default auto).\n* **`.crop({at, duration})`** – keep range, discard rest.\n* **`.remove({at, duration})`** – cut range, close gap.\n* **`.insert(source, {at})`** – insert audio or silence (number of seconds) at position.\n* **`.clip({at, duration})`** – zero-copy range reference.\n* **`.split(...offsets)`** – zero-copy split at timestamps.\n* **`.pad(before, after?)`** – silence at edges (seconds).\n* **`.repeat(n)`** – repeat n times.\n* **`.reverse({at?, duration?})`** – reverse audio or range.\n* **`.speed(rate)`** – playback speed (affects pitch and duration).\n* **`.remix(channels)`** – channel count: number or array map (`[1, 0]` swaps L/R).\n\n```js\na.trim(-30)                               // strip silence below -30dB\na.remove({ at: '2m', duration: 15 })      // cut 2:00–2:15, close gap\na.insert(intro, { at: 0 })               // prepend; .insert(3) appends 3s silence\nlet [pt1, pt2] = a.split('30m')          // zero-copy views\nlet hook = a.clip({ at: 60, duration: 30 })  // zero-copy excerpt\na.remix([0, 0])                           // L→both; .remix(1) for mono\n```\n\n### Process\n\nAmplitude, mixing, normalization. All support `{at, duration, channel}` ranges.\n\n* **`.gain(dB, opts?)`** – volume. Number, range, or `t => dB` function. `{ unit: 'linear' }` for multiplier.\n* **`.fade(in, out?, curve?)`** – fade in/out. Curves: `'linear'` `'exp'` `'log'` `'cos'`.\n* **`.normalize(target?)`** – remove DC offset, clamp, and normalize loudness.\n  * `'podcast'` – -16 LUFS, -1 dBTP.\n  * `'streaming'` – -14 LUFS.\n  * `'broadcast'` – -23 LUFS.\n  * `-3` – custom dB target (peak mode).\n  * no arg – peak 0dBFS.\n  * `{ mode: 'rms' }` – RMS normalization. Also `'peak'`, `'lufs'`.\n  * `{ ceiling: -1 }` – true peak limiter in dB.\n  * `{ dc: false }` – skip DC removal.\n* **`.mix(source, opts?)`** – overlay another audio (additive).\n* **`.pan(value, opts?)`** – stereo balance (−1 left, 0 center, 1 right). Accepts function.\n* **`.write(data, {at?})`** – overwrite samples with raw PCM.\n* **`.transform(fn)`** – inline processor: `(chs, ctx) => chs`. Not serialized.\n\n```js\na.gain(-3)                                // reduce 3dB\na.gain(6, { at: 10, duration: 5 })       // boost range\na.gain(t => -12 * Math.cos(t * TAU))     // automate over time\na.fade(0.5, -2, 'exp')                    // 0.5s in, 2s exp fade-out\na.normalize('podcast')                    // -16 LUFS; also 'streaming', 'broadcast'\na.mix(voice, { at: 2 })                  // overlay at 2s\na.pan(-0.3, { at: 10, duration: 5 })      // pan left for range\n```\n\n### Filter\n\nBiquad filters, chainable. All support `{at, duration}` ranges.\n\n* **`.highpass(freq)`**, **`.lowpass(freq)`** – pass filter.\n* **`.bandpass(freq, Q?)`**, **`.notch(freq, Q?)`** – band-pass / notch.\n* **`.lowshelf(freq, dB)`**, **`.highshelf(freq, dB)`** – shelf EQ.\n* **`.eq(freq, gain, Q?)`** – parametric EQ.\n* **`.filter(type, ...params)`** – generic dispatch.\n\n```js\na.highpass(80).lowshelf(200, -3)          // rumble + mud\na.eq(3000, 2, 1.5).highshelf(8000, 3)    // presence + air\na.notch(50)                               // remove hum\na.filter(customFn, { cutoff: 2000 })     // custom filter function\n```\n\n### I/O\n\nRead PCM, encode, stream, push. Format inferred from extension.\n\n* **`await .read(opts?)`** – rendered PCM. `{ format, channel }` to convert.\n* **`await .save(path, opts?)`** – encode + write. `{ at, duration }` for sub-range.\n* **`await .encode(format?, opts?)`** – encode to `Uint8Array`.\n* **`for await (let block of a)`** – async-iterable over blocks.\n* **`.clone()`** – deep copy, independent edits, shared pages.\n* **`.push(data, format?)`** – feed PCM into pushable instance. `.stop()` to finalize.\n\n```js\nlet pcm = await a.read()                  // Float32Array[]\nlet raw = await a.read({ format: 'int16', channel: 0 })\nawait a.save('out.mp3')                   // format from extension\nlet bytes = await a.encode('flac')        // Uint8Array\nfor await (let block of a) send(block)    // stream blocks\nlet b = a.clone()                         // independent copy, shared pages\n\nlet src = audio()                         // pushable source\nsrc.push(buf, 'int16')                    // feed PCM\nsrc.stop()                                // finalize\n```\n\n### Playback / Recording\n\nLive playback with dB volume, seeking, looping. Mic recording via `audio-mic`.\n\n* **`.play(opts?)`** – start playback. `{ at, duration, volume, loop }`. `.played` promise resolves when output starts.\n* **`.pause()`**, **`.resume()`**, **`.seek(t)`**, **`.stop()`** – playback control.\n* **`.record(opts?)`** – mic recording. `{ deviceId, sampleRate, channels }`.\n\n```js\na.play({ at: 30, duration: 10 })          // play 30s–40s\nawait a.played                             // wait for output to start\na.volume = 0.5; a.loop = true             // live adjustments\na.muted = true                             // mute without changing volume\na.pause(); a.seek(60); a.resume()         // jump to 1:00\na.stop()                                  // end playback or recording\n\nlet mic = audio()\nmic.record({ sampleRate: 16000, channels: 1 })\nmic.stop()\n```\n\n\n### Analysis\n\n`await .stat(name, opts?)` — without `bins` returns scalar, with `bins` returns `Float32Array`. Array of names returns array of results. Sub-ranges via `{at, duration}`, per-channel via `{channel}`.\n\n* **`'db'`** – peak amplitude in dBFS.\n* **`'rms'`** – RMS amplitude (linear).\n* **`'loudness'`** – integrated LUFS (ITU-R BS.1770).\n* **`'dc'`** – DC offset.\n* **`'clipping'`** – clipped samples (scalar: timestamps, binned: counts).\n* **`'silence'`** – silent ranges as `{at, duration}`.\n* **`'max'`**, **`'min'`** – peak envelope (use together for waveform rendering).\n* **`'spectrum'`** – mel-frequency spectrum in dB (A-weighted).\n* **`'cepstrum'`** – MFCCs.\n\n```js\nlet loud = await a.stat('loudness')                       // LUFS\nlet [db, clips] = await a.stat(['db', 'clipping'])        // multiple at once\nlet spec = await a.stat('spectrum', { bins: 128 })        // frequency bins\nlet peaks = await a.stat('max', { bins: 800 })            // waveform data\nawait a.stat('rms', { channel: 0 })                       // left only → number\nawait a.stat('rms', { channel: [0, 1] })                  // per-channel → [n, n]\nlet gaps = await a.stat('silence', { threshold: -40 })    // [{at, duration}, ...]\n```\n\n\n### Utility\n\nEvents, lifecycle, undo/redo, serialization.\n\n* **`.on(event, fn)`** / **`.off(event?, fn?)`** – subscribe / unsubscribe.\n  * `'data'` – pages decoded/pushed. Payload: `{ delta, offset, sampleRate, channels }`.\n  * `'change'` – any edit or undo.\n  * `'metadata'` – stream header decoded. Payload: `{ sampleRate, channels }`.\n  * `'timeupdate'` – playback position. Payload: `currentTime`.\n  * `'play'` – playback started or resumed.\n  * `'pause'` – playback paused.\n  * `'volumechange'` – volume or muted changed.\n  * `'ended'` – playback finished (not on loop).\n  * `'progress'` – during save/encode. Payload: `{ offset, total }` in seconds.\n* **`.dispose()`** – release resources. Supports `using` for auto-dispose.\n* **`.undo(n?)`** – undo last edit(s). Returns edit for redo via `.run()`.\n* **`.run(...edits)`** – apply edit objects `{ type, args, at?, duration? }`. Batch or replay.\n\n```js\na.on('data', ({ delta }) => draw(delta))  // decode progress\na.on('timeupdate', t => ui.update(t))     // playback position\n\na.undo()                                  // undo last edit\nb.run(...a.edits)                         // replay onto another file\nJSON.stringify(a); audio(json)            // serialize / restore\n```\n\n### Plugins\n\nExtend with custom ops and stats. See [Plugin Tutorial](docs/plugins.md).\n\n* **`audio.op(name, fn)`** – register op. Shorthand for `{ process: fn }`. Full descriptor: `{ process, plan, resolve, call }`.\n* **`audio.op(name)`** – query descriptor. **`audio.op()`** – all ops.\n* **`audio.stat(name, descriptor)`** – register stat. Shorthand `(chs, ctx) => [...]` or `{ block, reduce, query }`.\n\n```js\n// op: process function receives (channels[], ctx) per 1024-sample block\naudio.op('crush', (chs, ctx) => {\n  let steps = 2 ** (ctx.args[0] ?? 8)\n  return chs.map(ch => ch.map(s => Math.round(s * steps) / steps))\n})\n\n// stat: block function collects per-block, reduce enables scalar queries\naudio.stat('peak', {\n  block: (chs) => chs.map(ch => { let m = 0; for (let s of ch) m = Math.max(m, Math.abs(s)); return m }),\n  reduce: (src, from, to) => { let m = 0; for (let i = from; i < to; i++) m = Math.max(m, src[i]); return m },\n})\n\na.crush(4)                    // chainable like built-in ops\na.stat('peak')                // → scalar from reduce\na.stat('peak', { bins: 100 }) // → binned array\n```\n\n## CLI\n\n**`npm i -g audio`**\n\n```sh\naudio [file] [ops...] [-o output] [options]\n\n# ops\neq          mix         pad         pan       crop\nfade        gain        stat        trim      notch\nremix       speed       split       insert    remove\nrepeat      bandpass    highpass    lowpass   reverse\nlowshelf    highshelf   normalize\n\n# options\n-p play     -l loop     -o output   -f force  --format\n```\n\n### Playback\n\n\n<img src=\"player.gif\" alt=\"Audiojs demo\" width=\"624\">\n\n<!-- ```sh\naudio kirtan.mp3\n▶ 0:06:37 ━━━━━━━━────────────────────────────────────────── -0:36:30   ▁▂▃▄▅__\n          ▂▅▇▇██▇▆▇▇▇██▆▇▇▇▆▆▅▅▆▅▆▆▅▅▆▅▅▅▃▂▂▂▂▁_____________\n          50    500  1k     2k         5k       10k      20k\n\n          48k   2ch   43:07   -0.8dBFS   -30.8LUFS\n``` -->\n\n<kbd>␣</kbd> pause · <kbd>←</kbd>/<kbd>→</kbd> seek ±10s · <kbd>⇧←</kbd>/<kbd>⇧→</kbd> seek ±60s · <kbd>↑</kbd>/<kbd>↓</kbd> volume ±3dB · <kbd>l</kbd> loop · <kbd>q</kbd> quit\n\n```sh\n# Play fragment of the song\naudio song.mp3 10s..15s -p\n\n# Play clip (not full song)\naudio song.mp3 clip 10s..20s -p -l\n\n# Normalize before\n```\n\n### Edit\n\n```sh\n# clean up\naudio raw-take.wav trim -30db normalize podcast fade 0.3s -0.5s -o clean.wav\n\n# ranges\naudio in.wav gain -3db 1s..10s -o out.wav\n\n# filter chain\naudio in.mp3 highpass 80hz lowshelf 200hz -3db -o out.wav\n\n# join\naudio intro.mp3 + content.wav + outro.mp3 trim normalize fade 0.5s -2s -o ep.mp3\n\n# voiceover\naudio bg.mp3 gain -12db mix narration.wav 2s -o mixed.wav\n\n# split\naudio audiobook.mp3 split 30m 60m -o 'chapter-{i}.mp3'\n```\n\n### Analysis\n\n```sh\n# all default stats (db, rms, loudness, clipping, dc)\naudio speech.wav stat\n\n# specific stats\naudio speech.wav stat loudness rms\n\n# spectrum / cepstrum with bin count\naudio speech.wav stat spectrum 128\naudio speech.wav stat cepstrum 13\n\n# stat after transforms\naudio speech.wav gain -3db stat db\n```\n\n### Batch\n\n```sh\naudio '*.wav' trim normalize podcast -o '{name}.clean.{ext}'\naudio '*.wav' gain -3db -o '{name}.out.{ext}'\n```\n\n### Stdin/stdout\n\n```sh\ncat in.wav | audio gain -3db > out.wav\ncurl -s https://example.com/speech.mp3 | audio normalize -o clean.wav\nffmpeg -i video.mp4 -f wav - | audio trim normalize podcast > voice.wav\n```\n\n### Tab completion\n\n```sh\neval \"$(audio --completions zsh)\"       # add to ~/.zshrc\neval \"$(audio --completions bash)\"      # add to ~/.bashrc\naudio --completions fish | source       # fish\n```\n\n\n\n\n## FAQ\n\n<dl>\n<dt>How is this different from Web Audio API?</dt>\n<dd>Web Audio API is a real-time audio graph for playback and synthesis. This is for work on audio files specifically. For Web Audio API in Node, see <a href=\"https://github.com/audiojs/web-audio-api\">web-audio-api</a>.</dd>\n\n<dt>What formats are supported?</dt>\n<dd>Decode: WAV, MP3, FLAC, OGG Vorbis, Opus, AAC, AIFF, CAF, WebM, AMR, WMA, QOA via <a href=\"https://github.com/audiojs/audio-decode\">audio-decode</a>. Encode: WAV, MP3, FLAC, Opus, OGG, AIFF via <a href=\"https://github.com/audiojs/audio-encode\">audio-encode</a>. Codecs are WASM-based, lazy-loaded on first use.</dd>\n\n<dt>Does it need ffmpeg or native addons?</dt>\n<dd>No, pure JS + WASM. For CLI, you can install globally: <code>npm i -g audio</code>.</dd>\n\n<dt>How big is the bundle?</dt>\n<dd>~20K gzipped core. Codecs load on demand via <code>import()</code>, so unused formats aren't fetched.</dd>\n\n<dt>How does it handle large files?</dt>\n<dd>Audio is stored in fixed-size pages. In the browser, cold pages can evict to OPFS when memory exceeds budget. Stats stay resident (~7 MB for 2h stereo).</dd>\n\n<dt>Are edits destructive?</dt>\n<dd>No. <code>a.gain(-3).trim()</code> pushes entries to an edit list — source pages aren't touched. Edits replay on <code>read()</code> / <code>save()</code> / <code>for await</code>.</dd>\n\n<dt>Can I use it in the browser?</dt>\n<dd>Yes, same API. See <a href=\"#browser\">Browser</a> for bundle options and import maps.</dd>\n\n<dt>Does it need the full file before I can work with it?</dt>\n<dd>No, playback and edits work during decode. The <code>'data'</code> event fires as pages arrive.</dd>\n\n<dt>TypeScript?</dt>\n<dd>Yes, ships with <code>audio.d.ts</code>.</dd>\n</dl>\n\n\n## Ecosystem\n\n* [audio-decode](https://github.com/audiojs/audio-decode) – codec decoding (13+ formats)\n* [encode-audio](https://github.com/audiojs/audio-encode) – codec encoding\n* [audio-filter](https://github.com/audiojs/audio-filter) – filters (weighting, EQ, auditory)\n* [audio-speaker](https://github.com/audiojs/audio-speaker) – audio output\n* [audio-mic](https://github.com/audiojs/audio-mic) – audio input\n* [audio-type](https://github.com/nickolanack/audio-type) – format detection\n* [pcm-convert](https://github.com/nickolanack/pcm-convert) – PCM format conversion\n\n<p align=\"center\"><a href=\"./license.md\">MIT</a> · <a href=\"https://github.com/krishnized/license\">ॐ</a></p>\n","readmeFilename":"README.md","users":{"quietcoder":true}}