waveform audio file format encoder logic
encoder[from AudioBuffer]/downencoder[32, 24, 16 ,8]を使用可能。encoder/downencoder
define AudioBuffer.prototype
1. thrownone2. declare values, value, blockAlign
const vs=Array(14),v=b>>>3,blockAlign=this.numberOfChannels*v3. declare call
,c=32===b?(v,i)=>(i=>v.subarray(i,4+i))(i<<2):(c=>{
if(24===b)c=v=>(0>v?0x800000*v:0x7fffff*v).to3Array()
else if(16===b)c=v=>(0>v?0x8000*v:0x7fff*v).to2Array()
else if(8===b)c=v=>[0x80+(0>v?0x80*v:0x7f*v)]
else throw Error()
return(v,i)=>c(v[i].limit(false,-1).limit(true,1))
})()4. set values
vs[0]=ids[0]
vs[2]=ids[1]
vs[3]=ids[2]
vs[4]=new Uint8Array([0x10,0,0,0])
vs[5]=new Uint8Array([32===b?3:1,0])
vs[6]=this.numberOfChannels.to2Array()
vs[7]=this.sampleRate.to4Array()
vs[8]=(this.sampleRate*blockAlign).to4Array()
vs[9]=blockAlign.to2Array()
vs[10]=b.to2Array()
vs[11]=ids[3]
vs[13]=(c=>{
const vs=Array(this.numberOfChannels)
if(32===b)forEach(false,this.numberOfChannels,(_,i)=>vs[i]=new Uint8Array(this.getChannelData(i).buffer))
else forEach(false,this.numberOfChannels,(_,i)=>vs[i]=this.getChannelData(i))
return 24===b?define(0b01,numberToArray(true,3),()=>c(vs)):c(vs)
})(vs=>{
const data=new Uint8Array(this.length*blockAlign)
forEach(false,this.length,(_,y)=>forEach(false,this.numberOfChannels,(_,x)=>data.set(c(vs[x],y),x*v+y*blockAlign)))
return data
})
vs[1]=(36+vs[13].length).to4Array()
vs[12]=vs[13].length.to4Array()5. return
return new Blob(vs,{type:`audio/wav`})define Uint8Array.prototype
1. throwif(ids[0]!==this.toNumberFrom4(0))throw Error()
if(ids[1]!==this.toNumberFrom4(8))throw Error()2. declare index, value, call
let i=12,v,c3. declare values
const vs=Array(4)4. set values
vs[0]=this.subarray(0,i)
while(i<this.length){
const id=this.toNumberFrom4(i),size=this.toNumberFrom4(i+=4)
i+=4
if(ids[2]===id){
v=this.toNumberFrom2(14+i)
if(32===v)c=(c=>{
if(24===b)c=v=>(0>v?0x800000*v:0x7fffff*v).to3Array()
else if(16===b)c=v=>(0>v?0x8000*v:0x7fff*v).to2Array()
else if(8===b)c=v=>[0x80+(0>v?0x80*v:0x7f*v)]
else throw Error()
return(v,i)=>c(v[i].limit(false,-1).limit(true,1))
})()
else if(24===v)c=(c=>{
if(16===b)c=v=>(0>v?0x8000*v/0x800000:0x7fff*v/0x7fffff).to2Array()
else if(8===b)c=v=>[0x80+(0>v?0x80*v/0x800000:0x7f*v/0x7fffff)]
else throw Error()
return(v,i)=>c((v.toNumberFrom3(i*3)<<8)>>8)
})()
else if(16===v)c=(c=>{
if(8===b)c=v=>[0x80+(0>v?0x80*v/0x8000:0x7f*v/0x7fff)]
else throw Error()
return(v,i)=>c((v[i]<<16)>>16)
})()
else throw Error()
this.set((16).to4Array(),i-4)
this.set((1).to2Array(),i)
this.set((this.toNumberFrom4(8+i)*b/v).to4Array(),8+i)
this.set((this.toNumberFrom2(12+i)*b/v).to2Array(),12+i)
this.set(b.to2Array(),14+i)
vs[1]=this.subarray(i-8,i+size)
}else if(ids[3]===id){
if(!c)throw Error()
vs[2]=this.subarray(i-8,i)
vs[3]=(c=>{
const vs=this.slice(i,i+size)
if(32===v)return(vs=>24===b?define(0b01,numberToArray(true,3),()=>c(vs)):c(vs))(new Float32Array(vs.buffer))
else if(24===v)return(vs=>define(0b01,uint8ArrayToNumber(true,3),()=>c(vs)))(vs)
else return(vs=>c(vs))(new Uint16Array(vs.buffer))
})(vs=>{
const length=size/(v>>>3),data=new Uint8Array(length*(v=b>>>3))
this.set((36+data.length).to4Array(),4)
this.set(data.length.to4Array(),i-4)
forEach(false,length,(_,x)=>data.set(c(vs,x),x*v))
return data
})
}
i+=size
}5. return
return new Blob(vs,{type:`audio/wav`})