11( function ( window ) {
22
33 var WORKER_PATH = 'recorderWorker.js' ;
4+ var encoderWorker = new Worker ( 'mp3Worker.js' ) ;
45
56 var Recorder = function ( source , cfg ) {
67 var config = cfg || { } ;
78 var bufferLen = config . bufferLen || 4096 ;
8- var numChannels = config . numChannels || 2 ;
9+ var numChannels = config . numChannels || 1 ;
910 this . context = source . context ;
1011 this . node = ( this . context . createScriptProcessor ||
1112 this . context . createJavaScriptNode ) . call ( this . context ,
7071
7172 worker . onmessage = function ( e ) {
7273 var blob = e . data ;
73- currCallback ( blob ) ;
74+ var arrayBuffer ;
75+ var fileReader = new FileReader ( ) ;
76+
77+ fileReader . onload = function ( ) {
78+ arrayBuffer = this . result ;
79+ var buffer = new Uint8Array ( arrayBuffer ) ,
80+ data = parseWav ( buffer ) ;
81+
82+ encoderWorker . postMessage ( { cmd : 'init' , config :{
83+ mode : 3 ,
84+ channels :1 ,
85+ samplerate : data . sampleRate ,
86+ bitrate : data . bitsPerSample
87+ } } ) ;
88+
89+ encoderWorker . postMessage ( { cmd : 'encode' , buf : Uint8ArrayToFloat32Array ( data . samples ) } ) ;
90+ encoderWorker . postMessage ( { cmd : 'finish' } ) ;
91+ encoderWorker . onmessage = function ( e ) {
92+ if ( e . data . cmd == 'data' ) {
93+ var mp3Blob = new Blob ( [ new Uint8Array ( e . data . buf ) ] , { type : 'audio/mp3' } ) ;
94+ currCallback ( mp3Blob ) ;
95+ }
96+ } ;
97+ } ;
98+
99+ fileReader . readAsArrayBuffer ( blob ) ;
100+ }
101+
102+ function parseWav ( wav ) {
103+ function readInt ( i , bytes ) {
104+ var ret = 0 ,
105+ shft = 0 ;
106+ while ( bytes ) {
107+ ret += wav [ i ] << shft ;
108+ shft += 8 ;
109+ i ++ ;
110+ bytes -- ;
111+ }
112+ return ret ;
113+ }
114+ if ( readInt ( 20 , 2 ) != 1 ) throw 'Invalid compression code, not PCM' ;
115+ if ( readInt ( 22 , 2 ) != 1 ) throw 'Invalid number of channels, not 1' ;
116+ return {
117+ sampleRate : readInt ( 24 , 4 ) ,
118+ bitsPerSample : readInt ( 34 , 2 ) ,
119+ samples : wav . subarray ( 44 )
120+ } ;
121+ }
122+
123+ function Uint8ArrayToFloat32Array ( u8a ) {
124+ var f32Buffer = new Float32Array ( u8a . length ) ;
125+ for ( var i = 0 ; i < u8a . length ; i ++ ) {
126+ var value = u8a [ i << 1 ] + ( u8a [ ( i << 1 ) + 1 ] << 8 ) ;
127+ if ( value >= 0x8000 ) value |= ~ 0x7FFF ;
128+ f32Buffer [ i ] = value / 0x8000 ;
129+ }
130+ return f32Buffer ;
74131 }
75132
76133 source . connect ( this . node ) ;
81138 var url = ( window . URL || window . webkitURL ) . createObjectURL ( blob ) ;
82139 var link = window . document . createElement ( 'a' ) ;
83140 link . href = url ;
84- link . download = filename || 'output.wav ' ;
141+ link . download = filename || 'output.mp3 ' ;
85142 var click = document . createEvent ( "Event" ) ;
86143 click . initEvent ( "click" , true , true ) ;
87144 link . dispatchEvent ( click ) ;
88145 }
89146
90147 window . Recorder = Recorder ;
91148
92- } ) ( window ) ;
149+ } ) ( window ) ;
0 commit comments