@@ -5,6 +5,7 @@ define(function (require) {
5
5
// inspiration: recorder.js, Tone.js & typedarray.org
6
6
7
7
var p5sound = require ( 'master' ) ;
8
+ var convertToWav = require ( 'helpers' ) . convertToWav ;
8
9
var ac = p5sound . audiocontext ;
9
10
10
11
/**
@@ -244,101 +245,22 @@ define(function (require) {
244
245
this . _jsNode = null ;
245
246
} ;
246
247
247
- /**
248
- * Export a usable url for blob object.
249
- *
250
- * @method saveSoundToBlob
251
- * @param {p5.SoundFile } soundFile p5.SoundFile that you wish to export
252
- */
253
- p5 . prototype . saveSoundToBlob = function ( soundFile ) {
254
- const dataView = convertToWav ( soundFile )
255
- const audioBlob = new Blob ( [ dataView ] , { type : 'audio/wav' } )
256
- return URL . createObjectURL ( audioBlob )
257
- }
258
248
259
249
/**
260
- * Save a p5.SoundFile as a .wav audio file.
250
+ * Save a p5.SoundFile as a .wav file. The browser will prompt the user
251
+ * to download the file to their device.
252
+ * For uploading audio to a server, use
253
+ * <a href="/docs/reference/#/p5.SoundFile/saveBlob">`p5.SoundFile.saveBlob`</a>.
261
254
*
255
+ * @for p5
262
256
* @method saveSound
263
257
* @param {p5.SoundFile } soundFile p5.SoundFile that you wish to save
264
- * @param {String } name name of the resulting .wav file.
258
+ * @param {String } fileName name of the resulting .wav file.
265
259
*/
266
- p5 . prototype . saveSound = function ( soundFile , name ) {
267
- const dataView = convertToWav ( soundFile )
268
- p5 . prototype . writeFile ( [ dataView ] , name , 'wav' ) ;
260
+ // add to p5.prototype as this is used by the p5 `save()` method.
261
+ p5 . prototype . saveSound = function ( soundFile , fileName ) {
262
+ const dataView = convertToWav ( soundFile . buffer ) ;
263
+ p5 . prototype . writeFile ( [ dataView ] , fileName , 'wav' ) ;
269
264
} ;
270
265
271
- // helper methods to convert audio file as .wav format,
272
- // will use as saving .wav file and saving blob object
273
- function convertToWav ( soundFile ) {
274
- var leftChannel , rightChannel ;
275
- leftChannel = soundFile . buffer . getChannelData ( 0 ) ;
276
-
277
- // handle mono files
278
- if ( soundFile . buffer . numberOfChannels > 1 ) {
279
- rightChannel = soundFile . buffer . getChannelData ( 1 ) ;
280
- } else {
281
- rightChannel = leftChannel ;
282
- }
283
-
284
- var interleaved = interleave ( leftChannel , rightChannel ) ;
285
-
286
- // create the buffer and view to create the .WAV file
287
- var buffer = new window . ArrayBuffer ( 44 + interleaved . length * 2 ) ;
288
- var view = new window . DataView ( buffer ) ;
289
-
290
- // write the WAV container,
291
- // check spec at: https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
292
- // RIFF chunk descriptor
293
- writeUTFBytes ( view , 0 , 'RIFF' ) ;
294
- view . setUint32 ( 4 , 36 + interleaved . length * 2 , true ) ;
295
- writeUTFBytes ( view , 8 , 'WAVE' ) ;
296
- // FMT sub-chunk
297
- writeUTFBytes ( view , 12 , 'fmt ' ) ;
298
- view . setUint32 ( 16 , 16 , true ) ;
299
- view . setUint16 ( 20 , 1 , true ) ;
300
- // stereo (2 channels)
301
- view . setUint16 ( 22 , 2 , true ) ;
302
- view . setUint32 ( 24 , 44100 , true ) ;
303
- view . setUint32 ( 28 , 44100 * 4 , true ) ;
304
- view . setUint16 ( 32 , 4 , true ) ;
305
- view . setUint16 ( 34 , 16 , true ) ;
306
- // data sub-chunk
307
- writeUTFBytes ( view , 36 , 'data' ) ;
308
- view . setUint32 ( 40 , interleaved . length * 2 , true ) ;
309
-
310
- // write the PCM samples
311
- var lng = interleaved . length ;
312
- var index = 44 ;
313
- var volume = 1 ;
314
- for ( var i = 0 ; i < lng ; i ++ ) {
315
- view . setInt16 ( index , interleaved [ i ] * ( 0x7FFF * volume ) , true ) ;
316
- index += 2 ;
317
- }
318
-
319
- return view
320
- }
321
-
322
- // helper methods to save waves
323
- function interleave ( leftChannel , rightChannel ) {
324
- var length = leftChannel . length + rightChannel . length ;
325
- var result = new Float32Array ( length ) ;
326
-
327
- var inputIndex = 0 ;
328
-
329
- for ( var index = 0 ; index < length ; ) {
330
- result [ index ++ ] = leftChannel [ inputIndex ] ;
331
- result [ index ++ ] = rightChannel [ inputIndex ] ;
332
- inputIndex ++ ;
333
- }
334
- return result ;
335
- }
336
-
337
- function writeUTFBytes ( view , offset , string ) {
338
- var lng = string . length ;
339
- for ( var i = 0 ; i < lng ; i ++ ) {
340
- view . setUint8 ( offset + i , string . charCodeAt ( i ) ) ;
341
- }
342
- }
343
-
344
266
} ) ;
0 commit comments