36: 8, 38: 9, 40: 10, 42: 11, 44: 12, 46: 13, 48: 14, 50: 15
};
+/* on French/Belgian keyboards, emulate pad touches with keypresses */
+var KEYBOARD_CODES = Array('a', 'z', 'e', 'r', 't', 'u', 'i', 'o',
+ 'q', 's', 'd', 'f', 'g', 'h', 'j', 'k');
+
var midi = {
onMIDISuccess: function(midiAccess) {
return this;
};
-$(function() {
- var $nanopad = $('#nanopad');
- var sample_buffers = Array(16);
- var samples = Array(16);
- var audioCtx = new window.AudioContext();
- var gainNode = audioCtx.createGain();
- gainNode.connect(audioCtx.destination);
-
- $('.nanotouch input').on('change', function(ev) {
- var nanotouch = $(this).parent();
- var sample_idx = $nanopad.children().index(nanotouch);
- var reader = new FileReader();
- reader.onload = function(e) {
- audioCtx.decodeAudioData(this.result, function(buffer) {
- sample_buffers[sample_idx] = buffer;
- $(nanotouch).find('span.duration').text(parseInt(buffer.duration) + 's');
- $(nanotouch).removeClass('error').addClass('loaded');
- }, function(e) {
- $(nanotouch).find('span').text('');
- $(nanotouch).removeClass('loaded').addClass('error');
- });
+var nanofun = function() {
+ var self = this;
+
+ self.initAudio = function() {
+ self.sample_buffers = Array(16);
+ self.samples = Array(16);
+ self.audioCtx = new window.AudioContext();
+ self.gainNode = self.audioCtx.createGain();
+ self.gainNode.connect(self.audioCtx.destination);
+ }
+
+ self.initMIDI = function() {
+ if (navigator.requestMIDIAccess) {
+ navigator.requestMIDIAccess({sysex: true}).then(
+ function(midiAccess) { midi.onMIDISuccess(midiAccess); },
+ function(e) { midi.onMIDIFailure(e); }
+ );
+ }
+ }
+
+ self.initUI = function() {
+ var $nanopad = $('#nanopad');
+
+ $('.nanotouch input').on('change', function(ev) {
+ var nanotouch = $(this).parent();
+ var sample_idx = $nanopad.children().index(nanotouch);
+ var reader = new FileReader();
+ reader.onload = function(e) {
+ self.audioCtx.decodeAudioData(this.result, function(buffer) {
+ sample_buffers[sample_idx] = buffer;
+ $(nanotouch).find('span.duration').text(parseInt(buffer.duration) + 's');
+ $(nanotouch).removeClass('error').addClass('loaded');
+ }, function(e) {
+ $(nanotouch).find('span').text('');
+ $(nanotouch).removeClass('loaded').addClass('error');
+ });
+ }
+ reader.readAsArrayBuffer(this.files[0]);
+ $(nanotouch).find('span.name').text(this.files[0].name);
+ });
+
+ midi.onTouchOn = function(port, data, sample_idx) {
+ self.startSample(sample_idx);
}
- reader.readAsArrayBuffer(this.files[0]);
- $(nanotouch).find('span.name').text(this.files[0].name);
- });
- midi.onTouchOn = function(port, data, sample_idx) {
- var sample_buffer = sample_buffers[sample_idx];
+ $(document).keypress(function(ev) {
+ var sample_idx = KEYBOARD_CODES.indexOf(ev.key);
+ if (sample_idx != -1) {
+ self.startSample(sample_idx);
+ }
+ });
+ }
+
+ self.startSample = function(sample_idx) {
+ var sample_buffer = self.sample_buffers[sample_idx];
var nanotouch = $('.nanotouch')[sample_idx];
if (typeof(sample_buffer) != 'undefined') {
- console.log(samples[sample_idx]);
if (typeof(samples[sample_idx]) != 'undefined' && samples[sample_idx].context.state == 'running') {
- samples[sample_idx].stop(0);
- samples[sample_idx] = undefined;
+ self.samples[sample_idx].stop(0);
+ self.samples[sample_idx] = undefined;
} else {
- var sample = audioCtx.createBufferSource();
- samples[sample_idx] = sample;
+ var sample = self.audioCtx.createBufferSource();
+ self.samples[sample_idx] = sample;
sample.loop = false;
sample.connect(gainNode);
sample.buffer = sample_buffer;
sample.onended = function() {
console.log('ended');
$(nanotouch).removeClass('playing');
- samples[sample_idx] = undefined;
+ self.samples[sample_idx] = undefined;
}
$(nanotouch).addClass('playing');
sample.start(0);
}
}
- if (navigator.requestMIDIAccess) {
- navigator.requestMIDIAccess({
- sysex: true
- }).then(
- function(midiAccess) { midi.onMIDISuccess(midiAccess); },
- function(e) { midi.onMIDIFailure(e); }
- );
- }
+ self.initAudio();
+ self.initMIDI();
+ self.initUI();
+
+}
-});
+$(function() { nanofun(); });