css Audio - Active file-generic CSS - Active Generic - Active HTML - Active JS - Active SVG - Active Text - Active file-generic Video - Active header Love html icon-new-collection icon-person icon-team numbered-list123 pop-out spinner split-screen star tv

Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

            
              #preloader
 %h1 Loading
#container
 #drawer
  %form#samples
   %input{ :type => "text", :value => "https://dl.dropboxusercontent.com/u/87705298/sounds/kick.wav" }  
   %input{ :type => "text", :value => "https://dl.dropboxusercontent.com/u/87705298/sounds/snare.wav" }
   %input{ :type => "text", :value => "https://dl.dropboxusercontent.com/u/87705298/sounds/hihat.wav" }
   %input{ :type => "text", :value => "https://dl.dropboxusercontent.com/u/87705298/sounds/ssynth1.wav" }
   %input{ :type => "text", :value => "https://dl.dropboxusercontent.com/u/87705298/sounds/ssynth2.wav" }
   %input{ :type => "text", :value => "https://dl.dropboxusercontent.com/u/87705298/sounds/ssynth3.wav" }
   %input{ :type => "text", :value => "https://dl.dropboxusercontent.com/u/87705298/sounds/synth1.wav" }
   %input{ :type => "text", :value => "https://dl.dropboxusercontent.com/u/87705298/sounds/synth2.wav" }
   %input{ :type => "text", :value => "https://dl.dropboxusercontent.com/u/87705298/sounds/6.wav" }
 #panel
  - (0...16).each do |led|
   .led
  #sequencer
   - (0...9).each do |instrument|
    %div{ :class => "row", :instrument => instrument }
     - (0...17).each do |note|
      - if note < 16
       .note
      - else
       %input.knob.sample-volume-knob{ :type => "text", "data-height" => 25, "data-width" => 25, "data-angleArc" => 260, "data-angleOffset" => -130, "data-fgColor" => '#0af', "data-bgColor" => "#6e6e6e", "data-displayInput" => "false", "value" => 50, "data-thickness" => 0.6  }
  #controls
   - ['#0af', '#0fa', '#fa0'].each do |color|
    - (0...17).each do |i|
     - if i < 16
      %input.knob{ :type => "text", "data-height" => 25, "data-width" => 25, "data-note" => i, "data-angleArc" => 260, "data-angleOffset" => -130, "data-fgColor" => color, "data-bgColor" => "#6e6e6e", "data-displayInput" => "false", "value" => 50, "data-thickness" => 0.6 }
     - else
      %br
  #masters
   .button-group
    %button#saveBtn
     Save
    %button#loadBtn
     Load
   .button-group
    %button#pausePlayBtn
     Pause/Play
    %button#resetBtn
     Reset
   .knob-group
    %input.master#master-volume{ :type => "text", "data-fgColor" => '#0af', "data-bgColor" => "#6e6e6e", "data-height" => 80, "data-width" => 80, "data-angleArc" => 260, "data-angleOffset" => -130, :value => 50, :control => "volume" }
    %input.master#master-sustain{ :type => "text", "data-fgColor" => '#0fa', "data-bgColor" => "#6e6e6e", "data-height" => 80, "data-width" => 80, "data-angleArc" => 260, "data-angleOffset" => -130, :value => 50, :control => "sustain" }
    %input.master#master-pitch{ :type => "text", "data-fgColor" => '#fa0', "data-bgColor" => "#6e6e6e", "data-height" => 80, "data-width" => 80, "data-angleArc" => 260, "data-angleOffset" => -130, :value => 50, :control => "pitch" }
   
