2

I am working on a synth with the Web audio API. Right now I am struggling to load the impulse response for a reverb into an arrayBuffer, so that I can use it with the audio context.

As I am working locally, I tried to simply read the file with the IR (located in the same folder as the index.html, under audio/IR/irHall.ogg) from the filesystem as I do in Ruby projects. Now I think to understand that this is not possible due to security issues when running Javascript code in the browser.

So I tried this approach that I found in a tutorial



function loadAudio( object, url) {

    var request = new XMLHttpRequest();
    request.open('GET', url, true);
    request.responseType = 'arraybuffer';

    request.onload = function() {
        context.decodeAudioData(request.response, function(buffer) {
            object.buffer = buffer;
        });
    }
    request.send();
}


In my app, when I call this function with url = 'audio/IR/irHall.ogg' it gives me this error':

dub-machine.js:63 XMLHttpRequest cannot load file:///Users/bla/projects/dub-machine/audio/IR/irHall.ogg. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.`

I am sorry If it comes across as if I didn't research a lot. Matter of fact I am googling around for a solution for hours and keep getting more confused.

Can someone give me an idea what is the best/common way to load a file from the project to use its content in a javascript context?

Thanks!

Flip
  • 6,233
  • 7
  • 46
  • 75
  • 1
    The browser considers all `file://` URLs to be from unknown domains as a security measure. If you run your code from a local web server, such that the domain for the main page and the domain for the file are the same (like, `http://localhost` or whatever) then the XHR should work. – Pointy Aug 04 '16 at 16:23
  • http://www.html5rocks.com/en/tutorials/file/dndfiles/ – PM 77-1 Aug 04 '16 at 16:24
  • @Pointy Are there alternatives to setting up a local webserver? this seems to be a lot of work just to be able to load a file. – Flip Aug 04 '16 at 16:44
  • If you're going to write code to work in a browser, then you're kind-of stuck with browser behaviors. There are many simple HTTP servers designed to server only static content. – Pointy Aug 04 '16 at 16:49
  • 1
    its trivial to launch a web server ... see details at https://stackoverflow.com/questions/10752055/cross-origin-requests-are-only-supported-for-http-error-when-loading-a-local/21608670#21608670 for example at a terminal cd into dir of files you need to serve and issue python -m SimpleHTTPServer then open up browser at url http://localhost:8000 – Scott Stensland Aug 05 '16 at 12:47

1 Answers1

0

I found that setting up a simple static http server with node wasn't that much trouble at all and works perfectly for me. I followed this tutorial over at Sitepoint by Ian Oxley and went for the Paperboy example.

Just create a node file e.g. paperboy-server.js and fill it with this code:



var paperboy = require('paperboy'),
    http = require('http'),
    path = require('path')

var webroot = "/localpath/to/your/project",
    port = 8080

http.createServer(function(req, res){
    var ip = req.connection.remoteAddress
    paperboy
    .deliver(webroot, req, res)
    .addHeader('X-Powered-By', 'Atari')
    .before(function() {
      console.log('Request received for ' + req.url);
    })
    .after(function(statusCode) {
      console.log(statusCode + ' - ' + req.url + ' ' + ip);
    })
    .error(function(statusCode, msg) {
      console.log([statusCode, msg, req.url, ip].join(' '));
      res.writeHead(statusCode, { 'Content-Type': 'text/plain' });
      res.end('Error [' + statusCode + ']');
    })
    .otherwise(function(err) {
      console.log([404, err, req.url, ip].join(' '));
      res.writeHead(404, { 'Content-Type': 'text/plain' });
      res.end('Error 404: File not found');
    });
}).listen(port);

console.log('paperboy on his round at http://localhost:' + port);


I just changed webroot to statically point to the directory in which I am working for convenience.

Then I just start the node script in a terminal with: node paperboy-server.js

In the browser, instead of serving from the file system with file:///.. I can now use localhost:8080 to access my app and loading files as shown in the OP works fine.

Flip
  • 6,233
  • 7
  • 46
  • 75