Search code examples
angularjsweb-audio-api

How do I load an AudioBuffer with Angular $http?


I am getting started with the Web Audio Api to experiment a little with it wanted to see how best to work with it in AngularJS.

Other Web Audio stuff I have tried seems to work in Angular, such as creating a web audio sine wave etc, but I am just not sure of the best way to load audio in angular, if I then want to be able to manipulate it with the Web Audio API

I naively tried to put some functions directly into a AngularJS Controller which doesn't seem right - code below.

In the Chrome Dev Tools Network tab I can see the test.mp3 that should load notifies 'Failed to load response data'. However the path to the file is correct, and if I click on this in the dev tools the file opens up and starts playing.

Any help is greatly appreciated

// Controller and attempt to load audio
(function () {
'use strict';

angular
    .module('app')
    .controller('mvMainCtrl', mvMainCtrl);

mvMainCtrl.$inject = ['$resource', '$scope', '$http' ];

function mvMainCtrl($scope, $http, $resource) {


var ctx; //audio context 
var buf; //audio buffer 

//init the sound system 
function init() { 
  console.log("in init"); 
try { 
    ctx = new AudioContext(); 
    loadFile(); 
} catch(e) { 
    alert('you need webaudio support'); 
} 
} 


function loadFile() { 
  var req = new XMLHttpRequest(); 
  req.open("GET","/app/main/sounds/test.mp3",true); 
req.responseType = "arraybuffer"; 
req.onload = function() { 
    //decode the loaded data 
    ctx.decodeAudioData(req.response, function(buffer) { 
        buf = buffer; 
        play(); 
    }); 
}; 
req.send(); 
}


  loadFile();


 function playback() {
    var playSound = ctx.createBufferSource();
    playSound.buffer = buf;
    playSound.connect(ctx.destination);
    playSound.start(audioContext.currentTime);
 }


  playback();



 }
})();

Solution

  • I just had the same problem and after a couple of hours spent on this issue, I finaly found a way to get it work:

    Promise style:

    $http({
        method: 'GET',
        url: url,
        responseType: 'arraybuffer'
    }).then(function(response) {
        audioContext.decodeAudioData(response.data, function(buffer) {
            mainBuffer = buffer
        }, function(err) {
            console.log(err)
        })
    })
    

    Standard style:

    $http({
        method: 'GET',
        url: url,
        responseType: 'arraybuffer'         
    }).success(function(data) {
        audioContext.decodeAudioData(data, function(buffer) {
            mainBuffer = buffer
        }, function(err) {
            console.log(err)
        })
    })
    

    With XMLHttpRequest(), the file was corrupt, and the responseType attribut should be specified as arraybuffer.