#howto
 %p Designed to work in Webkit (chrome) browsers, some things are funky in firefox.
 %p
  %a{ :href => "https://www.youtube.com/watch?v=od4GjF5g5V0" }Demo
 %p In order to start making some tunes, turn on some of those square lights on the top of the sequencer. You can change what tunes these magical tune-lights play by clicking the little gray bar on the left of the sequencer, and pasting in URLs to your favorite .WAV files (Or any suitable sound file I suppose).
 %p Great! Definintely the world's next Skrillex in the making.
 %p Want to make your tunes better? Start playing with the little knobbies. The blue ones adjust the volume, the green ones adjust the tempo, the orange ones adjust the pitch. The little knobs adjust said functions on a note-by-note basis, the big ones adjust said functions on a song-wide level.
 %p The first 3 red rows are reserved for drum samples, and therefor are unaffected by the orange pitch knob.
 %p The next 3 green rows are reserved for melodies and things that are going to get heavily modified by the pitch (orange) knob
 %p The final 3 blue rows are like the drum rows in that they are not affected by the pitch control, but they are also not affected by the note-by-note volume control (the sample-by-sample volume control still works, however)
 %p
  %a{ :href => "mattroelle.com" } By: Matt roelle | mattroelle.com
            
          
!
            
              $bg-color: #4e4e4e
$side-color: #3b3b3b
$note-colors: #c77 #b66 #a55 #7c7 #6b6 #5a5 #77c #66b #55a

