#DoubleFail

The ‘Loopster’ failure

Planning

This week I tried to to build a project that originally simple to me. I wanted to build Loopster – a web app that will allow users to record short samples of music, save them, and use loop them to create a musical piece. I wanted Loopster to allow users to share their loops publicly, and to use loops by other users. Sort of the GitHub for music making.

So the goals were:

  • To build a web application that will allow users to record live stream (basically an analog stream).The recording could be done using the laptop microphone or the laptop input jack.
  • To allow users to trim their loops (or to try to detect the beats and to do it automatically).
  • To allow users to put some loops, which were created by them or by others, on a sequencer, and to enjoy them all together.

Bottom line:  Almost none of than happened.

Failing

I decided to use Web Audio API to implement the main functionality of the app. The Web Audio APIs are a little complicated, and it took my about 1-2 hours to be able to record sound through the laptop microphone.

Anything beyond that, just failed to work.
I spent another 8-10 hours trying to gain some progress on this project, but nothing seems to work anywhere near my expectations.

Eventually, the only thing that this app can do, is to open the laptop microphone, and play what it goes through it (which cause an immediate feedback..).

#fail
#fail

This is the (complicated) code for this (simple) interaction:
For some reason, WordPress took my html code too literaly

var AudioContext = window.AudioContext || window.webkitAudioContext; //cross browser compatibility
var myAudio = new AudioContext();
var record;

// get user's audio as an inputPoint
navigator.getUserMedia = (navigator.getUserMedia ||
                          navigator.webkitGetUserMedia ||
                          navigator.mozGetUserMedia ||
                          navigator.msGetUserMedia);

// audio nodes
var gain = myAudio.createGain();
gain.gain.value = 0;

// connecting the nodes
if (navigator.getUserMedia) {
   console.log('getUserMedia supported.');
   navigator.getUserMedia (
      {
         audio: true,
      },

      // Success callback
      function(stream){
        showButtons();
        play(stream);
        recordInput(stream);
      },

      // Error callback
      function(err) {
         console.log('The following gUM error occured: ' + err);
      }
   );
} else {
   console.log('getUserMedia not supported on your browser!');
}

function showButtons(){
  $("body").append('');
  $("body").append('');
  buttonEvents();
}

function play(stream) {
  var source = myAudio.createMediaStreamSource(stream);
  source.connect(gain);
  gain.connect(myAudio.destination);
}

// start recording
function recordInput(stream){
  record = new MediaRecorder(stream);
  record.start();
  console.log(record.state);
}

function buttonEvents() {
  console.log('callback worked');
  $("#play").click(function(){
    gain.gain.value = 0.5;
    console.log('click on play');
  });

  $("#stop").click(function(){
    gain.gain.value = 0;
    console.log('click on stop');
  });
}

// stop recording
$(window).keypress(function(key) {
  if ((key.keyCode === 32) && (record.state == 'recording')){
    console.log('Space pressed -- stopping recording process');
    record.pause();
    // record.exportWAV( doneEncoding );
    record.stop();
    console.log(record.state);
  }
});

You can try to use it using this link, but Chrome (and I’m sure that this is relevant to any other browser) doesn’t allow any web app to open the microphone if the app’s files are not being served using a secured connection.

#DoubleFail
#DoubleFail

If you still want to see it happening, you can go to the project page on GitHub, download the files, and open index.html on your beloved browser.

Learning (at least trying to..)

Ok, some lessons from this unpleasant experience:

  • I chose the wrong tools. Web Audio API is definitely a wonderful API, but learning it was not the purpose of this project. P5.js, for example, could do most of the things I wanted to do. Also, using P5.js could get be pretty fast to the stage where I can experiment with the app and test the overall experience, the design of the interaction, and so on, which to me, are way more interesting.
  • I must find ideas that I’m more passionate about. The idea behind Loopster is nice, but not nice enough. A ‘nice enough’ idea would have got me to get rid of all the complications and to build it as fast as possible.
    On the Loopster case, the only passion I found was in learning new API or to experiment with new tools. But to me, the tools are not the story.

I hope I’ll do better next time :\

Published by

Dror Ayalon

@drorayalon

Leave a Reply

Your email address will not be published. Required fields are marked *