Skip to content

Commit cb1d660

Browse files
committed
v0.9.6; added some convenience functions for audio file handling
1 parent 9ea58c1 commit cb1d660

File tree

3 files changed

+48
-8
lines changed

3 files changed

+48
-8
lines changed

src/sepia-web-audio.js

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ if (!(typeof SepiaFW == "object")){
33
}
44
(function (parentModule){
55
var WebAudio = parentModule.webAudio || {};
6-
WebAudio.version = "0.9.5";
6+
WebAudio.version = "0.9.6";
77

88
//Preparations
99
var AudioContext = window.AudioContext || window.webkitAudioContext;
@@ -907,7 +907,7 @@ if (!(typeof SepiaFW == "object")){
907907

908908
//MediaRecorder
909909
WebAudio.createAudioRecorder = function(stream, sourceInfo, recorderOptions){
910-
if (!recorderOptions) recorderOptions = {};
910+
if (!recorderOptions) recorderOptions = {}; //TODO: option 'decodeToAudioBuffer' is still experimental
911911
if (!recorderOptions.codec) recorderOptions.codec = "webm_ogg_opus";
912912
return new Promise(function(resolve, reject){
913913
(async function(){
@@ -948,7 +948,7 @@ if (!(typeof SepiaFW == "object")){
948948
mediaRecorder.onstop = function(e){
949949
//var blob = new Blob(chunks, {'type' : mimeType});
950950
//chunks = [];
951-
console.log("onstop", "state", mediaRecorder.state); //DEBUG TODO: remove
951+
//console.log("onstop", "state", mediaRecorder.state); //DEBUG
952952
if (onStop && !recorderOptions.decodeToAudioBuffer){
953953
onStop(); //TODO: we delay stop if we need to decode the blob first to keep original order
954954
}
@@ -958,7 +958,7 @@ if (!(typeof SepiaFW == "object")){
958958
//decode chunks
959959
if (onDataAvailable) mediaRecorder.ondataavailable = function(e){
960960
//catch last 'ondataavailable' and delay stop
961-
console.log("ondataavailable", "state", mediaRecorder.state); //DEBUG TODO: remove
961+
//console.log("ondataavailable", "state", mediaRecorder.state); //DEBUG
962962
if (mediaRecorder.state == "inactive") triggeredLastData = true;
963963
if (e && e.data){
964964
let startDecode = Date.now();
@@ -987,7 +987,7 @@ if (!(typeof SepiaFW == "object")){
987987
var stop = function(){
988988
if (stopTimer) clearTimeout(stopTimer);
989989
stoppedTS = Date.now();
990-
console.log("AudioRecorder state:", mediaRecorder.state); //DEBUG
990+
//console.log("AudioRecorder state:", mediaRecorder.state); //DEBUG
991991
if (mediaRecorder.state != "inactive") mediaRecorder.stop();
992992
};
993993
var start = function(){
@@ -1032,7 +1032,6 @@ if (!(typeof SepiaFW == "object")){
10321032
});
10331033
}
10341034
function blobToArray(blobData, callback){
1035-
console.log("blobData", blobData); //DEBUG
10361035
if (!blobData || !blobData.size){
10371036
callback();
10381037
}else if (typeof blobData.arrayBuffer == "function"){
@@ -1227,6 +1226,34 @@ if (!(typeof SepiaFW == "object")){
12271226
}
12281227
encoderWorker.postMessage({ctrl: {action: "construct", options: options}});
12291228
}
1229+
//Decode audio file to audio buffer
1230+
WebAudio.decodeAudioFile = function(fileUrl, sampleRate, channels, successCallback, errorCallback){
1231+
WebAudio.readFileAsBuffer(fileUrl, function(encodedArray){
1232+
var offlineAudioContext = new OfflineAudioContext(channels, encodedArray.byteLength, sampleRate);
1233+
offlineAudioContext.decodeAudioData(encodedArray, function(audioBuffer){
1234+
successCallback(audioBuffer);
1235+
}, function(err){
1236+
errorCallback(err);
1237+
});
1238+
}, function(err){
1239+
errorCallback(err);
1240+
});
1241+
}
1242+
//Decode audio file to audio buffer
1243+
WebAudio.decodeAudioFileToInt16Mono = function(fileUrl, sampleRate, successCallback, errorCallback){
1244+
var channels = 1;
1245+
WebAudio.decodeAudioFile(fileUrl, sampleRate, channels, function(audioBuffer){
1246+
var isFloat32 = true;
1247+
WebAudio.encodeWaveBuffer(audioBuffer.getChannelData(0), sampleRate, channels, isFloat32, function(res){
1248+
try {
1249+
var samplesInt16Mono = new Int16Array(res.wav.buffer);
1250+
successCallback(samplesInt16Mono);
1251+
}catch(err){
1252+
errorCallback(err);
1253+
}
1254+
}, errorCallback);
1255+
}, errorCallback);
1256+
}
12301257

12311258
//WASM resampler
12321259
WebAudio.resampleBufferViaSpeex = function(buffer, inputSampleRate, targetSampleRate, channels, quality, successCallback, errorCallback){
@@ -1339,6 +1366,19 @@ if (!(typeof SepiaFW == "object")){
13391366
}
13401367
}
13411368

1369+
//Add audio data as audio element to element on page (or body)
1370+
WebAudio.addAudioElementToPage = function(targetEle, audioData, audioType){
1371+
var audioEle = document.createElement("audio");
1372+
audioEle.src = window.URL.createObjectURL((audioData.constructor.name == "Blob")?
1373+
audioData : (new Blob([audioData], { type: (audioType || "audio/wav") })));
1374+
audioEle.setAttribute("controls", "controls");
1375+
var audioBox = document.createElement("div");
1376+
audioBox.appendChild(audioEle);
1377+
if (!targetEle) targetEle = document.body;
1378+
targetEle.appendChild(audioBox);
1379+
return audioEle;
1380+
}
1381+
13421382
//used to keep Promise structure, e.g.: Promise.resolve((optionalFun || noop)()).then(...)
13431383
function noop(){};
13441384

test.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ <h1>SEPIA Web Audio Processor</h1>
433433
targetSampleRate: targetSampleRate,
434434
//targetBufferSize: 512,
435435
modules: activeModules,
436-
destinationNode: undefined, //defaults to: audioContext.destination
436+
destinationNode: undefined, //defaults to: new "blind" destination (mic) or audioContext.destination (stream)
437437
startSuspended: true,
438438
debugLog: onDebugLog,
439439
customSourceTest: useWhiteNoiseTest,

test2.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ <h1>SEPIA Web Audio Processor</h1>
435435
targetSampleRate: targetSampleRate,
436436
//targetBufferSize: 512,
437437
modules: activeModules,
438-
destinationNode: undefined, //defaults to: audioContext.destination
438+
destinationNode: undefined, //defaults to: new "blind" destination (mic) or audioContext.destination (stream)
439439
startSuspended: true,
440440
debugLog: onDebugLog,
441441
customSourceTest: useWhiteNoiseTest,

0 commit comments

Comments
 (0)