@import url(https://fonts.googleapis.com/css?family=Open+Sans)

/* Mixins */
=keyframes($name)
  @keyframes #{$name}
    @content
  @-webkit-keyframes #{$name}
    @content
  @-moz-keyframes #{$name}
    @content

=transform($a)
  transform: $a
  -webkit-transform: $a
  -moz-transform: $a
  
=animation($a)
  animation: $a
  -webkit-animation: $a
  -moz-animation: $a
  
body
  background-color: #1e1e1e
  perspective: 1000
  -webkit-perspective: 1000
  -moz-perspective: 1000
  -webkit-touch-callout: none
  -webkit-user-select: none
  -khtml-user-select: none
  -moz-user-select: none
  -ms-user-select: none
  user-select: none
  
#container
  width: 499px
  margin: 50px auto
  position: relative
  border-radius: 4px
  display: none
    
#drawer
  position: absolute
  left: -2px
  top: 10px
  width: 260px
  border-radius: 3px
  background-color: darken($bg-color, 10%)
  text-align: center
  z-index: 10
  transition: all 0.5s ease-in-out
#drawer:before
  content: " "
  display: block
  width: 6px
  cursor: pointer
  position: absolute
  border-top-left-radius: 6px
  border-bottom-left-radius: 6px
  z-index: 10
  left: -5px
  height: 278px
  background-color: lighten($bg-color, 20%)

#drawer.active
  +transform(translateX(-255px))
    
#samples input
  border-radius: 2px
  outline: none
  border: none
  padding-left: 2px
  padding-right: 2px
  padding-top: 3px
  padding-bottom: 3px
  display: block
  width: 92%
  z-index: 50
  position: relative
  margin: 8px auto
  background-color: #444
  color: #cfcfcf
  
#panel
  width: 100%
  height: 100%
  position: relative
  z-index: 100
  background-color: $bg-color
  border-radius: 8px
  text-align: center
  border-left: 3px solid $side-color
  border-right: 3px solid $side-color
  border-bottom: 5px solid $side-color
    
#panel:after
  content: " "
  clear: both
  display: block
  
.led
  position: relative
  left: -15px
  width: 23px
  margin-left: 1px
  margin-right: 1px
  background-color: #aaa
  height: 4px
  display: inline-block
.led.active
  background-color: #3e3
  box-shadow: 0px 0px 10px #3e3

.note
  display: inline-block
  width: 25px
  height: 25px
  cursor: pointer
  border-radius: 2px
    
$i: 1
@each $color in $note-colors
  #sequencer > .row:nth-of-type(#{$i}) > .note
    background-color: darken($color, 30%)
    box-shadow: 0px 0px 2px darken($color, 30%)
  #sequencer > .row:nth-of-type(#{$i}) > .note:hover
    background-color: darken($color, 15%)
    box-shadow: 0px 0px 3px darken($color, 15%)
  #sequencer > .row:nth-of-type(#{$i}) > .note.active
    background-color: $color
    box-shadow: 0px 0px 4px $color
  $i: $i + 1
  
#controls
  text-align: left
  padding-left: 5px
    
#howto
  margin: 50px auto
  width: 480px
  background-color: #111
  padding: 8px
  box-sizing: border-box
  -webkit-box-sizing: border-box
  -moz-box-sizing: border-box
    
p, a
  font-family: "Open Sans", serif
  color: white
  font-size: 14px
  
.small
  font-size: 11px
  margin-top: 2px
  margin-bottom: 2px
  line-height: 1em
  
.knob-group
  float: right
  margin-right: 32px
  
.button-group
  display: inline-block
  float: left
  margin-left: 6px
  margin-top: 2px

.button-group button
  display: block
  text-align: center
  width: 90px
  font-family: 'Open Sans', serif
  outline: none
  border: none
  border-radius: 3px
  padding-top: 5px
  padding-bottom: 5px
  color: #eee
  background-color: #c44
  margin-top: 4px
  margin-bottom: 4px
  cursor: pointer  
            
          
!
            
              // Matthew Roelle 2014
// HTML/CSS/JS Sequencer, Bro

// Shoutout to the jQuery Knob plugin, it's used here for all the knobby UI
// https://github.com/aterrien/jQuery-Knob

$(document).ready(function() {
  // ===== Pause/Play state
  var playState = true;
  
  // ===== requestAnimationFrame browser check-a-roonie
  window.requestAnimationFrame = window.requestAnimationFrame || 	 
                                 window.mozRequestAnimationFrame ||
                                 window.webkitRequestAnimationFrame || 
                                 window.msRequestAnimationFrame;
  
  // ===== Web Audio context browser check-a-roonie
  var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
  
  // ===== Keep track of the mouse state
  var mouseDown = false;
  $(window)
  .mousedown(function() { mouseDown = true; })
  .mouseup(function() { mouseDown = false; });
  
  // ===== Load the samples & reload if they change src
  function loadAudio() {
    var samples = [];
    $('#samples input').each(function(i) {
      var src = $(this).val();
      var req = new XMLHttpRequest();
      req.open('GET', src, true);
      req.responseType = 'arraybuffer';
      
      req.onload = function() {
        audioCtx.decodeAudioData(req.response, function(buffer) {
          samples[i] = buffer;
        });
      }
      req.send();
    });
    return samples;
  }
  var samples = loadAudio();
  $('#samples input').change(function() {
    samples = loadAudio();
  });

  // ===== toggle the little drawer with the sample URLs
  $('#drawer').click(function(e) {
    if (e.offsetX < 2) { $('#drawer').toggleClass('active'); }
  });

  // ===== Toggle the notes active state based on mouse events
  $('.note')
  .mousedown(function() { $(this).toggleClass('active') })
  .mouseenter(function() { if (mouseDown) { $(this).toggleClass('active')} });

  // ===== Initialize knob interfaces
  $('.knob').knob();
  
  // ===== Keep track of master controls
  var masterControls = {
    volume: 0.5,
    pitch: 0.5,
    sustain: 0.5
  };
  $('.master').knob({ 'change': function(v) {
    masterControls[$(this.$[0]).attr('control')] = v / 100;
  }});
 
  // ===== reset button
  $('#resetBtn').click(function() {
    $('.note').removeClass('active');
    $('#panel .knob, .master').val(50).trigger('change');
  })
  
  // ===== pause/play button
  $('#pausePlayBtn').click(function() {
    playState = !playState;
  })
  
  // ===== saving and loading
  $('#saveBtn').click(function() {
    var state = {};
    state['wavURLs'] = [];
    $('#samples input').each(function() {
      state['wavURLs'].push($(this).val());
    });
    
    state['rows'] = [];
    $('#sequencer .row').each(function() {
      var row = [];
      $(this).children().each(function() {
        if ($(this).hasClass('active')) {
          row.push(1);
        } else {
        	row.push(0);                      
        }
      });
      state['rows'].push(row);
    });
    
    state['knobs'] = [];
    $('.knob').each(function() {
      state['knobs'].push($(this).val());
    });
    state['masters'] = [];
    $('.master').each(function() {
      state['masters'].push($(this).val());
    });
    
    prompt("Copy & Paste this to share", JSON.stringify(state));
  });
  function loadData(data) {
    data['rows'].forEach(function(row, i) {
      row.forEach(function(note, j) {
        if (note == 1) {
          $('#sequencer .row').eq(i).children('.note').eq(j).addClass('active');
        } else {
          $('#sequencer .row').eq(i).children('.note').eq(j).removeClass('active');
        }
      });
    });
    data['knobs'].forEach(function(val, i) {
      $('.knob').eq(i).val(val).trigger('change');
    });
    data['masters'].forEach(function(val, i) {
      $('.master').eq(i).val(val).trigger('change');
      if (i == 0) { masterControls['volume'] = Number(val) / 100; }
      if (i == 1) { masterControls['sustain'] = Number(val) / 100; }
      if (i == 2) { masterControls['pitch'] = Number(val) / 100; }
    });
  }
  $('#loadBtn').click(function() {
    var data = JSON.parse(prompt('Paste the track information', ''));
    loadData(data);
  });
  
  loadData({"wavURLs":["https://dl.dropboxusercontent.com/u/87705298/sounds/kick.wav","https://dl.dropboxusercontent.com/u/87705298/sounds/snare.wav","https://dl.dropboxusercontent.com/u/87705298/sounds/hihat.wav","https://dl.dropboxusercontent.com/u/87705298/sounds/ssynth1.wav","https://dl.dropboxusercontent.com/u/87705298/sounds/ssynth2.wav","https://dl.dropboxusercontent.com/u/87705298/sounds/ssynth3.wav","https://dl.dropboxusercontent.com/u/87705298/sounds/synth1.wav","https://dl.dropboxusercontent.com/u/87705298/sounds/synth2.wav","https://dl.dropboxusercontent.com/u/87705298/sounds/6.wav"],"rows":[[1,1,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0],[0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],[1,1,0,0,1,0,0,0,1,1,0,0,1,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],"knobs":["100","100","20","17","50","50","50","10","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","50","96","50","50","13","50","50","50","50","50","100","50","100","12","50","50"],"masters":["50","27","50"]});
  
  // ===== Sequence!
  function Sequence() {
    var i = 0,
        sequenced = false,
        $instruments = $('#sequencer > .row');
    
    function update() {
      if (playState) {
        if (i >= 16) { i = 0; }
        if (!sequenced) {
          $('.led').removeClass('active');
          $('.led').eq(i).addClass('active');
          sequenced = true;
          $instruments.each(function(j) {
            var note = $($(this).children()[i]),
                gain = audioCtx.createGain(),
                sample = samples[j];

            if (note.hasClass('active')) {
              //sample.play();
              var source = audioCtx.createBufferSource();
              try {
                if (j < 6) {
                  gain.gain.value = masterControls.volume * (Number($('#sequencer > .row').eq(j).children('*').children('input').val()) / 100) * (Number($('#controls > *').eq(i).children('input').val()) / 100);
                } else {
                  gain.gain.value = masterControls.volume * (Number($('#sequencer > .row').eq(j).children('*').children('input').val()) / 100);
                }
              } catch(e) {
                // Sometiems firefox just doesn't want to play nice...
                console.log('some things don\'t work right in firefox');
              }
              if (j > 2 && j < 6) {
               source.playbackRate.value = (0.5 - masterControls.pitch) + 1 - (0.5 - (Number($('#controls > *').eq(i + 34).children('input').val()) / 100));
              } else {
                source.playbackRate.value = (0.5 - masterControls.pitch) + 1;
              }
              source.playbackRate = 1;
              try {
                source.buffer = sample;
                source.connect(gain);
                gain.connect(audioCtx.destination);
                source.start(0);
              } catch(e) {
                // The URL for a sample was probably left blank
                console.log('please fill in all sample URLs');
              }
            }
          });
          setTimeout(function() {
            i++;
            sequenced = false;
          }, masterControls.sustain * 10 * 2 * (Number($('#controls > *').eq(i + 17).children('input').val())));
        }
      }
      requestAnimationFrame(update);
    }
    requestAnimationFrame(update);
  }
  Sequence();
});

$(window).load(function() { $('#preloader').hide(); $('#container').show(); });
            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.
Loading ..................

Console