8bitgrizzle

It wasn’t my first computer (that was the Commodore VIC-20), but one of my favourites was the ZX Spectrum. Looking back now it is amazing to see just how much fun can be squeezed out of 64k.

I’ve been playing around with a revised version of my meow-meow feline rhythm machine (converting from Processing to p5.js), and got distracted. As an aside I programmed a little sketch which displays my name in the style of a ZX Spectrum font. This is then cycled through, with each pixel triggering an audio sample from the ZX Spectrum.

You can play around with the sequence by destroying my name(!), and create your own 8-bit sequences.

CLICK HERE TO LAUNCH 8BITGRIZZLE

Here’s the script, should you wish to develop your own…

// 8BITGRIZZLE
// Written by Matthew Greasley
// http://matthewgreasley.co.uk
//
// Developed from ideas by Mick Grierson, Matthew Yee-King & Marco Gillies

var playhead;
var numBeats;
var currentBeat;
var track1 = [];
var track2 = [];
var track3 = [];
var track4 = [];
var track5 = [];
var track6 = [];
var buttonWidth;
var buttonHeight;
var width;
var height;
var index;
var track;

function preload() {
soundFormats('mp3', 'ogg', 'wav');
sample1 = loadSound('../samples/fx08.wav');
sample2 = loadSound('../samples/fx13.wav');
sample3 = loadSound('../samples/fx03.wav');
sample4 = loadSound('../samples/fx04.wav');
sample5 = loadSound('../samples/fx07.wav');
sample6 = loadSound('../samples/fx06.wav');
}

function setup() {

frameRate(40);
createCanvas(800, 600);

numBeats = 107;
currentBeat = 0;
playhead = 0;
width = 800;
height = 600;
buttonWidth = width/numBeats;
buttonHeight = height/72;

track1 = [1,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,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,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
track2 = [1,1,0,0,1,1,0,0,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,1,0,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,0,0,0,0,0,0,1,1,1,1,0,0,1,0,0,0,0,1];
track3 = [1,0,1,1,0,1,0,0,0,0,0,0,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,0,0,1,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,1];
track4 = [1,0,0,0,0,1,0,0,1,1,1,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,1,1,1,1,1,1,0,1,0,0,0,0,1,0,0,0,0,1,0,0,1,1,1,0,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,0,0,0,1,0,0,0,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1];
track5 = [1,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,1,1,0,1,0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1];
track6 = [1,0,0,0,0,1,0,0,1,1,1,1,1,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,1,0,0,1,1,1,1,1,0,0,1,0,0,1,0,0,0,0,0,0,1,1,1,1,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,1,1,1,1,1,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1,0,0,1,1,1,1,0];
}

function draw() {

background(200);

// DRAW GRID 

stroke(200);
for (i = 0; i < 7; i++)
line(0, (i*height/72), width, (i*height/72));
for (i = 0; i < numBeats + 1; i++)
line(i*width/numBeats, 0, i*width/numBeats, (6*height/72));

// FILL GRID WITH DRUM HITS 

for (i = 0; i < numBeats; i++)
{
noStroke();
fill(127);
if (track1[i])
rect(i*buttonWidth, (0*buttonHeight), buttonWidth, buttonHeight);
if (track2[i])
rect(i*buttonWidth, (1*buttonHeight), buttonWidth, buttonHeight);
if (track3[i])
rect(i*buttonWidth, (2*buttonHeight), buttonWidth, buttonHeight);
if (track4[i])
rect(i*buttonWidth, (3*buttonHeight), buttonWidth, buttonHeight);
if (track5[i])
rect(i*buttonWidth, (4*buttonHeight), buttonWidth, buttonHeight);
if (track6[i])
rect(i*buttonWidth, (5*buttonHeight), buttonWidth, buttonHeight);
} 

// CYCLE THROUGH LOOP, PLAY SAMPLES 

playhead ++;
if(playhead % 4 == 0){

if (currentBeat >= numBeats)
currentBeat = 0; 


if (track1[currentBeat]) { // track1 wants to play on this beat
sample1.play();
} 
if (track2[currentBeat]) {
sample2.play();
} 
if (track3[currentBeat]) {
sample3.play();
} 
if (track4[currentBeat]) {
sample4.play();
}
if (track5[currentBeat]) {
sample5.play();
}
if (track6[currentBeat]) {
sample6.play();
}

currentBeat++; 
}

// HIGHLIGHT CURRENT BEAT IN SEQUENCE

fill(25);
rect((currentBeat-1)*buttonWidth, 0, buttonWidth, buttonHeight);
fill(255,0,2);
rect((currentBeat-1)*buttonWidth, buttonHeight, buttonWidth, buttonHeight);
fill(253,255,0);
rect((currentBeat-1)*buttonWidth, buttonHeight*2, buttonWidth, buttonHeight);
fill(0,255,3);
rect((currentBeat-1)*buttonWidth, buttonHeight*3, buttonWidth, buttonHeight);
fill(1,255,254);
rect((currentBeat-1)*buttonWidth, buttonHeight*4, buttonWidth, buttonHeight);
fill(0,0,255);
rect((currentBeat-1)*buttonWidth, buttonHeight*5, buttonWidth, buttonHeight);
}


function mouseClicked() {
index = Math.floor(mouseX*numBeats/width); 
track = Math.floor((mouseY)*(72/(height)));

if (track == 0)
track1[index] = !track1[index];
if (track == 1)
track2[index] = !track2[index];
if (track == 2)
track3[index] = !track3[index];
if (track == 3)
track4[index] = !track4[index];
if (track == 4)
track5[index] = !track5[index];
if (track == 5)
track6[index] = !track6[index];
return false;
}

function keyPressed(z) {

track1 = [1,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,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,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
track2 = [1,1,0,0,1,1,0,0,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,1,0,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,0,0,0,0,0,0,1,1,1,1,0,0,1,0,0,0,0,1];
track3 = [1,0,1,1,0,1,0,0,0,0,0,0,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,0,0,1,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,1];
track4 = [1,0,0,0,0,1,0,0,1,1,1,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,1,1,1,1,1,1,0,1,0,0,0,0,1,0,0,0,0,1,0,0,1,1,1,0,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,0,0,0,1,0,0,0,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1];
track5 = [1,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,1,1,0,1,0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1];
track6 = [1,0,0,0,0,1,0,0,1,1,1,1,1,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,1,0,0,1,1,1,1,1,0,0,1,0,0,1,0,0,0,0,0,0,1,1,1,1,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,1,1,1,1,1,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1,0,0,1,1,1,1,0]; 
}