]> git.0d.be Git - nanofun.git/blobdiff - nanofun.js
use nanokontrol solo buttons for looping samples
[nanofun.git] / nanofun.js
index 3fd7203ae2a86a4c8bf013364d71b9258e72edc6..b3b58ac9faf9edbe385d55aa6a8af555d56f8412 100644 (file)
@@ -296,6 +296,7 @@ var nanofun = function() {
   self.initAudio = function() {
     self.sample_buffers = Array(16);
     self.samples = Array(16);
+    self.sample_start_times = Array(16);
     self.audioCtx = new window.AudioContext();
     self.touchGainNodes = Array(16);
     self.masterGainNode = self.audioCtx.createGain();
@@ -350,6 +351,7 @@ var nanofun = function() {
           var sample_idx = this.sample_idx;
           self.audioCtx.decodeAudioData(this.result, function(buffer) {
             sample_buffers[sample_idx] = buffer;
+            $nanotouch.find('span.duration').data('duration', buffer.duration);
             $nanotouch.find('span.duration').text(parseInt(buffer.duration) + 's');
             $nanotouch.removeClass('error').addClass('loaded');
           }, function(e) {
@@ -370,6 +372,19 @@ var nanofun = function() {
 
     midi.onControlChange = function(port, data, control, value) {
       if (control > 7 && control < 16) return; /* range between sliders and pots */
+      if (control >= 32 && control < 40) { /* "S" buttons */
+          var nanotouch = $('.nanotouch')[control-32];
+          if (value == 127) {
+            var checked = $(nanotouch).find('.loop input').prop('checked');
+            if (checked) {
+              $(nanotouch).find('.loop input').prop('checked', false);
+              device("nanoKONTROL2 MIDI 1").cc(control, 0);
+            } else {
+              $(nanotouch).find('.loop input').prop('checked', true);
+              device("nanoKONTROL2 MIDI 1").cc(control, 127);
+            }
+          }
+      }
       if (control > 23) return; /* after pots */
       if (control < 8) {
         control += 8; /* sliders, control bottom pads (8-15) */
@@ -414,6 +429,20 @@ var nanofun = function() {
       var touchIdx = parseInt($(this).parent().data('touch'));
       self.touchGainNodes[touchIdx].gain.value = fraction * fraction;
     });
+
+    self.time_interval_id = setInterval(function() {
+      for (var i=0; i<16; i++) {
+        var sample = self.samples[i];
+        if (sample !== undefined) {
+          var start_time = self.sample_start_times[i];
+          var current_position = sample.context.currentTime - start_time;
+          var nanotouch = $('.nanotouch')[i];
+          var duration = $(nanotouch).find('span.duration');
+          var total_duration = parseFloat($(duration).data('duration'))
+          $(duration).text(parseInt(total_duration - current_position) + 's');
+        }
+     }
+    }, 250);
   }
 
   self.startSample = function(sample_idx) {
@@ -427,14 +456,17 @@ var nanofun = function() {
         var sample = self.audioCtx.createBufferSource();
         var gainNode = self.touchGainNodes[sample_idx];
         self.samples[sample_idx] = sample;
-        sample.loop = false;
+        sample.loop = ($(nanotouch).find('.loop input:checked').length == 1);
         sample.connect(gainNode);
         sample.buffer = sample_buffer;
         sample.onended = function() {
           $(nanotouch).removeClass('playing');
+          var duration = $(nanotouch).find('span.duration');
+          $(duration).text(parseInt($(duration).data('duration')) + 's');
           self.samples[sample_idx] = undefined;
         }
         $(nanotouch).addClass('playing');
+        self.sample_start_times[sample_idx] = sample.context.currentTime;
         sample.start(0);
       }
     }