heliosdesign / helios-audio-mixer

Web Audio API mixer library
https://heliosdesign.github.io/helios-audio-mixer/demo
MIT License
60 stars 11 forks source link

BPM control #11

Closed nicolabortignon closed 8 years ago

nicolabortignon commented 8 years ago

Hi, I'd like to use this library and add extra control over the tracks bpm. Ideally what i want to do is detect the current tempo. Detect the rhythm pattern. Adjust the tempo (or just the bpm with a key tempo control) and play them one on the top of the other.

In other words exactly what a dj does.

Was wondering if you approached this problem before. I have a good understanding on how to implement the single features described above, but I'd like to hear your thoughts.

iainmcampbell commented 8 years ago

hi nicola! we've done parts of this this on a project we're working on at the moment. I haven’t built it into the library but it would be great to do so, ideally as an optional extension.

most of what we’ve done is just syncing the tracks. here’s our requestAnimationFrame function (paraphrased):

function sync(){
  masterTime.current = (new Date()/1000) - masterTime.start;

  if( (masterTime.current >= masterTime.duration) && playing ){

    // loop
    masterTime.start = (new Date()/1000)
    masterTime.current = 0

    for (var i = mix.tracks.length - 1; i >= 0; i--) {
      mix.tracks[i].currentTime(0)
    }

  } else {

    if( Math.abs(masterTime.current - mix.tracks[i].currentTime()) > 0.05 ){
      if(masterTime.current <= mix.tracks[i].duration()){
        mix.tracks[i].currentTime( masterTime.current );
      }
    }

  }

}

we're also doing a bit of beat tracking but it's all set up beforehand. we know the bpm and duration for the track, and we just display a visualization based on that. it’d be quite possible though to write some code to determine the bpm of a playing track using fft analysis.

nicolabortignon commented 8 years ago

Hi Iain, thanks for the answer.

I used to do bpm detection and track tempo/key manipulation AS3/Flash a while ago. I'm wondering if in javascript there is an equivalent of what in flash was the raw file in a bytearray representation.

If I manage to get that I can do bpm detection via a bpm autocorrelation algorithm. From there stretching the audio shouldn't be too hard (as long as the latency while processing is short enough)

iainmcampbell commented 8 years ago

nice! in javascript you can use an audio processor node to get the raw audio data (typically as a Uint8Array) as it plays. See createAnalyse() and getAnalysis() in track.js and the Analysis section in the readme. getByteFrequencyData() is the function that actually returns the FFT data. There’s probably another function that returns raw data without FFT if you want that; you'd have to look that up.

I imagine the latency while processing should be fine; in our experience the web audio API is very fast. We haven’t tried a lot of live effects though.