The Checkbox Drum Machine ☑️☑️☑️☑️ ☑️☑️☑️☑
How do I make an the checkbox drum machine ☑️☑️☑️☑️ ☑️☑️☑️☑?
Using Web Audio API to create drum like sounds.Using Angular for the "sequencer".Kick and snare from Chris Lowi's article Synthesising Drum Sounds with the Web Audio API. Licensed under a Creative Commons Attribution 3.0 Unported license: http://creativecommons.org/licenses/by/3.0/. What is a the checkbox drum machine ☑️☑️☑️☑️ ☑️☑️☑️☑? How do you make a the checkbox drum machine ☑️☑️☑️☑️ ☑️☑️☑️☑? This script and codes were developed by Johan Karlsson on 26 July 2022, Tuesday.
The Checkbox Drum Machine ☑️☑️☑️☑️ ☑️☑️☑️☑ - Script Codes HTML Codes
<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>The Checkbox Drum Machine ☑️☑️☑️☑️ ☑️☑️☑️☑️</title> <link rel="stylesheet" href="css/style.css">
</head>
<body> <div ng-app="seq" id="app" > <div ng-controller="SeqController"> <button ng-click="start()" ng-disabled="running">Start</button> <button ng-click="stop()" ng-disabled="!running">Stop</button> {{tick}} <p> <span class="left"> Bass <select ng-options="type for type in oscTypes" ng-model="bassOscType"> </select> </span> <span class="grid" ng-repeat="b in bass.values track by $index" ng-class="{'current': tick === $index}"> <input type="checkbox" ng-model="bass.values[$index]"/> </span> <button ng-click="bass = clear()">Clear</button> M:<input type="checkbox" ng-model="muteList['bass']"/> S:<input type="checkbox" ng-checked="currentSoloTrack === 'bass'" ng-click="solo('bass')"/> </p> <p> <span class="left">Hat</span> <span class="grid" ng-repeat="hat in hats.values track by $index" ng-class="{'current': tick === $index}" > <input type="checkbox" ng-model="hats.values[$index]"/> </span> <button ng-click="hats = clear()">Clear</button> M:<input type="checkbox" ng-model="muteList['hat']"/> S:<input type="checkbox" ng-checked="currentSoloTrack === 'hat'" ng-click="solo('hat')"/> </p> <p> <span class="left">Claves</span> <span class="grid" ng-repeat="clave in claves.values track by $index" ng-class="{'current': tick === $index}" > <input type="checkbox" ng-model="claves.values[$index]" /> </span> <button ng-click="claves = clear()">Clear</button> M:<input type="checkbox" ng-model="muteList['claves']"/> S:<input type="checkbox" ng-checked="currentSoloTrack === 'claves'" ng-click="solo('claves')"/> </p> <p> <span class="left">Snare</span> <span class="grid" ng-repeat="snare in snares.values track by $index" ng-class="{'current': tick === $index}" > <input type="checkbox" ng-model="snares.values[$index]" /> </span> <button ng-click="snares = clear()">Clear</button> M:<input type="checkbox" ng-model="muteList['snare']"/> S:<input type="checkbox" ng-checked="currentSoloTrack === 'snare'" ng-click="solo('snare')"/> </p> <p> <span class="left">Kick <select ng-options="type for type in oscTypes" ng-model="kickOscType"> </select> </span> <span class="grid" ng-repeat="kick in kicks.values track by $index" ng-class="{'current': tick === $index}"> <input type="checkbox" ng-model="kicks.values[$index]"/> </span> <button ng-click="kicks = clear()">Clear</button> M:<input title="Mute" type="checkbox" ng-model="muteList['kick']"/> S:<input type="checkbox" ng-checked="currentSoloTrack === 'kick'" ng-click="solo('kick')"/> </p> <span class="left"> BPM <input type="number" ng-model="bpm" class="narrow" min="1" max="256"/> </span> Swing: <input type="checkbox" ng-checked="useSwing" ng-click="toggleSwing()" /> <button ng-click="clearAll()">Clear All</button> <button ng-click="random()">Random</button> <button ng-click="preset()">Preset</button> <button ng-click="openShare()">Share your beat!</button> <div id="dialog" ng-show="share" class="hidden"> <h1>Share it!</h1> <h4>This is a unique URL for the beat you have created:</h4> <span>http://codepen.io/DonKarlssonSan/pen/LGvryY?config={{url}}</span> <p> <button ng-click="closeShare()">OK</button> </p> </div> </div>
</div> <script src='http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js'></script> <script src="js/index.js"></script>
</body>
</html>
The Checkbox Drum Machine ☑️☑️☑️☑️ ☑️☑️☑️☑ - Script Codes CSS Codes
.left { float: left; width: 120px;
}
span { background: transparent; transition: background 0.3s ease;
}
span.current { background: black;
}
span.grid:nth-child(4n+6) { border-left: black 2px solid;
}
.narrow { width: 60px;
}
#app { position: relative;
}
#dialog { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 600px; background-color: rgba(255,255,255,0.8); border: 2px solid black; padding: 20px; border-radius: 10px;
}
/* This is to hide the div for CodePen previews. Not needed when using ng-show.
*/
.hidden { display: none;
}
The Checkbox Drum Machine ☑️☑️☑️☑️ ☑️☑️☑️☑ - Script Codes JS Codes
/* Johan Karlsson, DonKarlssonSan Kick and snare from Chris Lowi's article "Synthesising Drum Sounds with the Web Audio API": https://dev.opera.com/articles/drum-sounds-webaudio/ Licensed under a Creative Commons Attribution 3.0 Unported license: http://creativecommons.org/licenses/by/3.0/ Kick modified slightly, snare even more.
*/
angular.module("seq", [])
.controller("SeqController", ["$scope", "$interval", function($scope, $interval) { var size = 16; function BoolArray() { this.size = size; this.allFalse(); } BoolArray.prototype.initWithFunc = function (func) { this.values = Array.apply(null, Array(this.size)).map(func); } BoolArray.prototype.allTrue = function () { this.initWithFunc(function() { return true; }); } BoolArray.prototype.allFalse = function () { this.initWithFunc(function() { return false; }); } BoolArray.prototype.random = function () { this.initWithFunc(function() { return Math.random() > 0.5; }); } BoolArray.prototype.toHexString = function () { var chars = ""; var binaryString = ""; for(var i = 0; i < 16; i++) { binaryString += this.values[i] ? "1" : "0"; if(binaryString.length === 4) { chars += parseInt(binaryString, 2).toString(16); binaryString = ""; } } return chars; } BoolArray.prototype.fromHexString = function (hex) { var bit = 1; var decimal = parseInt(hex, 16); var boolArray = new Array(16); for(var i = 0; i < 16; i++) { var val = (decimal & bit) !== 0; boolArray[15-i] = val; bit = bit << 1; } this.values = boolArray; } $scope.url = ""; $scope.share = false; $scope.bpm = 114; $scope.useSwing = false; $scope.running = false; $scope.oscTypes = ["sine", "triangle", "sawtooth", "square"]; $scope.bassOscType = $scope.oscTypes[1]; $scope.kickOscType = $scope.oscTypes[3]; $scope.currentSoloTrack = undefined; $scope.muteList = {}; $scope.muteList["bass"] = false; $scope.muteList["hat"] = false; $scope.muteList["claves"] = false; $scope.muteList["snare"] = false; $scope.muteList["kick"] = false; $scope.solo = function (track) { if(track === $scope.currentSoloTrack) { // Already is solo for(var key in $scope.muteList) { $scope.muteList[key] = false; } $scope.currentSoloTrack = undefined; } else { $scope.currentSoloTrack = track; for(var key in $scope.muteList) { $scope.muteList[key] = key !== track; } } } $scope.preset = function () { // 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 $scope.bass.values = [false, false, true, false, false, false, true, false, false, false, true, false, false, false, true, false]; $scope.hats.values = [true, true, true, true, false, true, true, true, false, true, true, true, false, true, true, true]; $scope.claves.values = [true, false, false, true, false, false, true, false, false, false, true, false, true, false, false, false]; $scope.snares.values = [false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, true]; $scope.kicks.values = [true, false, false, false, true, false, false, false, true, false, false, true, false, false, true, false]; } $scope.bass = new BoolArray(); $scope.hats = new BoolArray(); $scope.claves = new BoolArray(); $scope.snares = new BoolArray(); $scope.kicks = new BoolArray(); $scope.random = function () { $scope.bass.random(); $scope.hats.random(); $scope.claves.random(); $scope.snares.random(); $scope.kicks.random(); } $scope.random(); setSwing(); // Possibly overwerite with track config given by query string initTracksFromQueryString(); $scope.clear = function () { return new BoolArray(); } $scope.clearAll = function () { $scope.bass.allFalse(); $scope.hats.allFalse(); $scope.claves.allFalse(); $scope.snares.allFalse(); $scope.kicks.allFalse(); } function createNoiseBuffer() { var buffer = context.createBuffer(1, 4096, context.sampleRate) var data = buffer.getChannelData(0); for (var i = 0; i < 4096; i++) { data[i] = Math.random() * 2 - 1; } return buffer; } var AudioContext = window.AudioContext || window.webkitAudioContext; var context = new AudioContext(); var masterGain = context.createGain(); masterGain.gain.value = 0.8; masterGain.connect(context.destination); var noise = context.createBufferSource() var buffer = createNoiseBuffer(); noise.buffer = buffer; noise.loop = true; var noiseGain = context.createGain(); noiseGain.gain.value = 0; noise.connect(noiseGain); noiseGain.connect(masterGain); noise.start(0); function Bass (context, destination) { this.context = context; this.destination = destination; this.duration = 0.15; } Bass.prototype.play = function(time) { var bassOsc = this.context.createOscillator(); bassOsc.frequency.value = 80; bassOsc.type = $scope.bassOscType; var bassGain = this.context.createGain(); bassGain.gain.value = 0.6; bassOsc.connect(bassGain); bassGain.connect(this.destination); bassGain.gain.linearRampToValueAtTime(0.01, time + this.duration); bassOsc.start(time); bassOsc.stop(time + this.duration); } var bass = new Bass(context, masterGain); function Kick (context, destination) { this.context = context; this.destination = destination; this.duration = 0.8; } Kick.prototype.play = function(time) { var kick = this.context.createOscillator(); kick.type = $scope.kickOscType; var kickGain = this.context.createGain(); kickGain.gain.value = 0; kick.connect(kickGain); kickGain.connect(this.destination); kick.frequency.setValueAtTime(140, time); kickGain.gain.setValueAtTime(0.4, time); kick.frequency.exponentialRampToValueAtTime(1, time + this.duration); kickGain.gain.exponentialRampToValueAtTime(0.00001, time + this.duration); kick.start(time); kick.stop(time + this.duration); } var kick = new Kick(context, masterGain); function Snare(context, destination) { this.context = context; this.destination = destination; this.duration = 1.5; }; Snare.prototype.setup = function() { this.noise = this.context.createBufferSource(); this.noise.buffer = buffer; var noiseFilter = this.context.createBiquadFilter(); noiseFilter.type = "bandpass"; noiseFilter.Q.value = 6; noiseFilter.frequency.value = 7000; this.noiseEnvelope = this.context.createGain(); this.noise.connect(noiseFilter); noiseFilter.connect(this.noiseEnvelope) this.noiseEnvelope.connect(this.destination); this.osc = this.context.createOscillator(); this.osc.type = "triangle"; this.oscEnvelope = this.context.createGain(); this.osc.connect(this.oscEnvelope); this.oscEnvelope.connect(this.destination); }; Snare.prototype.play = function(time) { this.setup(); this.noiseEnvelope.gain.setValueAtTime(1, time); this.noiseEnvelope.gain.exponentialRampToValueAtTime(0.1, time + 0.9); this.noise.start(time) this.osc.frequency.setValueAtTime(200, time); this.oscEnvelope.gain.setValueAtTime(0.6, time); this.oscEnvelope.gain.exponentialRampToValueAtTime(0.0001, time + 0.16); this.osc.start(time) this.osc.stop(time + this.duration); this.noise.stop(time + this.duration); }; snare = new Snare(context, masterGain); function Claves(context, destination) { this.context = context; this.destination = destination; this.duration = 0.5; }; Claves.prototype.setup = function() { this.osc = this.context.createOscillator(); this.osc.type = "triangle"; this.oscEnvelope = this.context.createGain(); this.osc.connect(this.oscEnvelope); this.oscEnvelope.connect(this.destination); }; Claves.prototype.play = function(time) { this.setup(); this.osc.frequency.setValueAtTime(1700, time); this.oscEnvelope.gain.exponentialRampToValueAtTime(0.5, time + 0.01); this.oscEnvelope.gain.exponentialRampToValueAtTime(0.0001, time + 0.08); this.osc.start(time) this.osc.stop(time + this.duration); }; var claves = new Claves(context, masterGain); var swing; function setSwing() { if($scope.useSwing) { swing = [1.2, 0.8]; } else { swing = [1, 1]; } } $scope.toggleSwing = function() { $scope.useSwing = !$scope.useSwing; setSwing(); } var tick = 0; $scope.tick = -1; function play() { $interval.cancel(interval); var now = context.currentTime; if($scope.hats.values[tick] && !$scope.muteList["hat"]) { noiseGain.gain.linearRampToValueAtTime(0.1, now + 0.021); noiseGain.gain.linearRampToValueAtTime(0, now + 0.13); } if($scope.bass.values[tick] && !$scope.muteList["bass"]) { bass.play(now); } if($scope.kicks.values[tick] && !$scope.muteList["kick"]) { kick.play(now); } if($scope.snares.values[tick] && !$scope.muteList["snare"]) { snare.play(now); } if($scope.claves.values[tick] && !$scope.muteList["claves"]) { claves.play(now); } tick = (tick+1) % 16; $scope.tick = ($scope.tick+1) % 16; setInterval(); } function setInterval() { // bpm 120, beats per minute // ms delay between: 60/120*1000/4 var delay = 60/$scope.bpm * 1000 / 4; delay *= swing[1-(tick % 2)]; interval = $interval(play, delay); } var interval; $scope.start = function () { $scope.running = true; setInterval(); } $scope.stop = function () { $scope.running = false; $interval.cancel(interval); } function initTracksFromQueryString() { var config = getQueryVariable("config"); if(config === undefined) { console.log("No values"); } else if(config.length !== 24 && config.length !== 25) { // 4 * 5 + 1 + 1 + 2 : OLD // 4 * 5 + 1 + 1 + 2 + 1 : NEW // For each track we need four hex digits, // we have five tracks. // Then comes one digit for bass wave type. // Then one digit for kick wave type. // Then two hex digits for BPM. // Then one for swing ** This is new ** console.log("Wrong length for config"); } else { // Split in chunks of four characters var trackConfigs = config.match(/.{4}/g); $scope.bass.fromHexString(trackConfigs[0]); $scope.hats.fromHexString(trackConfigs[1]); $scope.claves.fromHexString(trackConfigs[2]); $scope.snares.fromHexString(trackConfigs[3]); $scope.kicks.fromHexString(trackConfigs[4]); var bassType = parseInt(config[20]); var kickType = parseInt(config[21]); $scope.bassOscType = $scope.oscTypes[bassType]; $scope.kickOscType = $scope.oscTypes[kickType]; $scope.bpm = parseInt(config[22]+config[23], 16) + 1; if(config.length === 25) { $scope.useSwing = config[24] === "1"; } setSwing(); } } function getQueryVariable(variable) { var query = window.location.search.substring(1); var vars = query.split("&"); for (var i = 0; i < vars.length; i++) { var pair = vars[i].split("="); if (pair[0] == variable) { return pair[1]; } } } function createBeatString() { var url = ""; url += $scope.bass.toHexString(); url += $scope.hats.toHexString(); url += $scope.claves.toHexString(); url += $scope.snares.toHexString(); url += $scope.kicks.toHexString(); url += $scope.oscTypes.indexOf($scope.bassOscType); url += $scope.oscTypes.indexOf($scope.kickOscType); var bpm = ($scope.bpm - 1).toString(16); while (bpm.length < 2) bpm = "0" + bpm; // zero prefix url += bpm; url += $scope.useSwing ? "1" : "0"; return url; } $scope.openShare = function () { $scope.url = createBeatString(); $scope.share = true; document.getElementById("dialog").classList.remove("hidden"); } $scope.closeShare = function () { $scope.url = ""; $scope.share = false; }
}]);
Developer | Johan Karlsson |
Username | DonKarlssonSan |
Uploaded | July 26, 2022 |
Rating | 4.5 |
Size | 6,021 Kb |
Views | 36,432 |
Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!
Name | Size |
Apply Filter Effects to Music | 4,027 Kb |
Brownian Motion | 2,549 Kb |
The Rainbow Spirograph | 4,016 Kb |
Lissajous x Lissajous | 3,369 Kb |
Diffusion-Limited Aggregation - Line | 2,550 Kb |
SoundCloud Music Visualizer | 4,211 Kb |
Wayward Walker Worms | 3,123 Kb |
Text by Brownian Motion | 3,182 Kb |
IFS Fractal Christmas Tree | 6,537 Kb |
In Tribute to Simon Plouffe | 2,376 Kb |
Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!
Name | Username | Size |
Long Shadow Button | Uixcrazy | 3,550 Kb |
Css3 loader | Clknap | 2,391 Kb |
Tab panels | Accessibility | 0 Kb |
Impress JS Algorhytmic Generator | Jeffscottward | 7,906 Kb |
To Do List with Delete | Mattlbrody | 2,068 Kb |
A Pen by Anoop | Anoopjohn | 330,760 Kb |
Cool Page Split Effect | Anthonyadamski | 6,128 Kb |
CSS background-size - GSAP | Jonathan | 2,209 Kb |
Css or Czz.. | Judag | 4,111 Kb |
Blog demo to use given styling | Andygirl | 2,412 Kb |
Surf anonymously, prevent hackers from acquiring your IP address, send anonymous email, and encrypt your Internet connection. High speed, ultra secure, and easy to use. Instant setup. Hide Your IP Now!