Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

playbackRate on AUDIO and pitch

Little bit of background:
People like games.
People use the internet.
The internet needs games.
Games use sound.
HTML5 has <audio>.

Okay, all good so far.

Recently I discovered - to my surprise - that IE9 actually supports playbackRate. I eagerly gave it a try. Even more surprising, it actually worked. I tried the same in Chrome, and while it worked it was horribly grating when I set it to 0.5. I've already ditched Firefox because it doesn't support MP3.

Moving on, here's my question: both IE and Chrome apply pitch correction when changing the playbackRate. IE does a great job, Chrome does a horrible one. Either way, I don't want this, I want the sounds to change pitch. With that kind of power I can delete 650 files I had to procedurally generate to have an alternate pitch, and will have far more freedom with my projects. Heck, I could even make a MOD track player in HTML5 (minus the Effects channel) if I really wanted to.

So, is there anything in the HTML5 specification that allows me to turn pitch correction off, and just have the sound be played as if the samples had literally been stretched apart of squeezed together?

like image 226
Niet the Dark Absol Avatar asked Jan 25 '12 04:01

Niet the Dark Absol


People also ask

What is audio playback rate?

playbackRate property sets the rate at which the media is being played back. This is used to implement user controls for fast forward, slow motion, and so forth. The normal playback rate is multiplied by this value to obtain the current rate, so a value of 1.0 indicates normal speed.

What is play back rate?

Play rate is a ratio that calculates the number of plays your video ad receives divided by its impressions (the number of times your video ad is shown).


2 Answers

From the Mozilla bug tracker issue on implementing playbackRate

WebKit solves this by exporting an additional (prefixed) attribute "preservesPitch" (proposed to the WhatWG here: http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2009-July/021100.html)

Presumably you can set preservesPitch (webkitPreservesPitch for webkit) to false to turn off this feature in Webkit at least. I'm not familiar with other browser support for this property.

like image 112
bcoughlan Avatar answered Oct 01 '22 00:10

bcoughlan


Chrome currently supports the Web Audio API ( http://www.w3.org/TR/webaudio/ ) which has a playbackRate audioParam that you can set. It's not as simple as the <audio> tag, but allows for all sorts of cool stuff. I'm currently using it to play with pitch-shifting / time-stretching distortion.

Here's an example of what you could do:

    //build a request and fire it off
    speedChanger.loader = (function(){

      var _request       = new XMLHttpRequest(),

          _handleRequest = function(url){
            _request.open('GET',url,true);
            _request.responseType = 'arraybuffer';
            _request.onload = function(){
              SpeedChanger.audioGraph.context.decodeAudioData(_request.response, function(buffer){
                _loadedBuffer = buffer;
                SpeedChanger.audioGraph.setBuffer(buffer);
                SpeedChanger.audioGraph.setBufferCache(buffer);

              },function(){//error stuff});
            };
            _request.send();
          };

      _handleRequest("audio/file.mp3");

  }());//loader

  grainTable.audioGraph = (function(){
    var _context = new webkitAudioContext(),         //this is the container for your entire audio graph
        _source = _context.createBufferSource(),     //your buffer will sit here
        _bufferCache,                                //buffer needs to be re-initialized before every play, so we'll cache what we've loaded here

        //for chaching / retrieving the buffer
        _getBufferCache = function(){
          return _bufferCache;  
        },
        _setBufferCache = function(_sound){
          _bufferCache = _sound;
        },

        //for setting the current instance of the buffer 
        _setBuffer = function(_sound){
          _source.buffer = _sound;
        },

        _setPlaybackRate = function(rate){
          _source.playbackRate.value = rate;
        },

        _setRate = function(myRate){
            _rate = myRate;
        }

        //play it
        _playSound = function(){

          _source.noteOff(0);                       //call noteOff to stop any instance already playing before we play ours

          _source = _context.createBufferSource();  //init the source
          _setBuffer(_bufferCache);                 //re-set the buffer

          _setPlaybackRate(_rate);                  //here's your playBackRate check

          _source.connect(_context.destination);    //connect to the speakers 
          _source.noteOn(0);                        //pass in 0 to play immediately
        },

}

    return{

      context        :_context,
      setBuffer      :_setBuffer,
      setBufferCache :_setBufferCache,
      playSound      :_playSound,
      setRate        :_setRate

    }

  }());//audioGraph
like image 23
joeLepper Avatar answered Oct 01 '22 01:10

joeLepper