Categories
Programming

Meow-Meow – Feline Rhythm Machine

Meow-Meow is a rhythm creator which uses cat sounds as its source. I wanted to learn more about Processing, a programming language designed for creating visual and interactive art so took a short course on Creative Programming for Digital Media & Mobile Apps. Part of the work I created for this course was Meow-Meow.

So how does it work? 5 samples can be toggled using the 16-step grid at the bottom of the device. Once triggered the filter and pitch of these sounds can be manipulated by dragging on the cat images at the top of the device.

Meow-Meow works best with a large screen and does not function well on a mobile browser. I’ve begun to re-write this using p5.js, so it can be fully web-based with extra functionality and a more mobile-friendly structure. In the meantime, please enjoy a video of Meow-Meow in action!

Categories
interactive

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]; 
}