├── README.md ├── makenoise.js └── makenoise.min.js /README.md: -------------------------------------------------------------------------------- 1 | # contributions-chiptune 2 | What does your contributions graph sound like? Find out with this script! It works iterating through the contributions graph one week at a time and assigning each day of the week a frequency based on its color value. The frequencies for the week are then overlayed and played by a Web Audio API oscillator, creating a neat chiptune. 3 | 4 | ##Hey there! Check out these cool hacks straight from the EmpireJS open source night! 5 | [Pat Needham](https://github.com/johnBartos/contributions-chiptune/tree/pat-version) - It sweeps, not beeps. Sounds great on sparse graphs 6 | 7 | ##How to use 8 | 1. Navigate to your git profile page and open up the dev console with f12 9 | 2. Paste [`makenoise.min.js`](https://raw.githubusercontent.com/johnBartos/contributions-chiptune/master/makenoise.min.js) (or non-min, if you're brave) into the console 10 | 3. Lower your volume a lil' bit 11 | 3. Press enter if you haven't already 12 | 13 | You can also change up the charasteristics of the chiptune via its function arguments found on the last line. 14 | 15 | `(audioContext, freq, delay, waveform)` 16 | - audioContext: Actually, you can't change this one 17 | - freq: The fundamental frequency. Higher number = higher pitch 18 | - delay: The time in `ms` between notes. Up is faster 19 | - waveform: The type of waveform oscillators generate. Proper values are `sine`, `square`, `sawtooth`, and `triangle` 20 | 21 | 22 | -------------------------------------------------------------------------------- /makenoise.js: -------------------------------------------------------------------------------- 1 | //#EEEEEE - 0 (min) 2 | //#D6E685 - 1 3 | //#8CC665 - 2 4 | //#44A340 - 3 5 | //#1E6823 - 4 (max) 6 | 7 | ((audioContext, freq, delay, waveform) => { 8 | 'use strict'; 9 | const levels = { '#eeeeee': freq, '#d6e685': freq * (3 / 2), '#8cc665': freq * (3 / 2) * 2, '#44a340': freq * (3 / 2) * 3, '#1e6823': freq * (3 / 2) * 4 }; 10 | 11 | const createOscillator = (fillNodeValue) => { 12 | const oscillator = audioContext.createOscillator(); 13 | const gainNode = audioContext.createGain(); 14 | gainNode.gain.value = 0.1; 15 | oscillator.type = waveform; 16 | oscillator.frequency.value = levels[fillNodeValue]; 17 | oscillator.connect(gainNode); 18 | gainNode.connect(audioContext.destination); 19 | 20 | return { 21 | start: () => oscillator.start(0), 22 | stop: () => oscillator.stop() 23 | }; 24 | }; 25 | 26 | const createNotes = (week) => { 27 | return week.map((day) => { 28 | const fillNodeValue = day.attributes.fill.nodeValue; 29 | const oscillator = createOscillator(fillNodeValue); 30 | 31 | return { 32 | play: () => { 33 | day.attributes.fill.nodeValue = 'red'; 34 | oscillator.start(); 35 | }, 36 | stop: () => { 37 | day.attributes.fill.nodeValue = fillNodeValue; 38 | oscillator.stop(); 39 | } 40 | }; 41 | }); 42 | }; 43 | 44 | const delayPlay = (noteBar) => { 45 | return (iter) => { 46 | setTimeout(() => { 47 | for (let note of noteBar) { 48 | note.play(); 49 | setTimeout(() => { 50 | note.stop(); 51 | }, delay / 2); 52 | } 53 | }, delay * iter); 54 | }; 55 | }; 56 | 57 | const noteBars = ([].slice.call(document.getElementsByTagName('g'))).slice(1).map((week) => { 58 | return createNotes([].slice.call(week.getElementsByClassName('day'))); 59 | }).map((day) => { 60 | return delayPlay(day); 61 | }); 62 | 63 | let i = 0; 64 | for (let noteBar of noteBars) { 65 | noteBar(i += 1); 66 | } 67 | })(new AudioContext, 440, 110, 'sawtooth'); 68 | -------------------------------------------------------------------------------- /makenoise.min.js: -------------------------------------------------------------------------------- 1 | ((audioContext,freq,delay,waveform)=>{"use strict";const levels={"#1e6823":freq*(3/2)*4,"#44a340":freq*(3/2)*3,"#8cc665":freq*(3/2)*2,"#d6e685":freq*(3/2),"#eeeeee":freq};const createOscillator=(fillNodeValue)=>{const oscillator=audioContext.createOscillator();const gainNode=audioContext.createGain();gainNode.gain.value=0.1;oscillator.type=waveform;oscillator.frequency.value=levels[fillNodeValue];oscillator.connect(gainNode);gainNode.connect(audioContext.destination);return{start:()=>oscillator.start(0),stop:()=>oscillator.stop()}};const createNotes=(week)=>{return week.map((day)=>{const fillNodeValue=day.attributes.fill.nodeValue;const oscillator=createOscillator(fillNodeValue);return{play:()=>{day.attributes.fill.nodeValue="red";oscillator.start()},stop:()=>{day.attributes.fill.nodeValue=fillNodeValue;oscillator.stop()}}})};const delayPlay=(noteBar)=>{return(iter)=>{setTimeout(()=>{for(let note of noteBar){note.play();setTimeout(()=>{note.stop()},delay/2)}},delay*iter)}};const noteBars=([].slice.call(document.getElementsByTagName("g"))).slice(1).map((week)=>{return createNotes([].slice.call(week.getElementsByClassName("day")))}).map((day)=>{return delayPlay(day)});let i=0;for(let noteBar of noteBars){noteBar(i+=1)}})(new AudioContext,440,110,"sawtooth"); 2 | --------------------------------------------------------------------------------